diff --git a/.gitignore b/.gitignore index 00dad77..1ff2331 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,35 @@ -node_modules +*~ +*.swp +tmp/ +npm-debug.log +.DS_Store +.idea +merged/ +.next +.vscode/ +node_modules/ +resources.txt .env -coverage -coverage.json +.versionFilesList.json +build/ +bin/ +notes.txt +cache +lepton_data/ typechain typechain-types -# Hardhat files -cache -artifacts +# OpenZeppelin +.openzeppelin/dev-*.json +.openzeppelin/.session +deployments/hardhat/*.json +# Code Coverage +coverage +.coverage +coverage.json +coverageEnv +artifacts +test-results.xml +yarn-error.log +.openzeppelin/unknown-31337.json diff --git a/.nvmrc b/.nvmrc new file mode 100755 index 0000000..72c7744 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +18.12.1 \ No newline at end of file diff --git a/README.md b/README.md index 62e6a07..7e85c1a 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,12 @@ # cpu-v2 Charged Particles Multiverse + +## Deploy + +Using [hardhat deploy](https://github.com/wighawag/hardhat-deploy) hardhat plugin. + +`yarn hardhat deploy --network NETWORK --tags CONTRACT_TAG` + +## Test + +`yarn hardhat test --network hardhat` \ No newline at end of file diff --git a/build/contracts/@openzeppelin/contracts/interfaces/IERC1271.sol/IERC1271.dbg.json b/build/contracts/@openzeppelin/contracts/interfaces/IERC1271.sol/IERC1271.dbg.json deleted file mode 100644 index 2ab51da..0000000 --- a/build/contracts/@openzeppelin/contracts/interfaces/IERC1271.sol/IERC1271.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../../../build-info/00c127ac0f1f040c8525c77a2284410d.json" -} diff --git a/build/contracts/@openzeppelin/contracts/interfaces/IERC1271.sol/IERC1271.json b/build/contracts/@openzeppelin/contracts/interfaces/IERC1271.sol/IERC1271.json deleted file mode 100644 index e8fc09c..0000000 --- a/build/contracts/@openzeppelin/contracts/interfaces/IERC1271.sol/IERC1271.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "IERC1271", - "sourceName": "@openzeppelin/contracts/interfaces/IERC1271.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "bytes32", - "name": "hash", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "signature", - "type": "bytes" - } - ], - "name": "isValidSignature", - "outputs": [ - { - "internalType": "bytes4", - "name": "magicValue", - "type": "bytes4" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "bytecode": "0x", - "deployedBytecode": "0x", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol/IERC1155Receiver.dbg.json b/build/contracts/@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol/IERC1155Receiver.dbg.json deleted file mode 100644 index 0a3aba9..0000000 --- a/build/contracts/@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol/IERC1155Receiver.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../../../../build-info/00c127ac0f1f040c8525c77a2284410d.json" -} diff --git a/build/contracts/@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol/IERC1155Receiver.json b/build/contracts/@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol/IERC1155Receiver.json deleted file mode 100644 index 55daf1e..0000000 --- a/build/contracts/@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol/IERC1155Receiver.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "IERC1155Receiver", - "sourceName": "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "uint256[]", - "name": "ids", - "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "values", - "type": "uint256[]" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "onERC1155BatchReceived", - "outputs": [ - { - "internalType": "bytes4", - "name": "", - "type": "bytes4" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "uint256", - "name": "id", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "onERC1155Received", - "outputs": [ - { - "internalType": "bytes4", - "name": "", - "type": "bytes4" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "bytecode": "0x", - "deployedBytecode": "0x", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/@openzeppelin/contracts/token/ERC721/ERC721.sol/ERC721.dbg.json b/build/contracts/@openzeppelin/contracts/token/ERC721/ERC721.sol/ERC721.dbg.json deleted file mode 100644 index e41b065..0000000 --- a/build/contracts/@openzeppelin/contracts/token/ERC721/ERC721.sol/ERC721.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../../../../build-info/621b40ccb08e9f77631297486483360b.json" -} diff --git a/build/contracts/@openzeppelin/contracts/token/ERC721/ERC721.sol/ERC721.json b/build/contracts/@openzeppelin/contracts/token/ERC721/ERC721.sol/ERC721.json deleted file mode 100644 index a150b39..0000000 --- a/build/contracts/@openzeppelin/contracts/token/ERC721/ERC721.sol/ERC721.json +++ /dev/null @@ -1,357 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "ERC721", - "sourceName": "@openzeppelin/contracts/token/ERC721/ERC721.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "string", - "name": "name_", - "type": "string" - }, - { - "internalType": "string", - "name": "symbol_", - "type": "string" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "approved", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "ApprovalForAll", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "getApproved", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "name": "isApprovedForAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "ownerOf", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "setApprovalForAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "tokenURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x60806040523480156200001157600080fd5b50604051620013e7380380620013e783398101604081905262000034916200011f565b600062000042838262000218565b50600162000051828262000218565b505050620002e4565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200008257600080fd5b81516001600160401b03808211156200009f576200009f6200005a565b604051601f8301601f19908116603f01168101908282118183101715620000ca57620000ca6200005a565b81604052838152602092508683858801011115620000e757600080fd5b600091505b838210156200010b5785820183015181830184015290820190620000ec565b600093810190920192909252949350505050565b600080604083850312156200013357600080fd5b82516001600160401b03808211156200014b57600080fd5b620001598683870162000070565b935060208501519150808211156200017057600080fd5b506200017f8582860162000070565b9150509250929050565b600181811c908216806200019e57607f821691505b602082108103620001bf57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200021357600081815260208120601f850160051c81016020861015620001ee5750805b601f850160051c820191505b818110156200020f57828155600101620001fa565b5050505b505050565b81516001600160401b038111156200023457620002346200005a565b6200024c8162000245845462000189565b84620001c5565b602080601f8311600181146200028457600084156200026b5750858301515b600019600386901b1c1916600185901b1785556200020f565b600085815260208120601f198616915b82811015620002b55788860151825594840194600190910190840162000294565b5085821015620002d45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6110f380620002f46000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c80636352211e1161008c578063a22cb46511610066578063a22cb465146101b3578063b88d4fde146101c6578063c87b56dd146101d9578063e985e9c5146101ec57600080fd5b80636352211e1461017757806370a082311461018a57806395d89b41146101ab57600080fd5b806301ffc9a7146100d457806306fdde03146100fc578063081812fc14610111578063095ea7b31461013c57806323b872dd1461015157806342842e0e14610164575b600080fd5b6100e76100e2366004610c7f565b610228565b60405190151581526020015b60405180910390f35b61010461027a565b6040516100f39190610cec565b61012461011f366004610cff565b61030c565b6040516001600160a01b0390911681526020016100f3565b61014f61014a366004610d34565b610333565b005b61014f61015f366004610d5e565b61044d565b61014f610172366004610d5e565b61047e565b610124610185366004610cff565b610499565b61019d610198366004610d9a565b6104f9565b6040519081526020016100f3565b61010461057f565b61014f6101c1366004610db5565b61058e565b61014f6101d4366004610e07565b61059d565b6101046101e7366004610cff565b6105d5565b6100e76101fa366004610ee3565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60006001600160e01b031982166380ac58cd60e01b148061025957506001600160e01b03198216635b5e139f60e01b145b8061027457506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606000805461028990610f16565b80601f01602080910402602001604051908101604052809291908181526020018280546102b590610f16565b80156103025780601f106102d757610100808354040283529160200191610302565b820191906000526020600020905b8154815290600101906020018083116102e557829003601f168201915b5050505050905090565b600061031782610649565b506000908152600460205260409020546001600160a01b031690565b600061033e82610499565b9050806001600160a01b0316836001600160a01b0316036103b05760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806103cc57506103cc81336101fa565b61043e5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c00000060648201526084016103a7565b61044883836106ab565b505050565b6104573382610719565b6104735760405162461bcd60e51b81526004016103a790610f50565b610448838383610798565b6104488383836040518060200160405280600081525061059d565b6000818152600260205260408120546001600160a01b0316806102745760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103a7565b60006001600160a01b0382166105635760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016103a7565b506001600160a01b031660009081526003602052604090205490565b60606001805461028990610f16565b6105993383836108fc565b5050565b6105a73383610719565b6105c35760405162461bcd60e51b81526004016103a790610f50565b6105cf848484846109ca565b50505050565b60606105e082610649565b60006105f760408051602081019091526000815290565b905060008151116106175760405180602001604052806000815250610642565b80610621846109fd565b604051602001610632929190610f9d565b6040516020818303038152906040525b9392505050565b6000818152600260205260409020546001600160a01b03166106a85760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103a7565b50565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906106e082610499565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061072583610499565b9050806001600160a01b0316846001600160a01b0316148061076c57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b806107905750836001600160a01b03166107858461030c565b6001600160a01b0316145b949350505050565b826001600160a01b03166107ab82610499565b6001600160a01b0316146107d15760405162461bcd60e51b81526004016103a790610fcc565b6001600160a01b0382166108335760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016103a7565b826001600160a01b031661084682610499565b6001600160a01b03161461086c5760405162461bcd60e51b81526004016103a790610fcc565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b816001600160a01b0316836001600160a01b03160361095d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016103a7565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6109d5848484610798565b6109e184848484610a90565b6105cf5760405162461bcd60e51b81526004016103a790611011565b60606000610a0a83610b91565b600101905060008167ffffffffffffffff811115610a2a57610a2a610df1565b6040519080825280601f01601f191660200182016040528015610a54576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084610a5e57509392505050565b60006001600160a01b0384163b15610b8657604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290610ad4903390899088908890600401611063565b6020604051808303816000875af1925050508015610b0f575060408051601f3d908101601f19168201909252610b0c918101906110a0565b60015b610b6c573d808015610b3d576040519150601f19603f3d011682016040523d82523d6000602084013e610b42565b606091505b508051600003610b645760405162461bcd60e51b81526004016103a790611011565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610790565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310610bd05772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310610bfc576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310610c1a57662386f26fc10000830492506010015b6305f5e1008310610c32576305f5e100830492506008015b6127108310610c4657612710830492506004015b60648310610c58576064830492506002015b600a83106102745760010192915050565b6001600160e01b0319811681146106a857600080fd5b600060208284031215610c9157600080fd5b813561064281610c69565b60005b83811015610cb7578181015183820152602001610c9f565b50506000910152565b60008151808452610cd8816020860160208601610c9c565b601f01601f19169290920160200192915050565b6020815260006106426020830184610cc0565b600060208284031215610d1157600080fd5b5035919050565b80356001600160a01b0381168114610d2f57600080fd5b919050565b60008060408385031215610d4757600080fd5b610d5083610d18565b946020939093013593505050565b600080600060608486031215610d7357600080fd5b610d7c84610d18565b9250610d8a60208501610d18565b9150604084013590509250925092565b600060208284031215610dac57600080fd5b61064282610d18565b60008060408385031215610dc857600080fd5b610dd183610d18565b915060208301358015158114610de657600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215610e1d57600080fd5b610e2685610d18565b9350610e3460208601610d18565b925060408501359150606085013567ffffffffffffffff80821115610e5857600080fd5b818701915087601f830112610e6c57600080fd5b813581811115610e7e57610e7e610df1565b604051601f8201601f19908116603f01168101908382118183101715610ea657610ea6610df1565b816040528281528a6020848701011115610ebf57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215610ef657600080fd5b610eff83610d18565b9150610f0d60208401610d18565b90509250929050565b600181811c90821680610f2a57607f821691505b602082108103610f4a57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b60008351610faf818460208801610c9c565b835190830190610fc3818360208801610c9c565b01949350505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061109690830184610cc0565b9695505050505050565b6000602082840312156110b257600080fd5b815161064281610c6956fea2646970667358221220572b001af737f9d43203516808c567baf41baf8d490bb57390158191aafea9c264736f6c63430008110033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c80636352211e1161008c578063a22cb46511610066578063a22cb465146101b3578063b88d4fde146101c6578063c87b56dd146101d9578063e985e9c5146101ec57600080fd5b80636352211e1461017757806370a082311461018a57806395d89b41146101ab57600080fd5b806301ffc9a7146100d457806306fdde03146100fc578063081812fc14610111578063095ea7b31461013c57806323b872dd1461015157806342842e0e14610164575b600080fd5b6100e76100e2366004610c7f565b610228565b60405190151581526020015b60405180910390f35b61010461027a565b6040516100f39190610cec565b61012461011f366004610cff565b61030c565b6040516001600160a01b0390911681526020016100f3565b61014f61014a366004610d34565b610333565b005b61014f61015f366004610d5e565b61044d565b61014f610172366004610d5e565b61047e565b610124610185366004610cff565b610499565b61019d610198366004610d9a565b6104f9565b6040519081526020016100f3565b61010461057f565b61014f6101c1366004610db5565b61058e565b61014f6101d4366004610e07565b61059d565b6101046101e7366004610cff565b6105d5565b6100e76101fa366004610ee3565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60006001600160e01b031982166380ac58cd60e01b148061025957506001600160e01b03198216635b5e139f60e01b145b8061027457506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606000805461028990610f16565b80601f01602080910402602001604051908101604052809291908181526020018280546102b590610f16565b80156103025780601f106102d757610100808354040283529160200191610302565b820191906000526020600020905b8154815290600101906020018083116102e557829003601f168201915b5050505050905090565b600061031782610649565b506000908152600460205260409020546001600160a01b031690565b600061033e82610499565b9050806001600160a01b0316836001600160a01b0316036103b05760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806103cc57506103cc81336101fa565b61043e5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c00000060648201526084016103a7565b61044883836106ab565b505050565b6104573382610719565b6104735760405162461bcd60e51b81526004016103a790610f50565b610448838383610798565b6104488383836040518060200160405280600081525061059d565b6000818152600260205260408120546001600160a01b0316806102745760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103a7565b60006001600160a01b0382166105635760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016103a7565b506001600160a01b031660009081526003602052604090205490565b60606001805461028990610f16565b6105993383836108fc565b5050565b6105a73383610719565b6105c35760405162461bcd60e51b81526004016103a790610f50565b6105cf848484846109ca565b50505050565b60606105e082610649565b60006105f760408051602081019091526000815290565b905060008151116106175760405180602001604052806000815250610642565b80610621846109fd565b604051602001610632929190610f9d565b6040516020818303038152906040525b9392505050565b6000818152600260205260409020546001600160a01b03166106a85760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103a7565b50565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906106e082610499565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061072583610499565b9050806001600160a01b0316846001600160a01b0316148061076c57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b806107905750836001600160a01b03166107858461030c565b6001600160a01b0316145b949350505050565b826001600160a01b03166107ab82610499565b6001600160a01b0316146107d15760405162461bcd60e51b81526004016103a790610fcc565b6001600160a01b0382166108335760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016103a7565b826001600160a01b031661084682610499565b6001600160a01b03161461086c5760405162461bcd60e51b81526004016103a790610fcc565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b816001600160a01b0316836001600160a01b03160361095d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016103a7565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6109d5848484610798565b6109e184848484610a90565b6105cf5760405162461bcd60e51b81526004016103a790611011565b60606000610a0a83610b91565b600101905060008167ffffffffffffffff811115610a2a57610a2a610df1565b6040519080825280601f01601f191660200182016040528015610a54576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084610a5e57509392505050565b60006001600160a01b0384163b15610b8657604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290610ad4903390899088908890600401611063565b6020604051808303816000875af1925050508015610b0f575060408051601f3d908101601f19168201909252610b0c918101906110a0565b60015b610b6c573d808015610b3d576040519150601f19603f3d011682016040523d82523d6000602084013e610b42565b606091505b508051600003610b645760405162461bcd60e51b81526004016103a790611011565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610790565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310610bd05772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310610bfc576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310610c1a57662386f26fc10000830492506010015b6305f5e1008310610c32576305f5e100830492506008015b6127108310610c4657612710830492506004015b60648310610c58576064830492506002015b600a83106102745760010192915050565b6001600160e01b0319811681146106a857600080fd5b600060208284031215610c9157600080fd5b813561064281610c69565b60005b83811015610cb7578181015183820152602001610c9f565b50506000910152565b60008151808452610cd8816020860160208601610c9c565b601f01601f19169290920160200192915050565b6020815260006106426020830184610cc0565b600060208284031215610d1157600080fd5b5035919050565b80356001600160a01b0381168114610d2f57600080fd5b919050565b60008060408385031215610d4757600080fd5b610d5083610d18565b946020939093013593505050565b600080600060608486031215610d7357600080fd5b610d7c84610d18565b9250610d8a60208501610d18565b9150604084013590509250925092565b600060208284031215610dac57600080fd5b61064282610d18565b60008060408385031215610dc857600080fd5b610dd183610d18565b915060208301358015158114610de657600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215610e1d57600080fd5b610e2685610d18565b9350610e3460208601610d18565b925060408501359150606085013567ffffffffffffffff80821115610e5857600080fd5b818701915087601f830112610e6c57600080fd5b813581811115610e7e57610e7e610df1565b604051601f8201601f19908116603f01168101908382118183101715610ea657610ea6610df1565b816040528281528a6020848701011115610ebf57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215610ef657600080fd5b610eff83610d18565b9150610f0d60208401610d18565b90509250929050565b600181811c90821680610f2a57607f821691505b602082108103610f4a57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b60008351610faf818460208801610c9c565b835190830190610fc3818360208801610c9c565b01949350505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061109690830184610cc0565b9695505050505050565b6000602082840312156110b257600080fd5b815161064281610c6956fea2646970667358221220572b001af737f9d43203516808c567baf41baf8d490bb57390158191aafea9c264736f6c63430008110033", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/@openzeppelin/contracts/token/ERC721/IERC721.sol/IERC721.dbg.json b/build/contracts/@openzeppelin/contracts/token/ERC721/IERC721.sol/IERC721.dbg.json deleted file mode 100644 index e41b065..0000000 --- a/build/contracts/@openzeppelin/contracts/token/ERC721/IERC721.sol/IERC721.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../../../../build-info/621b40ccb08e9f77631297486483360b.json" -} diff --git a/build/contracts/@openzeppelin/contracts/token/ERC721/IERC721.sol/IERC721.json b/build/contracts/@openzeppelin/contracts/token/ERC721/IERC721.sol/IERC721.json deleted file mode 100644 index 3677fd6..0000000 --- a/build/contracts/@openzeppelin/contracts/token/ERC721/IERC721.sol/IERC721.json +++ /dev/null @@ -1,296 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "IERC721", - "sourceName": "@openzeppelin/contracts/token/ERC721/IERC721.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "approved", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "ApprovalForAll", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "getApproved", - "outputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "name": "isApprovedForAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "ownerOf", - "outputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "setApprovalForAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x", - "deployedBytecode": "0x", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol/IERC721Receiver.dbg.json b/build/contracts/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol/IERC721Receiver.dbg.json deleted file mode 100644 index e41b065..0000000 --- a/build/contracts/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol/IERC721Receiver.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../../../../build-info/621b40ccb08e9f77631297486483360b.json" -} diff --git a/build/contracts/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol/IERC721Receiver.json b/build/contracts/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol/IERC721Receiver.json deleted file mode 100644 index e91c7b0..0000000 --- a/build/contracts/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol/IERC721Receiver.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "IERC721Receiver", - "sourceName": "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "onERC721Received", - "outputs": [ - { - "internalType": "bytes4", - "name": "", - "type": "bytes4" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x", - "deployedBytecode": "0x", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol/IERC721Metadata.dbg.json b/build/contracts/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol/IERC721Metadata.dbg.json deleted file mode 100644 index 92c778e..0000000 --- a/build/contracts/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol/IERC721Metadata.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../../../../../build-info/621b40ccb08e9f77631297486483360b.json" -} diff --git a/build/contracts/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol/IERC721Metadata.json b/build/contracts/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol/IERC721Metadata.json deleted file mode 100644 index 4eea2c2..0000000 --- a/build/contracts/@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol/IERC721Metadata.json +++ /dev/null @@ -1,341 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "IERC721Metadata", - "sourceName": "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "approved", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "ApprovalForAll", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "getApproved", - "outputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "name": "isApprovedForAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "ownerOf", - "outputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "setApprovalForAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "tokenURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x", - "deployedBytecode": "0x", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/@openzeppelin/contracts/utils/Address.sol/Address.dbg.json b/build/contracts/@openzeppelin/contracts/utils/Address.sol/Address.dbg.json deleted file mode 100644 index 17ad65d..0000000 --- a/build/contracts/@openzeppelin/contracts/utils/Address.sol/Address.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../../../build-info/621b40ccb08e9f77631297486483360b.json" -} diff --git a/build/contracts/@openzeppelin/contracts/utils/Address.sol/Address.json b/build/contracts/@openzeppelin/contracts/utils/Address.sol/Address.json deleted file mode 100644 index 542087b..0000000 --- a/build/contracts/@openzeppelin/contracts/utils/Address.sol/Address.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "Address", - "sourceName": "@openzeppelin/contracts/utils/Address.sol", - "abi": [], - "bytecode": "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c2f66f9f178ece4a6dd98f884b5a0716b0971dd5e11c4840c20ebf4ae264a08a64736f6c63430008110033", - "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c2f66f9f178ece4a6dd98f884b5a0716b0971dd5e11c4840c20ebf4ae264a08a64736f6c63430008110033", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/@openzeppelin/contracts/utils/Context.sol/Context.dbg.json b/build/contracts/@openzeppelin/contracts/utils/Context.sol/Context.dbg.json deleted file mode 100644 index 17ad65d..0000000 --- a/build/contracts/@openzeppelin/contracts/utils/Context.sol/Context.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../../../build-info/621b40ccb08e9f77631297486483360b.json" -} diff --git a/build/contracts/@openzeppelin/contracts/utils/Context.sol/Context.json b/build/contracts/@openzeppelin/contracts/utils/Context.sol/Context.json deleted file mode 100644 index 8fe86fc..0000000 --- a/build/contracts/@openzeppelin/contracts/utils/Context.sol/Context.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "Context", - "sourceName": "@openzeppelin/contracts/utils/Context.sol", - "abi": [], - "bytecode": "0x", - "deployedBytecode": "0x", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/@openzeppelin/contracts/utils/Strings.sol/Strings.dbg.json b/build/contracts/@openzeppelin/contracts/utils/Strings.sol/Strings.dbg.json deleted file mode 100644 index 17ad65d..0000000 --- a/build/contracts/@openzeppelin/contracts/utils/Strings.sol/Strings.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../../../build-info/621b40ccb08e9f77631297486483360b.json" -} diff --git a/build/contracts/@openzeppelin/contracts/utils/Strings.sol/Strings.json b/build/contracts/@openzeppelin/contracts/utils/Strings.sol/Strings.json deleted file mode 100644 index ecb3cff..0000000 --- a/build/contracts/@openzeppelin/contracts/utils/Strings.sol/Strings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "Strings", - "sourceName": "@openzeppelin/contracts/utils/Strings.sol", - "abi": [], - "bytecode": "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207228005f573e7589cb774d97bd31101840930508a97597061bccc052adec739964736f6c63430008110033", - "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207228005f573e7589cb774d97bd31101840930508a97597061bccc052adec739964736f6c63430008110033", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/@openzeppelin/contracts/utils/introspection/ERC165.sol/ERC165.dbg.json b/build/contracts/@openzeppelin/contracts/utils/introspection/ERC165.sol/ERC165.dbg.json deleted file mode 100644 index e41b065..0000000 --- a/build/contracts/@openzeppelin/contracts/utils/introspection/ERC165.sol/ERC165.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../../../../build-info/621b40ccb08e9f77631297486483360b.json" -} diff --git a/build/contracts/@openzeppelin/contracts/utils/introspection/ERC165.sol/ERC165.json b/build/contracts/@openzeppelin/contracts/utils/introspection/ERC165.sol/ERC165.json deleted file mode 100644 index 1304472..0000000 --- a/build/contracts/@openzeppelin/contracts/utils/introspection/ERC165.sol/ERC165.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "ERC165", - "sourceName": "@openzeppelin/contracts/utils/introspection/ERC165.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "bytecode": "0x", - "deployedBytecode": "0x", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/@openzeppelin/contracts/utils/introspection/IERC165.sol/IERC165.dbg.json b/build/contracts/@openzeppelin/contracts/utils/introspection/IERC165.sol/IERC165.dbg.json deleted file mode 100644 index e41b065..0000000 --- a/build/contracts/@openzeppelin/contracts/utils/introspection/IERC165.sol/IERC165.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../../../../build-info/621b40ccb08e9f77631297486483360b.json" -} diff --git a/build/contracts/@openzeppelin/contracts/utils/introspection/IERC165.sol/IERC165.json b/build/contracts/@openzeppelin/contracts/utils/introspection/IERC165.sol/IERC165.json deleted file mode 100644 index ff87f91..0000000 --- a/build/contracts/@openzeppelin/contracts/utils/introspection/IERC165.sol/IERC165.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "IERC165", - "sourceName": "@openzeppelin/contracts/utils/introspection/IERC165.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "bytecode": "0x", - "deployedBytecode": "0x", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/@openzeppelin/contracts/utils/math/Math.sol/Math.dbg.json b/build/contracts/@openzeppelin/contracts/utils/math/Math.sol/Math.dbg.json deleted file mode 100644 index e41b065..0000000 --- a/build/contracts/@openzeppelin/contracts/utils/math/Math.sol/Math.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../../../../build-info/621b40ccb08e9f77631297486483360b.json" -} diff --git a/build/contracts/@openzeppelin/contracts/utils/math/Math.sol/Math.json b/build/contracts/@openzeppelin/contracts/utils/math/Math.sol/Math.json deleted file mode 100644 index 62b19d8..0000000 --- a/build/contracts/@openzeppelin/contracts/utils/math/Math.sol/Math.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "Math", - "sourceName": "@openzeppelin/contracts/utils/math/Math.sol", - "abi": [], - "bytecode": "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212201de9e51b61992d4bc0178d54aa4499e531ca713ec14b54fe65ee03323d4b33a064736f6c63430008110033", - "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212201de9e51b61992d4bc0178d54aa4499e531ca713ec14b54fe65ee03323d4b33a064736f6c63430008110033", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/@openzeppelin/contracts/utils/math/SignedMath.sol/SignedMath.dbg.json b/build/contracts/@openzeppelin/contracts/utils/math/SignedMath.sol/SignedMath.dbg.json deleted file mode 100644 index e41b065..0000000 --- a/build/contracts/@openzeppelin/contracts/utils/math/SignedMath.sol/SignedMath.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../../../../build-info/621b40ccb08e9f77631297486483360b.json" -} diff --git a/build/contracts/@openzeppelin/contracts/utils/math/SignedMath.sol/SignedMath.json b/build/contracts/@openzeppelin/contracts/utils/math/SignedMath.sol/SignedMath.json deleted file mode 100644 index f4acd16..0000000 --- a/build/contracts/@openzeppelin/contracts/utils/math/SignedMath.sol/SignedMath.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "SignedMath", - "sourceName": "@openzeppelin/contracts/utils/math/SignedMath.sol", - "abi": [], - "bytecode": "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208d3d0f2f473dd5525584eea797d24f2cc2a25b02da4b2a4e93effba473dba0d064736f6c63430008110033", - "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208d3d0f2f473dd5525584eea797d24f2cc2a25b02da4b2a4e93effba473dba0d064736f6c63430008110033", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/build-info/00c127ac0f1f040c8525c77a2284410d.json b/build/contracts/build-info/00c127ac0f1f040c8525c77a2284410d.json deleted file mode 100644 index f6f71ec..0000000 --- a/build/contracts/build-info/00c127ac0f1f040c8525c77a2284410d.json +++ /dev/null @@ -1 +0,0 @@ -{"id":"00c127ac0f1f040c8525c77a2284410d","_format":"hh-sol-build-info-1","solcVersion":"0.8.17","solcLongVersion":"0.8.17+commit.8df45f5f","input":{"language":"Solidity","sources":{"@openzeppelin/contracts/interfaces/IERC1271.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n"},"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (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 *\n * NOTE: 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 *\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.\n *\n * NOTE: 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 *\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/token/ERC721/IERC721.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (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`.\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(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\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(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"},"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface 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 `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"},"@openzeppelin/contracts/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"},"contracts/AccountRegistryBridge.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.13;\n\nimport \"./interfaces/IRegistry.sol\";\ncontract AccountRegistryBridge {\n address public constant REGISTRY = \t0x02101dfB77FDE026414827Fdc604ddAF224F0921;\n address public constant IMPLMENTATION = 0x2D25602551487C3f3354dD80D76D54383A243358;\n\n function createAccount(address contractAddress, uint256 tokenId)\n external\n returns (address)\n {\n return IRegistry(REGISTRY).createAccount(\n IMPLMENTATION,\n block.chainid,\n contractAddress,\n tokenId,\n 0,\n ''\n );\n }\n\n function account(address contractAddress, uint256 tokenId)\n external\n view\n returns (address)\n {\n return IRegistry(REGISTRY).account(\n IMPLMENTATION,\n block.chainid,\n contractAddress,\n tokenId,\n 0\n );\n }\n}"},"contracts/ChargedParticles.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.13;\n\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./AccountRegistryBridge.sol\";\n\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\ncontract ChargedParticles is AccountRegistryBridge {\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n ) external returns (uint256 yieldTokensAmount) {\n \n }\n\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount) {\n\n }\n\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount) {\n\n }\n\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 receiverAmount) {\n\n }\n\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount) {\n\n }\n\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount) {\n\n }\n\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success) {\n address tokenBoundAccount = this.account(contractAddress, tokenId); \n IERC721(nftTokenAddress).safeTransferFrom(msg.sender, tokenBoundAccount, nftTokenId);\n }\n\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success) {\n address tokenBoundAccount = this.account(contractAddress, tokenId); \n IERC721(nftTokenAddress).safeTransferFrom(tokenBoundAccount, receiver, nftTokenId);\n }\n\n}\n"},"contracts/interfaces/IChargedParticles.sol":{"content":"// SPDX-License-Identifier: MIT\n\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Charged Particles\n */\ninterface IChargedParticles {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getStateAddress() external view returns (address stateAddress);\n function getSettingsAddress() external view returns (address settingsAddress);\n function getManagersAddress() external view returns (address managersAddress);\n\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\n\n /***********************************|\n | Particle Mechanics |\n |__________________________________*/\n\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n ) external returns (uint256 yieldTokensAmount);\n\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 receiverAmount);\n\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n}\n"},"contracts/interfaces/IERC6551Account.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\ninterface IERC6551AccountProxy {\n function implementation() external view returns (address);\n}\n\n/// @dev the ERC-165 identifier for this interface is `0xeff4d378`\ninterface IERC6551Account {\n event TransactionExecuted(address indexed target, uint256 indexed value, bytes data);\n\n receive() external payable;\n\n function executeCall(\n address to,\n uint256 value,\n bytes calldata data\n ) external payable returns (bytes memory);\n\n function token()\n external\n view\n returns (uint256 chainId, address tokenContract, uint256 tokenId);\n\n function owner() external view returns (address);\n}\n"},"contracts/interfaces/IRegistry.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\ninterface IRegistry {\n function createAccount(\n address implementation,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId,\n uint256 salt,\n bytes calldata initData\n ) external returns (address);\n\n function account(\n address implementation,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId,\n uint256 salt\n ) external view returns (address);\n}\n"},"contracts/lib/ERC6551AccountLib.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\nlibrary ERC6551AccountLib {\n function token()\n internal\n view\n returns (\n uint256,\n address,\n uint256\n )\n {\n bytes memory footer = new bytes(0x60);\n\n assembly {\n // copy 0x60 bytes from end of footer\n extcodecopy(address(), add(footer, 0x20), 0x4d, 0xad)\n }\n\n return abi.decode(footer, (uint256, address, uint256));\n }\n\n function salt() internal view returns (uint256) {\n bytes memory footer = new bytes(0x20);\n\n assembly {\n // copy 0x20 bytes from beginning of footer\n extcodecopy(address(), add(footer, 0x20), 0x2d, 0x4d)\n }\n\n return abi.decode(footer, (uint256));\n }\n}\n"},"contracts/MinimalisticAccount.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\nimport \"./interfaces/IERC6551Account.sol\";\nimport \"./lib/ERC6551AccountLib.sol\";\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC1271.sol\";\n\nerror NotAuthorized();\nerror InvalidInput();\nerror AccountLocked();\nerror ExceedsMaxLockTime();\nerror UntrustedImplementation();\nerror OwnershipCycle();\n\n/**\n * @title A smart contract account owned by a single ERC721 token\n */\ncontract MinimalisticAccount is\n IERC165,\n IERC6551Account,\n IERC721Receiver,\n IERC1155Receiver\n{\n /// @dev timestamp at which this account will be unlocked\n uint256 public lockedUntil;\n\n /// @dev mapping from owner => caller => has permissions\n mapping(address => mapping(address => bool)) public permissions;\n\n event OverrideUpdated(\n address owner,\n bytes4 selector,\n address implementation\n );\n\n event PermissionUpdated(address owner, address caller, bool hasPermission);\n\n event LockUpdated(uint256 lockedUntil);\n\n /// @dev reverts if caller is not the owner of the account\n modifier onlyOwner() {\n if (msg.sender != owner()) revert NotAuthorized();\n _;\n }\n\n /// @dev reverts if caller is not authorized to execute on this account\n modifier onlyAuthorized() {\n if (!isAuthorized(msg.sender)) revert NotAuthorized();\n _;\n }\n\n /// @dev reverts if this account is currently locked\n modifier onlyUnlocked() {\n if (isLocked()) revert AccountLocked();\n _;\n }\n\n constructor() {}\n\n /// @dev allows eth transfers by default, but allows account owner to override\n receive() external payable {\n }\n\n /// @dev executes a low-level call against an account if the caller is authorized to make calls\n function executeCall(\n address to,\n uint256 value,\n bytes calldata data\n ) external payable onlyAuthorized onlyUnlocked returns (bytes memory) {\n emit TransactionExecuted(to, value, data);\n\n return _call(to, value, data);\n }\n\n /// @dev grants a given caller execution permissions\n function setPermissions(\n address[] calldata callers,\n bool[] calldata _permissions\n ) external onlyUnlocked {\n address _owner = owner();\n if (msg.sender != _owner) revert NotAuthorized();\n\n uint256 length = callers.length;\n\n if (_permissions.length != length) revert InvalidInput();\n\n for (uint256 i = 0; i < length; i++) {\n permissions[_owner][callers[i]] = _permissions[i];\n emit PermissionUpdated(_owner, callers[i], _permissions[i]);\n }\n }\n\n /// @dev locks the account until a certain timestamp\n function lock(uint256 _lockedUntil) external onlyOwner onlyUnlocked {\n if (_lockedUntil > block.timestamp + 365 days)\n revert ExceedsMaxLockTime();\n\n lockedUntil = _lockedUntil;\n\n emit LockUpdated(_lockedUntil);\n }\n\n /// @dev returns the current lock status of the account as a boolean\n function isLocked() public view returns (bool) {\n return lockedUntil > block.timestamp;\n }\n\n /// @dev Returns the EIP-155 chain ID, token contract address, and token ID for the token that\n /// owns this account.\n function token()\n external\n view\n returns (\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n )\n {\n return ERC6551AccountLib.token();\n }\n\n /// @dev Returns the owner of the ERC-721 token which owns this account. By default, the owner\n /// of the token has full permissions on the account.\n function owner() public view returns (address) {\n (\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) = ERC6551AccountLib.token();\n\n if (chainId != block.chainid) return address(0);\n\n return IERC721(tokenContract).ownerOf(tokenId);\n }\n\n /// @dev Returns the authorization status for a given caller\n function isAuthorized(address caller) public view returns (bool) {\n (\n ,\n address tokenContract,\n uint256 tokenId\n ) = ERC6551AccountLib.token();\n address _owner = IERC721(tokenContract).ownerOf(tokenId);\n\n // authorize token owner\n if (caller == _owner) return true;\n\n // authorize caller if owner has granted permissions\n if (permissions[_owner][caller]) return true;\n\n return false;\n }\n\n /// @dev Returns true if a given interfaceId is supported by this account. This method can be\n /// extended by an override.\n function supportsInterface(bytes4 interfaceId)\n public\n pure \n override\n returns (bool)\n {\n bool defaultSupport = interfaceId == type(IERC165).interfaceId ||\n interfaceId == type(IERC1155Receiver).interfaceId ||\n interfaceId == type(IERC6551Account).interfaceId;\n\n if (defaultSupport) return true;\n\n return false;\n }\n\n /// @dev Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle.\n /// This function can be overriden.\n function onERC721Received(\n address,\n address,\n uint256 receivedTokenId,\n bytes memory\n ) public view override returns (bytes4) {\n (\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) = ERC6551AccountLib.token();\n\n if (\n chainId == block.chainid &&\n tokenContract == msg.sender &&\n tokenId == receivedTokenId\n ) revert OwnershipCycle();\n\n return this.onERC721Received.selector;\n }\n\n /// @dev Allows ERC-1155 tokens to be received. This function can be overriden.\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes memory\n ) public pure override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n /// @dev Allows ERC-1155 token batches to be received. This function can be overriden.\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] memory,\n uint256[] memory,\n bytes memory\n ) public pure override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n\n /// @dev Executes a low-level call\n function _call(\n address to,\n uint256 value,\n bytes calldata data\n ) internal returns (bytes memory result) {\n bool success;\n (success, result) = to.call{value: value}(data);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /// @dev Executes a low-level static call\n function _callStatic(address to, bytes calldata data)\n internal\n view\n returns (bytes memory result)\n {\n bool success;\n (success, result) = to.staticcall(data);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n}\n"}},"settings":{"optimizer":{"enabled":true,"runs":200},"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata","devdoc","userdoc","storageLayout","evm.gasEstimates"],"":["ast"]}},"metadata":{"useLiteralContent":true}}},"output":{"errors":[{"component":"general","errorCode":"5667","formattedMessage":"Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.\n --> contracts/ChargedParticles.sol:77:9:\n |\n77 | string calldata basketManagerId,\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n","message":"Unused function parameter. Remove or comment out the variable name to silence this warning.","severity":"warning","sourceLocation":{"end":2067,"file":"contracts/ChargedParticles.sol","start":2036},"type":"Warning"},{"component":"general","errorCode":"5667","formattedMessage":"Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.\n --> contracts/ChargedParticles.sol:80:9:\n |\n80 | uint256 nftTokenAmount\n | ^^^^^^^^^^^^^^^^^^^^^^\n\n","message":"Unused function parameter. Remove or comment out the variable name to silence this warning.","severity":"warning","sourceLocation":{"end":2160,"file":"contracts/ChargedParticles.sol","start":2138},"type":"Warning"},{"component":"general","errorCode":"5667","formattedMessage":"Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.\n --> contracts/ChargedParticles.sol:81:25:\n |\n81 | ) external returns (bool success) {\n | ^^^^^^^^^^^^\n\n","message":"Unused function parameter. Remove or comment out the variable name to silence this warning.","severity":"warning","sourceLocation":{"end":2197,"file":"contracts/ChargedParticles.sol","start":2185},"type":"Warning"},{"component":"general","errorCode":"5667","formattedMessage":"Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.\n --> contracts/ChargedParticles.sol:90:9:\n |\n90 | string calldata basketManagerId,\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n","message":"Unused function parameter. Remove or comment out the variable name to silence this warning.","severity":"warning","sourceLocation":{"end":2534,"file":"contracts/ChargedParticles.sol","start":2503},"type":"Warning"},{"component":"general","errorCode":"5667","formattedMessage":"Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.\n --> contracts/ChargedParticles.sol:93:9:\n |\n93 | uint256 nftTokenAmount\n | ^^^^^^^^^^^^^^^^^^^^^^\n\n","message":"Unused function parameter. Remove or comment out the variable name to silence this warning.","severity":"warning","sourceLocation":{"end":2627,"file":"contracts/ChargedParticles.sol","start":2605},"type":"Warning"},{"component":"general","errorCode":"5667","formattedMessage":"Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.\n --> contracts/ChargedParticles.sol:94:25:\n |\n94 | ) external returns (bool success) {\n | ^^^^^^^^^^^^\n\n","message":"Unused function parameter. Remove or comment out the variable name to silence this warning.","severity":"warning","sourceLocation":{"end":2664,"file":"contracts/ChargedParticles.sol","start":2652},"type":"Warning"}],"sources":{"@openzeppelin/contracts/interfaces/IERC1271.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/interfaces/IERC1271.sol","exportedSymbols":{"IERC1271":[13]},"id":14,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":1,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"92:23:0"},{"abstract":false,"baseContracts":[],"canonicalName":"IERC1271","contractDependencies":[],"contractKind":"interface","documentation":{"id":2,"nodeType":"StructuredDocumentation","src":"117:189:0","text":" @dev Interface of the ERC1271 standard signature validation method for\n contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n _Available since v4.1._"},"fullyImplemented":false,"id":13,"linearizedBaseContracts":[13],"name":"IERC1271","nameLocation":"317:8:0","nodeType":"ContractDefinition","nodes":[{"documentation":{"id":3,"nodeType":"StructuredDocumentation","src":"332:220:0","text":" @dev Should return whether the signature provided is valid for the provided data\n @param hash Hash of the data to be signed\n @param signature Signature byte array associated with _data"},"functionSelector":"1626ba7e","id":12,"implemented":false,"kind":"function","modifiers":[],"name":"isValidSignature","nameLocation":"566:16:0","nodeType":"FunctionDefinition","parameters":{"id":8,"nodeType":"ParameterList","parameters":[{"constant":false,"id":5,"mutability":"mutable","name":"hash","nameLocation":"591:4:0","nodeType":"VariableDeclaration","scope":12,"src":"583:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"},"typeName":{"id":4,"name":"bytes32","nodeType":"ElementaryTypeName","src":"583:7:0","typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}},"visibility":"internal"},{"constant":false,"id":7,"mutability":"mutable","name":"signature","nameLocation":"610:9:0","nodeType":"VariableDeclaration","scope":12,"src":"597:22:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":6,"name":"bytes","nodeType":"ElementaryTypeName","src":"597:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"582:38:0"},"returnParameters":{"id":11,"nodeType":"ParameterList","parameters":[{"constant":false,"id":10,"mutability":"mutable","name":"magicValue","nameLocation":"651:10:0","nodeType":"VariableDeclaration","scope":12,"src":"644:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":9,"name":"bytes4","nodeType":"ElementaryTypeName","src":"644:6:0","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"643:19:0"},"scope":13,"src":"557:106:0","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":14,"src":"307:358:0","usedErrors":[]}],"src":"92:574:0"},"id":0},"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol","exportedSymbols":{"IERC1155Receiver":[54],"IERC165":[200]},"id":55,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":15,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"118:23:1"},{"absolutePath":"@openzeppelin/contracts/utils/introspection/IERC165.sol","file":"../../utils/introspection/IERC165.sol","id":16,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":55,"sourceUnit":201,"src":"143:47:1","symbolAliases":[],"unitAlias":""},{"abstract":false,"baseContracts":[{"baseName":{"id":18,"name":"IERC165","nameLocations":["262:7:1"],"nodeType":"IdentifierPath","referencedDeclaration":200,"src":"262:7:1"},"id":19,"nodeType":"InheritanceSpecifier","src":"262:7:1"}],"canonicalName":"IERC1155Receiver","contractDependencies":[],"contractKind":"interface","documentation":{"id":17,"nodeType":"StructuredDocumentation","src":"192:39:1","text":" @dev _Available since v3.1._"},"fullyImplemented":false,"id":54,"linearizedBaseContracts":[54,200],"name":"IERC1155Receiver","nameLocation":"242:16:1","nodeType":"ContractDefinition","nodes":[{"documentation":{"id":20,"nodeType":"StructuredDocumentation","src":"276:826:1","text":" @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 NOTE: 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"},"functionSelector":"f23a6e61","id":35,"implemented":false,"kind":"function","modifiers":[],"name":"onERC1155Received","nameLocation":"1116:17:1","nodeType":"FunctionDefinition","parameters":{"id":31,"nodeType":"ParameterList","parameters":[{"constant":false,"id":22,"mutability":"mutable","name":"operator","nameLocation":"1151:8:1","nodeType":"VariableDeclaration","scope":35,"src":"1143:16:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":21,"name":"address","nodeType":"ElementaryTypeName","src":"1143:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":24,"mutability":"mutable","name":"from","nameLocation":"1177:4:1","nodeType":"VariableDeclaration","scope":35,"src":"1169:12:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":23,"name":"address","nodeType":"ElementaryTypeName","src":"1169:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":26,"mutability":"mutable","name":"id","nameLocation":"1199:2:1","nodeType":"VariableDeclaration","scope":35,"src":"1191:10:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":25,"name":"uint256","nodeType":"ElementaryTypeName","src":"1191:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":28,"mutability":"mutable","name":"value","nameLocation":"1219:5:1","nodeType":"VariableDeclaration","scope":35,"src":"1211:13:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":27,"name":"uint256","nodeType":"ElementaryTypeName","src":"1211:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":30,"mutability":"mutable","name":"data","nameLocation":"1249:4:1","nodeType":"VariableDeclaration","scope":35,"src":"1234:19:1","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":29,"name":"bytes","nodeType":"ElementaryTypeName","src":"1234:5:1","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1133:126:1"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[{"constant":false,"id":33,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":35,"src":"1278:6:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":32,"name":"bytes4","nodeType":"ElementaryTypeName","src":"1278:6:1","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"1277:8:1"},"scope":54,"src":"1107:179:1","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":36,"nodeType":"StructuredDocumentation","src":"1292:994:1","text":" @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.\n NOTE: 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"},"functionSelector":"bc197c81","id":53,"implemented":false,"kind":"function","modifiers":[],"name":"onERC1155BatchReceived","nameLocation":"2300:22:1","nodeType":"FunctionDefinition","parameters":{"id":49,"nodeType":"ParameterList","parameters":[{"constant":false,"id":38,"mutability":"mutable","name":"operator","nameLocation":"2340:8:1","nodeType":"VariableDeclaration","scope":53,"src":"2332:16:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":37,"name":"address","nodeType":"ElementaryTypeName","src":"2332:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":40,"mutability":"mutable","name":"from","nameLocation":"2366:4:1","nodeType":"VariableDeclaration","scope":53,"src":"2358:12:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":39,"name":"address","nodeType":"ElementaryTypeName","src":"2358:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":43,"mutability":"mutable","name":"ids","nameLocation":"2399:3:1","nodeType":"VariableDeclaration","scope":53,"src":"2380:22:1","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_calldata_ptr","typeString":"uint256[]"},"typeName":{"baseType":{"id":41,"name":"uint256","nodeType":"ElementaryTypeName","src":"2380:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":42,"nodeType":"ArrayTypeName","src":"2380:9:1","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_storage_ptr","typeString":"uint256[]"}},"visibility":"internal"},{"constant":false,"id":46,"mutability":"mutable","name":"values","nameLocation":"2431:6:1","nodeType":"VariableDeclaration","scope":53,"src":"2412:25:1","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_calldata_ptr","typeString":"uint256[]"},"typeName":{"baseType":{"id":44,"name":"uint256","nodeType":"ElementaryTypeName","src":"2412:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":45,"nodeType":"ArrayTypeName","src":"2412:9:1","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_storage_ptr","typeString":"uint256[]"}},"visibility":"internal"},{"constant":false,"id":48,"mutability":"mutable","name":"data","nameLocation":"2462:4:1","nodeType":"VariableDeclaration","scope":53,"src":"2447:19:1","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":47,"name":"bytes","nodeType":"ElementaryTypeName","src":"2447:5:1","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"2322:150:1"},"returnParameters":{"id":52,"nodeType":"ParameterList","parameters":[{"constant":false,"id":51,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":53,"src":"2491:6:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":50,"name":"bytes4","nodeType":"ElementaryTypeName","src":"2491:6:1","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"2490:8:1"},"scope":54,"src":"2291:208:1","stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"scope":55,"src":"232:2269:1","usedErrors":[]}],"src":"118:2384:1"},"id":1},"@openzeppelin/contracts/token/ERC721/IERC721.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721.sol","exportedSymbols":{"IERC165":[200],"IERC721":[170]},"id":171,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":56,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"108:23:2"},{"absolutePath":"@openzeppelin/contracts/utils/introspection/IERC165.sol","file":"../../utils/introspection/IERC165.sol","id":57,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":171,"sourceUnit":201,"src":"133:47:2","symbolAliases":[],"unitAlias":""},{"abstract":false,"baseContracts":[{"baseName":{"id":59,"name":"IERC165","nameLocations":["271:7:2"],"nodeType":"IdentifierPath","referencedDeclaration":200,"src":"271:7:2"},"id":60,"nodeType":"InheritanceSpecifier","src":"271:7:2"}],"canonicalName":"IERC721","contractDependencies":[],"contractKind":"interface","documentation":{"id":58,"nodeType":"StructuredDocumentation","src":"182:67:2","text":" @dev Required interface of an ERC721 compliant contract."},"fullyImplemented":false,"id":170,"linearizedBaseContracts":[170,200],"name":"IERC721","nameLocation":"260:7:2","nodeType":"ContractDefinition","nodes":[{"anonymous":false,"documentation":{"id":61,"nodeType":"StructuredDocumentation","src":"285:88:2","text":" @dev Emitted when `tokenId` token is transferred from `from` to `to`."},"eventSelector":"ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","id":69,"name":"Transfer","nameLocation":"384:8:2","nodeType":"EventDefinition","parameters":{"id":68,"nodeType":"ParameterList","parameters":[{"constant":false,"id":63,"indexed":true,"mutability":"mutable","name":"from","nameLocation":"409:4:2","nodeType":"VariableDeclaration","scope":69,"src":"393:20:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":62,"name":"address","nodeType":"ElementaryTypeName","src":"393:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":65,"indexed":true,"mutability":"mutable","name":"to","nameLocation":"431:2:2","nodeType":"VariableDeclaration","scope":69,"src":"415:18:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":64,"name":"address","nodeType":"ElementaryTypeName","src":"415:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":67,"indexed":true,"mutability":"mutable","name":"tokenId","nameLocation":"451:7:2","nodeType":"VariableDeclaration","scope":69,"src":"435:23:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":66,"name":"uint256","nodeType":"ElementaryTypeName","src":"435:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"392:67:2"},"src":"378:82:2"},{"anonymous":false,"documentation":{"id":70,"nodeType":"StructuredDocumentation","src":"466:94:2","text":" @dev Emitted when `owner` enables `approved` to manage the `tokenId` token."},"eventSelector":"8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925","id":78,"name":"Approval","nameLocation":"571:8:2","nodeType":"EventDefinition","parameters":{"id":77,"nodeType":"ParameterList","parameters":[{"constant":false,"id":72,"indexed":true,"mutability":"mutable","name":"owner","nameLocation":"596:5:2","nodeType":"VariableDeclaration","scope":78,"src":"580:21:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":71,"name":"address","nodeType":"ElementaryTypeName","src":"580:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":74,"indexed":true,"mutability":"mutable","name":"approved","nameLocation":"619:8:2","nodeType":"VariableDeclaration","scope":78,"src":"603:24:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":73,"name":"address","nodeType":"ElementaryTypeName","src":"603:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":76,"indexed":true,"mutability":"mutable","name":"tokenId","nameLocation":"645:7:2","nodeType":"VariableDeclaration","scope":78,"src":"629:23:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":75,"name":"uint256","nodeType":"ElementaryTypeName","src":"629:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"579:74:2"},"src":"565:89:2"},{"anonymous":false,"documentation":{"id":79,"nodeType":"StructuredDocumentation","src":"660:117:2","text":" @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets."},"eventSelector":"17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31","id":87,"name":"ApprovalForAll","nameLocation":"788:14:2","nodeType":"EventDefinition","parameters":{"id":86,"nodeType":"ParameterList","parameters":[{"constant":false,"id":81,"indexed":true,"mutability":"mutable","name":"owner","nameLocation":"819:5:2","nodeType":"VariableDeclaration","scope":87,"src":"803:21:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":80,"name":"address","nodeType":"ElementaryTypeName","src":"803:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":83,"indexed":true,"mutability":"mutable","name":"operator","nameLocation":"842:8:2","nodeType":"VariableDeclaration","scope":87,"src":"826:24:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":82,"name":"address","nodeType":"ElementaryTypeName","src":"826:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":85,"indexed":false,"mutability":"mutable","name":"approved","nameLocation":"857:8:2","nodeType":"VariableDeclaration","scope":87,"src":"852:13:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":84,"name":"bool","nodeType":"ElementaryTypeName","src":"852:4:2","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"802:64:2"},"src":"782:85:2"},{"documentation":{"id":88,"nodeType":"StructuredDocumentation","src":"873:76:2","text":" @dev Returns the number of tokens in ``owner``'s account."},"functionSelector":"70a08231","id":95,"implemented":false,"kind":"function","modifiers":[],"name":"balanceOf","nameLocation":"963:9:2","nodeType":"FunctionDefinition","parameters":{"id":91,"nodeType":"ParameterList","parameters":[{"constant":false,"id":90,"mutability":"mutable","name":"owner","nameLocation":"981:5:2","nodeType":"VariableDeclaration","scope":95,"src":"973:13:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":89,"name":"address","nodeType":"ElementaryTypeName","src":"973:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"972:15:2"},"returnParameters":{"id":94,"nodeType":"ParameterList","parameters":[{"constant":false,"id":93,"mutability":"mutable","name":"balance","nameLocation":"1019:7:2","nodeType":"VariableDeclaration","scope":95,"src":"1011:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":92,"name":"uint256","nodeType":"ElementaryTypeName","src":"1011:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1010:17:2"},"scope":170,"src":"954:74:2","stateMutability":"view","virtual":false,"visibility":"external"},{"documentation":{"id":96,"nodeType":"StructuredDocumentation","src":"1034:131:2","text":" @dev Returns the owner of the `tokenId` token.\n Requirements:\n - `tokenId` must exist."},"functionSelector":"6352211e","id":103,"implemented":false,"kind":"function","modifiers":[],"name":"ownerOf","nameLocation":"1179:7:2","nodeType":"FunctionDefinition","parameters":{"id":99,"nodeType":"ParameterList","parameters":[{"constant":false,"id":98,"mutability":"mutable","name":"tokenId","nameLocation":"1195:7:2","nodeType":"VariableDeclaration","scope":103,"src":"1187:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":97,"name":"uint256","nodeType":"ElementaryTypeName","src":"1187:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1186:17:2"},"returnParameters":{"id":102,"nodeType":"ParameterList","parameters":[{"constant":false,"id":101,"mutability":"mutable","name":"owner","nameLocation":"1235:5:2","nodeType":"VariableDeclaration","scope":103,"src":"1227:13:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":100,"name":"address","nodeType":"ElementaryTypeName","src":"1227:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1226:15:2"},"scope":170,"src":"1170:72:2","stateMutability":"view","virtual":false,"visibility":"external"},{"documentation":{"id":104,"nodeType":"StructuredDocumentation","src":"1248:556:2","text":" @dev Safely transfers `tokenId` token from `from` to `to`.\n Requirements:\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 Emits a {Transfer} event."},"functionSelector":"b88d4fde","id":115,"implemented":false,"kind":"function","modifiers":[],"name":"safeTransferFrom","nameLocation":"1818:16:2","nodeType":"FunctionDefinition","parameters":{"id":113,"nodeType":"ParameterList","parameters":[{"constant":false,"id":106,"mutability":"mutable","name":"from","nameLocation":"1843:4:2","nodeType":"VariableDeclaration","scope":115,"src":"1835:12:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":105,"name":"address","nodeType":"ElementaryTypeName","src":"1835:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":108,"mutability":"mutable","name":"to","nameLocation":"1857:2:2","nodeType":"VariableDeclaration","scope":115,"src":"1849:10:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":107,"name":"address","nodeType":"ElementaryTypeName","src":"1849:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":110,"mutability":"mutable","name":"tokenId","nameLocation":"1869:7:2","nodeType":"VariableDeclaration","scope":115,"src":"1861:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":109,"name":"uint256","nodeType":"ElementaryTypeName","src":"1861:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":112,"mutability":"mutable","name":"data","nameLocation":"1893:4:2","nodeType":"VariableDeclaration","scope":115,"src":"1878:19:2","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":111,"name":"bytes","nodeType":"ElementaryTypeName","src":"1878:5:2","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1834:64:2"},"returnParameters":{"id":114,"nodeType":"ParameterList","parameters":[],"src":"1907:0:2"},"scope":170,"src":"1809:99:2","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":116,"nodeType":"StructuredDocumentation","src":"1914:687:2","text":" @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 Requirements:\n - `from` cannot be the zero address.\n - `to` cannot be the zero address.\n - `tokenId` token must exist and be owned by `from`.\n - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n Emits a {Transfer} event."},"functionSelector":"42842e0e","id":125,"implemented":false,"kind":"function","modifiers":[],"name":"safeTransferFrom","nameLocation":"2615:16:2","nodeType":"FunctionDefinition","parameters":{"id":123,"nodeType":"ParameterList","parameters":[{"constant":false,"id":118,"mutability":"mutable","name":"from","nameLocation":"2640:4:2","nodeType":"VariableDeclaration","scope":125,"src":"2632:12:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":117,"name":"address","nodeType":"ElementaryTypeName","src":"2632:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":120,"mutability":"mutable","name":"to","nameLocation":"2654:2:2","nodeType":"VariableDeclaration","scope":125,"src":"2646:10:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":119,"name":"address","nodeType":"ElementaryTypeName","src":"2646:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":122,"mutability":"mutable","name":"tokenId","nameLocation":"2666:7:2","nodeType":"VariableDeclaration","scope":125,"src":"2658:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":121,"name":"uint256","nodeType":"ElementaryTypeName","src":"2658:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2631:43:2"},"returnParameters":{"id":124,"nodeType":"ParameterList","parameters":[],"src":"2683:0:2"},"scope":170,"src":"2606:78:2","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":126,"nodeType":"StructuredDocumentation","src":"2690:732:2","text":" @dev Transfers `tokenId` token from `from` to `to`.\n WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n understand this adds an external call which potentially creates a reentrancy vulnerability.\n Requirements:\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 Emits a {Transfer} event."},"functionSelector":"23b872dd","id":135,"implemented":false,"kind":"function","modifiers":[],"name":"transferFrom","nameLocation":"3436:12:2","nodeType":"FunctionDefinition","parameters":{"id":133,"nodeType":"ParameterList","parameters":[{"constant":false,"id":128,"mutability":"mutable","name":"from","nameLocation":"3457:4:2","nodeType":"VariableDeclaration","scope":135,"src":"3449:12:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":127,"name":"address","nodeType":"ElementaryTypeName","src":"3449:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":130,"mutability":"mutable","name":"to","nameLocation":"3471:2:2","nodeType":"VariableDeclaration","scope":135,"src":"3463:10:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":129,"name":"address","nodeType":"ElementaryTypeName","src":"3463:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":132,"mutability":"mutable","name":"tokenId","nameLocation":"3483:7:2","nodeType":"VariableDeclaration","scope":135,"src":"3475:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":131,"name":"uint256","nodeType":"ElementaryTypeName","src":"3475:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3448:43:2"},"returnParameters":{"id":134,"nodeType":"ParameterList","parameters":[],"src":"3500:0:2"},"scope":170,"src":"3427:74:2","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":136,"nodeType":"StructuredDocumentation","src":"3507:452:2","text":" @dev Gives permission to `to` to transfer `tokenId` token to another account.\n The approval is cleared when the token is transferred.\n Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n Requirements:\n - The caller must own the token or be an approved operator.\n - `tokenId` must exist.\n Emits an {Approval} event."},"functionSelector":"095ea7b3","id":143,"implemented":false,"kind":"function","modifiers":[],"name":"approve","nameLocation":"3973:7:2","nodeType":"FunctionDefinition","parameters":{"id":141,"nodeType":"ParameterList","parameters":[{"constant":false,"id":138,"mutability":"mutable","name":"to","nameLocation":"3989:2:2","nodeType":"VariableDeclaration","scope":143,"src":"3981:10:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":137,"name":"address","nodeType":"ElementaryTypeName","src":"3981:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":140,"mutability":"mutable","name":"tokenId","nameLocation":"4001:7:2","nodeType":"VariableDeclaration","scope":143,"src":"3993:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":139,"name":"uint256","nodeType":"ElementaryTypeName","src":"3993:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3980:29:2"},"returnParameters":{"id":142,"nodeType":"ParameterList","parameters":[],"src":"4018:0:2"},"scope":170,"src":"3964:55:2","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":144,"nodeType":"StructuredDocumentation","src":"4025:309:2","text":" @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 Requirements:\n - The `operator` cannot be the caller.\n Emits an {ApprovalForAll} event."},"functionSelector":"a22cb465","id":151,"implemented":false,"kind":"function","modifiers":[],"name":"setApprovalForAll","nameLocation":"4348:17:2","nodeType":"FunctionDefinition","parameters":{"id":149,"nodeType":"ParameterList","parameters":[{"constant":false,"id":146,"mutability":"mutable","name":"operator","nameLocation":"4374:8:2","nodeType":"VariableDeclaration","scope":151,"src":"4366:16:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":145,"name":"address","nodeType":"ElementaryTypeName","src":"4366:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":148,"mutability":"mutable","name":"approved","nameLocation":"4389:8:2","nodeType":"VariableDeclaration","scope":151,"src":"4384:13:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":147,"name":"bool","nodeType":"ElementaryTypeName","src":"4384:4:2","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"4365:33:2"},"returnParameters":{"id":150,"nodeType":"ParameterList","parameters":[],"src":"4407:0:2"},"scope":170,"src":"4339:69:2","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":152,"nodeType":"StructuredDocumentation","src":"4414:139:2","text":" @dev Returns the account approved for `tokenId` token.\n Requirements:\n - `tokenId` must exist."},"functionSelector":"081812fc","id":159,"implemented":false,"kind":"function","modifiers":[],"name":"getApproved","nameLocation":"4567:11:2","nodeType":"FunctionDefinition","parameters":{"id":155,"nodeType":"ParameterList","parameters":[{"constant":false,"id":154,"mutability":"mutable","name":"tokenId","nameLocation":"4587:7:2","nodeType":"VariableDeclaration","scope":159,"src":"4579:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":153,"name":"uint256","nodeType":"ElementaryTypeName","src":"4579:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"4578:17:2"},"returnParameters":{"id":158,"nodeType":"ParameterList","parameters":[{"constant":false,"id":157,"mutability":"mutable","name":"operator","nameLocation":"4627:8:2","nodeType":"VariableDeclaration","scope":159,"src":"4619:16:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":156,"name":"address","nodeType":"ElementaryTypeName","src":"4619:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"4618:18:2"},"scope":170,"src":"4558:79:2","stateMutability":"view","virtual":false,"visibility":"external"},{"documentation":{"id":160,"nodeType":"StructuredDocumentation","src":"4643:138:2","text":" @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n See {setApprovalForAll}"},"functionSelector":"e985e9c5","id":169,"implemented":false,"kind":"function","modifiers":[],"name":"isApprovedForAll","nameLocation":"4795:16:2","nodeType":"FunctionDefinition","parameters":{"id":165,"nodeType":"ParameterList","parameters":[{"constant":false,"id":162,"mutability":"mutable","name":"owner","nameLocation":"4820:5:2","nodeType":"VariableDeclaration","scope":169,"src":"4812:13:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":161,"name":"address","nodeType":"ElementaryTypeName","src":"4812:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":164,"mutability":"mutable","name":"operator","nameLocation":"4835:8:2","nodeType":"VariableDeclaration","scope":169,"src":"4827:16:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":163,"name":"address","nodeType":"ElementaryTypeName","src":"4827:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"4811:33:2"},"returnParameters":{"id":168,"nodeType":"ParameterList","parameters":[{"constant":false,"id":167,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":169,"src":"4868:4:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":166,"name":"bool","nodeType":"ElementaryTypeName","src":"4868:4:2","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"4867:6:2"},"scope":170,"src":"4786:88:2","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":171,"src":"250:4626:2","usedErrors":[]}],"src":"108:4769:2"},"id":2},"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol","exportedSymbols":{"IERC721Receiver":[188]},"id":189,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":172,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"116:23:3"},{"abstract":false,"baseContracts":[],"canonicalName":"IERC721Receiver","contractDependencies":[],"contractKind":"interface","documentation":{"id":173,"nodeType":"StructuredDocumentation","src":"141:152:3","text":" @title ERC721 token receiver interface\n @dev Interface for any contract that wants to support safeTransfers\n from ERC721 asset contracts."},"fullyImplemented":false,"id":188,"linearizedBaseContracts":[188],"name":"IERC721Receiver","nameLocation":"304:15:3","nodeType":"ContractDefinition","nodes":[{"documentation":{"id":174,"nodeType":"StructuredDocumentation","src":"326:493:3","text":" @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n by `operator` from `from`, this function is called.\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 The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`."},"functionSelector":"150b7a02","id":187,"implemented":false,"kind":"function","modifiers":[],"name":"onERC721Received","nameLocation":"833:16:3","nodeType":"FunctionDefinition","parameters":{"id":183,"nodeType":"ParameterList","parameters":[{"constant":false,"id":176,"mutability":"mutable","name":"operator","nameLocation":"867:8:3","nodeType":"VariableDeclaration","scope":187,"src":"859:16:3","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":175,"name":"address","nodeType":"ElementaryTypeName","src":"859:7:3","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":178,"mutability":"mutable","name":"from","nameLocation":"893:4:3","nodeType":"VariableDeclaration","scope":187,"src":"885:12:3","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":177,"name":"address","nodeType":"ElementaryTypeName","src":"885:7:3","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":180,"mutability":"mutable","name":"tokenId","nameLocation":"915:7:3","nodeType":"VariableDeclaration","scope":187,"src":"907:15:3","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":179,"name":"uint256","nodeType":"ElementaryTypeName","src":"907:7:3","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":182,"mutability":"mutable","name":"data","nameLocation":"947:4:3","nodeType":"VariableDeclaration","scope":187,"src":"932:19:3","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":181,"name":"bytes","nodeType":"ElementaryTypeName","src":"932:5:3","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"849:108:3"},"returnParameters":{"id":186,"nodeType":"ParameterList","parameters":[{"constant":false,"id":185,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":187,"src":"976:6:3","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":184,"name":"bytes4","nodeType":"ElementaryTypeName","src":"976:6:3","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"975:8:3"},"scope":188,"src":"824:160:3","stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"scope":189,"src":"294:692:3","usedErrors":[]}],"src":"116:871:3"},"id":3},"@openzeppelin/contracts/utils/introspection/IERC165.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/utils/introspection/IERC165.sol","exportedSymbols":{"IERC165":[200]},"id":201,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":190,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"100:23:4"},{"abstract":false,"baseContracts":[],"canonicalName":"IERC165","contractDependencies":[],"contractKind":"interface","documentation":{"id":191,"nodeType":"StructuredDocumentation","src":"125:279:4","text":" @dev Interface of the ERC165 standard, as defined in the\n https://eips.ethereum.org/EIPS/eip-165[EIP].\n Implementers can declare support of contract interfaces, which can then be\n queried by others ({ERC165Checker}).\n For an implementation, see {ERC165}."},"fullyImplemented":false,"id":200,"linearizedBaseContracts":[200],"name":"IERC165","nameLocation":"415:7:4","nodeType":"ContractDefinition","nodes":[{"documentation":{"id":192,"nodeType":"StructuredDocumentation","src":"429:340:4","text":" @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 This function call must use less than 30 000 gas."},"functionSelector":"01ffc9a7","id":199,"implemented":false,"kind":"function","modifiers":[],"name":"supportsInterface","nameLocation":"783:17:4","nodeType":"FunctionDefinition","parameters":{"id":195,"nodeType":"ParameterList","parameters":[{"constant":false,"id":194,"mutability":"mutable","name":"interfaceId","nameLocation":"808:11:4","nodeType":"VariableDeclaration","scope":199,"src":"801:18:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":193,"name":"bytes4","nodeType":"ElementaryTypeName","src":"801:6:4","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"800:20:4"},"returnParameters":{"id":198,"nodeType":"ParameterList","parameters":[{"constant":false,"id":197,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":199,"src":"844:4:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":196,"name":"bool","nodeType":"ElementaryTypeName","src":"844:4:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"843:6:4"},"scope":200,"src":"774:76:4","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":201,"src":"405:447:4","usedErrors":[]}],"src":"100:753:4"},"id":4},"contracts/AccountRegistryBridge.sol":{"ast":{"absolutePath":"contracts/AccountRegistryBridge.sol","exportedSymbols":{"AccountRegistryBridge":[255],"IRegistry":[1282]},"id":256,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":202,"literals":["solidity","^","0.8",".13"],"nodeType":"PragmaDirective","src":"33:24:5"},{"absolutePath":"contracts/interfaces/IRegistry.sol","file":"./interfaces/IRegistry.sol","id":203,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":256,"sourceUnit":1283,"src":"59:36:5","symbolAliases":[],"unitAlias":""},{"abstract":false,"baseContracts":[],"canonicalName":"AccountRegistryBridge","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"id":255,"linearizedBaseContracts":[255],"name":"AccountRegistryBridge","nameLocation":"105:21:5","nodeType":"ContractDefinition","nodes":[{"constant":true,"functionSelector":"06433b1b","id":206,"mutability":"constant","name":"REGISTRY","nameLocation":"157:8:5","nodeType":"VariableDeclaration","scope":255,"src":"133:78:5","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":204,"name":"address","nodeType":"ElementaryTypeName","src":"133:7:5","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"hexValue":"307830323130316466423737464445303236343134383237466463363034646441463232344630393231","id":205,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"169:42:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x02101dfB77FDE026414827Fdc604ddAF224F0921"},"visibility":"public"},{"constant":true,"functionSelector":"7fdfc7b2","id":209,"mutability":"constant","name":"IMPLMENTATION","nameLocation":"241:13:5","nodeType":"VariableDeclaration","scope":255,"src":"217:82:5","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":207,"name":"address","nodeType":"ElementaryTypeName","src":"217:7:5","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"hexValue":"307832443235363032353531343837433366333335346444383044373644353433383341323433333538","id":208,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"257:42:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x2D25602551487C3f3354dD80D76D54383A243358"},"visibility":"public"},{"body":{"id":231,"nodeType":"Block","src":"418:202:5","statements":[{"expression":{"arguments":[{"id":222,"name":"IMPLMENTATION","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":209,"src":"482:13:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"expression":{"id":223,"name":"block","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-4,"src":"509:5:5","typeDescriptions":{"typeIdentifier":"t_magic_block","typeString":"block"}},"id":224,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"515:7:5","memberName":"chainid","nodeType":"MemberAccess","src":"509:13:5","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":225,"name":"contractAddress","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":211,"src":"536:15:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":226,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"565:7:5","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"hexValue":"30","id":227,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"586:1:5","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},{"hexValue":"","id":228,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"601:2:5","typeDescriptions":{"typeIdentifier":"t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","typeString":"literal_string \"\""},"value":""}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},{"typeIdentifier":"t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","typeString":"literal_string \"\""}],"expression":{"arguments":[{"id":219,"name":"REGISTRY","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":206,"src":"445:8:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":218,"name":"IRegistry","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1282,"src":"435:9:5","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IRegistry_$1282_$","typeString":"type(contract IRegistry)"}},"id":220,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"435:19:5","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_IRegistry_$1282","typeString":"contract IRegistry"}},"id":221,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"455:13:5","memberName":"createAccount","nodeType":"MemberAccess","referencedDeclaration":1266,"src":"435:33:5","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$_t_uint256_$_t_address_$_t_uint256_$_t_uint256_$_t_bytes_memory_ptr_$returns$_t_address_$","typeString":"function (address,uint256,address,uint256,uint256,bytes memory) external returns (address)"}},"id":229,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"435:178:5","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"functionReturnParameters":217,"id":230,"nodeType":"Return","src":"428:185:5"}]},"functionSelector":"5fbfb9cf","id":232,"implemented":true,"kind":"function","modifiers":[],"name":"createAccount","nameLocation":"315:13:5","nodeType":"FunctionDefinition","parameters":{"id":214,"nodeType":"ParameterList","parameters":[{"constant":false,"id":211,"mutability":"mutable","name":"contractAddress","nameLocation":"337:15:5","nodeType":"VariableDeclaration","scope":232,"src":"329:23:5","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":210,"name":"address","nodeType":"ElementaryTypeName","src":"329:7:5","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":213,"mutability":"mutable","name":"tokenId","nameLocation":"362:7:5","nodeType":"VariableDeclaration","scope":232,"src":"354:15:5","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":212,"name":"uint256","nodeType":"ElementaryTypeName","src":"354:7:5","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"328:42:5"},"returnParameters":{"id":217,"nodeType":"ParameterList","parameters":[{"constant":false,"id":216,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":232,"src":"405:7:5","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":215,"name":"address","nodeType":"ElementaryTypeName","src":"405:7:5","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"404:9:5"},"scope":255,"src":"306:314:5","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":253,"nodeType":"Block","src":"745:180:5","statements":[{"expression":{"arguments":[{"id":245,"name":"IMPLMENTATION","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":209,"src":"803:13:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"expression":{"id":246,"name":"block","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-4,"src":"830:5:5","typeDescriptions":{"typeIdentifier":"t_magic_block","typeString":"block"}},"id":247,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"836:7:5","memberName":"chainid","nodeType":"MemberAccess","src":"830:13:5","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":248,"name":"contractAddress","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":234,"src":"857:15:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":249,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":236,"src":"886:7:5","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"hexValue":"30","id":250,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"907:1:5","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"expression":{"arguments":[{"id":242,"name":"REGISTRY","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":206,"src":"772:8:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":241,"name":"IRegistry","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1282,"src":"762:9:5","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IRegistry_$1282_$","typeString":"type(contract IRegistry)"}},"id":243,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"762:19:5","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_IRegistry_$1282","typeString":"contract IRegistry"}},"id":244,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"782:7:5","memberName":"account","nodeType":"MemberAccess","referencedDeclaration":1281,"src":"762:27:5","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$_t_uint256_$_t_address_$_t_uint256_$_t_uint256_$returns$_t_address_$","typeString":"function (address,uint256,address,uint256,uint256) view external returns (address)"}},"id":251,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"762:156:5","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"functionReturnParameters":240,"id":252,"nodeType":"Return","src":"755:163:5"}]},"functionSelector":"192df655","id":254,"implemented":true,"kind":"function","modifiers":[],"name":"account","nameLocation":"635:7:5","nodeType":"FunctionDefinition","parameters":{"id":237,"nodeType":"ParameterList","parameters":[{"constant":false,"id":234,"mutability":"mutable","name":"contractAddress","nameLocation":"651:15:5","nodeType":"VariableDeclaration","scope":254,"src":"643:23:5","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":233,"name":"address","nodeType":"ElementaryTypeName","src":"643:7:5","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":236,"mutability":"mutable","name":"tokenId","nameLocation":"676:7:5","nodeType":"VariableDeclaration","scope":254,"src":"668:15:5","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":235,"name":"uint256","nodeType":"ElementaryTypeName","src":"668:7:5","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"642:42:5"},"returnParameters":{"id":240,"nodeType":"ParameterList","parameters":[{"constant":false,"id":239,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":254,"src":"732:7:5","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":238,"name":"address","nodeType":"ElementaryTypeName","src":"732:7:5","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"731:9:5"},"scope":255,"src":"626:299:5","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":256,"src":"96:831:5","usedErrors":[]}],"src":"33:894:5"},"id":5},"contracts/ChargedParticles.sol":{"ast":{"absolutePath":"contracts/ChargedParticles.sol","exportedSymbols":{"AccountRegistryBridge":[255],"ChargedParticles":[448],"IChargedParticles":[1201],"IERC165":[200],"IERC721":[170],"IRegistry":[1282]},"id":449,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":257,"literals":["solidity","^","0.8",".13"],"nodeType":"PragmaDirective","src":"33:24:6"},{"absolutePath":"contracts/interfaces/IChargedParticles.sol","file":"./interfaces/IChargedParticles.sol","id":258,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":449,"sourceUnit":1202,"src":"59:44:6","symbolAliases":[],"unitAlias":""},{"absolutePath":"contracts/AccountRegistryBridge.sol","file":"./AccountRegistryBridge.sol","id":259,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":449,"sourceUnit":256,"src":"104:37:6","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721.sol","file":"@openzeppelin/contracts/token/ERC721/IERC721.sol","id":260,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":449,"sourceUnit":171,"src":"143:58:6","symbolAliases":[],"unitAlias":""},{"abstract":false,"baseContracts":[{"baseName":{"id":261,"name":"AccountRegistryBridge","nameLocations":["231:21:6"],"nodeType":"IdentifierPath","referencedDeclaration":255,"src":"231:21:6"},"id":262,"nodeType":"InheritanceSpecifier","src":"231:21:6"}],"canonicalName":"ChargedParticles","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"id":448,"linearizedBaseContracts":[448,255],"name":"ChargedParticles","nameLocation":"211:16:6","nodeType":"ContractDefinition","nodes":[{"body":{"id":279,"nodeType":"Block","src":"518:16:6","statements":[]},"functionSelector":"0bdde2ca","id":280,"implemented":true,"kind":"function","modifiers":[],"name":"energizeParticle","nameLocation":"268:16:6","nodeType":"FunctionDefinition","parameters":{"id":275,"nodeType":"ParameterList","parameters":[{"constant":false,"id":264,"mutability":"mutable","name":"contractAddress","nameLocation":"302:15:6","nodeType":"VariableDeclaration","scope":280,"src":"294:23:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":263,"name":"address","nodeType":"ElementaryTypeName","src":"294:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":266,"mutability":"mutable","name":"tokenId","nameLocation":"335:7:6","nodeType":"VariableDeclaration","scope":280,"src":"327:15:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":265,"name":"uint256","nodeType":"ElementaryTypeName","src":"327:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":268,"mutability":"mutable","name":"walletManagerId","nameLocation":"368:15:6","nodeType":"VariableDeclaration","scope":280,"src":"352:31:6","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":267,"name":"string","nodeType":"ElementaryTypeName","src":"352:6:6","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":270,"mutability":"mutable","name":"assetToken","nameLocation":"401:10:6","nodeType":"VariableDeclaration","scope":280,"src":"393:18:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":269,"name":"address","nodeType":"ElementaryTypeName","src":"393:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":272,"mutability":"mutable","name":"assetAmount","nameLocation":"429:11:6","nodeType":"VariableDeclaration","scope":280,"src":"421:19:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":271,"name":"uint256","nodeType":"ElementaryTypeName","src":"421:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":274,"mutability":"mutable","name":"referrer","nameLocation":"458:8:6","nodeType":"VariableDeclaration","scope":280,"src":"450:16:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":273,"name":"address","nodeType":"ElementaryTypeName","src":"450:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"284:188:6"},"returnParameters":{"id":278,"nodeType":"ParameterList","parameters":[{"constant":false,"id":277,"mutability":"mutable","name":"yieldTokensAmount","nameLocation":"499:17:6","nodeType":"VariableDeclaration","scope":280,"src":"491:25:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":276,"name":"uint256","nodeType":"ElementaryTypeName","src":"491:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"490:27:6"},"scope":448,"src":"259:275:6","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":297,"nodeType":"Block","src":"791:8:6","statements":[]},"functionSelector":"621a3b70","id":298,"implemented":true,"kind":"function","modifiers":[],"name":"dischargeParticle","nameLocation":"549:17:6","nodeType":"FunctionDefinition","parameters":{"id":291,"nodeType":"ParameterList","parameters":[{"constant":false,"id":282,"mutability":"mutable","name":"receiver","nameLocation":"584:8:6","nodeType":"VariableDeclaration","scope":298,"src":"576:16:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":281,"name":"address","nodeType":"ElementaryTypeName","src":"576:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":284,"mutability":"mutable","name":"contractAddress","nameLocation":"610:15:6","nodeType":"VariableDeclaration","scope":298,"src":"602:23:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":283,"name":"address","nodeType":"ElementaryTypeName","src":"602:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":286,"mutability":"mutable","name":"tokenId","nameLocation":"643:7:6","nodeType":"VariableDeclaration","scope":298,"src":"635:15:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":285,"name":"uint256","nodeType":"ElementaryTypeName","src":"635:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":288,"mutability":"mutable","name":"walletManagerId","nameLocation":"676:15:6","nodeType":"VariableDeclaration","scope":298,"src":"660:31:6","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":287,"name":"string","nodeType":"ElementaryTypeName","src":"660:6:6","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":290,"mutability":"mutable","name":"assetToken","nameLocation":"709:10:6","nodeType":"VariableDeclaration","scope":298,"src":"701:18:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":289,"name":"address","nodeType":"ElementaryTypeName","src":"701:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"566:159:6"},"returnParameters":{"id":296,"nodeType":"ParameterList","parameters":[{"constant":false,"id":293,"mutability":"mutable","name":"creatorAmount","nameLocation":"752:13:6","nodeType":"VariableDeclaration","scope":298,"src":"744:21:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":292,"name":"uint256","nodeType":"ElementaryTypeName","src":"744:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":295,"mutability":"mutable","name":"receiverAmount","nameLocation":"775:14:6","nodeType":"VariableDeclaration","scope":298,"src":"767:22:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":294,"name":"uint256","nodeType":"ElementaryTypeName","src":"767:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"743:47:6"},"scope":448,"src":"540:259:6","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":317,"nodeType":"Block","src":"1091:8:6","statements":[]},"functionSelector":"6697b359","id":318,"implemented":true,"kind":"function","modifiers":[],"name":"dischargeParticleAmount","nameLocation":"814:23:6","nodeType":"FunctionDefinition","parameters":{"id":311,"nodeType":"ParameterList","parameters":[{"constant":false,"id":300,"mutability":"mutable","name":"receiver","nameLocation":"855:8:6","nodeType":"VariableDeclaration","scope":318,"src":"847:16:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":299,"name":"address","nodeType":"ElementaryTypeName","src":"847:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":302,"mutability":"mutable","name":"contractAddress","nameLocation":"881:15:6","nodeType":"VariableDeclaration","scope":318,"src":"873:23:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":301,"name":"address","nodeType":"ElementaryTypeName","src":"873:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":304,"mutability":"mutable","name":"tokenId","nameLocation":"914:7:6","nodeType":"VariableDeclaration","scope":318,"src":"906:15:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":303,"name":"uint256","nodeType":"ElementaryTypeName","src":"906:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":306,"mutability":"mutable","name":"walletManagerId","nameLocation":"947:15:6","nodeType":"VariableDeclaration","scope":318,"src":"931:31:6","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":305,"name":"string","nodeType":"ElementaryTypeName","src":"931:6:6","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":308,"mutability":"mutable","name":"assetToken","nameLocation":"980:10:6","nodeType":"VariableDeclaration","scope":318,"src":"972:18:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":307,"name":"address","nodeType":"ElementaryTypeName","src":"972:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":310,"mutability":"mutable","name":"assetAmount","nameLocation":"1008:11:6","nodeType":"VariableDeclaration","scope":318,"src":"1000:19:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":309,"name":"uint256","nodeType":"ElementaryTypeName","src":"1000:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"837:188:6"},"returnParameters":{"id":316,"nodeType":"ParameterList","parameters":[{"constant":false,"id":313,"mutability":"mutable","name":"creatorAmount","nameLocation":"1052:13:6","nodeType":"VariableDeclaration","scope":318,"src":"1044:21:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":312,"name":"uint256","nodeType":"ElementaryTypeName","src":"1044:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":315,"mutability":"mutable","name":"receiverAmount","nameLocation":"1075:14:6","nodeType":"VariableDeclaration","scope":318,"src":"1067:22:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":314,"name":"uint256","nodeType":"ElementaryTypeName","src":"1067:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1043:47:6"},"scope":448,"src":"805:294:6","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":335,"nodeType":"Block","src":"1372:8:6","statements":[]},"functionSelector":"65d20ce2","id":336,"implemented":true,"kind":"function","modifiers":[],"name":"dischargeParticleForCreator","nameLocation":"1114:27:6","nodeType":"FunctionDefinition","parameters":{"id":331,"nodeType":"ParameterList","parameters":[{"constant":false,"id":320,"mutability":"mutable","name":"receiver","nameLocation":"1159:8:6","nodeType":"VariableDeclaration","scope":336,"src":"1151:16:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":319,"name":"address","nodeType":"ElementaryTypeName","src":"1151:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":322,"mutability":"mutable","name":"contractAddress","nameLocation":"1185:15:6","nodeType":"VariableDeclaration","scope":336,"src":"1177:23:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":321,"name":"address","nodeType":"ElementaryTypeName","src":"1177:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":324,"mutability":"mutable","name":"tokenId","nameLocation":"1218:7:6","nodeType":"VariableDeclaration","scope":336,"src":"1210:15:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":323,"name":"uint256","nodeType":"ElementaryTypeName","src":"1210:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":326,"mutability":"mutable","name":"walletManagerId","nameLocation":"1251:15:6","nodeType":"VariableDeclaration","scope":336,"src":"1235:31:6","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":325,"name":"string","nodeType":"ElementaryTypeName","src":"1235:6:6","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":328,"mutability":"mutable","name":"assetToken","nameLocation":"1284:10:6","nodeType":"VariableDeclaration","scope":336,"src":"1276:18:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":327,"name":"address","nodeType":"ElementaryTypeName","src":"1276:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":330,"mutability":"mutable","name":"assetAmount","nameLocation":"1312:11:6","nodeType":"VariableDeclaration","scope":336,"src":"1304:19:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":329,"name":"uint256","nodeType":"ElementaryTypeName","src":"1304:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1141:188:6"},"returnParameters":{"id":334,"nodeType":"ParameterList","parameters":[{"constant":false,"id":333,"mutability":"mutable","name":"receiverAmount","nameLocation":"1356:14:6","nodeType":"VariableDeclaration","scope":336,"src":"1348:22:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":332,"name":"uint256","nodeType":"ElementaryTypeName","src":"1348:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1347:24:6"},"scope":448,"src":"1105:275:6","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":353,"nodeType":"Block","src":"1635:8:6","statements":[]},"functionSelector":"acab923c","id":354,"implemented":true,"kind":"function","modifiers":[],"name":"releaseParticle","nameLocation":"1395:15:6","nodeType":"FunctionDefinition","parameters":{"id":347,"nodeType":"ParameterList","parameters":[{"constant":false,"id":338,"mutability":"mutable","name":"receiver","nameLocation":"1428:8:6","nodeType":"VariableDeclaration","scope":354,"src":"1420:16:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":337,"name":"address","nodeType":"ElementaryTypeName","src":"1420:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":340,"mutability":"mutable","name":"contractAddress","nameLocation":"1454:15:6","nodeType":"VariableDeclaration","scope":354,"src":"1446:23:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":339,"name":"address","nodeType":"ElementaryTypeName","src":"1446:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":342,"mutability":"mutable","name":"tokenId","nameLocation":"1487:7:6","nodeType":"VariableDeclaration","scope":354,"src":"1479:15:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":341,"name":"uint256","nodeType":"ElementaryTypeName","src":"1479:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":344,"mutability":"mutable","name":"walletManagerId","nameLocation":"1520:15:6","nodeType":"VariableDeclaration","scope":354,"src":"1504:31:6","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":343,"name":"string","nodeType":"ElementaryTypeName","src":"1504:6:6","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":346,"mutability":"mutable","name":"assetToken","nameLocation":"1553:10:6","nodeType":"VariableDeclaration","scope":354,"src":"1545:18:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":345,"name":"address","nodeType":"ElementaryTypeName","src":"1545:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1410:159:6"},"returnParameters":{"id":352,"nodeType":"ParameterList","parameters":[{"constant":false,"id":349,"mutability":"mutable","name":"creatorAmount","nameLocation":"1596:13:6","nodeType":"VariableDeclaration","scope":354,"src":"1588:21:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":348,"name":"uint256","nodeType":"ElementaryTypeName","src":"1588:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":351,"mutability":"mutable","name":"receiverAmount","nameLocation":"1619:14:6","nodeType":"VariableDeclaration","scope":354,"src":"1611:22:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":350,"name":"uint256","nodeType":"ElementaryTypeName","src":"1611:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1587:47:6"},"scope":448,"src":"1386:257:6","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":373,"nodeType":"Block","src":"1933:8:6","statements":[]},"functionSelector":"a8abef47","id":374,"implemented":true,"kind":"function","modifiers":[],"name":"releaseParticleAmount","nameLocation":"1658:21:6","nodeType":"FunctionDefinition","parameters":{"id":367,"nodeType":"ParameterList","parameters":[{"constant":false,"id":356,"mutability":"mutable","name":"receiver","nameLocation":"1697:8:6","nodeType":"VariableDeclaration","scope":374,"src":"1689:16:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":355,"name":"address","nodeType":"ElementaryTypeName","src":"1689:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":358,"mutability":"mutable","name":"contractAddress","nameLocation":"1723:15:6","nodeType":"VariableDeclaration","scope":374,"src":"1715:23:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":357,"name":"address","nodeType":"ElementaryTypeName","src":"1715:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":360,"mutability":"mutable","name":"tokenId","nameLocation":"1756:7:6","nodeType":"VariableDeclaration","scope":374,"src":"1748:15:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":359,"name":"uint256","nodeType":"ElementaryTypeName","src":"1748:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":362,"mutability":"mutable","name":"walletManagerId","nameLocation":"1789:15:6","nodeType":"VariableDeclaration","scope":374,"src":"1773:31:6","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":361,"name":"string","nodeType":"ElementaryTypeName","src":"1773:6:6","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":364,"mutability":"mutable","name":"assetToken","nameLocation":"1822:10:6","nodeType":"VariableDeclaration","scope":374,"src":"1814:18:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":363,"name":"address","nodeType":"ElementaryTypeName","src":"1814:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":366,"mutability":"mutable","name":"assetAmount","nameLocation":"1850:11:6","nodeType":"VariableDeclaration","scope":374,"src":"1842:19:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":365,"name":"uint256","nodeType":"ElementaryTypeName","src":"1842:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1679:188:6"},"returnParameters":{"id":372,"nodeType":"ParameterList","parameters":[{"constant":false,"id":369,"mutability":"mutable","name":"creatorAmount","nameLocation":"1894:13:6","nodeType":"VariableDeclaration","scope":374,"src":"1886:21:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":368,"name":"uint256","nodeType":"ElementaryTypeName","src":"1886:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":371,"mutability":"mutable","name":"receiverAmount","nameLocation":"1917:14:6","nodeType":"VariableDeclaration","scope":374,"src":"1909:22:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":370,"name":"uint256","nodeType":"ElementaryTypeName","src":"1909:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1885:47:6"},"scope":448,"src":"1649:292:6","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":409,"nodeType":"Block","src":"2199:178:6","statements":[{"assignments":[392],"declarations":[{"constant":false,"id":392,"mutability":"mutable","name":"tokenBoundAccount","nameLocation":"2217:17:6","nodeType":"VariableDeclaration","scope":409,"src":"2209:25:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":391,"name":"address","nodeType":"ElementaryTypeName","src":"2209:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":398,"initialValue":{"arguments":[{"id":395,"name":"contractAddress","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":376,"src":"2250:15:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":396,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":378,"src":"2267:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":393,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"2237:4:6","typeDescriptions":{"typeIdentifier":"t_contract$_ChargedParticles_$448","typeString":"contract ChargedParticles"}},"id":394,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"2242:7:6","memberName":"account","nodeType":"MemberAccess","referencedDeclaration":254,"src":"2237:12:6","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$_t_uint256_$returns$_t_address_$","typeString":"function (address,uint256) view external returns (address)"}},"id":397,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2237:38:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"2209:66:6"},{"expression":{"arguments":[{"expression":{"id":403,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"2328:3:6","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":404,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"2332:6:6","memberName":"sender","nodeType":"MemberAccess","src":"2328:10:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":405,"name":"tokenBoundAccount","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":392,"src":"2340:17:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":406,"name":"nftTokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":384,"src":"2359:10:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"arguments":[{"id":400,"name":"nftTokenAddress","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":382,"src":"2294:15:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":399,"name":"IERC721","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":170,"src":"2286:7:6","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC721_$170_$","typeString":"type(contract IERC721)"}},"id":401,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2286:24:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_IERC721_$170","typeString":"contract IERC721"}},"id":402,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"2311:16:6","memberName":"safeTransferFrom","nodeType":"MemberAccess","referencedDeclaration":125,"src":"2286:41:6","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$","typeString":"function (address,address,uint256) external"}},"id":407,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2286:84:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":408,"nodeType":"ExpressionStatement","src":"2286:84:6"}]},"functionSelector":"3ff956cc","id":410,"implemented":true,"kind":"function","modifiers":[],"name":"covalentBond","nameLocation":"1956:12:6","nodeType":"FunctionDefinition","parameters":{"id":387,"nodeType":"ParameterList","parameters":[{"constant":false,"id":376,"mutability":"mutable","name":"contractAddress","nameLocation":"1986:15:6","nodeType":"VariableDeclaration","scope":410,"src":"1978:23:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":375,"name":"address","nodeType":"ElementaryTypeName","src":"1978:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":378,"mutability":"mutable","name":"tokenId","nameLocation":"2019:7:6","nodeType":"VariableDeclaration","scope":410,"src":"2011:15:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":377,"name":"uint256","nodeType":"ElementaryTypeName","src":"2011:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":380,"mutability":"mutable","name":"basketManagerId","nameLocation":"2052:15:6","nodeType":"VariableDeclaration","scope":410,"src":"2036:31:6","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":379,"name":"string","nodeType":"ElementaryTypeName","src":"2036:6:6","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":382,"mutability":"mutable","name":"nftTokenAddress","nameLocation":"2085:15:6","nodeType":"VariableDeclaration","scope":410,"src":"2077:23:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":381,"name":"address","nodeType":"ElementaryTypeName","src":"2077:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":384,"mutability":"mutable","name":"nftTokenId","nameLocation":"2118:10:6","nodeType":"VariableDeclaration","scope":410,"src":"2110:18:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":383,"name":"uint256","nodeType":"ElementaryTypeName","src":"2110:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":386,"mutability":"mutable","name":"nftTokenAmount","nameLocation":"2146:14:6","nodeType":"VariableDeclaration","scope":410,"src":"2138:22:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":385,"name":"uint256","nodeType":"ElementaryTypeName","src":"2138:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1968:198:6"},"returnParameters":{"id":390,"nodeType":"ParameterList","parameters":[{"constant":false,"id":389,"mutability":"mutable","name":"success","nameLocation":"2190:7:6","nodeType":"VariableDeclaration","scope":410,"src":"2185:12:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":388,"name":"bool","nodeType":"ElementaryTypeName","src":"2185:4:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"2184:14:6"},"scope":448,"src":"1947:430:6","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":446,"nodeType":"Block","src":"2666:176:6","statements":[{"assignments":[430],"declarations":[{"constant":false,"id":430,"mutability":"mutable","name":"tokenBoundAccount","nameLocation":"2684:17:6","nodeType":"VariableDeclaration","scope":446,"src":"2676:25:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":429,"name":"address","nodeType":"ElementaryTypeName","src":"2676:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":436,"initialValue":{"arguments":[{"id":433,"name":"contractAddress","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":414,"src":"2717:15:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":434,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":416,"src":"2734:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":431,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"2704:4:6","typeDescriptions":{"typeIdentifier":"t_contract$_ChargedParticles_$448","typeString":"contract ChargedParticles"}},"id":432,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"2709:7:6","memberName":"account","nodeType":"MemberAccess","referencedDeclaration":254,"src":"2704:12:6","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$_t_uint256_$returns$_t_address_$","typeString":"function (address,uint256) view external returns (address)"}},"id":435,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2704:38:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"2676:66:6"},{"expression":{"arguments":[{"id":441,"name":"tokenBoundAccount","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":430,"src":"2795:17:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":442,"name":"receiver","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":412,"src":"2814:8:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":443,"name":"nftTokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":422,"src":"2824:10:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"arguments":[{"id":438,"name":"nftTokenAddress","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":420,"src":"2761:15:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":437,"name":"IERC721","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":170,"src":"2753:7:6","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC721_$170_$","typeString":"type(contract IERC721)"}},"id":439,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2753:24:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_IERC721_$170","typeString":"contract IERC721"}},"id":440,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"2778:16:6","memberName":"safeTransferFrom","nodeType":"MemberAccess","referencedDeclaration":125,"src":"2753:41:6","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$","typeString":"function (address,address,uint256) external"}},"id":444,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2753:82:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":445,"nodeType":"ExpressionStatement","src":"2753:82:6"}]},"functionSelector":"fe02fb00","id":447,"implemented":true,"kind":"function","modifiers":[],"name":"breakCovalentBond","nameLocation":"2392:17:6","nodeType":"FunctionDefinition","parameters":{"id":425,"nodeType":"ParameterList","parameters":[{"constant":false,"id":412,"mutability":"mutable","name":"receiver","nameLocation":"2427:8:6","nodeType":"VariableDeclaration","scope":447,"src":"2419:16:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":411,"name":"address","nodeType":"ElementaryTypeName","src":"2419:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":414,"mutability":"mutable","name":"contractAddress","nameLocation":"2453:15:6","nodeType":"VariableDeclaration","scope":447,"src":"2445:23:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":413,"name":"address","nodeType":"ElementaryTypeName","src":"2445:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":416,"mutability":"mutable","name":"tokenId","nameLocation":"2486:7:6","nodeType":"VariableDeclaration","scope":447,"src":"2478:15:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":415,"name":"uint256","nodeType":"ElementaryTypeName","src":"2478:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":418,"mutability":"mutable","name":"basketManagerId","nameLocation":"2519:15:6","nodeType":"VariableDeclaration","scope":447,"src":"2503:31:6","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":417,"name":"string","nodeType":"ElementaryTypeName","src":"2503:6:6","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":420,"mutability":"mutable","name":"nftTokenAddress","nameLocation":"2552:15:6","nodeType":"VariableDeclaration","scope":447,"src":"2544:23:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":419,"name":"address","nodeType":"ElementaryTypeName","src":"2544:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":422,"mutability":"mutable","name":"nftTokenId","nameLocation":"2585:10:6","nodeType":"VariableDeclaration","scope":447,"src":"2577:18:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":421,"name":"uint256","nodeType":"ElementaryTypeName","src":"2577:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":424,"mutability":"mutable","name":"nftTokenAmount","nameLocation":"2613:14:6","nodeType":"VariableDeclaration","scope":447,"src":"2605:22:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":423,"name":"uint256","nodeType":"ElementaryTypeName","src":"2605:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2409:224:6"},"returnParameters":{"id":428,"nodeType":"ParameterList","parameters":[{"constant":false,"id":427,"mutability":"mutable","name":"success","nameLocation":"2657:7:6","nodeType":"VariableDeclaration","scope":447,"src":"2652:12:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":426,"name":"bool","nodeType":"ElementaryTypeName","src":"2652:4:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"2651:14:6"},"scope":448,"src":"2383:459:6","stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"scope":449,"src":"202:2643:6","usedErrors":[]}],"src":"33:2813:6"},"id":6},"contracts/MinimalisticAccount.sol":{"ast":{"absolutePath":"contracts/MinimalisticAccount.sol","exportedSymbols":{"AccountLocked":[463],"ERC6551AccountLib":[1337],"ExceedsMaxLockTime":[465],"IERC1155Receiver":[54],"IERC1271":[13],"IERC165":[200],"IERC6551Account":[1247],"IERC6551AccountProxy":[1209],"IERC721":[170],"IERC721Receiver":[188],"InvalidInput":[461],"MinimalisticAccount":[983],"NotAuthorized":[459],"OwnershipCycle":[469],"UntrustedImplementation":[467]},"id":984,"license":"UNLICENSED","nodeType":"SourceUnit","nodes":[{"id":450,"literals":["solidity","^","0.8",".13"],"nodeType":"PragmaDirective","src":"39:24:7"},{"absolutePath":"contracts/interfaces/IERC6551Account.sol","file":"./interfaces/IERC6551Account.sol","id":451,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":984,"sourceUnit":1248,"src":"65:42:7","symbolAliases":[],"unitAlias":""},{"absolutePath":"contracts/lib/ERC6551AccountLib.sol","file":"./lib/ERC6551AccountLib.sol","id":452,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":984,"sourceUnit":1338,"src":"108:37:7","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/utils/introspection/IERC165.sol","file":"@openzeppelin/contracts/utils/introspection/IERC165.sol","id":453,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":984,"sourceUnit":201,"src":"147:65:7","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721.sol","file":"@openzeppelin/contracts/token/ERC721/IERC721.sol","id":454,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":984,"sourceUnit":171,"src":"213:58:7","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol","file":"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol","id":455,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":984,"sourceUnit":189,"src":"272:66:7","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol","file":"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol","id":456,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":984,"sourceUnit":55,"src":"339:68:7","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/interfaces/IERC1271.sol","file":"@openzeppelin/contracts/interfaces/IERC1271.sol","id":457,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":984,"sourceUnit":14,"src":"408:57:7","symbolAliases":[],"unitAlias":""},{"errorSelector":"ea8e4eb5","id":459,"name":"NotAuthorized","nameLocation":"473:13:7","nodeType":"ErrorDefinition","parameters":{"id":458,"nodeType":"ParameterList","parameters":[],"src":"486:2:7"},"src":"467:22:7"},{"errorSelector":"b4fa3fb3","id":461,"name":"InvalidInput","nameLocation":"496:12:7","nodeType":"ErrorDefinition","parameters":{"id":460,"nodeType":"ParameterList","parameters":[],"src":"508:2:7"},"src":"490:21:7"},{"errorSelector":"6315bfbb","id":463,"name":"AccountLocked","nameLocation":"518:13:7","nodeType":"ErrorDefinition","parameters":{"id":462,"nodeType":"ParameterList","parameters":[],"src":"531:2:7"},"src":"512:22:7"},{"errorSelector":"0c0a7be8","id":465,"name":"ExceedsMaxLockTime","nameLocation":"541:18:7","nodeType":"ErrorDefinition","parameters":{"id":464,"nodeType":"ParameterList","parameters":[],"src":"559:2:7"},"src":"535:27:7"},{"errorSelector":"b57d5a5e","id":467,"name":"UntrustedImplementation","nameLocation":"569:23:7","nodeType":"ErrorDefinition","parameters":{"id":466,"nodeType":"ParameterList","parameters":[],"src":"592:2:7"},"src":"563:32:7"},{"errorSelector":"b79e3f3f","id":469,"name":"OwnershipCycle","nameLocation":"602:14:7","nodeType":"ErrorDefinition","parameters":{"id":468,"nodeType":"ParameterList","parameters":[],"src":"616:2:7"},"src":"596:23:7"},{"abstract":false,"baseContracts":[{"baseName":{"id":471,"name":"IERC165","nameLocations":["731:7:7"],"nodeType":"IdentifierPath","referencedDeclaration":200,"src":"731:7:7"},"id":472,"nodeType":"InheritanceSpecifier","src":"731:7:7"},{"baseName":{"id":473,"name":"IERC6551Account","nameLocations":["744:15:7"],"nodeType":"IdentifierPath","referencedDeclaration":1247,"src":"744:15:7"},"id":474,"nodeType":"InheritanceSpecifier","src":"744:15:7"},{"baseName":{"id":475,"name":"IERC721Receiver","nameLocations":["765:15:7"],"nodeType":"IdentifierPath","referencedDeclaration":188,"src":"765:15:7"},"id":476,"nodeType":"InheritanceSpecifier","src":"765:15:7"},{"baseName":{"id":477,"name":"IERC1155Receiver","nameLocations":["786:16:7"],"nodeType":"IdentifierPath","referencedDeclaration":54,"src":"786:16:7"},"id":478,"nodeType":"InheritanceSpecifier","src":"786:16:7"}],"canonicalName":"MinimalisticAccount","contractDependencies":[],"contractKind":"contract","documentation":{"id":470,"nodeType":"StructuredDocumentation","src":"621:73:7","text":" @title A smart contract account owned by a single ERC721 token"},"fullyImplemented":true,"id":983,"linearizedBaseContracts":[983,54,188,1247,200],"name":"MinimalisticAccount","nameLocation":"704:19:7","nodeType":"ContractDefinition","nodes":[{"constant":false,"documentation":{"id":479,"nodeType":"StructuredDocumentation","src":"809:57:7","text":"@dev timestamp at which this account will be unlocked"},"functionSelector":"ce0617ec","id":481,"mutability":"mutable","name":"lockedUntil","nameLocation":"886:11:7","nodeType":"VariableDeclaration","scope":983,"src":"871:26:7","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":480,"name":"uint256","nodeType":"ElementaryTypeName","src":"871:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"constant":false,"documentation":{"id":482,"nodeType":"StructuredDocumentation","src":"904:56:7","text":"@dev mapping from owner => caller => has permissions"},"functionSelector":"1f9838b5","id":488,"mutability":"mutable","name":"permissions","nameLocation":"1017:11:7","nodeType":"VariableDeclaration","scope":983,"src":"965:63:7","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_mapping$_t_address_$_t_bool_$_$","typeString":"mapping(address => mapping(address => bool))"},"typeName":{"id":487,"keyType":{"id":483,"name":"address","nodeType":"ElementaryTypeName","src":"973:7:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"Mapping","src":"965:44:7","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_mapping$_t_address_$_t_bool_$_$","typeString":"mapping(address => mapping(address => bool))"},"valueType":{"id":486,"keyType":{"id":484,"name":"address","nodeType":"ElementaryTypeName","src":"992:7:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"Mapping","src":"984:24:7","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_bool_$","typeString":"mapping(address => bool)"},"valueType":{"id":485,"name":"bool","nodeType":"ElementaryTypeName","src":"1003:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}}},"visibility":"public"},{"anonymous":false,"eventSelector":"2c722487e90aca38ec1b074c3403210bd2bfb769b4da7f12f7bf0b9e37517c18","id":496,"name":"OverrideUpdated","nameLocation":"1041:15:7","nodeType":"EventDefinition","parameters":{"id":495,"nodeType":"ParameterList","parameters":[{"constant":false,"id":490,"indexed":false,"mutability":"mutable","name":"owner","nameLocation":"1074:5:7","nodeType":"VariableDeclaration","scope":496,"src":"1066:13:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":489,"name":"address","nodeType":"ElementaryTypeName","src":"1066:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":492,"indexed":false,"mutability":"mutable","name":"selector","nameLocation":"1096:8:7","nodeType":"VariableDeclaration","scope":496,"src":"1089:15:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":491,"name":"bytes4","nodeType":"ElementaryTypeName","src":"1089:6:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"},{"constant":false,"id":494,"indexed":false,"mutability":"mutable","name":"implementation","nameLocation":"1122:14:7","nodeType":"VariableDeclaration","scope":496,"src":"1114:22:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":493,"name":"address","nodeType":"ElementaryTypeName","src":"1114:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1056:86:7"},"src":"1035:108:7"},{"anonymous":false,"eventSelector":"394777a58092892d136a90c4bb7e4350c72ac50fba6a0208128677f36527dcf5","id":504,"name":"PermissionUpdated","nameLocation":"1155:17:7","nodeType":"EventDefinition","parameters":{"id":503,"nodeType":"ParameterList","parameters":[{"constant":false,"id":498,"indexed":false,"mutability":"mutable","name":"owner","nameLocation":"1181:5:7","nodeType":"VariableDeclaration","scope":504,"src":"1173:13:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":497,"name":"address","nodeType":"ElementaryTypeName","src":"1173:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":500,"indexed":false,"mutability":"mutable","name":"caller","nameLocation":"1196:6:7","nodeType":"VariableDeclaration","scope":504,"src":"1188:14:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":499,"name":"address","nodeType":"ElementaryTypeName","src":"1188:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":502,"indexed":false,"mutability":"mutable","name":"hasPermission","nameLocation":"1209:13:7","nodeType":"VariableDeclaration","scope":504,"src":"1204:18:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":501,"name":"bool","nodeType":"ElementaryTypeName","src":"1204:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1172:51:7"},"src":"1149:75:7"},{"anonymous":false,"eventSelector":"a7b24c66dd3269a292a60b3facdbb8f3e7557d1e19e64d99e0d6ee7250be63ad","id":508,"name":"LockUpdated","nameLocation":"1236:11:7","nodeType":"EventDefinition","parameters":{"id":507,"nodeType":"ParameterList","parameters":[{"constant":false,"id":506,"indexed":false,"mutability":"mutable","name":"lockedUntil","nameLocation":"1256:11:7","nodeType":"VariableDeclaration","scope":508,"src":"1248:19:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":505,"name":"uint256","nodeType":"ElementaryTypeName","src":"1248:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1247:21:7"},"src":"1230:39:7"},{"body":{"id":521,"nodeType":"Block","src":"1359:77:7","statements":[{"condition":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":515,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"expression":{"id":511,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"1373:3:7","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":512,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"1377:6:7","memberName":"sender","nodeType":"MemberAccess","src":"1373:10:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"!=","rightExpression":{"arguments":[],"expression":{"argumentTypes":[],"id":513,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":748,"src":"1387:5:7","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_address_$","typeString":"function () view returns (address)"}},"id":514,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1387:7:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"1373:21:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":519,"nodeType":"IfStatement","src":"1369:49:7","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":516,"name":"NotAuthorized","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":459,"src":"1403:13:7","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":517,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1403:15:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":518,"nodeType":"RevertStatement","src":"1396:22:7"}},{"id":520,"nodeType":"PlaceholderStatement","src":"1428:1:7"}]},"documentation":{"id":509,"nodeType":"StructuredDocumentation","src":"1275:58:7","text":"@dev reverts if caller is not the owner of the account"},"id":522,"name":"onlyOwner","nameLocation":"1347:9:7","nodeType":"ModifierDefinition","parameters":{"id":510,"nodeType":"ParameterList","parameters":[],"src":"1356:2:7"},"src":"1338:98:7","virtual":false,"visibility":"internal"},{"body":{"id":535,"nodeType":"Block","src":"1544:81:7","statements":[{"condition":{"id":529,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"!","prefix":true,"src":"1558:25:7","subExpression":{"arguments":[{"expression":{"id":526,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"1572:3:7","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":527,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"1576:6:7","memberName":"sender","nodeType":"MemberAccess","src":"1572:10:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":525,"name":"isAuthorized","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":790,"src":"1559:12:7","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_address_$returns$_t_bool_$","typeString":"function (address) view returns (bool)"}},"id":528,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1559:24:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":533,"nodeType":"IfStatement","src":"1554:53:7","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":530,"name":"NotAuthorized","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":459,"src":"1592:13:7","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":531,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1592:15:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":532,"nodeType":"RevertStatement","src":"1585:22:7"}},{"id":534,"nodeType":"PlaceholderStatement","src":"1617:1:7"}]},"documentation":{"id":523,"nodeType":"StructuredDocumentation","src":"1442:71:7","text":"@dev reverts if caller is not authorized to execute on this account"},"id":536,"name":"onlyAuthorized","nameLocation":"1527:14:7","nodeType":"ModifierDefinition","parameters":{"id":524,"nodeType":"ParameterList","parameters":[],"src":"1541:2:7"},"src":"1518:107:7","virtual":false,"visibility":"internal"},{"body":{"id":546,"nodeType":"Block","src":"1712:66:7","statements":[{"condition":{"arguments":[],"expression":{"argumentTypes":[],"id":539,"name":"isLocked","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":699,"src":"1726:8:7","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_bool_$","typeString":"function () view returns (bool)"}},"id":540,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1726:10:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":544,"nodeType":"IfStatement","src":"1722:38:7","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":541,"name":"AccountLocked","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":463,"src":"1745:13:7","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":542,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1745:15:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":543,"nodeType":"RevertStatement","src":"1738:22:7"}},{"id":545,"nodeType":"PlaceholderStatement","src":"1770:1:7"}]},"documentation":{"id":537,"nodeType":"StructuredDocumentation","src":"1631:52:7","text":"@dev reverts if this account is currently locked"},"id":547,"name":"onlyUnlocked","nameLocation":"1697:12:7","nodeType":"ModifierDefinition","parameters":{"id":538,"nodeType":"ParameterList","parameters":[],"src":"1709:2:7"},"src":"1688:90:7","virtual":false,"visibility":"internal"},{"body":{"id":550,"nodeType":"Block","src":"1798:2:7","statements":[]},"id":551,"implemented":true,"kind":"constructor","modifiers":[],"name":"","nameLocation":"-1:-1:-1","nodeType":"FunctionDefinition","parameters":{"id":548,"nodeType":"ParameterList","parameters":[],"src":"1795:2:7"},"returnParameters":{"id":549,"nodeType":"ParameterList","parameters":[],"src":"1798:0:7"},"scope":983,"src":"1784:16:7","stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"baseFunctions":[1221],"body":{"id":555,"nodeType":"Block","src":"1916:7:7","statements":[]},"documentation":{"id":552,"nodeType":"StructuredDocumentation","src":"1806:78:7","text":"@dev allows eth transfers by default, but allows account owner to override"},"id":556,"implemented":true,"kind":"receive","modifiers":[],"name":"","nameLocation":"-1:-1:-1","nodeType":"FunctionDefinition","parameters":{"id":553,"nodeType":"ParameterList","parameters":[],"src":"1896:2:7"},"returnParameters":{"id":554,"nodeType":"ParameterList","parameters":[],"src":"1916:0:7"},"scope":983,"src":"1889:34:7","stateMutability":"payable","virtual":false,"visibility":"external"},{"baseFunctions":[1232],"body":{"id":584,"nodeType":"Block","src":"2196:98:7","statements":[{"eventCall":{"arguments":[{"id":573,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":559,"src":"2231:2:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":574,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":561,"src":"2235:5:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":575,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":563,"src":"2242:4:7","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}],"id":572,"name":"TransactionExecuted","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1218,"src":"2211:19:7","typeDescriptions":{"typeIdentifier":"t_function_event_nonpayable$_t_address_$_t_uint256_$_t_bytes_memory_ptr_$returns$__$","typeString":"function (address,uint256,bytes memory)"}},"id":576,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2211:36:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":577,"nodeType":"EmitStatement","src":"2206:41:7"},{"expression":{"arguments":[{"id":579,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":559,"src":"2271:2:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":580,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":561,"src":"2275:5:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":581,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":563,"src":"2282:4:7","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}],"id":578,"name":"_call","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":954,"src":"2265:5:7","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_uint256_$_t_bytes_calldata_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (address,uint256,bytes calldata) returns (bytes memory)"}},"id":582,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2265:22:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"functionReturnParameters":571,"id":583,"nodeType":"Return","src":"2258:29:7"}]},"documentation":{"id":557,"nodeType":"StructuredDocumentation","src":"1929:95:7","text":"@dev executes a low-level call against an account if the caller is authorized to make calls"},"functionSelector":"9e5d4c49","id":585,"implemented":true,"kind":"function","modifiers":[{"id":566,"kind":"modifierInvocation","modifierName":{"id":565,"name":"onlyAuthorized","nameLocations":["2145:14:7"],"nodeType":"IdentifierPath","referencedDeclaration":536,"src":"2145:14:7"},"nodeType":"ModifierInvocation","src":"2145:14:7"},{"id":568,"kind":"modifierInvocation","modifierName":{"id":567,"name":"onlyUnlocked","nameLocations":["2160:12:7"],"nodeType":"IdentifierPath","referencedDeclaration":547,"src":"2160:12:7"},"nodeType":"ModifierInvocation","src":"2160:12:7"}],"name":"executeCall","nameLocation":"2038:11:7","nodeType":"FunctionDefinition","parameters":{"id":564,"nodeType":"ParameterList","parameters":[{"constant":false,"id":559,"mutability":"mutable","name":"to","nameLocation":"2067:2:7","nodeType":"VariableDeclaration","scope":585,"src":"2059:10:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":558,"name":"address","nodeType":"ElementaryTypeName","src":"2059:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":561,"mutability":"mutable","name":"value","nameLocation":"2087:5:7","nodeType":"VariableDeclaration","scope":585,"src":"2079:13:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":560,"name":"uint256","nodeType":"ElementaryTypeName","src":"2079:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":563,"mutability":"mutable","name":"data","nameLocation":"2117:4:7","nodeType":"VariableDeclaration","scope":585,"src":"2102:19:7","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":562,"name":"bytes","nodeType":"ElementaryTypeName","src":"2102:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"2049:78:7"},"returnParameters":{"id":571,"nodeType":"ParameterList","parameters":[{"constant":false,"id":570,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":585,"src":"2182:12:7","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":569,"name":"bytes","nodeType":"ElementaryTypeName","src":"2182:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"2181:14:7"},"scope":983,"src":"2029:265:7","stateMutability":"payable","virtual":false,"visibility":"external"},{"body":{"id":657,"nodeType":"Block","src":"2483:402:7","statements":[{"assignments":[598],"declarations":[{"constant":false,"id":598,"mutability":"mutable","name":"_owner","nameLocation":"2501:6:7","nodeType":"VariableDeclaration","scope":657,"src":"2493:14:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":597,"name":"address","nodeType":"ElementaryTypeName","src":"2493:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":601,"initialValue":{"arguments":[],"expression":{"argumentTypes":[],"id":599,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":748,"src":"2510:5:7","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_address_$","typeString":"function () view returns (address)"}},"id":600,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2510:7:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"2493:24:7"},{"condition":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":605,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"expression":{"id":602,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"2531:3:7","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":603,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"2535:6:7","memberName":"sender","nodeType":"MemberAccess","src":"2531:10:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"!=","rightExpression":{"id":604,"name":"_owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":598,"src":"2545:6:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"2531:20:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":609,"nodeType":"IfStatement","src":"2527:48:7","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":606,"name":"NotAuthorized","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":459,"src":"2560:13:7","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":607,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2560:15:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":608,"nodeType":"RevertStatement","src":"2553:22:7"}},{"assignments":[611],"declarations":[{"constant":false,"id":611,"mutability":"mutable","name":"length","nameLocation":"2594:6:7","nodeType":"VariableDeclaration","scope":657,"src":"2586:14:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":610,"name":"uint256","nodeType":"ElementaryTypeName","src":"2586:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":614,"initialValue":{"expression":{"id":612,"name":"callers","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":589,"src":"2603:7:7","typeDescriptions":{"typeIdentifier":"t_array$_t_address_$dyn_calldata_ptr","typeString":"address[] calldata"}},"id":613,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"2611:6:7","memberName":"length","nodeType":"MemberAccess","src":"2603:14:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"2586:31:7"},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":618,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"expression":{"id":615,"name":"_permissions","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":592,"src":"2632:12:7","typeDescriptions":{"typeIdentifier":"t_array$_t_bool_$dyn_calldata_ptr","typeString":"bool[] calldata"}},"id":616,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"2645:6:7","memberName":"length","nodeType":"MemberAccess","src":"2632:19:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"!=","rightExpression":{"id":617,"name":"length","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":611,"src":"2655:6:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"2632:29:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":622,"nodeType":"IfStatement","src":"2628:56:7","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":619,"name":"InvalidInput","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":461,"src":"2670:12:7","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":620,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2670:14:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":621,"nodeType":"RevertStatement","src":"2663:21:7"}},{"body":{"id":655,"nodeType":"Block","src":"2732:147:7","statements":[{"expression":{"id":643,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"baseExpression":{"baseExpression":{"id":633,"name":"permissions","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":488,"src":"2746:11:7","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_mapping$_t_address_$_t_bool_$_$","typeString":"mapping(address => mapping(address => bool))"}},"id":638,"indexExpression":{"id":634,"name":"_owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":598,"src":"2758:6:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"2746:19:7","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_bool_$","typeString":"mapping(address => bool)"}},"id":639,"indexExpression":{"baseExpression":{"id":635,"name":"callers","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":589,"src":"2766:7:7","typeDescriptions":{"typeIdentifier":"t_array$_t_address_$dyn_calldata_ptr","typeString":"address[] calldata"}},"id":637,"indexExpression":{"id":636,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":624,"src":"2774:1:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"2766:10:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"IndexAccess","src":"2746:31:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"baseExpression":{"id":640,"name":"_permissions","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":592,"src":"2780:12:7","typeDescriptions":{"typeIdentifier":"t_array$_t_bool_$dyn_calldata_ptr","typeString":"bool[] calldata"}},"id":642,"indexExpression":{"id":641,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":624,"src":"2793:1:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"2780:15:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"2746:49:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":644,"nodeType":"ExpressionStatement","src":"2746:49:7"},{"eventCall":{"arguments":[{"id":646,"name":"_owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":598,"src":"2832:6:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"baseExpression":{"id":647,"name":"callers","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":589,"src":"2840:7:7","typeDescriptions":{"typeIdentifier":"t_array$_t_address_$dyn_calldata_ptr","typeString":"address[] calldata"}},"id":649,"indexExpression":{"id":648,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":624,"src":"2848:1:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"2840:10:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"baseExpression":{"id":650,"name":"_permissions","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":592,"src":"2852:12:7","typeDescriptions":{"typeIdentifier":"t_array$_t_bool_$dyn_calldata_ptr","typeString":"bool[] calldata"}},"id":652,"indexExpression":{"id":651,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":624,"src":"2865:1:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"2852:15:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_bool","typeString":"bool"}],"id":645,"name":"PermissionUpdated","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":504,"src":"2814:17:7","typeDescriptions":{"typeIdentifier":"t_function_event_nonpayable$_t_address_$_t_address_$_t_bool_$returns$__$","typeString":"function (address,address,bool)"}},"id":653,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2814:54:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":654,"nodeType":"EmitStatement","src":"2809:59:7"}]},"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":629,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":627,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":624,"src":"2715:1:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"<","rightExpression":{"id":628,"name":"length","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":611,"src":"2719:6:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"2715:10:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":656,"initializationExpression":{"assignments":[624],"declarations":[{"constant":false,"id":624,"mutability":"mutable","name":"i","nameLocation":"2708:1:7","nodeType":"VariableDeclaration","scope":656,"src":"2700:9:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":623,"name":"uint256","nodeType":"ElementaryTypeName","src":"2700:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":626,"initialValue":{"hexValue":"30","id":625,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"2712:1:7","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"nodeType":"VariableDeclarationStatement","src":"2700:13:7"},"loopExpression":{"expression":{"id":631,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"2727:3:7","subExpression":{"id":630,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":624,"src":"2727:1:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":632,"nodeType":"ExpressionStatement","src":"2727:3:7"},"nodeType":"ForStatement","src":"2695:184:7"}]},"documentation":{"id":586,"nodeType":"StructuredDocumentation","src":"2300:52:7","text":"@dev grants a given caller execution permissions"},"functionSelector":"039721b1","id":658,"implemented":true,"kind":"function","modifiers":[{"id":595,"kind":"modifierInvocation","modifierName":{"id":594,"name":"onlyUnlocked","nameLocations":["2470:12:7"],"nodeType":"IdentifierPath","referencedDeclaration":547,"src":"2470:12:7"},"nodeType":"ModifierInvocation","src":"2470:12:7"}],"name":"setPermissions","nameLocation":"2366:14:7","nodeType":"FunctionDefinition","parameters":{"id":593,"nodeType":"ParameterList","parameters":[{"constant":false,"id":589,"mutability":"mutable","name":"callers","nameLocation":"2409:7:7","nodeType":"VariableDeclaration","scope":658,"src":"2390:26:7","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_array$_t_address_$dyn_calldata_ptr","typeString":"address[]"},"typeName":{"baseType":{"id":587,"name":"address","nodeType":"ElementaryTypeName","src":"2390:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":588,"nodeType":"ArrayTypeName","src":"2390:9:7","typeDescriptions":{"typeIdentifier":"t_array$_t_address_$dyn_storage_ptr","typeString":"address[]"}},"visibility":"internal"},{"constant":false,"id":592,"mutability":"mutable","name":"_permissions","nameLocation":"2442:12:7","nodeType":"VariableDeclaration","scope":658,"src":"2426:28:7","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_array$_t_bool_$dyn_calldata_ptr","typeString":"bool[]"},"typeName":{"baseType":{"id":590,"name":"bool","nodeType":"ElementaryTypeName","src":"2426:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":591,"nodeType":"ArrayTypeName","src":"2426:6:7","typeDescriptions":{"typeIdentifier":"t_array$_t_bool_$dyn_storage_ptr","typeString":"bool[]"}},"visibility":"internal"}],"src":"2380:80:7"},"returnParameters":{"id":596,"nodeType":"ParameterList","parameters":[],"src":"2483:0:7"},"scope":983,"src":"2357:528:7","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":686,"nodeType":"Block","src":"3016:181:7","statements":[{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":673,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":668,"name":"_lockedUntil","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":661,"src":"3030:12:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":672,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"expression":{"id":669,"name":"block","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-4,"src":"3045:5:7","typeDescriptions":{"typeIdentifier":"t_magic_block","typeString":"block"}},"id":670,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"3051:9:7","memberName":"timestamp","nodeType":"MemberAccess","src":"3045:15:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"hexValue":"333635","id":671,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3063:8:7","subdenomination":"days","typeDescriptions":{"typeIdentifier":"t_rational_31536000_by_1","typeString":"int_const 31536000"},"value":"365"},"src":"3045:26:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"3030:41:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":677,"nodeType":"IfStatement","src":"3026:86:7","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":674,"name":"ExceedsMaxLockTime","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":465,"src":"3092:18:7","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":675,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3092:20:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":676,"nodeType":"RevertStatement","src":"3085:27:7"}},{"expression":{"id":680,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":678,"name":"lockedUntil","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":481,"src":"3123:11:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":679,"name":"_lockedUntil","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":661,"src":"3137:12:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"3123:26:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":681,"nodeType":"ExpressionStatement","src":"3123:26:7"},{"eventCall":{"arguments":[{"id":683,"name":"_lockedUntil","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":661,"src":"3177:12:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":682,"name":"LockUpdated","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":508,"src":"3165:11:7","typeDescriptions":{"typeIdentifier":"t_function_event_nonpayable$_t_uint256_$returns$__$","typeString":"function (uint256)"}},"id":684,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3165:25:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":685,"nodeType":"EmitStatement","src":"3160:30:7"}]},"documentation":{"id":659,"nodeType":"StructuredDocumentation","src":"2891:52:7","text":"@dev locks the account until a certain timestamp"},"functionSelector":"dd467064","id":687,"implemented":true,"kind":"function","modifiers":[{"id":664,"kind":"modifierInvocation","modifierName":{"id":663,"name":"onlyOwner","nameLocations":["2993:9:7"],"nodeType":"IdentifierPath","referencedDeclaration":522,"src":"2993:9:7"},"nodeType":"ModifierInvocation","src":"2993:9:7"},{"id":666,"kind":"modifierInvocation","modifierName":{"id":665,"name":"onlyUnlocked","nameLocations":["3003:12:7"],"nodeType":"IdentifierPath","referencedDeclaration":547,"src":"3003:12:7"},"nodeType":"ModifierInvocation","src":"3003:12:7"}],"name":"lock","nameLocation":"2957:4:7","nodeType":"FunctionDefinition","parameters":{"id":662,"nodeType":"ParameterList","parameters":[{"constant":false,"id":661,"mutability":"mutable","name":"_lockedUntil","nameLocation":"2970:12:7","nodeType":"VariableDeclaration","scope":687,"src":"2962:20:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":660,"name":"uint256","nodeType":"ElementaryTypeName","src":"2962:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2961:22:7"},"returnParameters":{"id":667,"nodeType":"ParameterList","parameters":[],"src":"3016:0:7"},"scope":983,"src":"2948:249:7","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":698,"nodeType":"Block","src":"3323:53:7","statements":[{"expression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":696,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":693,"name":"lockedUntil","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":481,"src":"3340:11:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"expression":{"id":694,"name":"block","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-4,"src":"3354:5:7","typeDescriptions":{"typeIdentifier":"t_magic_block","typeString":"block"}},"id":695,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"3360:9:7","memberName":"timestamp","nodeType":"MemberAccess","src":"3354:15:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"3340:29:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"functionReturnParameters":692,"id":697,"nodeType":"Return","src":"3333:36:7"}]},"documentation":{"id":688,"nodeType":"StructuredDocumentation","src":"3203:68:7","text":"@dev returns the current lock status of the account as a boolean"},"functionSelector":"a4e2d634","id":699,"implemented":true,"kind":"function","modifiers":[],"name":"isLocked","nameLocation":"3285:8:7","nodeType":"FunctionDefinition","parameters":{"id":689,"nodeType":"ParameterList","parameters":[],"src":"3293:2:7"},"returnParameters":{"id":692,"nodeType":"ParameterList","parameters":[{"constant":false,"id":691,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":699,"src":"3317:4:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":690,"name":"bool","nodeType":"ElementaryTypeName","src":"3317:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"3316:6:7"},"scope":983,"src":"3276:100:7","stateMutability":"view","virtual":false,"visibility":"public"},{"baseFunctions":[1241],"body":{"id":713,"nodeType":"Block","src":"3679:49:7","statements":[{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":709,"name":"ERC6551AccountLib","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1337,"src":"3696:17:7","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_ERC6551AccountLib_$1337_$","typeString":"type(library ERC6551AccountLib)"}},"id":710,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"3714:5:7","memberName":"token","nodeType":"MemberAccess","referencedDeclaration":1314,"src":"3696:23:7","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_uint256_$_t_address_$_t_uint256_$","typeString":"function () view returns (uint256,address,uint256)"}},"id":711,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3696:25:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_uint256_$_t_address_$_t_uint256_$","typeString":"tuple(uint256,address,uint256)"}},"functionReturnParameters":708,"id":712,"nodeType":"Return","src":"3689:32:7"}]},"documentation":{"id":700,"nodeType":"StructuredDocumentation","src":"3382:121:7","text":"@dev Returns the EIP-155 chain ID, token contract address, and token ID for the token that\n owns this account."},"functionSelector":"fc0c546a","id":714,"implemented":true,"kind":"function","modifiers":[],"name":"token","nameLocation":"3517:5:7","nodeType":"FunctionDefinition","parameters":{"id":701,"nodeType":"ParameterList","parameters":[],"src":"3522:2:7"},"returnParameters":{"id":708,"nodeType":"ParameterList","parameters":[{"constant":false,"id":703,"mutability":"mutable","name":"chainId","nameLocation":"3593:7:7","nodeType":"VariableDeclaration","scope":714,"src":"3585:15:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":702,"name":"uint256","nodeType":"ElementaryTypeName","src":"3585:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":705,"mutability":"mutable","name":"tokenContract","nameLocation":"3622:13:7","nodeType":"VariableDeclaration","scope":714,"src":"3614:21:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":704,"name":"address","nodeType":"ElementaryTypeName","src":"3614:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":707,"mutability":"mutable","name":"tokenId","nameLocation":"3657:7:7","nodeType":"VariableDeclaration","scope":714,"src":"3649:15:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":706,"name":"uint256","nodeType":"ElementaryTypeName","src":"3649:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3571:103:7"},"scope":983,"src":"3508:220:7","stateMutability":"view","virtual":false,"visibility":"external"},{"baseFunctions":[1246],"body":{"id":747,"nodeType":"Block","src":"3938:263:7","statements":[{"assignments":[721,723,725],"declarations":[{"constant":false,"id":721,"mutability":"mutable","name":"chainId","nameLocation":"3970:7:7","nodeType":"VariableDeclaration","scope":747,"src":"3962:15:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":720,"name":"uint256","nodeType":"ElementaryTypeName","src":"3962:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":723,"mutability":"mutable","name":"tokenContract","nameLocation":"3999:13:7","nodeType":"VariableDeclaration","scope":747,"src":"3991:21:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":722,"name":"address","nodeType":"ElementaryTypeName","src":"3991:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":725,"mutability":"mutable","name":"tokenId","nameLocation":"4034:7:7","nodeType":"VariableDeclaration","scope":747,"src":"4026:15:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":724,"name":"uint256","nodeType":"ElementaryTypeName","src":"4026:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":729,"initialValue":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":726,"name":"ERC6551AccountLib","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1337,"src":"4054:17:7","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_ERC6551AccountLib_$1337_$","typeString":"type(library ERC6551AccountLib)"}},"id":727,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"4072:5:7","memberName":"token","nodeType":"MemberAccess","referencedDeclaration":1314,"src":"4054:23:7","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_uint256_$_t_address_$_t_uint256_$","typeString":"function () view returns (uint256,address,uint256)"}},"id":728,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4054:25:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_uint256_$_t_address_$_t_uint256_$","typeString":"tuple(uint256,address,uint256)"}},"nodeType":"VariableDeclarationStatement","src":"3948:131:7"},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":733,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":730,"name":"chainId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":721,"src":"4094:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"!=","rightExpression":{"expression":{"id":731,"name":"block","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-4,"src":"4105:5:7","typeDescriptions":{"typeIdentifier":"t_magic_block","typeString":"block"}},"id":732,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"4111:7:7","memberName":"chainid","nodeType":"MemberAccess","src":"4105:13:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"4094:24:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":739,"nodeType":"IfStatement","src":"4090:47:7","trueBody":{"expression":{"arguments":[{"hexValue":"30","id":736,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4135:1:7","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"id":735,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4127:7:7","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":734,"name":"address","nodeType":"ElementaryTypeName","src":"4127:7:7","typeDescriptions":{}}},"id":737,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4127:10:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"functionReturnParameters":719,"id":738,"nodeType":"Return","src":"4120:17:7"}},{"expression":{"arguments":[{"id":744,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":725,"src":"4186:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"arguments":[{"id":741,"name":"tokenContract","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":723,"src":"4163:13:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":740,"name":"IERC721","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":170,"src":"4155:7:7","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC721_$170_$","typeString":"type(contract IERC721)"}},"id":742,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4155:22:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_IERC721_$170","typeString":"contract IERC721"}},"id":743,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"4178:7:7","memberName":"ownerOf","nodeType":"MemberAccess","referencedDeclaration":103,"src":"4155:30:7","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_uint256_$returns$_t_address_$","typeString":"function (uint256) view external returns (address)"}},"id":745,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4155:39:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"functionReturnParameters":719,"id":746,"nodeType":"Return","src":"4148:46:7"}]},"documentation":{"id":715,"nodeType":"StructuredDocumentation","src":"3734:152:7","text":"@dev Returns the owner of the ERC-721 token which owns this account. By default, the owner\n of the token has full permissions on the account."},"functionSelector":"8da5cb5b","id":748,"implemented":true,"kind":"function","modifiers":[],"name":"owner","nameLocation":"3900:5:7","nodeType":"FunctionDefinition","parameters":{"id":716,"nodeType":"ParameterList","parameters":[],"src":"3905:2:7"},"returnParameters":{"id":719,"nodeType":"ParameterList","parameters":[{"constant":false,"id":718,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":748,"src":"3929:7:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":717,"name":"address","nodeType":"ElementaryTypeName","src":"3929:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"3928:9:7"},"scope":983,"src":"3891:310:7","stateMutability":"view","virtual":false,"visibility":"public"},{"body":{"id":789,"nodeType":"Block","src":"4337:415:7","statements":[{"assignments":[null,757,759],"declarations":[null,{"constant":false,"id":757,"mutability":"mutable","name":"tokenContract","nameLocation":"4383:13:7","nodeType":"VariableDeclaration","scope":789,"src":"4375:21:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":756,"name":"address","nodeType":"ElementaryTypeName","src":"4375:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":759,"mutability":"mutable","name":"tokenId","nameLocation":"4418:7:7","nodeType":"VariableDeclaration","scope":789,"src":"4410:15:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":758,"name":"uint256","nodeType":"ElementaryTypeName","src":"4410:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":763,"initialValue":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":760,"name":"ERC6551AccountLib","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1337,"src":"4438:17:7","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_ERC6551AccountLib_$1337_$","typeString":"type(library ERC6551AccountLib)"}},"id":761,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"4456:5:7","memberName":"token","nodeType":"MemberAccess","referencedDeclaration":1314,"src":"4438:23:7","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_uint256_$_t_address_$_t_uint256_$","typeString":"function () view returns (uint256,address,uint256)"}},"id":762,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4438:25:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_uint256_$_t_address_$_t_uint256_$","typeString":"tuple(uint256,address,uint256)"}},"nodeType":"VariableDeclarationStatement","src":"4347:116:7"},{"assignments":[765],"declarations":[{"constant":false,"id":765,"mutability":"mutable","name":"_owner","nameLocation":"4481:6:7","nodeType":"VariableDeclaration","scope":789,"src":"4473:14:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":764,"name":"address","nodeType":"ElementaryTypeName","src":"4473:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":772,"initialValue":{"arguments":[{"id":770,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":759,"src":"4521:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"arguments":[{"id":767,"name":"tokenContract","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":757,"src":"4498:13:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":766,"name":"IERC721","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":170,"src":"4490:7:7","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC721_$170_$","typeString":"type(contract IERC721)"}},"id":768,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4490:22:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_IERC721_$170","typeString":"contract IERC721"}},"id":769,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"4513:7:7","memberName":"ownerOf","nodeType":"MemberAccess","referencedDeclaration":103,"src":"4490:30:7","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_uint256_$returns$_t_address_$","typeString":"function (uint256) view external returns (address)"}},"id":771,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4490:39:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"4473:56:7"},{"condition":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":775,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":773,"name":"caller","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":751,"src":"4577:6:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"id":774,"name":"_owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":765,"src":"4587:6:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"4577:16:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":778,"nodeType":"IfStatement","src":"4573:33:7","trueBody":{"expression":{"hexValue":"74727565","id":776,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"4602:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"true"},"functionReturnParameters":755,"id":777,"nodeType":"Return","src":"4595:11:7"}},{"condition":{"baseExpression":{"baseExpression":{"id":779,"name":"permissions","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":488,"src":"4682:11:7","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_mapping$_t_address_$_t_bool_$_$","typeString":"mapping(address => mapping(address => bool))"}},"id":781,"indexExpression":{"id":780,"name":"_owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":765,"src":"4694:6:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"4682:19:7","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_bool_$","typeString":"mapping(address => bool)"}},"id":783,"indexExpression":{"id":782,"name":"caller","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":751,"src":"4702:6:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"4682:27:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":786,"nodeType":"IfStatement","src":"4678:44:7","trueBody":{"expression":{"hexValue":"74727565","id":784,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"4718:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"true"},"functionReturnParameters":755,"id":785,"nodeType":"Return","src":"4711:11:7"}},{"expression":{"hexValue":"66616c7365","id":787,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"4740:5:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"},"functionReturnParameters":755,"id":788,"nodeType":"Return","src":"4733:12:7"}]},"documentation":{"id":749,"nodeType":"StructuredDocumentation","src":"4207:60:7","text":"@dev Returns the authorization status for a given caller"},"functionSelector":"fe9fbb80","id":790,"implemented":true,"kind":"function","modifiers":[],"name":"isAuthorized","nameLocation":"4281:12:7","nodeType":"FunctionDefinition","parameters":{"id":752,"nodeType":"ParameterList","parameters":[{"constant":false,"id":751,"mutability":"mutable","name":"caller","nameLocation":"4302:6:7","nodeType":"VariableDeclaration","scope":790,"src":"4294:14:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":750,"name":"address","nodeType":"ElementaryTypeName","src":"4294:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"4293:16:7"},"returnParameters":{"id":755,"nodeType":"ParameterList","parameters":[{"constant":false,"id":754,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":790,"src":"4331:4:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":753,"name":"bool","nodeType":"ElementaryTypeName","src":"4331:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"4330:6:7"},"scope":983,"src":"4272:480:7","stateMutability":"view","virtual":false,"visibility":"public"},{"baseFunctions":[199],"body":{"id":828,"nodeType":"Block","src":"5009:273:7","statements":[{"assignments":[800],"declarations":[{"constant":false,"id":800,"mutability":"mutable","name":"defaultSupport","nameLocation":"5024:14:7","nodeType":"VariableDeclaration","scope":828,"src":"5019:19:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":799,"name":"bool","nodeType":"ElementaryTypeName","src":"5019:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":821,"initialValue":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":820,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":813,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"id":806,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":801,"name":"interfaceId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":793,"src":"5041:11:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"arguments":[{"id":803,"name":"IERC165","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":200,"src":"5061:7:7","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC165_$200_$","typeString":"type(contract IERC165)"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_type$_t_contract$_IERC165_$200_$","typeString":"type(contract IERC165)"}],"id":802,"name":"type","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-27,"src":"5056:4:7","typeDescriptions":{"typeIdentifier":"t_function_metatype_pure$__$returns$__$","typeString":"function () pure"}},"id":804,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5056:13:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_magic_meta_type_t_contract$_IERC165_$200","typeString":"type(contract IERC165)"}},"id":805,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"5070:11:7","memberName":"interfaceId","nodeType":"MemberAccess","src":"5056:25:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"src":"5041:40:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"||","rightExpression":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"id":812,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":807,"name":"interfaceId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":793,"src":"5097:11:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"arguments":[{"id":809,"name":"IERC1155Receiver","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":54,"src":"5117:16:7","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC1155Receiver_$54_$","typeString":"type(contract IERC1155Receiver)"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_type$_t_contract$_IERC1155Receiver_$54_$","typeString":"type(contract IERC1155Receiver)"}],"id":808,"name":"type","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-27,"src":"5112:4:7","typeDescriptions":{"typeIdentifier":"t_function_metatype_pure$__$returns$__$","typeString":"function () pure"}},"id":810,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5112:22:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_magic_meta_type_t_contract$_IERC1155Receiver_$54","typeString":"type(contract IERC1155Receiver)"}},"id":811,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"5135:11:7","memberName":"interfaceId","nodeType":"MemberAccess","src":"5112:34:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"src":"5097:49:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"5041:105:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"||","rightExpression":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"id":819,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":814,"name":"interfaceId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":793,"src":"5162:11:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"arguments":[{"id":816,"name":"IERC6551Account","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1247,"src":"5182:15:7","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC6551Account_$1247_$","typeString":"type(contract IERC6551Account)"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_type$_t_contract$_IERC6551Account_$1247_$","typeString":"type(contract IERC6551Account)"}],"id":815,"name":"type","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-27,"src":"5177:4:7","typeDescriptions":{"typeIdentifier":"t_function_metatype_pure$__$returns$__$","typeString":"function () pure"}},"id":817,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5177:21:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_magic_meta_type_t_contract$_IERC6551Account_$1247","typeString":"type(contract IERC6551Account)"}},"id":818,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"5199:11:7","memberName":"interfaceId","nodeType":"MemberAccess","src":"5177:33:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"src":"5162:48:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"5041:169:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"5019:191:7"},{"condition":{"id":822,"name":"defaultSupport","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":800,"src":"5225:14:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":825,"nodeType":"IfStatement","src":"5221:31:7","trueBody":{"expression":{"hexValue":"74727565","id":823,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"5248:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"true"},"functionReturnParameters":798,"id":824,"nodeType":"Return","src":"5241:11:7"}},{"expression":{"hexValue":"66616c7365","id":826,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"5270:5:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"},"functionReturnParameters":798,"id":827,"nodeType":"Return","src":"5263:12:7"}]},"documentation":{"id":791,"nodeType":"StructuredDocumentation","src":"4758:126:7","text":"@dev Returns true if a given interfaceId is supported by this account. This method can be\n extended by an override."},"functionSelector":"01ffc9a7","id":829,"implemented":true,"kind":"function","modifiers":[],"name":"supportsInterface","nameLocation":"4898:17:7","nodeType":"FunctionDefinition","overrides":{"id":795,"nodeType":"OverrideSpecifier","overrides":[],"src":"4973:8:7"},"parameters":{"id":794,"nodeType":"ParameterList","parameters":[{"constant":false,"id":793,"mutability":"mutable","name":"interfaceId","nameLocation":"4923:11:7","nodeType":"VariableDeclaration","scope":829,"src":"4916:18:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":792,"name":"bytes4","nodeType":"ElementaryTypeName","src":"4916:6:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"4915:20:7"},"returnParameters":{"id":798,"nodeType":"ParameterList","parameters":[{"constant":false,"id":797,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":829,"src":"4999:4:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":796,"name":"bool","nodeType":"ElementaryTypeName","src":"4999:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"4998:6:7"},"scope":983,"src":"4889:393:7","stateMutability":"pure","virtual":false,"visibility":"public"},{"baseFunctions":[187],"body":{"id":875,"nodeType":"Block","src":"5586:367:7","statements":[{"assignments":[845,847,849],"declarations":[{"constant":false,"id":845,"mutability":"mutable","name":"chainId","nameLocation":"5618:7:7","nodeType":"VariableDeclaration","scope":875,"src":"5610:15:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":844,"name":"uint256","nodeType":"ElementaryTypeName","src":"5610:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":847,"mutability":"mutable","name":"tokenContract","nameLocation":"5647:13:7","nodeType":"VariableDeclaration","scope":875,"src":"5639:21:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":846,"name":"address","nodeType":"ElementaryTypeName","src":"5639:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":849,"mutability":"mutable","name":"tokenId","nameLocation":"5682:7:7","nodeType":"VariableDeclaration","scope":875,"src":"5674:15:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":848,"name":"uint256","nodeType":"ElementaryTypeName","src":"5674:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":853,"initialValue":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":850,"name":"ERC6551AccountLib","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1337,"src":"5702:17:7","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_ERC6551AccountLib_$1337_$","typeString":"type(library ERC6551AccountLib)"}},"id":851,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"5720:5:7","memberName":"token","nodeType":"MemberAccess","referencedDeclaration":1314,"src":"5702:23:7","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_uint256_$_t_address_$_t_uint256_$","typeString":"function () view returns (uint256,address,uint256)"}},"id":852,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5702:25:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_uint256_$_t_address_$_t_uint256_$","typeString":"tuple(uint256,address,uint256)"}},"nodeType":"VariableDeclarationStatement","src":"5596:131:7"},{"condition":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":866,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":862,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":857,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":854,"name":"chainId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":845,"src":"5755:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"id":855,"name":"block","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-4,"src":"5766:5:7","typeDescriptions":{"typeIdentifier":"t_magic_block","typeString":"block"}},"id":856,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"5772:7:7","memberName":"chainid","nodeType":"MemberAccess","src":"5766:13:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5755:24:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"&&","rightExpression":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":861,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":858,"name":"tokenContract","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":847,"src":"5795:13:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"id":859,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"5812:3:7","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":860,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"5816:6:7","memberName":"sender","nodeType":"MemberAccess","src":"5812:10:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"5795:27:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"5755:67:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"&&","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":865,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":863,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":849,"src":"5838:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"id":864,"name":"receivedTokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":836,"src":"5849:15:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5838:26:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"5755:109:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":870,"nodeType":"IfStatement","src":"5738:160:7","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":867,"name":"OwnershipCycle","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":469,"src":"5882:14:7","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":868,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5882:16:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":869,"nodeType":"RevertStatement","src":"5875:23:7"}},{"expression":{"expression":{"expression":{"id":871,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"5916:4:7","typeDescriptions":{"typeIdentifier":"t_contract$_MinimalisticAccount_$983","typeString":"contract MinimalisticAccount"}},"id":872,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"5921:16:7","memberName":"onERC721Received","nodeType":"MemberAccess","referencedDeclaration":876,"src":"5916:21:7","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$_t_address_$_t_uint256_$_t_bytes_memory_ptr_$returns$_t_bytes4_$","typeString":"function (address,address,uint256,bytes memory) view external returns (bytes4)"}},"id":873,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"5938:8:7","memberName":"selector","nodeType":"MemberAccess","src":"5916:30:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"functionReturnParameters":843,"id":874,"nodeType":"Return","src":"5909:37:7"}]},"documentation":{"id":830,"nodeType":"StructuredDocumentation","src":"5288:134:7","text":"@dev Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle.\n This function can be overriden."},"functionSelector":"150b7a02","id":876,"implemented":true,"kind":"function","modifiers":[],"name":"onERC721Received","nameLocation":"5436:16:7","nodeType":"FunctionDefinition","overrides":{"id":840,"nodeType":"OverrideSpecifier","overrides":[],"src":"5560:8:7"},"parameters":{"id":839,"nodeType":"ParameterList","parameters":[{"constant":false,"id":832,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":876,"src":"5462:7:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":831,"name":"address","nodeType":"ElementaryTypeName","src":"5462:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":834,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":876,"src":"5479:7:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":833,"name":"address","nodeType":"ElementaryTypeName","src":"5479:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":836,"mutability":"mutable","name":"receivedTokenId","nameLocation":"5504:15:7","nodeType":"VariableDeclaration","scope":876,"src":"5496:23:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":835,"name":"uint256","nodeType":"ElementaryTypeName","src":"5496:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":838,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":876,"src":"5529:12:7","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":837,"name":"bytes","nodeType":"ElementaryTypeName","src":"5529:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"5452:95:7"},"returnParameters":{"id":843,"nodeType":"ParameterList","parameters":[{"constant":false,"id":842,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":876,"src":"5578:6:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":841,"name":"bytes4","nodeType":"ElementaryTypeName","src":"5578:6:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"5577:8:7"},"scope":983,"src":"5427:526:7","stateMutability":"view","virtual":false,"visibility":"public"},{"baseFunctions":[35],"body":{"id":897,"nodeType":"Block","src":"6204:55:7","statements":[{"expression":{"expression":{"expression":{"id":893,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"6221:4:7","typeDescriptions":{"typeIdentifier":"t_contract$_MinimalisticAccount_$983","typeString":"contract MinimalisticAccount"}},"id":894,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"6226:17:7","memberName":"onERC1155Received","nodeType":"MemberAccess","referencedDeclaration":898,"src":"6221:22:7","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_address_$_t_address_$_t_uint256_$_t_uint256_$_t_bytes_memory_ptr_$returns$_t_bytes4_$","typeString":"function (address,address,uint256,uint256,bytes memory) pure external returns (bytes4)"}},"id":895,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"6244:8:7","memberName":"selector","nodeType":"MemberAccess","src":"6221:31:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"functionReturnParameters":892,"id":896,"nodeType":"Return","src":"6214:38:7"}]},"documentation":{"id":877,"nodeType":"StructuredDocumentation","src":"5959:79:7","text":"@dev Allows ERC-1155 tokens to be received. This function can be overriden."},"functionSelector":"f23a6e61","id":898,"implemented":true,"kind":"function","modifiers":[],"name":"onERC1155Received","nameLocation":"6052:17:7","nodeType":"FunctionDefinition","overrides":{"id":889,"nodeType":"OverrideSpecifier","overrides":[],"src":"6178:8:7"},"parameters":{"id":888,"nodeType":"ParameterList","parameters":[{"constant":false,"id":879,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":898,"src":"6079:7:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":878,"name":"address","nodeType":"ElementaryTypeName","src":"6079:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":881,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":898,"src":"6096:7:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":880,"name":"address","nodeType":"ElementaryTypeName","src":"6096:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":883,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":898,"src":"6113:7:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":882,"name":"uint256","nodeType":"ElementaryTypeName","src":"6113:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":885,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":898,"src":"6130:7:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":884,"name":"uint256","nodeType":"ElementaryTypeName","src":"6130:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":887,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":898,"src":"6147:12:7","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":886,"name":"bytes","nodeType":"ElementaryTypeName","src":"6147:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"6069:96:7"},"returnParameters":{"id":892,"nodeType":"ParameterList","parameters":[{"constant":false,"id":891,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":898,"src":"6196:6:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":890,"name":"bytes4","nodeType":"ElementaryTypeName","src":"6196:6:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"6195:8:7"},"scope":983,"src":"6043:216:7","stateMutability":"pure","virtual":false,"visibility":"public"},{"baseFunctions":[53],"body":{"id":921,"nodeType":"Block","src":"6540:60:7","statements":[{"expression":{"expression":{"expression":{"id":917,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"6557:4:7","typeDescriptions":{"typeIdentifier":"t_contract$_MinimalisticAccount_$983","typeString":"contract MinimalisticAccount"}},"id":918,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"6562:22:7","memberName":"onERC1155BatchReceived","nodeType":"MemberAccess","referencedDeclaration":922,"src":"6557:27:7","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_address_$_t_address_$_t_array$_t_uint256_$dyn_memory_ptr_$_t_array$_t_uint256_$dyn_memory_ptr_$_t_bytes_memory_ptr_$returns$_t_bytes4_$","typeString":"function (address,address,uint256[] memory,uint256[] memory,bytes memory) pure external returns (bytes4)"}},"id":919,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"6585:8:7","memberName":"selector","nodeType":"MemberAccess","src":"6557:36:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"functionReturnParameters":916,"id":920,"nodeType":"Return","src":"6550:43:7"}]},"documentation":{"id":899,"nodeType":"StructuredDocumentation","src":"6265:86:7","text":"@dev Allows ERC-1155 token batches to be received. This function can be overriden."},"functionSelector":"bc197c81","id":922,"implemented":true,"kind":"function","modifiers":[],"name":"onERC1155BatchReceived","nameLocation":"6365:22:7","nodeType":"FunctionDefinition","overrides":{"id":913,"nodeType":"OverrideSpecifier","overrides":[],"src":"6514:8:7"},"parameters":{"id":912,"nodeType":"ParameterList","parameters":[{"constant":false,"id":901,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":922,"src":"6397:7:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":900,"name":"address","nodeType":"ElementaryTypeName","src":"6397:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":903,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":922,"src":"6414:7:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":902,"name":"address","nodeType":"ElementaryTypeName","src":"6414:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":906,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":922,"src":"6431:16:7","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_memory_ptr","typeString":"uint256[]"},"typeName":{"baseType":{"id":904,"name":"uint256","nodeType":"ElementaryTypeName","src":"6431:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":905,"nodeType":"ArrayTypeName","src":"6431:9:7","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_storage_ptr","typeString":"uint256[]"}},"visibility":"internal"},{"constant":false,"id":909,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":922,"src":"6457:16:7","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_memory_ptr","typeString":"uint256[]"},"typeName":{"baseType":{"id":907,"name":"uint256","nodeType":"ElementaryTypeName","src":"6457:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":908,"nodeType":"ArrayTypeName","src":"6457:9:7","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_storage_ptr","typeString":"uint256[]"}},"visibility":"internal"},{"constant":false,"id":911,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":922,"src":"6483:12:7","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":910,"name":"bytes","nodeType":"ElementaryTypeName","src":"6483:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"6387:114:7"},"returnParameters":{"id":916,"nodeType":"ParameterList","parameters":[{"constant":false,"id":915,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":922,"src":"6532:6:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":914,"name":"bytes4","nodeType":"ElementaryTypeName","src":"6532:6:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"6531:8:7"},"scope":983,"src":"6356:244:7","stateMutability":"pure","virtual":false,"visibility":"public"},{"body":{"id":953,"nodeType":"Block","src":"6777:213:7","statements":[{"assignments":[935],"declarations":[{"constant":false,"id":935,"mutability":"mutable","name":"success","nameLocation":"6792:7:7","nodeType":"VariableDeclaration","scope":953,"src":"6787:12:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":934,"name":"bool","nodeType":"ElementaryTypeName","src":"6787:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":936,"nodeType":"VariableDeclarationStatement","src":"6787:12:7"},{"expression":{"id":946,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"components":[{"id":937,"name":"success","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":935,"src":"6810:7:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"id":938,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":932,"src":"6819:6:7","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"id":939,"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"TupleExpression","src":"6809:17:7","typeDescriptions":{"typeIdentifier":"t_tuple$_t_bool_$_t_bytes_memory_ptr_$","typeString":"tuple(bool,bytes memory)"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"arguments":[{"id":944,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":929,"src":"6851:4:7","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}],"expression":{"id":940,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":925,"src":"6829:2:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":941,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"6832:4:7","memberName":"call","nodeType":"MemberAccess","src":"6829:7:7","typeDescriptions":{"typeIdentifier":"t_function_barecall_payable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$","typeString":"function (bytes memory) payable returns (bool,bytes memory)"}},"id":943,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"names":["value"],"nodeType":"FunctionCallOptions","options":[{"id":942,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":927,"src":"6844:5:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"src":"6829:21:7","typeDescriptions":{"typeIdentifier":"t_function_barecall_payable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$value","typeString":"function (bytes memory) payable returns (bool,bytes memory)"}},"id":945,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"6829:27:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_bool_$_t_bytes_memory_ptr_$","typeString":"tuple(bool,bytes memory)"}},"src":"6809:47:7","typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":947,"nodeType":"ExpressionStatement","src":"6809:47:7"},{"condition":{"id":949,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"!","prefix":true,"src":"6871:8:7","subExpression":{"id":948,"name":"success","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":935,"src":"6872:7:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":952,"nodeType":"IfStatement","src":"6867:117:7","trueBody":{"id":951,"nodeType":"Block","src":"6881:103:7","statements":[{"AST":{"nodeType":"YulBlock","src":"6904:70:7","statements":[{"expression":{"arguments":[{"arguments":[{"name":"result","nodeType":"YulIdentifier","src":"6933:6:7"},{"kind":"number","nodeType":"YulLiteral","src":"6941:2:7","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6929:3:7"},"nodeType":"YulFunctionCall","src":"6929:15:7"},{"arguments":[{"name":"result","nodeType":"YulIdentifier","src":"6952:6:7"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"6946:5:7"},"nodeType":"YulFunctionCall","src":"6946:13:7"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"6922:6:7"},"nodeType":"YulFunctionCall","src":"6922:38:7"},"nodeType":"YulExpressionStatement","src":"6922:38:7"}]},"evmVersion":"london","externalReferences":[{"declaration":932,"isOffset":false,"isSlot":false,"src":"6933:6:7","valueSize":1},{"declaration":932,"isOffset":false,"isSlot":false,"src":"6952:6:7","valueSize":1}],"id":950,"nodeType":"InlineAssembly","src":"6895:79:7"}]}}]},"documentation":{"id":923,"nodeType":"StructuredDocumentation","src":"6606:34:7","text":"@dev Executes a low-level call"},"id":954,"implemented":true,"kind":"function","modifiers":[],"name":"_call","nameLocation":"6654:5:7","nodeType":"FunctionDefinition","parameters":{"id":930,"nodeType":"ParameterList","parameters":[{"constant":false,"id":925,"mutability":"mutable","name":"to","nameLocation":"6677:2:7","nodeType":"VariableDeclaration","scope":954,"src":"6669:10:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":924,"name":"address","nodeType":"ElementaryTypeName","src":"6669:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":927,"mutability":"mutable","name":"value","nameLocation":"6697:5:7","nodeType":"VariableDeclaration","scope":954,"src":"6689:13:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":926,"name":"uint256","nodeType":"ElementaryTypeName","src":"6689:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":929,"mutability":"mutable","name":"data","nameLocation":"6727:4:7","nodeType":"VariableDeclaration","scope":954,"src":"6712:19:7","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":928,"name":"bytes","nodeType":"ElementaryTypeName","src":"6712:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"6659:78:7"},"returnParameters":{"id":933,"nodeType":"ParameterList","parameters":[{"constant":false,"id":932,"mutability":"mutable","name":"result","nameLocation":"6769:6:7","nodeType":"VariableDeclaration","scope":954,"src":"6756:19:7","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":931,"name":"bytes","nodeType":"ElementaryTypeName","src":"6756:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"6755:21:7"},"scope":983,"src":"6645:345:7","stateMutability":"nonpayable","virtual":false,"visibility":"internal"},{"body":{"id":981,"nodeType":"Block","src":"7168:205:7","statements":[{"assignments":[965],"declarations":[{"constant":false,"id":965,"mutability":"mutable","name":"success","nameLocation":"7183:7:7","nodeType":"VariableDeclaration","scope":981,"src":"7178:12:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":964,"name":"bool","nodeType":"ElementaryTypeName","src":"7178:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":966,"nodeType":"VariableDeclarationStatement","src":"7178:12:7"},{"expression":{"id":974,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"components":[{"id":967,"name":"success","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":965,"src":"7201:7:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"id":968,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":962,"src":"7210:6:7","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"id":969,"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"TupleExpression","src":"7200:17:7","typeDescriptions":{"typeIdentifier":"t_tuple$_t_bool_$_t_bytes_memory_ptr_$","typeString":"tuple(bool,bytes memory)"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"arguments":[{"id":972,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":959,"src":"7234:4:7","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}],"expression":{"id":970,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":957,"src":"7220:2:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":971,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"7223:10:7","memberName":"staticcall","nodeType":"MemberAccess","src":"7220:13:7","typeDescriptions":{"typeIdentifier":"t_function_barestaticcall_view$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$","typeString":"function (bytes memory) view returns (bool,bytes memory)"}},"id":973,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"7220:19:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_bool_$_t_bytes_memory_ptr_$","typeString":"tuple(bool,bytes memory)"}},"src":"7200:39:7","typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":975,"nodeType":"ExpressionStatement","src":"7200:39:7"},{"condition":{"id":977,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"!","prefix":true,"src":"7254:8:7","subExpression":{"id":976,"name":"success","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":965,"src":"7255:7:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":980,"nodeType":"IfStatement","src":"7250:117:7","trueBody":{"id":979,"nodeType":"Block","src":"7264:103:7","statements":[{"AST":{"nodeType":"YulBlock","src":"7287:70:7","statements":[{"expression":{"arguments":[{"arguments":[{"name":"result","nodeType":"YulIdentifier","src":"7316:6:7"},{"kind":"number","nodeType":"YulLiteral","src":"7324:2:7","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7312:3:7"},"nodeType":"YulFunctionCall","src":"7312:15:7"},{"arguments":[{"name":"result","nodeType":"YulIdentifier","src":"7335:6:7"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"7329:5:7"},"nodeType":"YulFunctionCall","src":"7329:13:7"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7305:6:7"},"nodeType":"YulFunctionCall","src":"7305:38:7"},"nodeType":"YulExpressionStatement","src":"7305:38:7"}]},"evmVersion":"london","externalReferences":[{"declaration":962,"isOffset":false,"isSlot":false,"src":"7316:6:7","valueSize":1},{"declaration":962,"isOffset":false,"isSlot":false,"src":"7335:6:7","valueSize":1}],"id":978,"nodeType":"InlineAssembly","src":"7278:79:7"}]}}]},"documentation":{"id":955,"nodeType":"StructuredDocumentation","src":"6996:41:7","text":"@dev Executes a low-level static call"},"id":982,"implemented":true,"kind":"function","modifiers":[],"name":"_callStatic","nameLocation":"7051:11:7","nodeType":"FunctionDefinition","parameters":{"id":960,"nodeType":"ParameterList","parameters":[{"constant":false,"id":957,"mutability":"mutable","name":"to","nameLocation":"7071:2:7","nodeType":"VariableDeclaration","scope":982,"src":"7063:10:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":956,"name":"address","nodeType":"ElementaryTypeName","src":"7063:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":959,"mutability":"mutable","name":"data","nameLocation":"7090:4:7","nodeType":"VariableDeclaration","scope":982,"src":"7075:19:7","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":958,"name":"bytes","nodeType":"ElementaryTypeName","src":"7075:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"7062:33:7"},"returnParameters":{"id":963,"nodeType":"ParameterList","parameters":[{"constant":false,"id":962,"mutability":"mutable","name":"result","nameLocation":"7156:6:7","nodeType":"VariableDeclaration","scope":982,"src":"7143:19:7","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":961,"name":"bytes","nodeType":"ElementaryTypeName","src":"7143:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"7142:21:7"},"scope":983,"src":"7042:331:7","stateMutability":"view","virtual":false,"visibility":"internal"}],"scope":984,"src":"695:6680:7","usedErrors":[459,461,463,465,469]}],"src":"39:7337:7"},"id":7},"contracts/interfaces/IChargedParticles.sol":{"ast":{"absolutePath":"contracts/interfaces/IChargedParticles.sol","exportedSymbols":{"IChargedParticles":[1201]},"id":1202,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":985,"literals":["solidity",">=","0.6",".0"],"nodeType":"PragmaDirective","src":"1236:24:8"},{"abstract":false,"baseContracts":[],"canonicalName":"IChargedParticles","contractDependencies":[],"contractKind":"interface","documentation":{"id":986,"nodeType":"StructuredDocumentation","src":"1262:50:8","text":" @notice Interface for Charged Particles"},"fullyImplemented":false,"id":1201,"linearizedBaseContracts":[1201],"name":"IChargedParticles","nameLocation":"1323:17:8","nodeType":"ContractDefinition","nodes":[{"functionSelector":"31969e57","id":991,"implemented":false,"kind":"function","modifiers":[],"name":"getStateAddress","nameLocation":"1476:15:8","nodeType":"FunctionDefinition","parameters":{"id":987,"nodeType":"ParameterList","parameters":[],"src":"1491:2:8"},"returnParameters":{"id":990,"nodeType":"ParameterList","parameters":[{"constant":false,"id":989,"mutability":"mutable","name":"stateAddress","nameLocation":"1525:12:8","nodeType":"VariableDeclaration","scope":991,"src":"1517:20:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":988,"name":"address","nodeType":"ElementaryTypeName","src":"1517:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1516:22:8"},"scope":1201,"src":"1467:72:8","stateMutability":"view","virtual":false,"visibility":"external"},{"functionSelector":"d00999fe","id":996,"implemented":false,"kind":"function","modifiers":[],"name":"getSettingsAddress","nameLocation":"1551:18:8","nodeType":"FunctionDefinition","parameters":{"id":992,"nodeType":"ParameterList","parameters":[],"src":"1569:2:8"},"returnParameters":{"id":995,"nodeType":"ParameterList","parameters":[{"constant":false,"id":994,"mutability":"mutable","name":"settingsAddress","nameLocation":"1603:15:8","nodeType":"VariableDeclaration","scope":996,"src":"1595:23:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":993,"name":"address","nodeType":"ElementaryTypeName","src":"1595:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1594:25:8"},"scope":1201,"src":"1542:78:8","stateMutability":"view","virtual":false,"visibility":"external"},{"functionSelector":"8742f168","id":1001,"implemented":false,"kind":"function","modifiers":[],"name":"getManagersAddress","nameLocation":"1632:18:8","nodeType":"FunctionDefinition","parameters":{"id":997,"nodeType":"ParameterList","parameters":[],"src":"1650:2:8"},"returnParameters":{"id":1000,"nodeType":"ParameterList","parameters":[{"constant":false,"id":999,"mutability":"mutable","name":"managersAddress","nameLocation":"1684:15:8","nodeType":"VariableDeclaration","scope":1001,"src":"1676:23:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":998,"name":"address","nodeType":"ElementaryTypeName","src":"1676:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1675:25:8"},"scope":1201,"src":"1623:78:8","stateMutability":"view","virtual":false,"visibility":"external"},{"functionSelector":"ee895623","id":1008,"implemented":false,"kind":"function","modifiers":[],"name":"getFeesForDeposit","nameLocation":"1714:17:8","nodeType":"FunctionDefinition","parameters":{"id":1004,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1003,"mutability":"mutable","name":"assetAmount","nameLocation":"1740:11:8","nodeType":"VariableDeclaration","scope":1008,"src":"1732:19:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1002,"name":"uint256","nodeType":"ElementaryTypeName","src":"1732:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1731:21:8"},"returnParameters":{"id":1007,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1006,"mutability":"mutable","name":"protocolFee","nameLocation":"1784:11:8","nodeType":"VariableDeclaration","scope":1008,"src":"1776:19:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1005,"name":"uint256","nodeType":"ElementaryTypeName","src":"1776:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1775:21:8"},"scope":1201,"src":"1705:92:8","stateMutability":"view","virtual":false,"visibility":"external"},{"functionSelector":"e6ea6ce7","id":1021,"implemented":false,"kind":"function","modifiers":[],"name":"baseParticleMass","nameLocation":"1809:16:8","nodeType":"FunctionDefinition","parameters":{"id":1017,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1010,"mutability":"mutable","name":"contractAddress","nameLocation":"1834:15:8","nodeType":"VariableDeclaration","scope":1021,"src":"1826:23:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1009,"name":"address","nodeType":"ElementaryTypeName","src":"1826:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1012,"mutability":"mutable","name":"tokenId","nameLocation":"1859:7:8","nodeType":"VariableDeclaration","scope":1021,"src":"1851:15:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1011,"name":"uint256","nodeType":"ElementaryTypeName","src":"1851:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1014,"mutability":"mutable","name":"walletManagerId","nameLocation":"1884:15:8","nodeType":"VariableDeclaration","scope":1021,"src":"1868:31:8","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":1013,"name":"string","nodeType":"ElementaryTypeName","src":"1868:6:8","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":1016,"mutability":"mutable","name":"assetToken","nameLocation":"1909:10:8","nodeType":"VariableDeclaration","scope":1021,"src":"1901:18:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1015,"name":"address","nodeType":"ElementaryTypeName","src":"1901:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1825:95:8"},"returnParameters":{"id":1020,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1019,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1021,"src":"1939:7:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1018,"name":"uint256","nodeType":"ElementaryTypeName","src":"1939:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1938:9:8"},"scope":1201,"src":"1800:148:8","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"99fa4c73","id":1034,"implemented":false,"kind":"function","modifiers":[],"name":"currentParticleCharge","nameLocation":"1960:21:8","nodeType":"FunctionDefinition","parameters":{"id":1030,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1023,"mutability":"mutable","name":"contractAddress","nameLocation":"1990:15:8","nodeType":"VariableDeclaration","scope":1034,"src":"1982:23:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1022,"name":"address","nodeType":"ElementaryTypeName","src":"1982:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1025,"mutability":"mutable","name":"tokenId","nameLocation":"2015:7:8","nodeType":"VariableDeclaration","scope":1034,"src":"2007:15:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1024,"name":"uint256","nodeType":"ElementaryTypeName","src":"2007:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1027,"mutability":"mutable","name":"walletManagerId","nameLocation":"2040:15:8","nodeType":"VariableDeclaration","scope":1034,"src":"2024:31:8","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":1026,"name":"string","nodeType":"ElementaryTypeName","src":"2024:6:8","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":1029,"mutability":"mutable","name":"assetToken","nameLocation":"2065:10:8","nodeType":"VariableDeclaration","scope":1034,"src":"2057:18:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1028,"name":"address","nodeType":"ElementaryTypeName","src":"2057:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1981:95:8"},"returnParameters":{"id":1033,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1032,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1034,"src":"2095:7:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1031,"name":"uint256","nodeType":"ElementaryTypeName","src":"2095:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2094:9:8"},"scope":1201,"src":"1951:153:8","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"ca92acd0","id":1047,"implemented":false,"kind":"function","modifiers":[],"name":"currentParticleKinetics","nameLocation":"2116:23:8","nodeType":"FunctionDefinition","parameters":{"id":1043,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1036,"mutability":"mutable","name":"contractAddress","nameLocation":"2148:15:8","nodeType":"VariableDeclaration","scope":1047,"src":"2140:23:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1035,"name":"address","nodeType":"ElementaryTypeName","src":"2140:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1038,"mutability":"mutable","name":"tokenId","nameLocation":"2173:7:8","nodeType":"VariableDeclaration","scope":1047,"src":"2165:15:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1037,"name":"uint256","nodeType":"ElementaryTypeName","src":"2165:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1040,"mutability":"mutable","name":"walletManagerId","nameLocation":"2198:15:8","nodeType":"VariableDeclaration","scope":1047,"src":"2182:31:8","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":1039,"name":"string","nodeType":"ElementaryTypeName","src":"2182:6:8","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":1042,"mutability":"mutable","name":"assetToken","nameLocation":"2223:10:8","nodeType":"VariableDeclaration","scope":1047,"src":"2215:18:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1041,"name":"address","nodeType":"ElementaryTypeName","src":"2215:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"2139:95:8"},"returnParameters":{"id":1046,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1045,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1047,"src":"2253:7:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1044,"name":"uint256","nodeType":"ElementaryTypeName","src":"2253:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2252:9:8"},"scope":1201,"src":"2107:155:8","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"a13eafd5","id":1058,"implemented":false,"kind":"function","modifiers":[],"name":"currentParticleCovalentBonds","nameLocation":"2274:28:8","nodeType":"FunctionDefinition","parameters":{"id":1054,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1049,"mutability":"mutable","name":"contractAddress","nameLocation":"2311:15:8","nodeType":"VariableDeclaration","scope":1058,"src":"2303:23:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1048,"name":"address","nodeType":"ElementaryTypeName","src":"2303:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1051,"mutability":"mutable","name":"tokenId","nameLocation":"2336:7:8","nodeType":"VariableDeclaration","scope":1058,"src":"2328:15:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1050,"name":"uint256","nodeType":"ElementaryTypeName","src":"2328:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1053,"mutability":"mutable","name":"basketManagerId","nameLocation":"2361:15:8","nodeType":"VariableDeclaration","scope":1058,"src":"2345:31:8","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":1052,"name":"string","nodeType":"ElementaryTypeName","src":"2345:6:8","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2302:75:8"},"returnParameters":{"id":1057,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1056,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1058,"src":"2401:7:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1055,"name":"uint256","nodeType":"ElementaryTypeName","src":"2401:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2400:9:8"},"scope":1201,"src":"2265:145:8","stateMutability":"view","virtual":false,"visibility":"external"},{"functionSelector":"0bdde2ca","id":1075,"implemented":false,"kind":"function","modifiers":[],"name":"energizeParticle","nameLocation":"2544:16:8","nodeType":"FunctionDefinition","parameters":{"id":1071,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1060,"mutability":"mutable","name":"contractAddress","nameLocation":"2576:15:8","nodeType":"VariableDeclaration","scope":1075,"src":"2568:23:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1059,"name":"address","nodeType":"ElementaryTypeName","src":"2568:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1062,"mutability":"mutable","name":"tokenId","nameLocation":"2607:7:8","nodeType":"VariableDeclaration","scope":1075,"src":"2599:15:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1061,"name":"uint256","nodeType":"ElementaryTypeName","src":"2599:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1064,"mutability":"mutable","name":"walletManagerId","nameLocation":"2638:15:8","nodeType":"VariableDeclaration","scope":1075,"src":"2622:31:8","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":1063,"name":"string","nodeType":"ElementaryTypeName","src":"2622:6:8","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":1066,"mutability":"mutable","name":"assetToken","nameLocation":"2669:10:8","nodeType":"VariableDeclaration","scope":1075,"src":"2661:18:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1065,"name":"address","nodeType":"ElementaryTypeName","src":"2661:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1068,"mutability":"mutable","name":"assetAmount","nameLocation":"2695:11:8","nodeType":"VariableDeclaration","scope":1075,"src":"2687:19:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1067,"name":"uint256","nodeType":"ElementaryTypeName","src":"2687:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1070,"mutability":"mutable","name":"referrer","nameLocation":"2722:8:8","nodeType":"VariableDeclaration","scope":1075,"src":"2714:16:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1069,"name":"address","nodeType":"ElementaryTypeName","src":"2714:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"2560:174:8"},"returnParameters":{"id":1074,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1073,"mutability":"mutable","name":"yieldTokensAmount","nameLocation":"2761:17:8","nodeType":"VariableDeclaration","scope":1075,"src":"2753:25:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1072,"name":"uint256","nodeType":"ElementaryTypeName","src":"2753:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2752:27:8"},"scope":1201,"src":"2535:245:8","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"621a3b70","id":1092,"implemented":false,"kind":"function","modifiers":[],"name":"dischargeParticle","nameLocation":"2793:17:8","nodeType":"FunctionDefinition","parameters":{"id":1086,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1077,"mutability":"mutable","name":"receiver","nameLocation":"2826:8:8","nodeType":"VariableDeclaration","scope":1092,"src":"2818:16:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1076,"name":"address","nodeType":"ElementaryTypeName","src":"2818:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1079,"mutability":"mutable","name":"contractAddress","nameLocation":"2850:15:8","nodeType":"VariableDeclaration","scope":1092,"src":"2842:23:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1078,"name":"address","nodeType":"ElementaryTypeName","src":"2842:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1081,"mutability":"mutable","name":"tokenId","nameLocation":"2881:7:8","nodeType":"VariableDeclaration","scope":1092,"src":"2873:15:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1080,"name":"uint256","nodeType":"ElementaryTypeName","src":"2873:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1083,"mutability":"mutable","name":"walletManagerId","nameLocation":"2912:15:8","nodeType":"VariableDeclaration","scope":1092,"src":"2896:31:8","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":1082,"name":"string","nodeType":"ElementaryTypeName","src":"2896:6:8","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":1085,"mutability":"mutable","name":"assetToken","nameLocation":"2943:10:8","nodeType":"VariableDeclaration","scope":1092,"src":"2935:18:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1084,"name":"address","nodeType":"ElementaryTypeName","src":"2935:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"2810:147:8"},"returnParameters":{"id":1091,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1088,"mutability":"mutable","name":"creatorAmount","nameLocation":"2984:13:8","nodeType":"VariableDeclaration","scope":1092,"src":"2976:21:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1087,"name":"uint256","nodeType":"ElementaryTypeName","src":"2976:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1090,"mutability":"mutable","name":"receiverAmount","nameLocation":"3007:14:8","nodeType":"VariableDeclaration","scope":1092,"src":"2999:22:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1089,"name":"uint256","nodeType":"ElementaryTypeName","src":"2999:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2975:47:8"},"scope":1201,"src":"2784:239:8","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"6697b359","id":1111,"implemented":false,"kind":"function","modifiers":[],"name":"dischargeParticleAmount","nameLocation":"3036:23:8","nodeType":"FunctionDefinition","parameters":{"id":1105,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1094,"mutability":"mutable","name":"receiver","nameLocation":"3075:8:8","nodeType":"VariableDeclaration","scope":1111,"src":"3067:16:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1093,"name":"address","nodeType":"ElementaryTypeName","src":"3067:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1096,"mutability":"mutable","name":"contractAddress","nameLocation":"3099:15:8","nodeType":"VariableDeclaration","scope":1111,"src":"3091:23:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1095,"name":"address","nodeType":"ElementaryTypeName","src":"3091:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1098,"mutability":"mutable","name":"tokenId","nameLocation":"3130:7:8","nodeType":"VariableDeclaration","scope":1111,"src":"3122:15:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1097,"name":"uint256","nodeType":"ElementaryTypeName","src":"3122:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1100,"mutability":"mutable","name":"walletManagerId","nameLocation":"3161:15:8","nodeType":"VariableDeclaration","scope":1111,"src":"3145:31:8","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":1099,"name":"string","nodeType":"ElementaryTypeName","src":"3145:6:8","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":1102,"mutability":"mutable","name":"assetToken","nameLocation":"3192:10:8","nodeType":"VariableDeclaration","scope":1111,"src":"3184:18:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1101,"name":"address","nodeType":"ElementaryTypeName","src":"3184:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1104,"mutability":"mutable","name":"assetAmount","nameLocation":"3218:11:8","nodeType":"VariableDeclaration","scope":1111,"src":"3210:19:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1103,"name":"uint256","nodeType":"ElementaryTypeName","src":"3210:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3059:174:8"},"returnParameters":{"id":1110,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1107,"mutability":"mutable","name":"creatorAmount","nameLocation":"3260:13:8","nodeType":"VariableDeclaration","scope":1111,"src":"3252:21:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1106,"name":"uint256","nodeType":"ElementaryTypeName","src":"3252:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1109,"mutability":"mutable","name":"receiverAmount","nameLocation":"3283:14:8","nodeType":"VariableDeclaration","scope":1111,"src":"3275:22:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1108,"name":"uint256","nodeType":"ElementaryTypeName","src":"3275:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3251:47:8"},"scope":1201,"src":"3027:272:8","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"65d20ce2","id":1128,"implemented":false,"kind":"function","modifiers":[],"name":"dischargeParticleForCreator","nameLocation":"3312:27:8","nodeType":"FunctionDefinition","parameters":{"id":1124,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1113,"mutability":"mutable","name":"receiver","nameLocation":"3355:8:8","nodeType":"VariableDeclaration","scope":1128,"src":"3347:16:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1112,"name":"address","nodeType":"ElementaryTypeName","src":"3347:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1115,"mutability":"mutable","name":"contractAddress","nameLocation":"3379:15:8","nodeType":"VariableDeclaration","scope":1128,"src":"3371:23:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1114,"name":"address","nodeType":"ElementaryTypeName","src":"3371:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1117,"mutability":"mutable","name":"tokenId","nameLocation":"3410:7:8","nodeType":"VariableDeclaration","scope":1128,"src":"3402:15:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1116,"name":"uint256","nodeType":"ElementaryTypeName","src":"3402:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1119,"mutability":"mutable","name":"walletManagerId","nameLocation":"3441:15:8","nodeType":"VariableDeclaration","scope":1128,"src":"3425:31:8","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":1118,"name":"string","nodeType":"ElementaryTypeName","src":"3425:6:8","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":1121,"mutability":"mutable","name":"assetToken","nameLocation":"3472:10:8","nodeType":"VariableDeclaration","scope":1128,"src":"3464:18:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1120,"name":"address","nodeType":"ElementaryTypeName","src":"3464:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1123,"mutability":"mutable","name":"assetAmount","nameLocation":"3498:11:8","nodeType":"VariableDeclaration","scope":1128,"src":"3490:19:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1122,"name":"uint256","nodeType":"ElementaryTypeName","src":"3490:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3339:174:8"},"returnParameters":{"id":1127,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1126,"mutability":"mutable","name":"receiverAmount","nameLocation":"3540:14:8","nodeType":"VariableDeclaration","scope":1128,"src":"3532:22:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1125,"name":"uint256","nodeType":"ElementaryTypeName","src":"3532:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3531:24:8"},"scope":1201,"src":"3303:253:8","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"acab923c","id":1145,"implemented":false,"kind":"function","modifiers":[],"name":"releaseParticle","nameLocation":"3569:15:8","nodeType":"FunctionDefinition","parameters":{"id":1139,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1130,"mutability":"mutable","name":"receiver","nameLocation":"3600:8:8","nodeType":"VariableDeclaration","scope":1145,"src":"3592:16:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1129,"name":"address","nodeType":"ElementaryTypeName","src":"3592:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1132,"mutability":"mutable","name":"contractAddress","nameLocation":"3624:15:8","nodeType":"VariableDeclaration","scope":1145,"src":"3616:23:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1131,"name":"address","nodeType":"ElementaryTypeName","src":"3616:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1134,"mutability":"mutable","name":"tokenId","nameLocation":"3655:7:8","nodeType":"VariableDeclaration","scope":1145,"src":"3647:15:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1133,"name":"uint256","nodeType":"ElementaryTypeName","src":"3647:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1136,"mutability":"mutable","name":"walletManagerId","nameLocation":"3686:15:8","nodeType":"VariableDeclaration","scope":1145,"src":"3670:31:8","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":1135,"name":"string","nodeType":"ElementaryTypeName","src":"3670:6:8","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":1138,"mutability":"mutable","name":"assetToken","nameLocation":"3717:10:8","nodeType":"VariableDeclaration","scope":1145,"src":"3709:18:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1137,"name":"address","nodeType":"ElementaryTypeName","src":"3709:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"3584:147:8"},"returnParameters":{"id":1144,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1141,"mutability":"mutable","name":"creatorAmount","nameLocation":"3758:13:8","nodeType":"VariableDeclaration","scope":1145,"src":"3750:21:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1140,"name":"uint256","nodeType":"ElementaryTypeName","src":"3750:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1143,"mutability":"mutable","name":"receiverAmount","nameLocation":"3781:14:8","nodeType":"VariableDeclaration","scope":1145,"src":"3773:22:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1142,"name":"uint256","nodeType":"ElementaryTypeName","src":"3773:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3749:47:8"},"scope":1201,"src":"3560:237:8","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"a8abef47","id":1164,"implemented":false,"kind":"function","modifiers":[],"name":"releaseParticleAmount","nameLocation":"3810:21:8","nodeType":"FunctionDefinition","parameters":{"id":1158,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1147,"mutability":"mutable","name":"receiver","nameLocation":"3845:8:8","nodeType":"VariableDeclaration","scope":1164,"src":"3837:16:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1146,"name":"address","nodeType":"ElementaryTypeName","src":"3837:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1149,"mutability":"mutable","name":"contractAddress","nameLocation":"3867:15:8","nodeType":"VariableDeclaration","scope":1164,"src":"3859:23:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1148,"name":"address","nodeType":"ElementaryTypeName","src":"3859:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1151,"mutability":"mutable","name":"tokenId","nameLocation":"3896:7:8","nodeType":"VariableDeclaration","scope":1164,"src":"3888:15:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1150,"name":"uint256","nodeType":"ElementaryTypeName","src":"3888:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1153,"mutability":"mutable","name":"walletManagerId","nameLocation":"3925:15:8","nodeType":"VariableDeclaration","scope":1164,"src":"3909:31:8","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":1152,"name":"string","nodeType":"ElementaryTypeName","src":"3909:6:8","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":1155,"mutability":"mutable","name":"assetToken","nameLocation":"3954:10:8","nodeType":"VariableDeclaration","scope":1164,"src":"3946:18:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1154,"name":"address","nodeType":"ElementaryTypeName","src":"3946:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1157,"mutability":"mutable","name":"assetAmount","nameLocation":"3978:11:8","nodeType":"VariableDeclaration","scope":1164,"src":"3970:19:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1156,"name":"uint256","nodeType":"ElementaryTypeName","src":"3970:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3831:162:8"},"returnParameters":{"id":1163,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1160,"mutability":"mutable","name":"creatorAmount","nameLocation":"4020:13:8","nodeType":"VariableDeclaration","scope":1164,"src":"4012:21:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1159,"name":"uint256","nodeType":"ElementaryTypeName","src":"4012:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1162,"mutability":"mutable","name":"receiverAmount","nameLocation":"4043:14:8","nodeType":"VariableDeclaration","scope":1164,"src":"4035:22:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1161,"name":"uint256","nodeType":"ElementaryTypeName","src":"4035:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"4011:47:8"},"scope":1201,"src":"3801:258:8","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"3ff956cc","id":1181,"implemented":false,"kind":"function","modifiers":[],"name":"covalentBond","nameLocation":"4072:12:8","nodeType":"FunctionDefinition","parameters":{"id":1177,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1166,"mutability":"mutable","name":"contractAddress","nameLocation":"4098:15:8","nodeType":"VariableDeclaration","scope":1181,"src":"4090:23:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1165,"name":"address","nodeType":"ElementaryTypeName","src":"4090:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1168,"mutability":"mutable","name":"tokenId","nameLocation":"4127:7:8","nodeType":"VariableDeclaration","scope":1181,"src":"4119:15:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1167,"name":"uint256","nodeType":"ElementaryTypeName","src":"4119:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1170,"mutability":"mutable","name":"basketManagerId","nameLocation":"4156:15:8","nodeType":"VariableDeclaration","scope":1181,"src":"4140:31:8","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":1169,"name":"string","nodeType":"ElementaryTypeName","src":"4140:6:8","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":1172,"mutability":"mutable","name":"nftTokenAddress","nameLocation":"4185:15:8","nodeType":"VariableDeclaration","scope":1181,"src":"4177:23:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1171,"name":"address","nodeType":"ElementaryTypeName","src":"4177:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1174,"mutability":"mutable","name":"nftTokenId","nameLocation":"4214:10:8","nodeType":"VariableDeclaration","scope":1181,"src":"4206:18:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1173,"name":"uint256","nodeType":"ElementaryTypeName","src":"4206:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1176,"mutability":"mutable","name":"nftTokenAmount","nameLocation":"4238:14:8","nodeType":"VariableDeclaration","scope":1181,"src":"4230:22:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1175,"name":"uint256","nodeType":"ElementaryTypeName","src":"4230:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"4084:172:8"},"returnParameters":{"id":1180,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1179,"mutability":"mutable","name":"success","nameLocation":"4280:7:8","nodeType":"VariableDeclaration","scope":1181,"src":"4275:12:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":1178,"name":"bool","nodeType":"ElementaryTypeName","src":"4275:4:8","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"4274:14:8"},"scope":1201,"src":"4063:226:8","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"fe02fb00","id":1200,"implemented":false,"kind":"function","modifiers":[],"name":"breakCovalentBond","nameLocation":"4302:17:8","nodeType":"FunctionDefinition","parameters":{"id":1196,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1183,"mutability":"mutable","name":"receiver","nameLocation":"4333:8:8","nodeType":"VariableDeclaration","scope":1200,"src":"4325:16:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1182,"name":"address","nodeType":"ElementaryTypeName","src":"4325:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1185,"mutability":"mutable","name":"contractAddress","nameLocation":"4355:15:8","nodeType":"VariableDeclaration","scope":1200,"src":"4347:23:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1184,"name":"address","nodeType":"ElementaryTypeName","src":"4347:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1187,"mutability":"mutable","name":"tokenId","nameLocation":"4384:7:8","nodeType":"VariableDeclaration","scope":1200,"src":"4376:15:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1186,"name":"uint256","nodeType":"ElementaryTypeName","src":"4376:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1189,"mutability":"mutable","name":"basketManagerId","nameLocation":"4413:15:8","nodeType":"VariableDeclaration","scope":1200,"src":"4397:31:8","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":1188,"name":"string","nodeType":"ElementaryTypeName","src":"4397:6:8","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":1191,"mutability":"mutable","name":"nftTokenAddress","nameLocation":"4442:15:8","nodeType":"VariableDeclaration","scope":1200,"src":"4434:23:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1190,"name":"address","nodeType":"ElementaryTypeName","src":"4434:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1193,"mutability":"mutable","name":"nftTokenId","nameLocation":"4471:10:8","nodeType":"VariableDeclaration","scope":1200,"src":"4463:18:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1192,"name":"uint256","nodeType":"ElementaryTypeName","src":"4463:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1195,"mutability":"mutable","name":"nftTokenAmount","nameLocation":"4495:14:8","nodeType":"VariableDeclaration","scope":1200,"src":"4487:22:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1194,"name":"uint256","nodeType":"ElementaryTypeName","src":"4487:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"4319:194:8"},"returnParameters":{"id":1199,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1198,"mutability":"mutable","name":"success","nameLocation":"4537:7:8","nodeType":"VariableDeclaration","scope":1200,"src":"4532:12:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":1197,"name":"bool","nodeType":"ElementaryTypeName","src":"4532:4:8","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"4531:14:8"},"scope":1201,"src":"4293:253:8","stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"scope":1202,"src":"1313:3235:8","usedErrors":[]}],"src":"1236:3313:8"},"id":8},"contracts/interfaces/IERC6551Account.sol":{"ast":{"absolutePath":"contracts/interfaces/IERC6551Account.sol","exportedSymbols":{"IERC6551Account":[1247],"IERC6551AccountProxy":[1209]},"id":1248,"license":"UNLICENSED","nodeType":"SourceUnit","nodes":[{"id":1203,"literals":["solidity","^","0.8",".13"],"nodeType":"PragmaDirective","src":"39:24:9"},{"abstract":false,"baseContracts":[],"canonicalName":"IERC6551AccountProxy","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"id":1209,"linearizedBaseContracts":[1209],"name":"IERC6551AccountProxy","nameLocation":"75:20:9","nodeType":"ContractDefinition","nodes":[{"functionSelector":"5c60da1b","id":1208,"implemented":false,"kind":"function","modifiers":[],"name":"implementation","nameLocation":"111:14:9","nodeType":"FunctionDefinition","parameters":{"id":1204,"nodeType":"ParameterList","parameters":[],"src":"125:2:9"},"returnParameters":{"id":1207,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1206,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1208,"src":"151:7:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1205,"name":"address","nodeType":"ElementaryTypeName","src":"151:7:9","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"150:9:9"},"scope":1209,"src":"102:58:9","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":1248,"src":"65:97:9","usedErrors":[]},{"abstract":false,"baseContracts":[],"canonicalName":"IERC6551Account","contractDependencies":[],"contractKind":"interface","documentation":{"id":1210,"nodeType":"StructuredDocumentation","src":"164:67:9","text":"@dev the ERC-165 identifier for this interface is `0xeff4d378`"},"fullyImplemented":false,"id":1247,"linearizedBaseContracts":[1247],"name":"IERC6551Account","nameLocation":"241:15:9","nodeType":"ContractDefinition","nodes":[{"anonymous":false,"eventSelector":"47d99ad340f52da66535aff7e10da1ceb85a32bcbd9fa1c42314d194545e14d2","id":1218,"name":"TransactionExecuted","nameLocation":"269:19:9","nodeType":"EventDefinition","parameters":{"id":1217,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1212,"indexed":true,"mutability":"mutable","name":"target","nameLocation":"305:6:9","nodeType":"VariableDeclaration","scope":1218,"src":"289:22:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1211,"name":"address","nodeType":"ElementaryTypeName","src":"289:7:9","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1214,"indexed":true,"mutability":"mutable","name":"value","nameLocation":"329:5:9","nodeType":"VariableDeclaration","scope":1218,"src":"313:21:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1213,"name":"uint256","nodeType":"ElementaryTypeName","src":"313:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1216,"indexed":false,"mutability":"mutable","name":"data","nameLocation":"342:4:9","nodeType":"VariableDeclaration","scope":1218,"src":"336:10:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1215,"name":"bytes","nodeType":"ElementaryTypeName","src":"336:5:9","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"288:59:9"},"src":"263:85:9"},{"id":1221,"implemented":false,"kind":"receive","modifiers":[],"name":"","nameLocation":"-1:-1:-1","nodeType":"FunctionDefinition","parameters":{"id":1219,"nodeType":"ParameterList","parameters":[],"src":"361:2:9"},"returnParameters":{"id":1220,"nodeType":"ParameterList","parameters":[],"src":"380:0:9"},"scope":1247,"src":"354:27:9","stateMutability":"payable","virtual":false,"visibility":"external"},{"functionSelector":"9e5d4c49","id":1232,"implemented":false,"kind":"function","modifiers":[],"name":"executeCall","nameLocation":"396:11:9","nodeType":"FunctionDefinition","parameters":{"id":1228,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1223,"mutability":"mutable","name":"to","nameLocation":"425:2:9","nodeType":"VariableDeclaration","scope":1232,"src":"417:10:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1222,"name":"address","nodeType":"ElementaryTypeName","src":"417:7:9","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1225,"mutability":"mutable","name":"value","nameLocation":"445:5:9","nodeType":"VariableDeclaration","scope":1232,"src":"437:13:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1224,"name":"uint256","nodeType":"ElementaryTypeName","src":"437:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1227,"mutability":"mutable","name":"data","nameLocation":"475:4:9","nodeType":"VariableDeclaration","scope":1232,"src":"460:19:9","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":1226,"name":"bytes","nodeType":"ElementaryTypeName","src":"460:5:9","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"407:78:9"},"returnParameters":{"id":1231,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1230,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1232,"src":"512:12:9","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1229,"name":"bytes","nodeType":"ElementaryTypeName","src":"512:5:9","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"511:14:9"},"scope":1247,"src":"387:139:9","stateMutability":"payable","virtual":false,"visibility":"external"},{"functionSelector":"fc0c546a","id":1241,"implemented":false,"kind":"function","modifiers":[],"name":"token","nameLocation":"541:5:9","nodeType":"FunctionDefinition","parameters":{"id":1233,"nodeType":"ParameterList","parameters":[],"src":"546:2:9"},"returnParameters":{"id":1240,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1235,"mutability":"mutable","name":"chainId","nameLocation":"604:7:9","nodeType":"VariableDeclaration","scope":1241,"src":"596:15:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1234,"name":"uint256","nodeType":"ElementaryTypeName","src":"596:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1237,"mutability":"mutable","name":"tokenContract","nameLocation":"621:13:9","nodeType":"VariableDeclaration","scope":1241,"src":"613:21:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1236,"name":"address","nodeType":"ElementaryTypeName","src":"613:7:9","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1239,"mutability":"mutable","name":"tokenId","nameLocation":"644:7:9","nodeType":"VariableDeclaration","scope":1241,"src":"636:15:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1238,"name":"uint256","nodeType":"ElementaryTypeName","src":"636:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"595:57:9"},"scope":1247,"src":"532:121:9","stateMutability":"view","virtual":false,"visibility":"external"},{"functionSelector":"8da5cb5b","id":1246,"implemented":false,"kind":"function","modifiers":[],"name":"owner","nameLocation":"668:5:9","nodeType":"FunctionDefinition","parameters":{"id":1242,"nodeType":"ParameterList","parameters":[],"src":"673:2:9"},"returnParameters":{"id":1245,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1244,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1246,"src":"699:7:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1243,"name":"address","nodeType":"ElementaryTypeName","src":"699:7:9","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"698:9:9"},"scope":1247,"src":"659:49:9","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":1248,"src":"231:479:9","usedErrors":[]}],"src":"39:672:9"},"id":9},"contracts/interfaces/IRegistry.sol":{"ast":{"absolutePath":"contracts/interfaces/IRegistry.sol","exportedSymbols":{"IRegistry":[1282]},"id":1283,"license":"UNLICENSED","nodeType":"SourceUnit","nodes":[{"id":1249,"literals":["solidity","^","0.8",".13"],"nodeType":"PragmaDirective","src":"39:24:10"},{"abstract":false,"baseContracts":[],"canonicalName":"IRegistry","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"id":1282,"linearizedBaseContracts":[1282],"name":"IRegistry","nameLocation":"75:9:10","nodeType":"ContractDefinition","nodes":[{"functionSelector":"da7323b3","id":1266,"implemented":false,"kind":"function","modifiers":[],"name":"createAccount","nameLocation":"100:13:10","nodeType":"FunctionDefinition","parameters":{"id":1262,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1251,"mutability":"mutable","name":"implementation","nameLocation":"131:14:10","nodeType":"VariableDeclaration","scope":1266,"src":"123:22:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1250,"name":"address","nodeType":"ElementaryTypeName","src":"123:7:10","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1253,"mutability":"mutable","name":"chainId","nameLocation":"163:7:10","nodeType":"VariableDeclaration","scope":1266,"src":"155:15:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1252,"name":"uint256","nodeType":"ElementaryTypeName","src":"155:7:10","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1255,"mutability":"mutable","name":"tokenContract","nameLocation":"188:13:10","nodeType":"VariableDeclaration","scope":1266,"src":"180:21:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1254,"name":"address","nodeType":"ElementaryTypeName","src":"180:7:10","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1257,"mutability":"mutable","name":"tokenId","nameLocation":"219:7:10","nodeType":"VariableDeclaration","scope":1266,"src":"211:15:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1256,"name":"uint256","nodeType":"ElementaryTypeName","src":"211:7:10","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1259,"mutability":"mutable","name":"salt","nameLocation":"244:4:10","nodeType":"VariableDeclaration","scope":1266,"src":"236:12:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1258,"name":"uint256","nodeType":"ElementaryTypeName","src":"236:7:10","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1261,"mutability":"mutable","name":"initData","nameLocation":"273:8:10","nodeType":"VariableDeclaration","scope":1266,"src":"258:23:10","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":1260,"name":"bytes","nodeType":"ElementaryTypeName","src":"258:5:10","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"113:174:10"},"returnParameters":{"id":1265,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1264,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1266,"src":"306:7:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1263,"name":"address","nodeType":"ElementaryTypeName","src":"306:7:10","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"305:9:10"},"scope":1282,"src":"91:224:10","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"5e9bc536","id":1281,"implemented":false,"kind":"function","modifiers":[],"name":"account","nameLocation":"330:7:10","nodeType":"FunctionDefinition","parameters":{"id":1277,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1268,"mutability":"mutable","name":"implementation","nameLocation":"355:14:10","nodeType":"VariableDeclaration","scope":1281,"src":"347:22:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1267,"name":"address","nodeType":"ElementaryTypeName","src":"347:7:10","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1270,"mutability":"mutable","name":"chainId","nameLocation":"387:7:10","nodeType":"VariableDeclaration","scope":1281,"src":"379:15:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1269,"name":"uint256","nodeType":"ElementaryTypeName","src":"379:7:10","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1272,"mutability":"mutable","name":"tokenContract","nameLocation":"412:13:10","nodeType":"VariableDeclaration","scope":1281,"src":"404:21:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1271,"name":"address","nodeType":"ElementaryTypeName","src":"404:7:10","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1274,"mutability":"mutable","name":"tokenId","nameLocation":"443:7:10","nodeType":"VariableDeclaration","scope":1281,"src":"435:15:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1273,"name":"uint256","nodeType":"ElementaryTypeName","src":"435:7:10","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1276,"mutability":"mutable","name":"salt","nameLocation":"468:4:10","nodeType":"VariableDeclaration","scope":1281,"src":"460:12:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1275,"name":"uint256","nodeType":"ElementaryTypeName","src":"460:7:10","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"337:141:10"},"returnParameters":{"id":1280,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1279,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1281,"src":"502:7:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1278,"name":"address","nodeType":"ElementaryTypeName","src":"502:7:10","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"501:9:10"},"scope":1282,"src":"321:190:10","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":1283,"src":"65:448:10","usedErrors":[]}],"src":"39:475:10"},"id":10},"contracts/lib/ERC6551AccountLib.sol":{"ast":{"absolutePath":"contracts/lib/ERC6551AccountLib.sol","exportedSymbols":{"ERC6551AccountLib":[1337]},"id":1338,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":1284,"literals":["solidity","^","0.8",".13"],"nodeType":"PragmaDirective","src":"32:24:11"},{"abstract":false,"baseContracts":[],"canonicalName":"ERC6551AccountLib","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"id":1337,"linearizedBaseContracts":[1337],"name":"ERC6551AccountLib","nameLocation":"66:17:11","nodeType":"ContractDefinition","nodes":[{"body":{"id":1313,"nodeType":"Block","src":"231:265:11","statements":[{"assignments":[1294],"declarations":[{"constant":false,"id":1294,"mutability":"mutable","name":"footer","nameLocation":"254:6:11","nodeType":"VariableDeclaration","scope":1313,"src":"241:19:11","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1293,"name":"bytes","nodeType":"ElementaryTypeName","src":"241:5:11","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"id":1299,"initialValue":{"arguments":[{"hexValue":"30783630","id":1297,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"273:4:11","typeDescriptions":{"typeIdentifier":"t_rational_96_by_1","typeString":"int_const 96"},"value":"0x60"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_96_by_1","typeString":"int_const 96"}],"id":1296,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"NewExpression","src":"263:9:11","typeDescriptions":{"typeIdentifier":"t_function_objectcreation_pure$_t_uint256_$returns$_t_bytes_memory_ptr_$","typeString":"function (uint256) pure returns (bytes memory)"},"typeName":{"id":1295,"name":"bytes","nodeType":"ElementaryTypeName","src":"267:5:11","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}}},"id":1298,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"263:15:11","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"nodeType":"VariableDeclarationStatement","src":"241:37:11"},{"AST":{"nodeType":"YulBlock","src":"298:127:11","statements":[{"expression":{"arguments":[{"arguments":[],"functionName":{"name":"address","nodeType":"YulIdentifier","src":"374:7:11"},"nodeType":"YulFunctionCall","src":"374:9:11"},{"arguments":[{"name":"footer","nodeType":"YulIdentifier","src":"389:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"397:4:11","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"385:3:11"},"nodeType":"YulFunctionCall","src":"385:17:11"},{"kind":"number","nodeType":"YulLiteral","src":"404:4:11","type":"","value":"0x4d"},{"kind":"number","nodeType":"YulLiteral","src":"410:4:11","type":"","value":"0xad"}],"functionName":{"name":"extcodecopy","nodeType":"YulIdentifier","src":"362:11:11"},"nodeType":"YulFunctionCall","src":"362:53:11"},"nodeType":"YulExpressionStatement","src":"362:53:11"}]},"evmVersion":"london","externalReferences":[{"declaration":1294,"isOffset":false,"isSlot":false,"src":"389:6:11","valueSize":1}],"id":1300,"nodeType":"InlineAssembly","src":"289:136:11"},{"expression":{"arguments":[{"id":1303,"name":"footer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1294,"src":"453:6:11","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},{"components":[{"id":1305,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"462:7:11","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":1304,"name":"uint256","nodeType":"ElementaryTypeName","src":"462:7:11","typeDescriptions":{}}},{"id":1307,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"471:7:11","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":1306,"name":"address","nodeType":"ElementaryTypeName","src":"471:7:11","typeDescriptions":{}}},{"id":1309,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"480:7:11","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":1308,"name":"uint256","nodeType":"ElementaryTypeName","src":"480:7:11","typeDescriptions":{}}}],"id":1310,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"TupleExpression","src":"461:27:11","typeDescriptions":{"typeIdentifier":"t_tuple$_t_type$_t_uint256_$_$_t_type$_t_address_$_$_t_type$_t_uint256_$_$","typeString":"tuple(type(uint256),type(address),type(uint256))"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"},{"typeIdentifier":"t_tuple$_t_type$_t_uint256_$_$_t_type$_t_address_$_$_t_type$_t_uint256_$_$","typeString":"tuple(type(uint256),type(address),type(uint256))"}],"expression":{"id":1301,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"442:3:11","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":1302,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"446:6:11","memberName":"decode","nodeType":"MemberAccess","src":"442:10:11","typeDescriptions":{"typeIdentifier":"t_function_abidecode_pure$__$returns$__$","typeString":"function () pure"}},"id":1311,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"442:47:11","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_uint256_$_t_address_payable_$_t_uint256_$","typeString":"tuple(uint256,address payable,uint256)"}},"functionReturnParameters":1292,"id":1312,"nodeType":"Return","src":"435:54:11"}]},"id":1314,"implemented":true,"kind":"function","modifiers":[],"name":"token","nameLocation":"99:5:11","nodeType":"FunctionDefinition","parameters":{"id":1285,"nodeType":"ParameterList","parameters":[],"src":"104:2:11"},"returnParameters":{"id":1292,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1287,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1314,"src":"167:7:11","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1286,"name":"uint256","nodeType":"ElementaryTypeName","src":"167:7:11","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1289,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1314,"src":"188:7:11","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1288,"name":"address","nodeType":"ElementaryTypeName","src":"188:7:11","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1291,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1314,"src":"209:7:11","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1290,"name":"uint256","nodeType":"ElementaryTypeName","src":"209:7:11","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"153:73:11"},"scope":1337,"src":"90:406:11","stateMutability":"view","virtual":false,"visibility":"internal"},{"body":{"id":1335,"nodeType":"Block","src":"550:253:11","statements":[{"assignments":[1320],"declarations":[{"constant":false,"id":1320,"mutability":"mutable","name":"footer","nameLocation":"573:6:11","nodeType":"VariableDeclaration","scope":1335,"src":"560:19:11","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1319,"name":"bytes","nodeType":"ElementaryTypeName","src":"560:5:11","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"id":1325,"initialValue":{"arguments":[{"hexValue":"30783230","id":1323,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"592:4:11","typeDescriptions":{"typeIdentifier":"t_rational_32_by_1","typeString":"int_const 32"},"value":"0x20"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_32_by_1","typeString":"int_const 32"}],"id":1322,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"NewExpression","src":"582:9:11","typeDescriptions":{"typeIdentifier":"t_function_objectcreation_pure$_t_uint256_$returns$_t_bytes_memory_ptr_$","typeString":"function (uint256) pure returns (bytes memory)"},"typeName":{"id":1321,"name":"bytes","nodeType":"ElementaryTypeName","src":"586:5:11","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}}},"id":1324,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"582:15:11","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"nodeType":"VariableDeclarationStatement","src":"560:37:11"},{"AST":{"nodeType":"YulBlock","src":"617:133:11","statements":[{"expression":{"arguments":[{"arguments":[],"functionName":{"name":"address","nodeType":"YulIdentifier","src":"699:7:11"},"nodeType":"YulFunctionCall","src":"699:9:11"},{"arguments":[{"name":"footer","nodeType":"YulIdentifier","src":"714:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"722:4:11","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"710:3:11"},"nodeType":"YulFunctionCall","src":"710:17:11"},{"kind":"number","nodeType":"YulLiteral","src":"729:4:11","type":"","value":"0x2d"},{"kind":"number","nodeType":"YulLiteral","src":"735:4:11","type":"","value":"0x4d"}],"functionName":{"name":"extcodecopy","nodeType":"YulIdentifier","src":"687:11:11"},"nodeType":"YulFunctionCall","src":"687:53:11"},"nodeType":"YulExpressionStatement","src":"687:53:11"}]},"evmVersion":"london","externalReferences":[{"declaration":1320,"isOffset":false,"isSlot":false,"src":"714:6:11","valueSize":1}],"id":1326,"nodeType":"InlineAssembly","src":"608:142:11"},{"expression":{"arguments":[{"id":1329,"name":"footer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1320,"src":"778:6:11","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},{"components":[{"id":1331,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"787:7:11","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":1330,"name":"uint256","nodeType":"ElementaryTypeName","src":"787:7:11","typeDescriptions":{}}}],"id":1332,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"TupleExpression","src":"786:9:11","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"},{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"}],"expression":{"id":1327,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"767:3:11","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":1328,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"771:6:11","memberName":"decode","nodeType":"MemberAccess","src":"767:10:11","typeDescriptions":{"typeIdentifier":"t_function_abidecode_pure$__$returns$__$","typeString":"function () pure"}},"id":1333,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"767:29:11","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"functionReturnParameters":1318,"id":1334,"nodeType":"Return","src":"760:36:11"}]},"id":1336,"implemented":true,"kind":"function","modifiers":[],"name":"salt","nameLocation":"511:4:11","nodeType":"FunctionDefinition","parameters":{"id":1315,"nodeType":"ParameterList","parameters":[],"src":"515:2:11"},"returnParameters":{"id":1318,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1317,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1336,"src":"541:7:11","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1316,"name":"uint256","nodeType":"ElementaryTypeName","src":"541:7:11","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"540:9:11"},"scope":1337,"src":"502:301:11","stateMutability":"view","virtual":false,"visibility":"internal"}],"scope":1338,"src":"58:747:11","usedErrors":[]}],"src":"32:774:11"},"id":11}},"contracts":{"@openzeppelin/contracts/interfaces/IERC1271.sol":{"IERC1271":{"abi":[{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"magicValue","type":"bytes4"}],"stateMutability":"view","type":"function"}],"devdoc":{"details":"Interface of the ERC1271 standard signature validation method for contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271]. _Available since v4.1._","kind":"dev","methods":{"isValidSignature(bytes32,bytes)":{"details":"Should return whether the signature provided is valid for the provided data","params":{"hash":"Hash of the data to be signed","signature":"Signature byte array associated with _data"}}},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"isValidSignature(bytes32,bytes)":"1626ba7e"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Interface of the ERC1271 standard signature validation method for contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271]. _Available since v4.1._\",\"kind\":\"dev\",\"methods\":{\"isValidSignature(bytes32,bytes)\":{\"details\":\"Should return whether the signature provided is valid for the provided data\",\"params\":{\"hash\":\"Hash of the data to be signed\",\"signature\":\"Signature byte array associated with _data\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":\"IERC1271\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol":{"IERC1155Receiver":{"abi":[{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}],"devdoc":{"details":"_Available since v3.1._","kind":"dev","methods":{"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":{"details":"Handles the receipt of a multiple ERC1155 token types. This function is called at the end of a `safeBatchTransferFrom` after the balances have been updated. NOTE: To accept the transfer(s), this must return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` (i.e. 0xbc197c81, or its own function selector).","params":{"data":"Additional data with no specified format","from":"The address which previously owned the token","ids":"An array containing ids of each token being transferred (order and length must match values array)","operator":"The address which initiated the batch transfer (i.e. msg.sender)","values":"An array containing amounts of each token being transferred (order and length must match ids array)"},"returns":{"_0":"`bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed"}},"onERC1155Received(address,address,uint256,uint256,bytes)":{"details":"Handles the receipt of a single ERC1155 token type. This function is called at the end of a `safeTransferFrom` after the balance has been updated. NOTE: To accept the transfer, this must return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` (i.e. 0xf23a6e61, or its own function selector).","params":{"data":"Additional data with no specified format","from":"The address which previously owned the token","id":"The ID of the token being transferred","operator":"The address which initiated the transfer (i.e. msg.sender)","value":"The amount of tokens being transferred"},"returns":{"_0":"`bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed"}},"supportsInterface(bytes4)":{"details":"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas."}},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":"bc197c81","onERC1155Received(address,address,uint256,uint256,bytes)":"f23a6e61","supportsInterface(bytes4)":"01ffc9a7"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onERC1155BatchReceived\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onERC1155Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"_Available since v3.1._\",\"kind\":\"dev\",\"methods\":{\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"details\":\"Handles the receipt of a multiple ERC1155 token types. This function is called at the end of a `safeBatchTransferFrom` after the balances have been updated. NOTE: To accept the transfer(s), this must return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` (i.e. 0xbc197c81, or its own function selector).\",\"params\":{\"data\":\"Additional data with no specified format\",\"from\":\"The address which previously owned the token\",\"ids\":\"An array containing ids of each token being transferred (order and length must match values array)\",\"operator\":\"The address which initiated the batch transfer (i.e. msg.sender)\",\"values\":\"An array containing amounts of each token being transferred (order and length must match ids array)\"},\"returns\":{\"_0\":\"`bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\"}},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"details\":\"Handles the receipt of a single ERC1155 token type. This function is called at the end of a `safeTransferFrom` after the balance has been updated. NOTE: To accept the transfer, this must return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` (i.e. 0xf23a6e61, or its own function selector).\",\"params\":{\"data\":\"Additional data with no specified format\",\"from\":\"The address which previously owned the token\",\"id\":\"The ID of the token being transferred\",\"operator\":\"The address which initiated the transfer (i.e. msg.sender)\",\"value\":\"The amount of tokens being transferred\"},\"returns\":{\"_0\":\"`bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\"}},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":\"IERC1155Receiver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (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 *\\n * NOTE: 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 *\\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.\\n *\\n * NOTE: 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 *\\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\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/token/ERC721/IERC721.sol":{"IERC721":{"abi":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"operator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"details":"Required interface of an ERC721 compliant contract.","events":{"Approval(address,address,uint256)":{"details":"Emitted when `owner` enables `approved` to manage the `tokenId` token."},"ApprovalForAll(address,address,bool)":{"details":"Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets."},"Transfer(address,address,uint256)":{"details":"Emitted when `tokenId` token is transferred from `from` to `to`."}},"kind":"dev","methods":{"approve(address,uint256)":{"details":"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event."},"balanceOf(address)":{"details":"Returns the number of tokens in ``owner``'s account."},"getApproved(uint256)":{"details":"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist."},"isApprovedForAll(address,address)":{"details":"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}"},"ownerOf(uint256)":{"details":"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist."},"safeTransferFrom(address,address,uint256)":{"details":"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event."},"safeTransferFrom(address,address,uint256,bytes)":{"details":"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event."},"setApprovalForAll(address,bool)":{"details":"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the caller. Emits an {ApprovalForAll} event."},"supportsInterface(bytes4)":{"details":"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas."},"transferFrom(address,address,uint256)":{"details":"Transfers `tokenId` token from `from` to `to`. WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event."}},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"approve(address,uint256)":"095ea7b3","balanceOf(address)":"70a08231","getApproved(uint256)":"081812fc","isApprovedForAll(address,address)":"e985e9c5","ownerOf(uint256)":"6352211e","safeTransferFrom(address,address,uint256)":"42842e0e","safeTransferFrom(address,address,uint256,bytes)":"b88d4fde","setApprovalForAll(address,bool)":"a22cb465","supportsInterface(bytes4)":"01ffc9a7","transferFrom(address,address,uint256)":"23b872dd"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Required interface of an ERC721 compliant contract.\",\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when `owner` enables `approved` to manage the `tokenId` token.\"},\"ApprovalForAll(address,address,bool)\":{\"details\":\"Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\"},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `tokenId` token is transferred from `from` to `to`.\"}},\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"details\":\"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event.\"},\"balanceOf(address)\":{\"details\":\"Returns the number of tokens in ``owner``'s account.\"},\"getApproved(uint256)\":{\"details\":\"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist.\"},\"isApprovedForAll(address,address)\":{\"details\":\"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}\"},\"ownerOf(uint256)\":{\"details\":\"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the caller. Emits an {ApprovalForAll} event.\"},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"Transfers `tokenId` token from `from` to `to`. WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":\"IERC721\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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`.\\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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\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(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol":{"IERC721Receiver":{"abi":[{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"details":"Interface for any contract that wants to support safeTransfers from ERC721 asset contracts.","kind":"dev","methods":{"onERC721Received(address,address,uint256,bytes)":{"details":"Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} by `operator` from `from`, this function is called. It must return its Solidity selector to confirm the token transfer. If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`."}},"title":"ERC721 token receiver interface","version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"onERC721Received(address,address,uint256,bytes)":"150b7a02"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Interface for any contract that wants to support safeTransfers from ERC721 asset contracts.\",\"kind\":\"dev\",\"methods\":{\"onERC721Received(address,address,uint256,bytes)\":{\"details\":\"Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} by `operator` from `from`, this function is called. It must return its Solidity selector to confirm the token transfer. If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\"}},\"title\":\"ERC721 token receiver interface\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":\"IERC721Receiver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface 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 `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/utils/introspection/IERC165.sol":{"IERC165":{"abi":[{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}],"devdoc":{"details":"Interface of the ERC165 standard, as defined in the https://eips.ethereum.org/EIPS/eip-165[EIP]. Implementers can declare support of contract interfaces, which can then be queried by others ({ERC165Checker}). For an implementation, see {ERC165}.","kind":"dev","methods":{"supportsInterface(bytes4)":{"details":"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas."}},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"supportsInterface(bytes4)":"01ffc9a7"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Interface of the ERC165 standard, as defined in the https://eips.ethereum.org/EIPS/eip-165[EIP]. Implementers can declare support of contract interfaces, which can then be queried by others ({ERC165Checker}). For an implementation, see {ERC165}.\",\"kind\":\"dev\",\"methods\":{\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":\"IERC165\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/AccountRegistryBridge.sol":{"AccountRegistryBridge":{"abi":[{"inputs":[],"name":"IMPLMENTATION","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REGISTRY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"account","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"createAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"608060405234801561001057600080fd5b506102ad806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806306433b1b14610051578063192df655146100885780635fbfb9cf1461009b5780637fdfc7b2146100ae575b600080fd5b61006c7302101dfb77fde026414827fdc604ddaf224f092181565b6040516001600160a01b03909116815260200160405180910390f35b61006c61009636600461022e565b6100c9565b61006c6100a936600461022e565b61017d565b61006c732d25602551487c3f3354dd80d76d54383a24335881565b604051632f4de29b60e11b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b038316604482015260648101829052600060848201819052907302101dfb77fde026414827fdc604ddaf224f092190635e9bc5369060a401602060405180830381865afa158015610152573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610176919061025a565b9392505050565b60405163da7323b360e01b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b03831660448201526064810182905260006084820181905260c060a483015260c48201819052907302101dfb77fde026414827fdc604ddaf224f09219063da7323b39060e4016020604051808303816000875af1158015610152573d6000803e3d6000fd5b6001600160a01b038116811461022b57600080fd5b50565b6000806040838503121561024157600080fd5b823561024c81610216565b946020939093013593505050565b60006020828403121561026c57600080fd5b81516101768161021656fea2646970667358221220f72638b68db63c3c7b140a211fbc4be6ca1d9a152259dbe8d00d66564794b6e164736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2AD DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x4C JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x6433B1B EQ PUSH2 0x51 JUMPI DUP1 PUSH4 0x192DF655 EQ PUSH2 0x88 JUMPI DUP1 PUSH4 0x5FBFB9CF EQ PUSH2 0x9B JUMPI DUP1 PUSH4 0x7FDFC7B2 EQ PUSH2 0xAE JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x6C PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x6C PUSH2 0x96 CALLDATASIZE PUSH1 0x4 PUSH2 0x22E JUMP JUMPDEST PUSH2 0xC9 JUMP JUMPDEST PUSH2 0x6C PUSH2 0xA9 CALLDATASIZE PUSH1 0x4 PUSH2 0x22E JUMP JUMPDEST PUSH2 0x17D JUMP JUMPDEST PUSH2 0x6C PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x2F4DE29B PUSH1 0xE1 SHL DUP2 MSTORE PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 PUSH1 0x4 DUP3 ADD MSTORE CHAINID PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 PUSH1 0x84 DUP3 ADD DUP2 SWAP1 MSTORE SWAP1 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 SWAP1 PUSH4 0x5E9BC536 SWAP1 PUSH1 0xA4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x152 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x176 SWAP2 SWAP1 PUSH2 0x25A JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0xDA7323B3 PUSH1 0xE0 SHL DUP2 MSTORE PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 PUSH1 0x4 DUP3 ADD MSTORE CHAINID PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 PUSH1 0x84 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0xC0 PUSH1 0xA4 DUP4 ADD MSTORE PUSH1 0xC4 DUP3 ADD DUP2 SWAP1 MSTORE SWAP1 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 SWAP1 PUSH4 0xDA7323B3 SWAP1 PUSH1 0xE4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x152 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0x22B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x241 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH2 0x24C DUP2 PUSH2 0x216 JUMP JUMPDEST SWAP5 PUSH1 0x20 SWAP4 SWAP1 SWAP4 ADD CALLDATALOAD SWAP4 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x26C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x176 DUP2 PUSH2 0x216 JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0xF7 0x26 CODESIZE 0xB6 DUP14 0xB6 EXTCODECOPY EXTCODECOPY PUSH28 0x140A211FBC4BE6CA1D9A152259DBE8D00D66564794B6E164736F6C63 NUMBER STOP ADDMOD GT STOP CALLER ","sourceMap":"96:831:5:-:0;;;;;;;;;;;;;;;;;;;"},"deployedBytecode":{"functionDebugData":{"@IMPLMENTATION_209":{"entryPoint":null,"id":209,"parameterSlots":0,"returnSlots":0},"@REGISTRY_206":{"entryPoint":null,"id":206,"parameterSlots":0,"returnSlots":0},"@account_254":{"entryPoint":201,"id":254,"parameterSlots":2,"returnSlots":1},"@createAccount_232":{"entryPoint":381,"id":232,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_address_fromMemory":{"entryPoint":602,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_addresst_uint256":{"entryPoint":558,"id":null,"parameterSlots":2,"returnSlots":2},"abi_encode_tuple_t_address__to_t_address__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1__to_t_address_t_uint256_t_address_t_uint256_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":6,"returnSlots":1},"abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470__to_t_address_t_uint256_t_address_t_uint256_t_uint256_t_bytes_memory_ptr__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":6,"returnSlots":1},"validator_revert_address":{"entryPoint":534,"id":null,"parameterSlots":1,"returnSlots":0}},"generatedSources":[{"ast":{"nodeType":"YulBlock","src":"0:2175:12","statements":[{"nodeType":"YulBlock","src":"6:3:12","statements":[]},{"body":{"nodeType":"YulBlock","src":"115:102:12","statements":[{"nodeType":"YulAssignment","src":"125:26:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"137:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"148:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"133:3:12"},"nodeType":"YulFunctionCall","src":"133:18:12"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"125:4:12"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"167:9:12"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"182:6:12"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"198:3:12","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"203:1:12","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"194:3:12"},"nodeType":"YulFunctionCall","src":"194:11:12"},{"kind":"number","nodeType":"YulLiteral","src":"207:1:12","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"190:3:12"},"nodeType":"YulFunctionCall","src":"190:19:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"178:3:12"},"nodeType":"YulFunctionCall","src":"178:32:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"160:6:12"},"nodeType":"YulFunctionCall","src":"160:51:12"},"nodeType":"YulExpressionStatement","src":"160:51:12"}]},"name":"abi_encode_tuple_t_address__to_t_address__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"84:9:12","type":""},{"name":"value0","nodeType":"YulTypedName","src":"95:6:12","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"106:4:12","type":""}],"src":"14:203:12"},{"body":{"nodeType":"YulBlock","src":"267:86:12","statements":[{"body":{"nodeType":"YulBlock","src":"331:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"340:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"343:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"333:6:12"},"nodeType":"YulFunctionCall","src":"333:12:12"},"nodeType":"YulExpressionStatement","src":"333:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"290:5:12"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"301:5:12"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"316:3:12","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"321:1:12","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"312:3:12"},"nodeType":"YulFunctionCall","src":"312:11:12"},{"kind":"number","nodeType":"YulLiteral","src":"325:1:12","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"308:3:12"},"nodeType":"YulFunctionCall","src":"308:19:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"297:3:12"},"nodeType":"YulFunctionCall","src":"297:31:12"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"287:2:12"},"nodeType":"YulFunctionCall","src":"287:42:12"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"280:6:12"},"nodeType":"YulFunctionCall","src":"280:50:12"},"nodeType":"YulIf","src":"277:70:12"}]},"name":"validator_revert_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"value","nodeType":"YulTypedName","src":"256:5:12","type":""}],"src":"222:131:12"},{"body":{"nodeType":"YulBlock","src":"445:228:12","statements":[{"body":{"nodeType":"YulBlock","src":"491:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"500:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"503:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"493:6:12"},"nodeType":"YulFunctionCall","src":"493:12:12"},"nodeType":"YulExpressionStatement","src":"493:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"466:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"475:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"462:3:12"},"nodeType":"YulFunctionCall","src":"462:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"487:2:12","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"458:3:12"},"nodeType":"YulFunctionCall","src":"458:32:12"},"nodeType":"YulIf","src":"455:52:12"},{"nodeType":"YulVariableDeclaration","src":"516:36:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"542:9:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"529:12:12"},"nodeType":"YulFunctionCall","src":"529:23:12"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"520:5:12","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"586:5:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"561:24:12"},"nodeType":"YulFunctionCall","src":"561:31:12"},"nodeType":"YulExpressionStatement","src":"561:31:12"},{"nodeType":"YulAssignment","src":"601:15:12","value":{"name":"value","nodeType":"YulIdentifier","src":"611:5:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"601:6:12"}]},{"nodeType":"YulAssignment","src":"625:42:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"652:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"663:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"648:3:12"},"nodeType":"YulFunctionCall","src":"648:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"635:12:12"},"nodeType":"YulFunctionCall","src":"635:32:12"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"625:6:12"}]}]},"name":"abi_decode_tuple_t_addresst_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"403:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"414:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"426:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"434:6:12","type":""}],"src":"358:315:12"},{"body":{"nodeType":"YulBlock","src":"899:306:12","statements":[{"nodeType":"YulAssignment","src":"909:27:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"921:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"932:3:12","type":"","value":"160"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"917:3:12"},"nodeType":"YulFunctionCall","src":"917:19:12"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"909:4:12"}]},{"nodeType":"YulVariableDeclaration","src":"945:29:12","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"963:3:12","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"968:1:12","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"959:3:12"},"nodeType":"YulFunctionCall","src":"959:11:12"},{"kind":"number","nodeType":"YulLiteral","src":"972:1:12","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"955:3:12"},"nodeType":"YulFunctionCall","src":"955:19:12"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"949:2:12","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"990:9:12"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"1005:6:12"},{"name":"_1","nodeType":"YulIdentifier","src":"1013:2:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1001:3:12"},"nodeType":"YulFunctionCall","src":"1001:15:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"983:6:12"},"nodeType":"YulFunctionCall","src":"983:34:12"},"nodeType":"YulExpressionStatement","src":"983:34:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1037:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"1048:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1033:3:12"},"nodeType":"YulFunctionCall","src":"1033:18:12"},{"name":"value1","nodeType":"YulIdentifier","src":"1053:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1026:6:12"},"nodeType":"YulFunctionCall","src":"1026:34:12"},"nodeType":"YulExpressionStatement","src":"1026:34:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1080:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"1091:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1076:3:12"},"nodeType":"YulFunctionCall","src":"1076:18:12"},{"arguments":[{"name":"value2","nodeType":"YulIdentifier","src":"1100:6:12"},{"name":"_1","nodeType":"YulIdentifier","src":"1108:2:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1096:3:12"},"nodeType":"YulFunctionCall","src":"1096:15:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1069:6:12"},"nodeType":"YulFunctionCall","src":"1069:43:12"},"nodeType":"YulExpressionStatement","src":"1069:43:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1132:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"1143:2:12","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1128:3:12"},"nodeType":"YulFunctionCall","src":"1128:18:12"},{"name":"value3","nodeType":"YulIdentifier","src":"1148:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1121:6:12"},"nodeType":"YulFunctionCall","src":"1121:34:12"},"nodeType":"YulExpressionStatement","src":"1121:34:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1175:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"1186:3:12","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1171:3:12"},"nodeType":"YulFunctionCall","src":"1171:19:12"},{"name":"value4","nodeType":"YulIdentifier","src":"1192:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1164:6:12"},"nodeType":"YulFunctionCall","src":"1164:35:12"},"nodeType":"YulExpressionStatement","src":"1164:35:12"}]},"name":"abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1__to_t_address_t_uint256_t_address_t_uint256_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"836:9:12","type":""},{"name":"value4","nodeType":"YulTypedName","src":"847:6:12","type":""},{"name":"value3","nodeType":"YulTypedName","src":"855:6:12","type":""},{"name":"value2","nodeType":"YulTypedName","src":"863:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"871:6:12","type":""},{"name":"value0","nodeType":"YulTypedName","src":"879:6:12","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"890:4:12","type":""}],"src":"678:527:12"},{"body":{"nodeType":"YulBlock","src":"1291:170:12","statements":[{"body":{"nodeType":"YulBlock","src":"1337:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1346:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1349:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1339:6:12"},"nodeType":"YulFunctionCall","src":"1339:12:12"},"nodeType":"YulExpressionStatement","src":"1339:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"1312:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"1321:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1308:3:12"},"nodeType":"YulFunctionCall","src":"1308:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"1333:2:12","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"1304:3:12"},"nodeType":"YulFunctionCall","src":"1304:32:12"},"nodeType":"YulIf","src":"1301:52:12"},{"nodeType":"YulVariableDeclaration","src":"1362:29:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1381:9:12"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"1375:5:12"},"nodeType":"YulFunctionCall","src":"1375:16:12"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"1366:5:12","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1425:5:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"1400:24:12"},"nodeType":"YulFunctionCall","src":"1400:31:12"},"nodeType":"YulExpressionStatement","src":"1400:31:12"},{"nodeType":"YulAssignment","src":"1440:15:12","value":{"name":"value","nodeType":"YulIdentifier","src":"1450:5:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"1440:6:12"}]}]},"name":"abi_decode_tuple_t_address_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"1257:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"1268:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"1280:6:12","type":""}],"src":"1210:251:12"},{"body":{"nodeType":"YulBlock","src":"1787:386:12","statements":[{"nodeType":"YulVariableDeclaration","src":"1797:29:12","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1815:3:12","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"1820:1:12","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1811:3:12"},"nodeType":"YulFunctionCall","src":"1811:11:12"},{"kind":"number","nodeType":"YulLiteral","src":"1824:1:12","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1807:3:12"},"nodeType":"YulFunctionCall","src":"1807:19:12"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"1801:2:12","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1842:9:12"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"1857:6:12"},{"name":"_1","nodeType":"YulIdentifier","src":"1865:2:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1853:3:12"},"nodeType":"YulFunctionCall","src":"1853:15:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1835:6:12"},"nodeType":"YulFunctionCall","src":"1835:34:12"},"nodeType":"YulExpressionStatement","src":"1835:34:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1889:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"1900:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1885:3:12"},"nodeType":"YulFunctionCall","src":"1885:18:12"},{"name":"value1","nodeType":"YulIdentifier","src":"1905:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1878:6:12"},"nodeType":"YulFunctionCall","src":"1878:34:12"},"nodeType":"YulExpressionStatement","src":"1878:34:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1932:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"1943:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1928:3:12"},"nodeType":"YulFunctionCall","src":"1928:18:12"},{"arguments":[{"name":"value2","nodeType":"YulIdentifier","src":"1952:6:12"},{"name":"_1","nodeType":"YulIdentifier","src":"1960:2:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1948:3:12"},"nodeType":"YulFunctionCall","src":"1948:15:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1921:6:12"},"nodeType":"YulFunctionCall","src":"1921:43:12"},"nodeType":"YulExpressionStatement","src":"1921:43:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1984:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"1995:2:12","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1980:3:12"},"nodeType":"YulFunctionCall","src":"1980:18:12"},{"name":"value3","nodeType":"YulIdentifier","src":"2000:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1973:6:12"},"nodeType":"YulFunctionCall","src":"1973:34:12"},"nodeType":"YulExpressionStatement","src":"1973:34:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2027:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"2038:3:12","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2023:3:12"},"nodeType":"YulFunctionCall","src":"2023:19:12"},{"name":"value4","nodeType":"YulIdentifier","src":"2044:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2016:6:12"},"nodeType":"YulFunctionCall","src":"2016:35:12"},"nodeType":"YulExpressionStatement","src":"2016:35:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2071:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"2082:3:12","type":"","value":"160"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2067:3:12"},"nodeType":"YulFunctionCall","src":"2067:19:12"},{"kind":"number","nodeType":"YulLiteral","src":"2088:3:12","type":"","value":"192"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2060:6:12"},"nodeType":"YulFunctionCall","src":"2060:32:12"},"nodeType":"YulExpressionStatement","src":"2060:32:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2112:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"2123:3:12","type":"","value":"192"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2108:3:12"},"nodeType":"YulFunctionCall","src":"2108:19:12"},{"kind":"number","nodeType":"YulLiteral","src":"2129:1:12","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2101:6:12"},"nodeType":"YulFunctionCall","src":"2101:30:12"},"nodeType":"YulExpressionStatement","src":"2101:30:12"},{"nodeType":"YulAssignment","src":"2140:27:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2152:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"2163:3:12","type":"","value":"224"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2148:3:12"},"nodeType":"YulFunctionCall","src":"2148:19:12"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"2140:4:12"}]}]},"name":"abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470__to_t_address_t_uint256_t_address_t_uint256_t_uint256_t_bytes_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"1724:9:12","type":""},{"name":"value4","nodeType":"YulTypedName","src":"1735:6:12","type":""},{"name":"value3","nodeType":"YulTypedName","src":"1743:6:12","type":""},{"name":"value2","nodeType":"YulTypedName","src":"1751:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"1759:6:12","type":""},{"name":"value0","nodeType":"YulTypedName","src":"1767:6:12","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"1778:4:12","type":""}],"src":"1466:707:12"}]},"contents":"{\n { }\n function abi_encode_tuple_t_address__to_t_address__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, sub(shl(160, 1), 1)))\n }\n function validator_revert_address(value)\n {\n if iszero(eq(value, and(value, sub(shl(160, 1), 1)))) { revert(0, 0) }\n }\n function abi_decode_tuple_t_addresst_uint256(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n value1 := calldataload(add(headStart, 32))\n }\n function abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1__to_t_address_t_uint256_t_address_t_uint256_t_uint256__fromStack_reversed(headStart, value4, value3, value2, value1, value0) -> tail\n {\n tail := add(headStart, 160)\n let _1 := sub(shl(160, 1), 1)\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), value1)\n mstore(add(headStart, 64), and(value2, _1))\n mstore(add(headStart, 96), value3)\n mstore(add(headStart, 128), value4)\n }\n function abi_decode_tuple_t_address_fromMemory(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := mload(headStart)\n validator_revert_address(value)\n value0 := value\n }\n function abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470__to_t_address_t_uint256_t_address_t_uint256_t_uint256_t_bytes_memory_ptr__fromStack_reversed(headStart, value4, value3, value2, value1, value0) -> tail\n {\n let _1 := sub(shl(160, 1), 1)\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), value1)\n mstore(add(headStart, 64), and(value2, _1))\n mstore(add(headStart, 96), value3)\n mstore(add(headStart, 128), value4)\n mstore(add(headStart, 160), 192)\n mstore(add(headStart, 192), 0)\n tail := add(headStart, 224)\n }\n}","id":12,"language":"Yul","name":"#utility.yul"}],"immutableReferences":{},"linkReferences":{},"object":"608060405234801561001057600080fd5b506004361061004c5760003560e01c806306433b1b14610051578063192df655146100885780635fbfb9cf1461009b5780637fdfc7b2146100ae575b600080fd5b61006c7302101dfb77fde026414827fdc604ddaf224f092181565b6040516001600160a01b03909116815260200160405180910390f35b61006c61009636600461022e565b6100c9565b61006c6100a936600461022e565b61017d565b61006c732d25602551487c3f3354dd80d76d54383a24335881565b604051632f4de29b60e11b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b038316604482015260648101829052600060848201819052907302101dfb77fde026414827fdc604ddaf224f092190635e9bc5369060a401602060405180830381865afa158015610152573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610176919061025a565b9392505050565b60405163da7323b360e01b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b03831660448201526064810182905260006084820181905260c060a483015260c48201819052907302101dfb77fde026414827fdc604ddaf224f09219063da7323b39060e4016020604051808303816000875af1158015610152573d6000803e3d6000fd5b6001600160a01b038116811461022b57600080fd5b50565b6000806040838503121561024157600080fd5b823561024c81610216565b946020939093013593505050565b60006020828403121561026c57600080fd5b81516101768161021656fea2646970667358221220f72638b68db63c3c7b140a211fbc4be6ca1d9a152259dbe8d00d66564794b6e164736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x4C JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x6433B1B EQ PUSH2 0x51 JUMPI DUP1 PUSH4 0x192DF655 EQ PUSH2 0x88 JUMPI DUP1 PUSH4 0x5FBFB9CF EQ PUSH2 0x9B JUMPI DUP1 PUSH4 0x7FDFC7B2 EQ PUSH2 0xAE JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x6C PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x6C PUSH2 0x96 CALLDATASIZE PUSH1 0x4 PUSH2 0x22E JUMP JUMPDEST PUSH2 0xC9 JUMP JUMPDEST PUSH2 0x6C PUSH2 0xA9 CALLDATASIZE PUSH1 0x4 PUSH2 0x22E JUMP JUMPDEST PUSH2 0x17D JUMP JUMPDEST PUSH2 0x6C PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x2F4DE29B PUSH1 0xE1 SHL DUP2 MSTORE PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 PUSH1 0x4 DUP3 ADD MSTORE CHAINID PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 PUSH1 0x84 DUP3 ADD DUP2 SWAP1 MSTORE SWAP1 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 SWAP1 PUSH4 0x5E9BC536 SWAP1 PUSH1 0xA4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x152 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x176 SWAP2 SWAP1 PUSH2 0x25A JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0xDA7323B3 PUSH1 0xE0 SHL DUP2 MSTORE PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 PUSH1 0x4 DUP3 ADD MSTORE CHAINID PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 PUSH1 0x84 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0xC0 PUSH1 0xA4 DUP4 ADD MSTORE PUSH1 0xC4 DUP3 ADD DUP2 SWAP1 MSTORE SWAP1 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 SWAP1 PUSH4 0xDA7323B3 SWAP1 PUSH1 0xE4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x152 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0x22B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x241 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH2 0x24C DUP2 PUSH2 0x216 JUMP JUMPDEST SWAP5 PUSH1 0x20 SWAP4 SWAP1 SWAP4 ADD CALLDATALOAD SWAP4 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x26C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x176 DUP2 PUSH2 0x216 JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0xF7 0x26 CODESIZE 0xB6 DUP14 0xB6 EXTCODECOPY EXTCODECOPY PUSH28 0x140A211FBC4BE6CA1D9A152259DBE8D00D66564794B6E164736F6C63 NUMBER STOP ADDMOD GT STOP CALLER ","sourceMap":"96:831:5:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;133:78;;169:42;133:78;;;;;-1:-1:-1;;;;;178:32:12;;;160:51;;148:2;133:18;:78:5;;;;;;;626:299;;;;;;:::i;:::-;;:::i;306:314::-;;;;;;:::i;:::-;;:::i;217:82::-;;257:42;217:82;;626:299;762:156;;-1:-1:-1;;;762:156:5;;257:42;762:156;;;983:34:12;830:13:5;1033:18:12;;;1026:34;-1:-1:-1;;;;;1096:15:12;;1076:18;;;1069:43;1128:18;;;1121:34;;;732:7:5;1171:19:12;;;1164:35;;;732:7:5;169:42;;762:27;;917:19:12;;762:156:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;755:163;626:299;-1:-1:-1;;;626:299:5:o;306:314::-;435:178;;-1:-1:-1;;;435:178:5;;257:42;435:178;;;1835:34:12;509:13:5;1885:18:12;;;1878:34;-1:-1:-1;;;;;1948:15:12;;1928:18;;;1921:43;1980:18;;;1973:34;;;405:7:5;2023:19:12;;;2016:35;;;2088:3;2067:19;;;2060:32;2108:19;;;2101:30;;;405:7:5;169:42;;435:33;;2148:19:12;;435:178:5;;;;;;;;;;;;;;;;;;;;;;;222:131:12;-1:-1:-1;;;;;297:31:12;;287:42;;277:70;;343:1;340;333:12;277:70;222:131;:::o;358:315::-;426:6;434;487:2;475:9;466:7;462:23;458:32;455:52;;;503:1;500;493:12;455:52;542:9;529:23;561:31;586:5;561:31;:::i;:::-;611:5;663:2;648:18;;;;635:32;;-1:-1:-1;;;358:315:12:o;1210:251::-;1280:6;1333:2;1321:9;1312:7;1308:23;1304:32;1301:52;;;1349:1;1346;1339:12;1301:52;1381:9;1375:16;1400:31;1425:5;1400:31;:::i"},"gasEstimates":{"creation":{"codeDepositCost":"137000","executionCost":"183","totalCost":"137183"},"external":{"IMPLMENTATION()":"248","REGISTRY()":"182","account(address,uint256)":"infinite","createAccount(address,uint256)":"infinite"}},"methodIdentifiers":{"IMPLMENTATION()":"7fdfc7b2","REGISTRY()":"06433b1b","account(address,uint256)":"192df655","createAccount(address,uint256)":"5fbfb9cf"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"IMPLMENTATION\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REGISTRY\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"account\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/AccountRegistryBridge.sol\":\"AccountRegistryBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/AccountRegistryBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.13;\\n\\nimport \\\"./interfaces/IRegistry.sol\\\";\\ncontract AccountRegistryBridge {\\n address public constant REGISTRY = \\t0x02101dfB77FDE026414827Fdc604ddAF224F0921;\\n address public constant IMPLMENTATION = 0x2D25602551487C3f3354dD80D76D54383A243358;\\n\\n function createAccount(address contractAddress, uint256 tokenId)\\n external\\n returns (address)\\n {\\n return IRegistry(REGISTRY).createAccount(\\n IMPLMENTATION,\\n block.chainid,\\n contractAddress,\\n tokenId,\\n 0,\\n ''\\n );\\n }\\n\\n function account(address contractAddress, uint256 tokenId)\\n external\\n view\\n returns (address)\\n {\\n return IRegistry(REGISTRY).account(\\n IMPLMENTATION,\\n block.chainid,\\n contractAddress,\\n tokenId,\\n 0\\n );\\n }\\n}\",\"keccak256\":\"0x4536af05c6fa43a3fd532415b4d39c190c35904aee16c48ea453a3b2baf976ea\",\"license\":\"MIT\"},\"contracts/interfaces/IRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\ninterface IRegistry {\\n function createAccount(\\n address implementation,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId,\\n uint256 salt,\\n bytes calldata initData\\n ) external returns (address);\\n\\n function account(\\n address implementation,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId,\\n uint256 salt\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xd24999d4d474bd349b1e2e5006eff215c5d9a64a481a9ebac3293f98603fbd27\",\"license\":\"UNLICENSED\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/ChargedParticles.sol":{"ChargedParticles":{"abi":[{"inputs":[],"name":"IMPLMENTATION","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REGISTRY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"account","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"basketManagerId","type":"string"},{"internalType":"address","name":"nftTokenAddress","type":"address"},{"internalType":"uint256","name":"nftTokenId","type":"uint256"},{"internalType":"uint256","name":"nftTokenAmount","type":"uint256"}],"name":"breakCovalentBond","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"basketManagerId","type":"string"},{"internalType":"address","name":"nftTokenAddress","type":"address"},{"internalType":"uint256","name":"nftTokenId","type":"uint256"},{"internalType":"uint256","name":"nftTokenAmount","type":"uint256"}],"name":"covalentBond","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"createAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"}],"name":"dischargeParticle","outputs":[{"internalType":"uint256","name":"creatorAmount","type":"uint256"},{"internalType":"uint256","name":"receiverAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"},{"internalType":"uint256","name":"assetAmount","type":"uint256"}],"name":"dischargeParticleAmount","outputs":[{"internalType":"uint256","name":"creatorAmount","type":"uint256"},{"internalType":"uint256","name":"receiverAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"},{"internalType":"uint256","name":"assetAmount","type":"uint256"}],"name":"dischargeParticleForCreator","outputs":[{"internalType":"uint256","name":"receiverAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"},{"internalType":"uint256","name":"assetAmount","type":"uint256"},{"internalType":"address","name":"referrer","type":"address"}],"name":"energizeParticle","outputs":[{"internalType":"uint256","name":"yieldTokensAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"}],"name":"releaseParticle","outputs":[{"internalType":"uint256","name":"creatorAmount","type":"uint256"},{"internalType":"uint256","name":"receiverAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"},{"internalType":"uint256","name":"assetAmount","type":"uint256"}],"name":"releaseParticleAmount","outputs":[{"internalType":"uint256","name":"creatorAmount","type":"uint256"},{"internalType":"uint256","name":"receiverAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"608060405234801561001057600080fd5b506108b7806100206000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c806365d20ce21161007157806365d20ce2146101945780636697b359146101a25780637fdfc7b2146101bf578063a8abef47146101a2578063acab923c14610163578063fe02fb00146101da57600080fd5b806306433b1b146100b95780630bdde2ca146100f1578063192df6551461011a5780633ff956cc1461012d5780635fbfb9cf14610150578063621a3b7014610163575b600080fd5b6100d47302101dfb77fde026414827fdc604ddaf224f092181565b6040516001600160a01b0390911681526020015b60405180910390f35b61010c6100ff366004610576565b6000979650505050505050565b6040519081526020016100e8565b6100d4610128366004610606565b6101ed565b61014061013b366004610632565b6102a1565b60405190151581526020016100e8565b6100d461015e366004610606565b61038d565b61017f6101713660046106b8565b600080965096945050505050565b604080519283526020830191909152016100e8565b61010c6100ff36600461073d565b61017f6101b036600461073d565b60008097509795505050505050565b6100d4732d25602551487c3f3354dd80d76d54383a24335881565b6101406101e83660046107cd565b610426565b604051632f4de29b60e11b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b038316604482015260648101829052600060848201819052907302101dfb77fde026414827fdc604ddaf224f092190635e9bc5369060a401602060405180830381865afa158015610276573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029a9190610864565b9392505050565b60405163192df65560e01b81526001600160a01b0388166004820152602481018790526000908190309063192df65590604401602060405180830381865afa1580156102f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103159190610864565b604051632142170760e11b81523360048201526001600160a01b03808316602483015260448201879052919250908616906342842e0e90606401600060405180830381600087803b15801561036957600080fd5b505af115801561037d573d6000803e3d6000fd5b5050505050979650505050505050565b60405163da7323b360e01b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b03831660448201526064810182905260006084820181905260c060a483015260c48201819052907302101dfb77fde026414827fdc604ddaf224f09219063da7323b39060e4016020604051808303816000875af1158015610276573d6000803e3d6000fd5b60405163192df65560e01b81526001600160a01b0388166004820152602481018790526000908190309063192df65590604401602060405180830381865afa158015610476573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049a9190610864565b604051632142170760e11b81526001600160a01b0380831660048301528c8116602483015260448201879052919250908616906342842e0e90606401600060405180830381600087803b1580156104f057600080fd5b505af1158015610504573d6000803e3d6000fd5b505050505098975050505050505050565b6001600160a01b038116811461052a57600080fd5b50565b60008083601f84011261053f57600080fd5b50813567ffffffffffffffff81111561055757600080fd5b60208301915083602082850101111561056f57600080fd5b9250929050565b600080600080600080600060c0888a03121561059157600080fd5b873561059c81610515565b965060208801359550604088013567ffffffffffffffff8111156105bf57600080fd5b6105cb8a828b0161052d565b90965094505060608801356105df81610515565b92506080880135915060a08801356105f681610515565b8091505092959891949750929550565b6000806040838503121561061957600080fd5b823561062481610515565b946020939093013593505050565b600080600080600080600060c0888a03121561064d57600080fd5b873561065881610515565b965060208801359550604088013567ffffffffffffffff81111561067b57600080fd5b6106878a828b0161052d565b909650945050606088013561069b81610515565b969995985093969295946080840135945060a09093013592915050565b60008060008060008060a087890312156106d157600080fd5b86356106dc81610515565b955060208701356106ec81610515565b945060408701359350606087013567ffffffffffffffff81111561070f57600080fd5b61071b89828a0161052d565b909450925050608087013561072f81610515565b809150509295509295509295565b600080600080600080600060c0888a03121561075857600080fd5b873561076381610515565b9650602088013561077381610515565b955060408801359450606088013567ffffffffffffffff81111561079657600080fd5b6107a28a828b0161052d565b90955093505060808801356107b681610515565b8092505060a0880135905092959891949750929550565b60008060008060008060008060e0898b0312156107e957600080fd5b88356107f481610515565b9750602089013561080481610515565b965060408901359550606089013567ffffffffffffffff81111561082757600080fd5b6108338b828c0161052d565b909650945050608089013561084781610515565b979a969950949793969295929450505060a08201359160c0013590565b60006020828403121561087657600080fd5b815161029a8161051556fea26469706673582212205aad4bc7bca1ad16a1a304738f9f9fb1fc0d380c528fcbc9be3c13c3f029355264736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x8B7 DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0xB4 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x65D20CE2 GT PUSH2 0x71 JUMPI DUP1 PUSH4 0x65D20CE2 EQ PUSH2 0x194 JUMPI DUP1 PUSH4 0x6697B359 EQ PUSH2 0x1A2 JUMPI DUP1 PUSH4 0x7FDFC7B2 EQ PUSH2 0x1BF JUMPI DUP1 PUSH4 0xA8ABEF47 EQ PUSH2 0x1A2 JUMPI DUP1 PUSH4 0xACAB923C EQ PUSH2 0x163 JUMPI DUP1 PUSH4 0xFE02FB00 EQ PUSH2 0x1DA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x6433B1B EQ PUSH2 0xB9 JUMPI DUP1 PUSH4 0xBDDE2CA EQ PUSH2 0xF1 JUMPI DUP1 PUSH4 0x192DF655 EQ PUSH2 0x11A JUMPI DUP1 PUSH4 0x3FF956CC EQ PUSH2 0x12D JUMPI DUP1 PUSH4 0x5FBFB9CF EQ PUSH2 0x150 JUMPI DUP1 PUSH4 0x621A3B70 EQ PUSH2 0x163 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD4 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x10C PUSH2 0xFF CALLDATASIZE PUSH1 0x4 PUSH2 0x576 JUMP JUMPDEST PUSH1 0x0 SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xE8 JUMP JUMPDEST PUSH2 0xD4 PUSH2 0x128 CALLDATASIZE PUSH1 0x4 PUSH2 0x606 JUMP JUMPDEST PUSH2 0x1ED JUMP JUMPDEST PUSH2 0x140 PUSH2 0x13B CALLDATASIZE PUSH1 0x4 PUSH2 0x632 JUMP JUMPDEST PUSH2 0x2A1 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xE8 JUMP JUMPDEST PUSH2 0xD4 PUSH2 0x15E CALLDATASIZE PUSH1 0x4 PUSH2 0x606 JUMP JUMPDEST PUSH2 0x38D JUMP JUMPDEST PUSH2 0x17F PUSH2 0x171 CALLDATASIZE PUSH1 0x4 PUSH2 0x6B8 JUMP JUMPDEST PUSH1 0x0 DUP1 SWAP7 POP SWAP7 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP3 DUP4 MSTORE PUSH1 0x20 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE ADD PUSH2 0xE8 JUMP JUMPDEST PUSH2 0x10C PUSH2 0xFF CALLDATASIZE PUSH1 0x4 PUSH2 0x73D JUMP JUMPDEST PUSH2 0x17F PUSH2 0x1B0 CALLDATASIZE PUSH1 0x4 PUSH2 0x73D JUMP JUMPDEST PUSH1 0x0 DUP1 SWAP8 POP SWAP8 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH2 0xD4 PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 DUP2 JUMP JUMPDEST PUSH2 0x140 PUSH2 0x1E8 CALLDATASIZE PUSH1 0x4 PUSH2 0x7CD JUMP JUMPDEST PUSH2 0x426 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x2F4DE29B PUSH1 0xE1 SHL DUP2 MSTORE PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 PUSH1 0x4 DUP3 ADD MSTORE CHAINID PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 PUSH1 0x84 DUP3 ADD DUP2 SWAP1 MSTORE SWAP1 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 SWAP1 PUSH4 0x5E9BC536 SWAP1 PUSH1 0xA4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x276 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x29A SWAP2 SWAP1 PUSH2 0x864 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x192DF655 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP9 AND PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x24 DUP2 ADD DUP8 SWAP1 MSTORE PUSH1 0x0 SWAP1 DUP2 SWAP1 ADDRESS SWAP1 PUSH4 0x192DF655 SWAP1 PUSH1 0x44 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x2F1 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x315 SWAP2 SWAP1 PUSH2 0x864 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x21421707 PUSH1 0xE1 SHL DUP2 MSTORE CALLER PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP1 DUP4 AND PUSH1 0x24 DUP4 ADD MSTORE PUSH1 0x44 DUP3 ADD DUP8 SWAP1 MSTORE SWAP2 SWAP3 POP SWAP1 DUP7 AND SWAP1 PUSH4 0x42842E0E SWAP1 PUSH1 0x64 ADD PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x369 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x37D JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0xDA7323B3 PUSH1 0xE0 SHL DUP2 MSTORE PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 PUSH1 0x4 DUP3 ADD MSTORE CHAINID PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 PUSH1 0x84 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0xC0 PUSH1 0xA4 DUP4 ADD MSTORE PUSH1 0xC4 DUP3 ADD DUP2 SWAP1 MSTORE SWAP1 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 SWAP1 PUSH4 0xDA7323B3 SWAP1 PUSH1 0xE4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x276 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x192DF655 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP9 AND PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x24 DUP2 ADD DUP8 SWAP1 MSTORE PUSH1 0x0 SWAP1 DUP2 SWAP1 ADDRESS SWAP1 PUSH4 0x192DF655 SWAP1 PUSH1 0x44 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x476 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x49A SWAP2 SWAP1 PUSH2 0x864 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x21421707 PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP1 DUP4 AND PUSH1 0x4 DUP4 ADD MSTORE DUP13 DUP2 AND PUSH1 0x24 DUP4 ADD MSTORE PUSH1 0x44 DUP3 ADD DUP8 SWAP1 MSTORE SWAP2 SWAP3 POP SWAP1 DUP7 AND SWAP1 PUSH4 0x42842E0E SWAP1 PUSH1 0x64 ADD PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x4F0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x504 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP SWAP9 SWAP8 POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0x52A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x53F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x557 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0x56F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xC0 DUP9 DUP11 SUB SLT ISZERO PUSH2 0x591 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 CALLDATALOAD PUSH2 0x59C DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP7 POP PUSH1 0x20 DUP9 ADD CALLDATALOAD SWAP6 POP PUSH1 0x40 DUP9 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x5BF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x5CB DUP11 DUP3 DUP12 ADD PUSH2 0x52D JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP POP PUSH1 0x60 DUP9 ADD CALLDATALOAD PUSH2 0x5DF DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP3 POP PUSH1 0x80 DUP9 ADD CALLDATALOAD SWAP2 POP PUSH1 0xA0 DUP9 ADD CALLDATALOAD PUSH2 0x5F6 DUP2 PUSH2 0x515 JUMP JUMPDEST DUP1 SWAP2 POP POP SWAP3 SWAP6 SWAP9 SWAP2 SWAP5 SWAP8 POP SWAP3 SWAP6 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x619 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH2 0x624 DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP5 PUSH1 0x20 SWAP4 SWAP1 SWAP4 ADD CALLDATALOAD SWAP4 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xC0 DUP9 DUP11 SUB SLT ISZERO PUSH2 0x64D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 CALLDATALOAD PUSH2 0x658 DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP7 POP PUSH1 0x20 DUP9 ADD CALLDATALOAD SWAP6 POP PUSH1 0x40 DUP9 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x67B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x687 DUP11 DUP3 DUP12 ADD PUSH2 0x52D JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP POP PUSH1 0x60 DUP9 ADD CALLDATALOAD PUSH2 0x69B DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP7 SWAP10 SWAP6 SWAP9 POP SWAP4 SWAP7 SWAP3 SWAP6 SWAP5 PUSH1 0x80 DUP5 ADD CALLDATALOAD SWAP5 POP PUSH1 0xA0 SWAP1 SWAP4 ADD CALLDATALOAD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0xA0 DUP8 DUP10 SUB SLT ISZERO PUSH2 0x6D1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP7 CALLDATALOAD PUSH2 0x6DC DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP6 POP PUSH1 0x20 DUP8 ADD CALLDATALOAD PUSH2 0x6EC DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP5 POP PUSH1 0x40 DUP8 ADD CALLDATALOAD SWAP4 POP PUSH1 0x60 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x70F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x71B DUP10 DUP3 DUP11 ADD PUSH2 0x52D JUMP JUMPDEST SWAP1 SWAP5 POP SWAP3 POP POP PUSH1 0x80 DUP8 ADD CALLDATALOAD PUSH2 0x72F DUP2 PUSH2 0x515 JUMP JUMPDEST DUP1 SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 POP SWAP3 SWAP6 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xC0 DUP9 DUP11 SUB SLT ISZERO PUSH2 0x758 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 CALLDATALOAD PUSH2 0x763 DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP7 POP PUSH1 0x20 DUP9 ADD CALLDATALOAD PUSH2 0x773 DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP6 POP PUSH1 0x40 DUP9 ADD CALLDATALOAD SWAP5 POP PUSH1 0x60 DUP9 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x796 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x7A2 DUP11 DUP3 DUP12 ADD PUSH2 0x52D JUMP JUMPDEST SWAP1 SWAP6 POP SWAP4 POP POP PUSH1 0x80 DUP9 ADD CALLDATALOAD PUSH2 0x7B6 DUP2 PUSH2 0x515 JUMP JUMPDEST DUP1 SWAP3 POP POP PUSH1 0xA0 DUP9 ADD CALLDATALOAD SWAP1 POP SWAP3 SWAP6 SWAP9 SWAP2 SWAP5 SWAP8 POP SWAP3 SWAP6 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0xE0 DUP10 DUP12 SUB SLT ISZERO PUSH2 0x7E9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP9 CALLDATALOAD PUSH2 0x7F4 DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP8 POP PUSH1 0x20 DUP10 ADD CALLDATALOAD PUSH2 0x804 DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP7 POP PUSH1 0x40 DUP10 ADD CALLDATALOAD SWAP6 POP PUSH1 0x60 DUP10 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x827 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x833 DUP12 DUP3 DUP13 ADD PUSH2 0x52D JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP POP PUSH1 0x80 DUP10 ADD CALLDATALOAD PUSH2 0x847 DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP8 SWAP11 SWAP7 SWAP10 POP SWAP5 SWAP8 SWAP4 SWAP7 SWAP3 SWAP6 SWAP3 SWAP5 POP POP POP PUSH1 0xA0 DUP3 ADD CALLDATALOAD SWAP2 PUSH1 0xC0 ADD CALLDATALOAD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x876 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x29A DUP2 PUSH2 0x515 JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 GAS 0xAD 0x4B 0xC7 0xBC LOG1 0xAD AND LOG1 LOG3 DIV PUSH20 0x8F9F9FB1FC0D380C528FCBC9BE3C13C3F0293552 PUSH5 0x736F6C6343 STOP ADDMOD GT STOP CALLER ","sourceMap":"202:2643:6:-:0;;;;;;;;;;;;;;;;;;;"},"deployedBytecode":{"functionDebugData":{"@IMPLMENTATION_209":{"entryPoint":null,"id":209,"parameterSlots":0,"returnSlots":0},"@REGISTRY_206":{"entryPoint":null,"id":206,"parameterSlots":0,"returnSlots":0},"@account_254":{"entryPoint":493,"id":254,"parameterSlots":2,"returnSlots":1},"@breakCovalentBond_447":{"entryPoint":1062,"id":447,"parameterSlots":8,"returnSlots":1},"@covalentBond_410":{"entryPoint":673,"id":410,"parameterSlots":7,"returnSlots":1},"@createAccount_232":{"entryPoint":909,"id":232,"parameterSlots":2,"returnSlots":1},"@dischargeParticleAmount_318":{"entryPoint":null,"id":318,"parameterSlots":7,"returnSlots":2},"@dischargeParticleForCreator_336":{"entryPoint":null,"id":336,"parameterSlots":7,"returnSlots":1},"@dischargeParticle_298":{"entryPoint":null,"id":298,"parameterSlots":6,"returnSlots":2},"@energizeParticle_280":{"entryPoint":null,"id":280,"parameterSlots":7,"returnSlots":1},"@releaseParticleAmount_374":{"entryPoint":null,"id":374,"parameterSlots":7,"returnSlots":2},"@releaseParticle_354":{"entryPoint":null,"id":354,"parameterSlots":6,"returnSlots":2},"abi_decode_string_calldata":{"entryPoint":1325,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_tuple_t_address_fromMemory":{"entryPoint":2148,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_addresst_addresst_uint256t_string_calldata_ptrt_address":{"entryPoint":1720,"id":null,"parameterSlots":2,"returnSlots":6},"abi_decode_tuple_t_addresst_addresst_uint256t_string_calldata_ptrt_addresst_uint256":{"entryPoint":1853,"id":null,"parameterSlots":2,"returnSlots":7},"abi_decode_tuple_t_addresst_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_uint256":{"entryPoint":1997,"id":null,"parameterSlots":2,"returnSlots":8},"abi_decode_tuple_t_addresst_uint256":{"entryPoint":1542,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_tuple_t_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_address":{"entryPoint":1398,"id":null,"parameterSlots":2,"returnSlots":7},"abi_decode_tuple_t_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_uint256":{"entryPoint":1586,"id":null,"parameterSlots":2,"returnSlots":7},"abi_encode_tuple_t_address__to_t_address__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_address_t_address_t_uint256__to_t_address_t_address_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":4,"returnSlots":1},"abi_encode_tuple_t_address_t_uint256__to_t_address_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":3,"returnSlots":1},"abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1__to_t_address_t_uint256_t_address_t_uint256_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":6,"returnSlots":1},"abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470__to_t_address_t_uint256_t_address_t_uint256_t_uint256_t_bytes_memory_ptr__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":6,"returnSlots":1},"abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_uint256_t_uint256__to_t_uint256_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":3,"returnSlots":1},"validator_revert_address":{"entryPoint":1301,"id":null,"parameterSlots":1,"returnSlots":0}},"generatedSources":[{"ast":{"nodeType":"YulBlock","src":"0:8601:12","statements":[{"nodeType":"YulBlock","src":"6:3:12","statements":[]},{"body":{"nodeType":"YulBlock","src":"115:102:12","statements":[{"nodeType":"YulAssignment","src":"125:26:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"137:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"148:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"133:3:12"},"nodeType":"YulFunctionCall","src":"133:18:12"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"125:4:12"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"167:9:12"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"182:6:12"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"198:3:12","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"203:1:12","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"194:3:12"},"nodeType":"YulFunctionCall","src":"194:11:12"},{"kind":"number","nodeType":"YulLiteral","src":"207:1:12","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"190:3:12"},"nodeType":"YulFunctionCall","src":"190:19:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"178:3:12"},"nodeType":"YulFunctionCall","src":"178:32:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"160:6:12"},"nodeType":"YulFunctionCall","src":"160:51:12"},"nodeType":"YulExpressionStatement","src":"160:51:12"}]},"name":"abi_encode_tuple_t_address__to_t_address__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"84:9:12","type":""},{"name":"value0","nodeType":"YulTypedName","src":"95:6:12","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"106:4:12","type":""}],"src":"14:203:12"},{"body":{"nodeType":"YulBlock","src":"267:86:12","statements":[{"body":{"nodeType":"YulBlock","src":"331:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"340:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"343:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"333:6:12"},"nodeType":"YulFunctionCall","src":"333:12:12"},"nodeType":"YulExpressionStatement","src":"333:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"290:5:12"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"301:5:12"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"316:3:12","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"321:1:12","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"312:3:12"},"nodeType":"YulFunctionCall","src":"312:11:12"},{"kind":"number","nodeType":"YulLiteral","src":"325:1:12","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"308:3:12"},"nodeType":"YulFunctionCall","src":"308:19:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"297:3:12"},"nodeType":"YulFunctionCall","src":"297:31:12"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"287:2:12"},"nodeType":"YulFunctionCall","src":"287:42:12"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"280:6:12"},"nodeType":"YulFunctionCall","src":"280:50:12"},"nodeType":"YulIf","src":"277:70:12"}]},"name":"validator_revert_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"value","nodeType":"YulTypedName","src":"256:5:12","type":""}],"src":"222:131:12"},{"body":{"nodeType":"YulBlock","src":"431:275:12","statements":[{"body":{"nodeType":"YulBlock","src":"480:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"489:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"492:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"482:6:12"},"nodeType":"YulFunctionCall","src":"482:12:12"},"nodeType":"YulExpressionStatement","src":"482:12:12"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"459:6:12"},{"kind":"number","nodeType":"YulLiteral","src":"467:4:12","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"455:3:12"},"nodeType":"YulFunctionCall","src":"455:17:12"},{"name":"end","nodeType":"YulIdentifier","src":"474:3:12"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"451:3:12"},"nodeType":"YulFunctionCall","src":"451:27:12"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"444:6:12"},"nodeType":"YulFunctionCall","src":"444:35:12"},"nodeType":"YulIf","src":"441:55:12"},{"nodeType":"YulAssignment","src":"505:30:12","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"528:6:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"515:12:12"},"nodeType":"YulFunctionCall","src":"515:20:12"},"variableNames":[{"name":"length","nodeType":"YulIdentifier","src":"505:6:12"}]},{"body":{"nodeType":"YulBlock","src":"578:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"587:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"590:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"580:6:12"},"nodeType":"YulFunctionCall","src":"580:12:12"},"nodeType":"YulExpressionStatement","src":"580:12:12"}]},"condition":{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"550:6:12"},{"kind":"number","nodeType":"YulLiteral","src":"558:18:12","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"547:2:12"},"nodeType":"YulFunctionCall","src":"547:30:12"},"nodeType":"YulIf","src":"544:50:12"},{"nodeType":"YulAssignment","src":"603:29:12","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"619:6:12"},{"kind":"number","nodeType":"YulLiteral","src":"627:4:12","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"615:3:12"},"nodeType":"YulFunctionCall","src":"615:17:12"},"variableNames":[{"name":"arrayPos","nodeType":"YulIdentifier","src":"603:8:12"}]},{"body":{"nodeType":"YulBlock","src":"684:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"693:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"696:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"686:6:12"},"nodeType":"YulFunctionCall","src":"686:12:12"},"nodeType":"YulExpressionStatement","src":"686:12:12"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"655:6:12"},{"name":"length","nodeType":"YulIdentifier","src":"663:6:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"651:3:12"},"nodeType":"YulFunctionCall","src":"651:19:12"},{"kind":"number","nodeType":"YulLiteral","src":"672:4:12","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"647:3:12"},"nodeType":"YulFunctionCall","src":"647:30:12"},{"name":"end","nodeType":"YulIdentifier","src":"679:3:12"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"644:2:12"},"nodeType":"YulFunctionCall","src":"644:39:12"},"nodeType":"YulIf","src":"641:59:12"}]},"name":"abi_decode_string_calldata","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"394:6:12","type":""},{"name":"end","nodeType":"YulTypedName","src":"402:3:12","type":""}],"returnVariables":[{"name":"arrayPos","nodeType":"YulTypedName","src":"410:8:12","type":""},{"name":"length","nodeType":"YulTypedName","src":"420:6:12","type":""}],"src":"358:348:12"},{"body":{"nodeType":"YulBlock","src":"886:792:12","statements":[{"body":{"nodeType":"YulBlock","src":"933:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"942:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"945:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"935:6:12"},"nodeType":"YulFunctionCall","src":"935:12:12"},"nodeType":"YulExpressionStatement","src":"935:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"907:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"916:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"903:3:12"},"nodeType":"YulFunctionCall","src":"903:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"928:3:12","type":"","value":"192"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"899:3:12"},"nodeType":"YulFunctionCall","src":"899:33:12"},"nodeType":"YulIf","src":"896:53:12"},{"nodeType":"YulVariableDeclaration","src":"958:36:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"984:9:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"971:12:12"},"nodeType":"YulFunctionCall","src":"971:23:12"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"962:5:12","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1028:5:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"1003:24:12"},"nodeType":"YulFunctionCall","src":"1003:31:12"},"nodeType":"YulExpressionStatement","src":"1003:31:12"},{"nodeType":"YulAssignment","src":"1043:15:12","value":{"name":"value","nodeType":"YulIdentifier","src":"1053:5:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"1043:6:12"}]},{"nodeType":"YulAssignment","src":"1067:42:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1094:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"1105:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1090:3:12"},"nodeType":"YulFunctionCall","src":"1090:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1077:12:12"},"nodeType":"YulFunctionCall","src":"1077:32:12"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"1067:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"1118:46:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1149:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"1160:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1145:3:12"},"nodeType":"YulFunctionCall","src":"1145:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1132:12:12"},"nodeType":"YulFunctionCall","src":"1132:32:12"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"1122:6:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"1207:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1216:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1219:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1209:6:12"},"nodeType":"YulFunctionCall","src":"1209:12:12"},"nodeType":"YulExpressionStatement","src":"1209:12:12"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"1179:6:12"},{"kind":"number","nodeType":"YulLiteral","src":"1187:18:12","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"1176:2:12"},"nodeType":"YulFunctionCall","src":"1176:30:12"},"nodeType":"YulIf","src":"1173:50:12"},{"nodeType":"YulVariableDeclaration","src":"1232:85:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1289:9:12"},{"name":"offset","nodeType":"YulIdentifier","src":"1300:6:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1285:3:12"},"nodeType":"YulFunctionCall","src":"1285:22:12"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"1309:7:12"}],"functionName":{"name":"abi_decode_string_calldata","nodeType":"YulIdentifier","src":"1258:26:12"},"nodeType":"YulFunctionCall","src":"1258:59:12"},"variables":[{"name":"value2_1","nodeType":"YulTypedName","src":"1236:8:12","type":""},{"name":"value3_1","nodeType":"YulTypedName","src":"1246:8:12","type":""}]},{"nodeType":"YulAssignment","src":"1326:18:12","value":{"name":"value2_1","nodeType":"YulIdentifier","src":"1336:8:12"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"1326:6:12"}]},{"nodeType":"YulAssignment","src":"1353:18:12","value":{"name":"value3_1","nodeType":"YulIdentifier","src":"1363:8:12"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"1353:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"1380:47:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1412:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"1423:2:12","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1408:3:12"},"nodeType":"YulFunctionCall","src":"1408:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1395:12:12"},"nodeType":"YulFunctionCall","src":"1395:32:12"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"1384:7:12","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"1461:7:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"1436:24:12"},"nodeType":"YulFunctionCall","src":"1436:33:12"},"nodeType":"YulExpressionStatement","src":"1436:33:12"},{"nodeType":"YulAssignment","src":"1478:17:12","value":{"name":"value_1","nodeType":"YulIdentifier","src":"1488:7:12"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"1478:6:12"}]},{"nodeType":"YulAssignment","src":"1504:43:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1531:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"1542:3:12","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1527:3:12"},"nodeType":"YulFunctionCall","src":"1527:19:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1514:12:12"},"nodeType":"YulFunctionCall","src":"1514:33:12"},"variableNames":[{"name":"value5","nodeType":"YulIdentifier","src":"1504:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"1556:48:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1588:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"1599:3:12","type":"","value":"160"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1584:3:12"},"nodeType":"YulFunctionCall","src":"1584:19:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1571:12:12"},"nodeType":"YulFunctionCall","src":"1571:33:12"},"variables":[{"name":"value_2","nodeType":"YulTypedName","src":"1560:7:12","type":""}]},{"expression":{"arguments":[{"name":"value_2","nodeType":"YulIdentifier","src":"1638:7:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"1613:24:12"},"nodeType":"YulFunctionCall","src":"1613:33:12"},"nodeType":"YulExpressionStatement","src":"1613:33:12"},{"nodeType":"YulAssignment","src":"1655:17:12","value":{"name":"value_2","nodeType":"YulIdentifier","src":"1665:7:12"},"variableNames":[{"name":"value6","nodeType":"YulIdentifier","src":"1655:6:12"}]}]},"name":"abi_decode_tuple_t_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"804:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"815:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"827:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"835:6:12","type":""},{"name":"value2","nodeType":"YulTypedName","src":"843:6:12","type":""},{"name":"value3","nodeType":"YulTypedName","src":"851:6:12","type":""},{"name":"value4","nodeType":"YulTypedName","src":"859:6:12","type":""},{"name":"value5","nodeType":"YulTypedName","src":"867:6:12","type":""},{"name":"value6","nodeType":"YulTypedName","src":"875:6:12","type":""}],"src":"711:967:12"},{"body":{"nodeType":"YulBlock","src":"1784:76:12","statements":[{"nodeType":"YulAssignment","src":"1794:26:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1806:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"1817:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1802:3:12"},"nodeType":"YulFunctionCall","src":"1802:18:12"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"1794:4:12"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1836:9:12"},{"name":"value0","nodeType":"YulIdentifier","src":"1847:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1829:6:12"},"nodeType":"YulFunctionCall","src":"1829:25:12"},"nodeType":"YulExpressionStatement","src":"1829:25:12"}]},"name":"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"1753:9:12","type":""},{"name":"value0","nodeType":"YulTypedName","src":"1764:6:12","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"1775:4:12","type":""}],"src":"1683:177:12"},{"body":{"nodeType":"YulBlock","src":"1952:228:12","statements":[{"body":{"nodeType":"YulBlock","src":"1998:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2007:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2010:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2000:6:12"},"nodeType":"YulFunctionCall","src":"2000:12:12"},"nodeType":"YulExpressionStatement","src":"2000:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"1973:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"1982:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1969:3:12"},"nodeType":"YulFunctionCall","src":"1969:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"1994:2:12","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"1965:3:12"},"nodeType":"YulFunctionCall","src":"1965:32:12"},"nodeType":"YulIf","src":"1962:52:12"},{"nodeType":"YulVariableDeclaration","src":"2023:36:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2049:9:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2036:12:12"},"nodeType":"YulFunctionCall","src":"2036:23:12"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"2027:5:12","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"2093:5:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"2068:24:12"},"nodeType":"YulFunctionCall","src":"2068:31:12"},"nodeType":"YulExpressionStatement","src":"2068:31:12"},{"nodeType":"YulAssignment","src":"2108:15:12","value":{"name":"value","nodeType":"YulIdentifier","src":"2118:5:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"2108:6:12"}]},{"nodeType":"YulAssignment","src":"2132:42:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2159:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"2170:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2155:3:12"},"nodeType":"YulFunctionCall","src":"2155:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2142:12:12"},"nodeType":"YulFunctionCall","src":"2142:32:12"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"2132:6:12"}]}]},"name":"abi_decode_tuple_t_addresst_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"1910:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"1921:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"1933:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"1941:6:12","type":""}],"src":"1865:315:12"},{"body":{"nodeType":"YulBlock","src":"2360:719:12","statements":[{"body":{"nodeType":"YulBlock","src":"2407:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2416:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2419:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2409:6:12"},"nodeType":"YulFunctionCall","src":"2409:12:12"},"nodeType":"YulExpressionStatement","src":"2409:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"2381:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"2390:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"2377:3:12"},"nodeType":"YulFunctionCall","src":"2377:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"2402:3:12","type":"","value":"192"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"2373:3:12"},"nodeType":"YulFunctionCall","src":"2373:33:12"},"nodeType":"YulIf","src":"2370:53:12"},{"nodeType":"YulVariableDeclaration","src":"2432:36:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2458:9:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2445:12:12"},"nodeType":"YulFunctionCall","src":"2445:23:12"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"2436:5:12","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"2502:5:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"2477:24:12"},"nodeType":"YulFunctionCall","src":"2477:31:12"},"nodeType":"YulExpressionStatement","src":"2477:31:12"},{"nodeType":"YulAssignment","src":"2517:15:12","value":{"name":"value","nodeType":"YulIdentifier","src":"2527:5:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"2517:6:12"}]},{"nodeType":"YulAssignment","src":"2541:42:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2568:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"2579:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2564:3:12"},"nodeType":"YulFunctionCall","src":"2564:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2551:12:12"},"nodeType":"YulFunctionCall","src":"2551:32:12"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"2541:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"2592:46:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2623:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"2634:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2619:3:12"},"nodeType":"YulFunctionCall","src":"2619:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2606:12:12"},"nodeType":"YulFunctionCall","src":"2606:32:12"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"2596:6:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"2681:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2690:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2693:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2683:6:12"},"nodeType":"YulFunctionCall","src":"2683:12:12"},"nodeType":"YulExpressionStatement","src":"2683:12:12"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2653:6:12"},{"kind":"number","nodeType":"YulLiteral","src":"2661:18:12","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2650:2:12"},"nodeType":"YulFunctionCall","src":"2650:30:12"},"nodeType":"YulIf","src":"2647:50:12"},{"nodeType":"YulVariableDeclaration","src":"2706:85:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2763:9:12"},{"name":"offset","nodeType":"YulIdentifier","src":"2774:6:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2759:3:12"},"nodeType":"YulFunctionCall","src":"2759:22:12"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"2783:7:12"}],"functionName":{"name":"abi_decode_string_calldata","nodeType":"YulIdentifier","src":"2732:26:12"},"nodeType":"YulFunctionCall","src":"2732:59:12"},"variables":[{"name":"value2_1","nodeType":"YulTypedName","src":"2710:8:12","type":""},{"name":"value3_1","nodeType":"YulTypedName","src":"2720:8:12","type":""}]},{"nodeType":"YulAssignment","src":"2800:18:12","value":{"name":"value2_1","nodeType":"YulIdentifier","src":"2810:8:12"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"2800:6:12"}]},{"nodeType":"YulAssignment","src":"2827:18:12","value":{"name":"value3_1","nodeType":"YulIdentifier","src":"2837:8:12"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"2827:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"2854:47:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2886:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"2897:2:12","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2882:3:12"},"nodeType":"YulFunctionCall","src":"2882:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2869:12:12"},"nodeType":"YulFunctionCall","src":"2869:32:12"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"2858:7:12","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"2935:7:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"2910:24:12"},"nodeType":"YulFunctionCall","src":"2910:33:12"},"nodeType":"YulExpressionStatement","src":"2910:33:12"},{"nodeType":"YulAssignment","src":"2952:17:12","value":{"name":"value_1","nodeType":"YulIdentifier","src":"2962:7:12"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"2952:6:12"}]},{"nodeType":"YulAssignment","src":"2978:43:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3005:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"3016:3:12","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3001:3:12"},"nodeType":"YulFunctionCall","src":"3001:19:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2988:12:12"},"nodeType":"YulFunctionCall","src":"2988:33:12"},"variableNames":[{"name":"value5","nodeType":"YulIdentifier","src":"2978:6:12"}]},{"nodeType":"YulAssignment","src":"3030:43:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3057:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"3068:3:12","type":"","value":"160"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3053:3:12"},"nodeType":"YulFunctionCall","src":"3053:19:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3040:12:12"},"nodeType":"YulFunctionCall","src":"3040:33:12"},"variableNames":[{"name":"value6","nodeType":"YulIdentifier","src":"3030:6:12"}]}]},"name":"abi_decode_tuple_t_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"2278:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"2289:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"2301:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"2309:6:12","type":""},{"name":"value2","nodeType":"YulTypedName","src":"2317:6:12","type":""},{"name":"value3","nodeType":"YulTypedName","src":"2325:6:12","type":""},{"name":"value4","nodeType":"YulTypedName","src":"2333:6:12","type":""},{"name":"value5","nodeType":"YulTypedName","src":"2341:6:12","type":""},{"name":"value6","nodeType":"YulTypedName","src":"2349:6:12","type":""}],"src":"2185:894:12"},{"body":{"nodeType":"YulBlock","src":"3179:92:12","statements":[{"nodeType":"YulAssignment","src":"3189:26:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3201:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"3212:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3197:3:12"},"nodeType":"YulFunctionCall","src":"3197:18:12"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"3189:4:12"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3231:9:12"},{"arguments":[{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"3256:6:12"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"3249:6:12"},"nodeType":"YulFunctionCall","src":"3249:14:12"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"3242:6:12"},"nodeType":"YulFunctionCall","src":"3242:22:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"3224:6:12"},"nodeType":"YulFunctionCall","src":"3224:41:12"},"nodeType":"YulExpressionStatement","src":"3224:41:12"}]},"name":"abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"3148:9:12","type":""},{"name":"value0","nodeType":"YulTypedName","src":"3159:6:12","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"3170:4:12","type":""}],"src":"3084:187:12"},{"body":{"nodeType":"YulBlock","src":"3434:740:12","statements":[{"body":{"nodeType":"YulBlock","src":"3481:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3490:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3493:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3483:6:12"},"nodeType":"YulFunctionCall","src":"3483:12:12"},"nodeType":"YulExpressionStatement","src":"3483:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"3455:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"3464:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"3451:3:12"},"nodeType":"YulFunctionCall","src":"3451:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"3476:3:12","type":"","value":"160"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"3447:3:12"},"nodeType":"YulFunctionCall","src":"3447:33:12"},"nodeType":"YulIf","src":"3444:53:12"},{"nodeType":"YulVariableDeclaration","src":"3506:36:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3532:9:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3519:12:12"},"nodeType":"YulFunctionCall","src":"3519:23:12"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"3510:5:12","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"3576:5:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"3551:24:12"},"nodeType":"YulFunctionCall","src":"3551:31:12"},"nodeType":"YulExpressionStatement","src":"3551:31:12"},{"nodeType":"YulAssignment","src":"3591:15:12","value":{"name":"value","nodeType":"YulIdentifier","src":"3601:5:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"3591:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"3615:47:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3647:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"3658:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3643:3:12"},"nodeType":"YulFunctionCall","src":"3643:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3630:12:12"},"nodeType":"YulFunctionCall","src":"3630:32:12"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"3619:7:12","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"3696:7:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"3671:24:12"},"nodeType":"YulFunctionCall","src":"3671:33:12"},"nodeType":"YulExpressionStatement","src":"3671:33:12"},{"nodeType":"YulAssignment","src":"3713:17:12","value":{"name":"value_1","nodeType":"YulIdentifier","src":"3723:7:12"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"3713:6:12"}]},{"nodeType":"YulAssignment","src":"3739:42:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3766:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"3777:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3762:3:12"},"nodeType":"YulFunctionCall","src":"3762:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3749:12:12"},"nodeType":"YulFunctionCall","src":"3749:32:12"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"3739:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"3790:46:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3821:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"3832:2:12","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3817:3:12"},"nodeType":"YulFunctionCall","src":"3817:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3804:12:12"},"nodeType":"YulFunctionCall","src":"3804:32:12"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"3794:6:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"3879:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3888:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3891:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3881:6:12"},"nodeType":"YulFunctionCall","src":"3881:12:12"},"nodeType":"YulExpressionStatement","src":"3881:12:12"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"3851:6:12"},{"kind":"number","nodeType":"YulLiteral","src":"3859:18:12","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"3848:2:12"},"nodeType":"YulFunctionCall","src":"3848:30:12"},"nodeType":"YulIf","src":"3845:50:12"},{"nodeType":"YulVariableDeclaration","src":"3904:85:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3961:9:12"},{"name":"offset","nodeType":"YulIdentifier","src":"3972:6:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3957:3:12"},"nodeType":"YulFunctionCall","src":"3957:22:12"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"3981:7:12"}],"functionName":{"name":"abi_decode_string_calldata","nodeType":"YulIdentifier","src":"3930:26:12"},"nodeType":"YulFunctionCall","src":"3930:59:12"},"variables":[{"name":"value3_1","nodeType":"YulTypedName","src":"3908:8:12","type":""},{"name":"value4_1","nodeType":"YulTypedName","src":"3918:8:12","type":""}]},{"nodeType":"YulAssignment","src":"3998:18:12","value":{"name":"value3_1","nodeType":"YulIdentifier","src":"4008:8:12"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"3998:6:12"}]},{"nodeType":"YulAssignment","src":"4025:18:12","value":{"name":"value4_1","nodeType":"YulIdentifier","src":"4035:8:12"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"4025:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"4052:48:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4084:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"4095:3:12","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4080:3:12"},"nodeType":"YulFunctionCall","src":"4080:19:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4067:12:12"},"nodeType":"YulFunctionCall","src":"4067:33:12"},"variables":[{"name":"value_2","nodeType":"YulTypedName","src":"4056:7:12","type":""}]},{"expression":{"arguments":[{"name":"value_2","nodeType":"YulIdentifier","src":"4134:7:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"4109:24:12"},"nodeType":"YulFunctionCall","src":"4109:33:12"},"nodeType":"YulExpressionStatement","src":"4109:33:12"},{"nodeType":"YulAssignment","src":"4151:17:12","value":{"name":"value_2","nodeType":"YulIdentifier","src":"4161:7:12"},"variableNames":[{"name":"value5","nodeType":"YulIdentifier","src":"4151:6:12"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256t_string_calldata_ptrt_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"3360:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"3371:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"3383:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"3391:6:12","type":""},{"name":"value2","nodeType":"YulTypedName","src":"3399:6:12","type":""},{"name":"value3","nodeType":"YulTypedName","src":"3407:6:12","type":""},{"name":"value4","nodeType":"YulTypedName","src":"3415:6:12","type":""},{"name":"value5","nodeType":"YulTypedName","src":"3423:6:12","type":""}],"src":"3276:898:12"},{"body":{"nodeType":"YulBlock","src":"4308:119:12","statements":[{"nodeType":"YulAssignment","src":"4318:26:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4330:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"4341:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4326:3:12"},"nodeType":"YulFunctionCall","src":"4326:18:12"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"4318:4:12"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4360:9:12"},{"name":"value0","nodeType":"YulIdentifier","src":"4371:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"4353:6:12"},"nodeType":"YulFunctionCall","src":"4353:25:12"},"nodeType":"YulExpressionStatement","src":"4353:25:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4398:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"4409:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4394:3:12"},"nodeType":"YulFunctionCall","src":"4394:18:12"},{"name":"value1","nodeType":"YulIdentifier","src":"4414:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"4387:6:12"},"nodeType":"YulFunctionCall","src":"4387:34:12"},"nodeType":"YulExpressionStatement","src":"4387:34:12"}]},"name":"abi_encode_tuple_t_uint256_t_uint256__to_t_uint256_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"4269:9:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"4280:6:12","type":""},{"name":"value0","nodeType":"YulTypedName","src":"4288:6:12","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"4299:4:12","type":""}],"src":"4179:248:12"},{"body":{"nodeType":"YulBlock","src":"4607:792:12","statements":[{"body":{"nodeType":"YulBlock","src":"4654:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4663:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4666:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4656:6:12"},"nodeType":"YulFunctionCall","src":"4656:12:12"},"nodeType":"YulExpressionStatement","src":"4656:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"4628:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"4637:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"4624:3:12"},"nodeType":"YulFunctionCall","src":"4624:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"4649:3:12","type":"","value":"192"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"4620:3:12"},"nodeType":"YulFunctionCall","src":"4620:33:12"},"nodeType":"YulIf","src":"4617:53:12"},{"nodeType":"YulVariableDeclaration","src":"4679:36:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4705:9:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4692:12:12"},"nodeType":"YulFunctionCall","src":"4692:23:12"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"4683:5:12","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"4749:5:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"4724:24:12"},"nodeType":"YulFunctionCall","src":"4724:31:12"},"nodeType":"YulExpressionStatement","src":"4724:31:12"},{"nodeType":"YulAssignment","src":"4764:15:12","value":{"name":"value","nodeType":"YulIdentifier","src":"4774:5:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"4764:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"4788:47:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4820:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"4831:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4816:3:12"},"nodeType":"YulFunctionCall","src":"4816:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4803:12:12"},"nodeType":"YulFunctionCall","src":"4803:32:12"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"4792:7:12","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"4869:7:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"4844:24:12"},"nodeType":"YulFunctionCall","src":"4844:33:12"},"nodeType":"YulExpressionStatement","src":"4844:33:12"},{"nodeType":"YulAssignment","src":"4886:17:12","value":{"name":"value_1","nodeType":"YulIdentifier","src":"4896:7:12"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"4886:6:12"}]},{"nodeType":"YulAssignment","src":"4912:42:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4939:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"4950:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4935:3:12"},"nodeType":"YulFunctionCall","src":"4935:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4922:12:12"},"nodeType":"YulFunctionCall","src":"4922:32:12"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"4912:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"4963:46:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4994:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"5005:2:12","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4990:3:12"},"nodeType":"YulFunctionCall","src":"4990:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4977:12:12"},"nodeType":"YulFunctionCall","src":"4977:32:12"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"4967:6:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"5052:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5061:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"5064:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"5054:6:12"},"nodeType":"YulFunctionCall","src":"5054:12:12"},"nodeType":"YulExpressionStatement","src":"5054:12:12"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"5024:6:12"},{"kind":"number","nodeType":"YulLiteral","src":"5032:18:12","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"5021:2:12"},"nodeType":"YulFunctionCall","src":"5021:30:12"},"nodeType":"YulIf","src":"5018:50:12"},{"nodeType":"YulVariableDeclaration","src":"5077:85:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5134:9:12"},{"name":"offset","nodeType":"YulIdentifier","src":"5145:6:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5130:3:12"},"nodeType":"YulFunctionCall","src":"5130:22:12"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"5154:7:12"}],"functionName":{"name":"abi_decode_string_calldata","nodeType":"YulIdentifier","src":"5103:26:12"},"nodeType":"YulFunctionCall","src":"5103:59:12"},"variables":[{"name":"value3_1","nodeType":"YulTypedName","src":"5081:8:12","type":""},{"name":"value4_1","nodeType":"YulTypedName","src":"5091:8:12","type":""}]},{"nodeType":"YulAssignment","src":"5171:18:12","value":{"name":"value3_1","nodeType":"YulIdentifier","src":"5181:8:12"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"5171:6:12"}]},{"nodeType":"YulAssignment","src":"5198:18:12","value":{"name":"value4_1","nodeType":"YulIdentifier","src":"5208:8:12"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"5198:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"5225:48:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5257:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"5268:3:12","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5253:3:12"},"nodeType":"YulFunctionCall","src":"5253:19:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5240:12:12"},"nodeType":"YulFunctionCall","src":"5240:33:12"},"variables":[{"name":"value_2","nodeType":"YulTypedName","src":"5229:7:12","type":""}]},{"expression":{"arguments":[{"name":"value_2","nodeType":"YulIdentifier","src":"5307:7:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"5282:24:12"},"nodeType":"YulFunctionCall","src":"5282:33:12"},"nodeType":"YulExpressionStatement","src":"5282:33:12"},{"nodeType":"YulAssignment","src":"5324:17:12","value":{"name":"value_2","nodeType":"YulIdentifier","src":"5334:7:12"},"variableNames":[{"name":"value5","nodeType":"YulIdentifier","src":"5324:6:12"}]},{"nodeType":"YulAssignment","src":"5350:43:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5377:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"5388:3:12","type":"","value":"160"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5373:3:12"},"nodeType":"YulFunctionCall","src":"5373:19:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5360:12:12"},"nodeType":"YulFunctionCall","src":"5360:33:12"},"variableNames":[{"name":"value6","nodeType":"YulIdentifier","src":"5350:6:12"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256t_string_calldata_ptrt_addresst_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"4525:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"4536:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"4548:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"4556:6:12","type":""},{"name":"value2","nodeType":"YulTypedName","src":"4564:6:12","type":""},{"name":"value3","nodeType":"YulTypedName","src":"4572:6:12","type":""},{"name":"value4","nodeType":"YulTypedName","src":"4580:6:12","type":""},{"name":"value5","nodeType":"YulTypedName","src":"4588:6:12","type":""},{"name":"value6","nodeType":"YulTypedName","src":"4596:6:12","type":""}],"src":"4432:967:12"},{"body":{"nodeType":"YulBlock","src":"5596:844:12","statements":[{"body":{"nodeType":"YulBlock","src":"5643:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5652:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"5655:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"5645:6:12"},"nodeType":"YulFunctionCall","src":"5645:12:12"},"nodeType":"YulExpressionStatement","src":"5645:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"5617:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"5626:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"5613:3:12"},"nodeType":"YulFunctionCall","src":"5613:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"5638:3:12","type":"","value":"224"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"5609:3:12"},"nodeType":"YulFunctionCall","src":"5609:33:12"},"nodeType":"YulIf","src":"5606:53:12"},{"nodeType":"YulVariableDeclaration","src":"5668:36:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5694:9:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5681:12:12"},"nodeType":"YulFunctionCall","src":"5681:23:12"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"5672:5:12","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"5738:5:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"5713:24:12"},"nodeType":"YulFunctionCall","src":"5713:31:12"},"nodeType":"YulExpressionStatement","src":"5713:31:12"},{"nodeType":"YulAssignment","src":"5753:15:12","value":{"name":"value","nodeType":"YulIdentifier","src":"5763:5:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"5753:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"5777:47:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5809:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"5820:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5805:3:12"},"nodeType":"YulFunctionCall","src":"5805:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5792:12:12"},"nodeType":"YulFunctionCall","src":"5792:32:12"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"5781:7:12","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"5858:7:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"5833:24:12"},"nodeType":"YulFunctionCall","src":"5833:33:12"},"nodeType":"YulExpressionStatement","src":"5833:33:12"},{"nodeType":"YulAssignment","src":"5875:17:12","value":{"name":"value_1","nodeType":"YulIdentifier","src":"5885:7:12"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"5875:6:12"}]},{"nodeType":"YulAssignment","src":"5901:42:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5928:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"5939:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5924:3:12"},"nodeType":"YulFunctionCall","src":"5924:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5911:12:12"},"nodeType":"YulFunctionCall","src":"5911:32:12"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"5901:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"5952:46:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5983:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"5994:2:12","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5979:3:12"},"nodeType":"YulFunctionCall","src":"5979:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5966:12:12"},"nodeType":"YulFunctionCall","src":"5966:32:12"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"5956:6:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"6041:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6050:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"6053:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"6043:6:12"},"nodeType":"YulFunctionCall","src":"6043:12:12"},"nodeType":"YulExpressionStatement","src":"6043:12:12"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"6013:6:12"},{"kind":"number","nodeType":"YulLiteral","src":"6021:18:12","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"6010:2:12"},"nodeType":"YulFunctionCall","src":"6010:30:12"},"nodeType":"YulIf","src":"6007:50:12"},{"nodeType":"YulVariableDeclaration","src":"6066:85:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6123:9:12"},{"name":"offset","nodeType":"YulIdentifier","src":"6134:6:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6119:3:12"},"nodeType":"YulFunctionCall","src":"6119:22:12"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"6143:7:12"}],"functionName":{"name":"abi_decode_string_calldata","nodeType":"YulIdentifier","src":"6092:26:12"},"nodeType":"YulFunctionCall","src":"6092:59:12"},"variables":[{"name":"value3_1","nodeType":"YulTypedName","src":"6070:8:12","type":""},{"name":"value4_1","nodeType":"YulTypedName","src":"6080:8:12","type":""}]},{"nodeType":"YulAssignment","src":"6160:18:12","value":{"name":"value3_1","nodeType":"YulIdentifier","src":"6170:8:12"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"6160:6:12"}]},{"nodeType":"YulAssignment","src":"6187:18:12","value":{"name":"value4_1","nodeType":"YulIdentifier","src":"6197:8:12"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"6187:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"6214:48:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6246:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"6257:3:12","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6242:3:12"},"nodeType":"YulFunctionCall","src":"6242:19:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6229:12:12"},"nodeType":"YulFunctionCall","src":"6229:33:12"},"variables":[{"name":"value_2","nodeType":"YulTypedName","src":"6218:7:12","type":""}]},{"expression":{"arguments":[{"name":"value_2","nodeType":"YulIdentifier","src":"6296:7:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"6271:24:12"},"nodeType":"YulFunctionCall","src":"6271:33:12"},"nodeType":"YulExpressionStatement","src":"6271:33:12"},{"nodeType":"YulAssignment","src":"6313:17:12","value":{"name":"value_2","nodeType":"YulIdentifier","src":"6323:7:12"},"variableNames":[{"name":"value5","nodeType":"YulIdentifier","src":"6313:6:12"}]},{"nodeType":"YulAssignment","src":"6339:43:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6366:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"6377:3:12","type":"","value":"160"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6362:3:12"},"nodeType":"YulFunctionCall","src":"6362:19:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6349:12:12"},"nodeType":"YulFunctionCall","src":"6349:33:12"},"variableNames":[{"name":"value6","nodeType":"YulIdentifier","src":"6339:6:12"}]},{"nodeType":"YulAssignment","src":"6391:43:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6418:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"6429:3:12","type":"","value":"192"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6414:3:12"},"nodeType":"YulFunctionCall","src":"6414:19:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6401:12:12"},"nodeType":"YulFunctionCall","src":"6401:33:12"},"variableNames":[{"name":"value7","nodeType":"YulIdentifier","src":"6391:6:12"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"5506:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"5517:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"5529:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"5537:6:12","type":""},{"name":"value2","nodeType":"YulTypedName","src":"5545:6:12","type":""},{"name":"value3","nodeType":"YulTypedName","src":"5553:6:12","type":""},{"name":"value4","nodeType":"YulTypedName","src":"5561:6:12","type":""},{"name":"value5","nodeType":"YulTypedName","src":"5569:6:12","type":""},{"name":"value6","nodeType":"YulTypedName","src":"5577:6:12","type":""},{"name":"value7","nodeType":"YulTypedName","src":"5585:6:12","type":""}],"src":"5404:1036:12"},{"body":{"nodeType":"YulBlock","src":"6666:306:12","statements":[{"nodeType":"YulAssignment","src":"6676:27:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6688:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"6699:3:12","type":"","value":"160"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6684:3:12"},"nodeType":"YulFunctionCall","src":"6684:19:12"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"6676:4:12"}]},{"nodeType":"YulVariableDeclaration","src":"6712:29:12","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6730:3:12","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"6735:1:12","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"6726:3:12"},"nodeType":"YulFunctionCall","src":"6726:11:12"},{"kind":"number","nodeType":"YulLiteral","src":"6739:1:12","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"6722:3:12"},"nodeType":"YulFunctionCall","src":"6722:19:12"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"6716:2:12","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6757:9:12"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"6772:6:12"},{"name":"_1","nodeType":"YulIdentifier","src":"6780:2:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"6768:3:12"},"nodeType":"YulFunctionCall","src":"6768:15:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6750:6:12"},"nodeType":"YulFunctionCall","src":"6750:34:12"},"nodeType":"YulExpressionStatement","src":"6750:34:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6804:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"6815:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6800:3:12"},"nodeType":"YulFunctionCall","src":"6800:18:12"},{"name":"value1","nodeType":"YulIdentifier","src":"6820:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6793:6:12"},"nodeType":"YulFunctionCall","src":"6793:34:12"},"nodeType":"YulExpressionStatement","src":"6793:34:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6847:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"6858:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6843:3:12"},"nodeType":"YulFunctionCall","src":"6843:18:12"},{"arguments":[{"name":"value2","nodeType":"YulIdentifier","src":"6867:6:12"},{"name":"_1","nodeType":"YulIdentifier","src":"6875:2:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"6863:3:12"},"nodeType":"YulFunctionCall","src":"6863:15:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6836:6:12"},"nodeType":"YulFunctionCall","src":"6836:43:12"},"nodeType":"YulExpressionStatement","src":"6836:43:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6899:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"6910:2:12","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6895:3:12"},"nodeType":"YulFunctionCall","src":"6895:18:12"},{"name":"value3","nodeType":"YulIdentifier","src":"6915:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6888:6:12"},"nodeType":"YulFunctionCall","src":"6888:34:12"},"nodeType":"YulExpressionStatement","src":"6888:34:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6942:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"6953:3:12","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6938:3:12"},"nodeType":"YulFunctionCall","src":"6938:19:12"},{"name":"value4","nodeType":"YulIdentifier","src":"6959:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6931:6:12"},"nodeType":"YulFunctionCall","src":"6931:35:12"},"nodeType":"YulExpressionStatement","src":"6931:35:12"}]},"name":"abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1__to_t_address_t_uint256_t_address_t_uint256_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"6603:9:12","type":""},{"name":"value4","nodeType":"YulTypedName","src":"6614:6:12","type":""},{"name":"value3","nodeType":"YulTypedName","src":"6622:6:12","type":""},{"name":"value2","nodeType":"YulTypedName","src":"6630:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"6638:6:12","type":""},{"name":"value0","nodeType":"YulTypedName","src":"6646:6:12","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"6657:4:12","type":""}],"src":"6445:527:12"},{"body":{"nodeType":"YulBlock","src":"7058:170:12","statements":[{"body":{"nodeType":"YulBlock","src":"7104:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7113:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"7116:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7106:6:12"},"nodeType":"YulFunctionCall","src":"7106:12:12"},"nodeType":"YulExpressionStatement","src":"7106:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"7079:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"7088:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"7075:3:12"},"nodeType":"YulFunctionCall","src":"7075:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"7100:2:12","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"7071:3:12"},"nodeType":"YulFunctionCall","src":"7071:32:12"},"nodeType":"YulIf","src":"7068:52:12"},{"nodeType":"YulVariableDeclaration","src":"7129:29:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7148:9:12"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"7142:5:12"},"nodeType":"YulFunctionCall","src":"7142:16:12"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"7133:5:12","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"7192:5:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"7167:24:12"},"nodeType":"YulFunctionCall","src":"7167:31:12"},"nodeType":"YulExpressionStatement","src":"7167:31:12"},{"nodeType":"YulAssignment","src":"7207:15:12","value":{"name":"value","nodeType":"YulIdentifier","src":"7217:5:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"7207:6:12"}]}]},"name":"abi_decode_tuple_t_address_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"7024:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"7035:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"7047:6:12","type":""}],"src":"6977:251:12"},{"body":{"nodeType":"YulBlock","src":"7362:145:12","statements":[{"nodeType":"YulAssignment","src":"7372:26:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7384:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"7395:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7380:3:12"},"nodeType":"YulFunctionCall","src":"7380:18:12"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"7372:4:12"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7414:9:12"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"7429:6:12"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7445:3:12","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"7450:1:12","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"7441:3:12"},"nodeType":"YulFunctionCall","src":"7441:11:12"},{"kind":"number","nodeType":"YulLiteral","src":"7454:1:12","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"7437:3:12"},"nodeType":"YulFunctionCall","src":"7437:19:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"7425:3:12"},"nodeType":"YulFunctionCall","src":"7425:32:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7407:6:12"},"nodeType":"YulFunctionCall","src":"7407:51:12"},"nodeType":"YulExpressionStatement","src":"7407:51:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7478:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"7489:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7474:3:12"},"nodeType":"YulFunctionCall","src":"7474:18:12"},{"name":"value1","nodeType":"YulIdentifier","src":"7494:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7467:6:12"},"nodeType":"YulFunctionCall","src":"7467:34:12"},"nodeType":"YulExpressionStatement","src":"7467:34:12"}]},"name":"abi_encode_tuple_t_address_t_uint256__to_t_address_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"7323:9:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"7334:6:12","type":""},{"name":"value0","nodeType":"YulTypedName","src":"7342:6:12","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"7353:4:12","type":""}],"src":"7233:274:12"},{"body":{"nodeType":"YulBlock","src":"7669:218:12","statements":[{"nodeType":"YulAssignment","src":"7679:26:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7691:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"7702:2:12","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7687:3:12"},"nodeType":"YulFunctionCall","src":"7687:18:12"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"7679:4:12"}]},{"nodeType":"YulVariableDeclaration","src":"7714:29:12","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7732:3:12","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"7737:1:12","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"7728:3:12"},"nodeType":"YulFunctionCall","src":"7728:11:12"},{"kind":"number","nodeType":"YulLiteral","src":"7741:1:12","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"7724:3:12"},"nodeType":"YulFunctionCall","src":"7724:19:12"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"7718:2:12","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7759:9:12"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"7774:6:12"},{"name":"_1","nodeType":"YulIdentifier","src":"7782:2:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"7770:3:12"},"nodeType":"YulFunctionCall","src":"7770:15:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7752:6:12"},"nodeType":"YulFunctionCall","src":"7752:34:12"},"nodeType":"YulExpressionStatement","src":"7752:34:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7806:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"7817:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7802:3:12"},"nodeType":"YulFunctionCall","src":"7802:18:12"},{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"7826:6:12"},{"name":"_1","nodeType":"YulIdentifier","src":"7834:2:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"7822:3:12"},"nodeType":"YulFunctionCall","src":"7822:15:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7795:6:12"},"nodeType":"YulFunctionCall","src":"7795:43:12"},"nodeType":"YulExpressionStatement","src":"7795:43:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7858:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"7869:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7854:3:12"},"nodeType":"YulFunctionCall","src":"7854:18:12"},{"name":"value2","nodeType":"YulIdentifier","src":"7874:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7847:6:12"},"nodeType":"YulFunctionCall","src":"7847:34:12"},"nodeType":"YulExpressionStatement","src":"7847:34:12"}]},"name":"abi_encode_tuple_t_address_t_address_t_uint256__to_t_address_t_address_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"7622:9:12","type":""},{"name":"value2","nodeType":"YulTypedName","src":"7633:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"7641:6:12","type":""},{"name":"value0","nodeType":"YulTypedName","src":"7649:6:12","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"7660:4:12","type":""}],"src":"7512:375:12"},{"body":{"nodeType":"YulBlock","src":"8213:386:12","statements":[{"nodeType":"YulVariableDeclaration","src":"8223:29:12","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"8241:3:12","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"8246:1:12","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"8237:3:12"},"nodeType":"YulFunctionCall","src":"8237:11:12"},{"kind":"number","nodeType":"YulLiteral","src":"8250:1:12","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"8233:3:12"},"nodeType":"YulFunctionCall","src":"8233:19:12"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"8227:2:12","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8268:9:12"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"8283:6:12"},{"name":"_1","nodeType":"YulIdentifier","src":"8291:2:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"8279:3:12"},"nodeType":"YulFunctionCall","src":"8279:15:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8261:6:12"},"nodeType":"YulFunctionCall","src":"8261:34:12"},"nodeType":"YulExpressionStatement","src":"8261:34:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8315:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"8326:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8311:3:12"},"nodeType":"YulFunctionCall","src":"8311:18:12"},{"name":"value1","nodeType":"YulIdentifier","src":"8331:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8304:6:12"},"nodeType":"YulFunctionCall","src":"8304:34:12"},"nodeType":"YulExpressionStatement","src":"8304:34:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8358:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"8369:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8354:3:12"},"nodeType":"YulFunctionCall","src":"8354:18:12"},{"arguments":[{"name":"value2","nodeType":"YulIdentifier","src":"8378:6:12"},{"name":"_1","nodeType":"YulIdentifier","src":"8386:2:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"8374:3:12"},"nodeType":"YulFunctionCall","src":"8374:15:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8347:6:12"},"nodeType":"YulFunctionCall","src":"8347:43:12"},"nodeType":"YulExpressionStatement","src":"8347:43:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8410:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"8421:2:12","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8406:3:12"},"nodeType":"YulFunctionCall","src":"8406:18:12"},{"name":"value3","nodeType":"YulIdentifier","src":"8426:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8399:6:12"},"nodeType":"YulFunctionCall","src":"8399:34:12"},"nodeType":"YulExpressionStatement","src":"8399:34:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8453:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"8464:3:12","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8449:3:12"},"nodeType":"YulFunctionCall","src":"8449:19:12"},{"name":"value4","nodeType":"YulIdentifier","src":"8470:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8442:6:12"},"nodeType":"YulFunctionCall","src":"8442:35:12"},"nodeType":"YulExpressionStatement","src":"8442:35:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8497:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"8508:3:12","type":"","value":"160"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8493:3:12"},"nodeType":"YulFunctionCall","src":"8493:19:12"},{"kind":"number","nodeType":"YulLiteral","src":"8514:3:12","type":"","value":"192"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8486:6:12"},"nodeType":"YulFunctionCall","src":"8486:32:12"},"nodeType":"YulExpressionStatement","src":"8486:32:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8538:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"8549:3:12","type":"","value":"192"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8534:3:12"},"nodeType":"YulFunctionCall","src":"8534:19:12"},{"kind":"number","nodeType":"YulLiteral","src":"8555:1:12","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8527:6:12"},"nodeType":"YulFunctionCall","src":"8527:30:12"},"nodeType":"YulExpressionStatement","src":"8527:30:12"},{"nodeType":"YulAssignment","src":"8566:27:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8578:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"8589:3:12","type":"","value":"224"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8574:3:12"},"nodeType":"YulFunctionCall","src":"8574:19:12"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"8566:4:12"}]}]},"name":"abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470__to_t_address_t_uint256_t_address_t_uint256_t_uint256_t_bytes_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"8150:9:12","type":""},{"name":"value4","nodeType":"YulTypedName","src":"8161:6:12","type":""},{"name":"value3","nodeType":"YulTypedName","src":"8169:6:12","type":""},{"name":"value2","nodeType":"YulTypedName","src":"8177:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"8185:6:12","type":""},{"name":"value0","nodeType":"YulTypedName","src":"8193:6:12","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"8204:4:12","type":""}],"src":"7892:707:12"}]},"contents":"{\n { }\n function abi_encode_tuple_t_address__to_t_address__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, sub(shl(160, 1), 1)))\n }\n function validator_revert_address(value)\n {\n if iszero(eq(value, and(value, sub(shl(160, 1), 1)))) { revert(0, 0) }\n }\n function abi_decode_string_calldata(offset, end) -> arrayPos, length\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n length := calldataload(offset)\n if gt(length, 0xffffffffffffffff) { revert(0, 0) }\n arrayPos := add(offset, 0x20)\n if gt(add(add(offset, length), 0x20), end) { revert(0, 0) }\n }\n function abi_decode_tuple_t_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_address(headStart, dataEnd) -> value0, value1, value2, value3, value4, value5, value6\n {\n if slt(sub(dataEnd, headStart), 192) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n value1 := calldataload(add(headStart, 32))\n let offset := calldataload(add(headStart, 64))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n let value2_1, value3_1 := abi_decode_string_calldata(add(headStart, offset), dataEnd)\n value2 := value2_1\n value3 := value3_1\n let value_1 := calldataload(add(headStart, 96))\n validator_revert_address(value_1)\n value4 := value_1\n value5 := calldataload(add(headStart, 128))\n let value_2 := calldataload(add(headStart, 160))\n validator_revert_address(value_2)\n value6 := value_2\n }\n function abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, value0)\n }\n function abi_decode_tuple_t_addresst_uint256(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n value1 := calldataload(add(headStart, 32))\n }\n function abi_decode_tuple_t_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_uint256(headStart, dataEnd) -> value0, value1, value2, value3, value4, value5, value6\n {\n if slt(sub(dataEnd, headStart), 192) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n value1 := calldataload(add(headStart, 32))\n let offset := calldataload(add(headStart, 64))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n let value2_1, value3_1 := abi_decode_string_calldata(add(headStart, offset), dataEnd)\n value2 := value2_1\n value3 := value3_1\n let value_1 := calldataload(add(headStart, 96))\n validator_revert_address(value_1)\n value4 := value_1\n value5 := calldataload(add(headStart, 128))\n value6 := calldataload(add(headStart, 160))\n }\n function abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, iszero(iszero(value0)))\n }\n function abi_decode_tuple_t_addresst_addresst_uint256t_string_calldata_ptrt_address(headStart, dataEnd) -> value0, value1, value2, value3, value4, value5\n {\n if slt(sub(dataEnd, headStart), 160) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n value2 := calldataload(add(headStart, 64))\n let offset := calldataload(add(headStart, 96))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n let value3_1, value4_1 := abi_decode_string_calldata(add(headStart, offset), dataEnd)\n value3 := value3_1\n value4 := value4_1\n let value_2 := calldataload(add(headStart, 128))\n validator_revert_address(value_2)\n value5 := value_2\n }\n function abi_encode_tuple_t_uint256_t_uint256__to_t_uint256_t_uint256__fromStack_reversed(headStart, value1, value0) -> tail\n {\n tail := add(headStart, 64)\n mstore(headStart, value0)\n mstore(add(headStart, 32), value1)\n }\n function abi_decode_tuple_t_addresst_addresst_uint256t_string_calldata_ptrt_addresst_uint256(headStart, dataEnd) -> value0, value1, value2, value3, value4, value5, value6\n {\n if slt(sub(dataEnd, headStart), 192) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n value2 := calldataload(add(headStart, 64))\n let offset := calldataload(add(headStart, 96))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n let value3_1, value4_1 := abi_decode_string_calldata(add(headStart, offset), dataEnd)\n value3 := value3_1\n value4 := value4_1\n let value_2 := calldataload(add(headStart, 128))\n validator_revert_address(value_2)\n value5 := value_2\n value6 := calldataload(add(headStart, 160))\n }\n function abi_decode_tuple_t_addresst_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_uint256(headStart, dataEnd) -> value0, value1, value2, value3, value4, value5, value6, value7\n {\n if slt(sub(dataEnd, headStart), 224) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n value2 := calldataload(add(headStart, 64))\n let offset := calldataload(add(headStart, 96))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n let value3_1, value4_1 := abi_decode_string_calldata(add(headStart, offset), dataEnd)\n value3 := value3_1\n value4 := value4_1\n let value_2 := calldataload(add(headStart, 128))\n validator_revert_address(value_2)\n value5 := value_2\n value6 := calldataload(add(headStart, 160))\n value7 := calldataload(add(headStart, 192))\n }\n function abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1__to_t_address_t_uint256_t_address_t_uint256_t_uint256__fromStack_reversed(headStart, value4, value3, value2, value1, value0) -> tail\n {\n tail := add(headStart, 160)\n let _1 := sub(shl(160, 1), 1)\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), value1)\n mstore(add(headStart, 64), and(value2, _1))\n mstore(add(headStart, 96), value3)\n mstore(add(headStart, 128), value4)\n }\n function abi_decode_tuple_t_address_fromMemory(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := mload(headStart)\n validator_revert_address(value)\n value0 := value\n }\n function abi_encode_tuple_t_address_t_uint256__to_t_address_t_uint256__fromStack_reversed(headStart, value1, value0) -> tail\n {\n tail := add(headStart, 64)\n mstore(headStart, and(value0, sub(shl(160, 1), 1)))\n mstore(add(headStart, 32), value1)\n }\n function abi_encode_tuple_t_address_t_address_t_uint256__to_t_address_t_address_t_uint256__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n tail := add(headStart, 96)\n let _1 := sub(shl(160, 1), 1)\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), and(value1, _1))\n mstore(add(headStart, 64), value2)\n }\n function abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470__to_t_address_t_uint256_t_address_t_uint256_t_uint256_t_bytes_memory_ptr__fromStack_reversed(headStart, value4, value3, value2, value1, value0) -> tail\n {\n let _1 := sub(shl(160, 1), 1)\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), value1)\n mstore(add(headStart, 64), and(value2, _1))\n mstore(add(headStart, 96), value3)\n mstore(add(headStart, 128), value4)\n mstore(add(headStart, 160), 192)\n mstore(add(headStart, 192), 0)\n tail := add(headStart, 224)\n }\n}","id":12,"language":"Yul","name":"#utility.yul"}],"immutableReferences":{},"linkReferences":{},"object":"608060405234801561001057600080fd5b50600436106100b45760003560e01c806365d20ce21161007157806365d20ce2146101945780636697b359146101a25780637fdfc7b2146101bf578063a8abef47146101a2578063acab923c14610163578063fe02fb00146101da57600080fd5b806306433b1b146100b95780630bdde2ca146100f1578063192df6551461011a5780633ff956cc1461012d5780635fbfb9cf14610150578063621a3b7014610163575b600080fd5b6100d47302101dfb77fde026414827fdc604ddaf224f092181565b6040516001600160a01b0390911681526020015b60405180910390f35b61010c6100ff366004610576565b6000979650505050505050565b6040519081526020016100e8565b6100d4610128366004610606565b6101ed565b61014061013b366004610632565b6102a1565b60405190151581526020016100e8565b6100d461015e366004610606565b61038d565b61017f6101713660046106b8565b600080965096945050505050565b604080519283526020830191909152016100e8565b61010c6100ff36600461073d565b61017f6101b036600461073d565b60008097509795505050505050565b6100d4732d25602551487c3f3354dd80d76d54383a24335881565b6101406101e83660046107cd565b610426565b604051632f4de29b60e11b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b038316604482015260648101829052600060848201819052907302101dfb77fde026414827fdc604ddaf224f092190635e9bc5369060a401602060405180830381865afa158015610276573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029a9190610864565b9392505050565b60405163192df65560e01b81526001600160a01b0388166004820152602481018790526000908190309063192df65590604401602060405180830381865afa1580156102f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103159190610864565b604051632142170760e11b81523360048201526001600160a01b03808316602483015260448201879052919250908616906342842e0e90606401600060405180830381600087803b15801561036957600080fd5b505af115801561037d573d6000803e3d6000fd5b5050505050979650505050505050565b60405163da7323b360e01b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b03831660448201526064810182905260006084820181905260c060a483015260c48201819052907302101dfb77fde026414827fdc604ddaf224f09219063da7323b39060e4016020604051808303816000875af1158015610276573d6000803e3d6000fd5b60405163192df65560e01b81526001600160a01b0388166004820152602481018790526000908190309063192df65590604401602060405180830381865afa158015610476573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049a9190610864565b604051632142170760e11b81526001600160a01b0380831660048301528c8116602483015260448201879052919250908616906342842e0e90606401600060405180830381600087803b1580156104f057600080fd5b505af1158015610504573d6000803e3d6000fd5b505050505098975050505050505050565b6001600160a01b038116811461052a57600080fd5b50565b60008083601f84011261053f57600080fd5b50813567ffffffffffffffff81111561055757600080fd5b60208301915083602082850101111561056f57600080fd5b9250929050565b600080600080600080600060c0888a03121561059157600080fd5b873561059c81610515565b965060208801359550604088013567ffffffffffffffff8111156105bf57600080fd5b6105cb8a828b0161052d565b90965094505060608801356105df81610515565b92506080880135915060a08801356105f681610515565b8091505092959891949750929550565b6000806040838503121561061957600080fd5b823561062481610515565b946020939093013593505050565b600080600080600080600060c0888a03121561064d57600080fd5b873561065881610515565b965060208801359550604088013567ffffffffffffffff81111561067b57600080fd5b6106878a828b0161052d565b909650945050606088013561069b81610515565b969995985093969295946080840135945060a09093013592915050565b60008060008060008060a087890312156106d157600080fd5b86356106dc81610515565b955060208701356106ec81610515565b945060408701359350606087013567ffffffffffffffff81111561070f57600080fd5b61071b89828a0161052d565b909450925050608087013561072f81610515565b809150509295509295509295565b600080600080600080600060c0888a03121561075857600080fd5b873561076381610515565b9650602088013561077381610515565b955060408801359450606088013567ffffffffffffffff81111561079657600080fd5b6107a28a828b0161052d565b90955093505060808801356107b681610515565b8092505060a0880135905092959891949750929550565b60008060008060008060008060e0898b0312156107e957600080fd5b88356107f481610515565b9750602089013561080481610515565b965060408901359550606089013567ffffffffffffffff81111561082757600080fd5b6108338b828c0161052d565b909650945050608089013561084781610515565b979a969950949793969295929450505060a08201359160c0013590565b60006020828403121561087657600080fd5b815161029a8161051556fea26469706673582212205aad4bc7bca1ad16a1a304738f9f9fb1fc0d380c528fcbc9be3c13c3f029355264736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0xB4 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x65D20CE2 GT PUSH2 0x71 JUMPI DUP1 PUSH4 0x65D20CE2 EQ PUSH2 0x194 JUMPI DUP1 PUSH4 0x6697B359 EQ PUSH2 0x1A2 JUMPI DUP1 PUSH4 0x7FDFC7B2 EQ PUSH2 0x1BF JUMPI DUP1 PUSH4 0xA8ABEF47 EQ PUSH2 0x1A2 JUMPI DUP1 PUSH4 0xACAB923C EQ PUSH2 0x163 JUMPI DUP1 PUSH4 0xFE02FB00 EQ PUSH2 0x1DA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x6433B1B EQ PUSH2 0xB9 JUMPI DUP1 PUSH4 0xBDDE2CA EQ PUSH2 0xF1 JUMPI DUP1 PUSH4 0x192DF655 EQ PUSH2 0x11A JUMPI DUP1 PUSH4 0x3FF956CC EQ PUSH2 0x12D JUMPI DUP1 PUSH4 0x5FBFB9CF EQ PUSH2 0x150 JUMPI DUP1 PUSH4 0x621A3B70 EQ PUSH2 0x163 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD4 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x10C PUSH2 0xFF CALLDATASIZE PUSH1 0x4 PUSH2 0x576 JUMP JUMPDEST PUSH1 0x0 SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xE8 JUMP JUMPDEST PUSH2 0xD4 PUSH2 0x128 CALLDATASIZE PUSH1 0x4 PUSH2 0x606 JUMP JUMPDEST PUSH2 0x1ED JUMP JUMPDEST PUSH2 0x140 PUSH2 0x13B CALLDATASIZE PUSH1 0x4 PUSH2 0x632 JUMP JUMPDEST PUSH2 0x2A1 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xE8 JUMP JUMPDEST PUSH2 0xD4 PUSH2 0x15E CALLDATASIZE PUSH1 0x4 PUSH2 0x606 JUMP JUMPDEST PUSH2 0x38D JUMP JUMPDEST PUSH2 0x17F PUSH2 0x171 CALLDATASIZE PUSH1 0x4 PUSH2 0x6B8 JUMP JUMPDEST PUSH1 0x0 DUP1 SWAP7 POP SWAP7 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP3 DUP4 MSTORE PUSH1 0x20 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE ADD PUSH2 0xE8 JUMP JUMPDEST PUSH2 0x10C PUSH2 0xFF CALLDATASIZE PUSH1 0x4 PUSH2 0x73D JUMP JUMPDEST PUSH2 0x17F PUSH2 0x1B0 CALLDATASIZE PUSH1 0x4 PUSH2 0x73D JUMP JUMPDEST PUSH1 0x0 DUP1 SWAP8 POP SWAP8 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH2 0xD4 PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 DUP2 JUMP JUMPDEST PUSH2 0x140 PUSH2 0x1E8 CALLDATASIZE PUSH1 0x4 PUSH2 0x7CD JUMP JUMPDEST PUSH2 0x426 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x2F4DE29B PUSH1 0xE1 SHL DUP2 MSTORE PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 PUSH1 0x4 DUP3 ADD MSTORE CHAINID PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 PUSH1 0x84 DUP3 ADD DUP2 SWAP1 MSTORE SWAP1 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 SWAP1 PUSH4 0x5E9BC536 SWAP1 PUSH1 0xA4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x276 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x29A SWAP2 SWAP1 PUSH2 0x864 JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x192DF655 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP9 AND PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x24 DUP2 ADD DUP8 SWAP1 MSTORE PUSH1 0x0 SWAP1 DUP2 SWAP1 ADDRESS SWAP1 PUSH4 0x192DF655 SWAP1 PUSH1 0x44 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x2F1 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x315 SWAP2 SWAP1 PUSH2 0x864 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x21421707 PUSH1 0xE1 SHL DUP2 MSTORE CALLER PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP1 DUP4 AND PUSH1 0x24 DUP4 ADD MSTORE PUSH1 0x44 DUP3 ADD DUP8 SWAP1 MSTORE SWAP2 SWAP3 POP SWAP1 DUP7 AND SWAP1 PUSH4 0x42842E0E SWAP1 PUSH1 0x64 ADD PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x369 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x37D JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0xDA7323B3 PUSH1 0xE0 SHL DUP2 MSTORE PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 PUSH1 0x4 DUP3 ADD MSTORE CHAINID PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 PUSH1 0x84 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0xC0 PUSH1 0xA4 DUP4 ADD MSTORE PUSH1 0xC4 DUP3 ADD DUP2 SWAP1 MSTORE SWAP1 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 SWAP1 PUSH4 0xDA7323B3 SWAP1 PUSH1 0xE4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x276 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x192DF655 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP9 AND PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x24 DUP2 ADD DUP8 SWAP1 MSTORE PUSH1 0x0 SWAP1 DUP2 SWAP1 ADDRESS SWAP1 PUSH4 0x192DF655 SWAP1 PUSH1 0x44 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x476 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x49A SWAP2 SWAP1 PUSH2 0x864 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x21421707 PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP1 DUP4 AND PUSH1 0x4 DUP4 ADD MSTORE DUP13 DUP2 AND PUSH1 0x24 DUP4 ADD MSTORE PUSH1 0x44 DUP3 ADD DUP8 SWAP1 MSTORE SWAP2 SWAP3 POP SWAP1 DUP7 AND SWAP1 PUSH4 0x42842E0E SWAP1 PUSH1 0x64 ADD PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x4F0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x504 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP SWAP9 SWAP8 POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0x52A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x53F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x557 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0x56F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xC0 DUP9 DUP11 SUB SLT ISZERO PUSH2 0x591 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 CALLDATALOAD PUSH2 0x59C DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP7 POP PUSH1 0x20 DUP9 ADD CALLDATALOAD SWAP6 POP PUSH1 0x40 DUP9 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x5BF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x5CB DUP11 DUP3 DUP12 ADD PUSH2 0x52D JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP POP PUSH1 0x60 DUP9 ADD CALLDATALOAD PUSH2 0x5DF DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP3 POP PUSH1 0x80 DUP9 ADD CALLDATALOAD SWAP2 POP PUSH1 0xA0 DUP9 ADD CALLDATALOAD PUSH2 0x5F6 DUP2 PUSH2 0x515 JUMP JUMPDEST DUP1 SWAP2 POP POP SWAP3 SWAP6 SWAP9 SWAP2 SWAP5 SWAP8 POP SWAP3 SWAP6 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x619 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH2 0x624 DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP5 PUSH1 0x20 SWAP4 SWAP1 SWAP4 ADD CALLDATALOAD SWAP4 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xC0 DUP9 DUP11 SUB SLT ISZERO PUSH2 0x64D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 CALLDATALOAD PUSH2 0x658 DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP7 POP PUSH1 0x20 DUP9 ADD CALLDATALOAD SWAP6 POP PUSH1 0x40 DUP9 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x67B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x687 DUP11 DUP3 DUP12 ADD PUSH2 0x52D JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP POP PUSH1 0x60 DUP9 ADD CALLDATALOAD PUSH2 0x69B DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP7 SWAP10 SWAP6 SWAP9 POP SWAP4 SWAP7 SWAP3 SWAP6 SWAP5 PUSH1 0x80 DUP5 ADD CALLDATALOAD SWAP5 POP PUSH1 0xA0 SWAP1 SWAP4 ADD CALLDATALOAD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0xA0 DUP8 DUP10 SUB SLT ISZERO PUSH2 0x6D1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP7 CALLDATALOAD PUSH2 0x6DC DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP6 POP PUSH1 0x20 DUP8 ADD CALLDATALOAD PUSH2 0x6EC DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP5 POP PUSH1 0x40 DUP8 ADD CALLDATALOAD SWAP4 POP PUSH1 0x60 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x70F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x71B DUP10 DUP3 DUP11 ADD PUSH2 0x52D JUMP JUMPDEST SWAP1 SWAP5 POP SWAP3 POP POP PUSH1 0x80 DUP8 ADD CALLDATALOAD PUSH2 0x72F DUP2 PUSH2 0x515 JUMP JUMPDEST DUP1 SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 POP SWAP3 SWAP6 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xC0 DUP9 DUP11 SUB SLT ISZERO PUSH2 0x758 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 CALLDATALOAD PUSH2 0x763 DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP7 POP PUSH1 0x20 DUP9 ADD CALLDATALOAD PUSH2 0x773 DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP6 POP PUSH1 0x40 DUP9 ADD CALLDATALOAD SWAP5 POP PUSH1 0x60 DUP9 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x796 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x7A2 DUP11 DUP3 DUP12 ADD PUSH2 0x52D JUMP JUMPDEST SWAP1 SWAP6 POP SWAP4 POP POP PUSH1 0x80 DUP9 ADD CALLDATALOAD PUSH2 0x7B6 DUP2 PUSH2 0x515 JUMP JUMPDEST DUP1 SWAP3 POP POP PUSH1 0xA0 DUP9 ADD CALLDATALOAD SWAP1 POP SWAP3 SWAP6 SWAP9 SWAP2 SWAP5 SWAP8 POP SWAP3 SWAP6 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0xE0 DUP10 DUP12 SUB SLT ISZERO PUSH2 0x7E9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP9 CALLDATALOAD PUSH2 0x7F4 DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP8 POP PUSH1 0x20 DUP10 ADD CALLDATALOAD PUSH2 0x804 DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP7 POP PUSH1 0x40 DUP10 ADD CALLDATALOAD SWAP6 POP PUSH1 0x60 DUP10 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x827 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x833 DUP12 DUP3 DUP13 ADD PUSH2 0x52D JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP POP PUSH1 0x80 DUP10 ADD CALLDATALOAD PUSH2 0x847 DUP2 PUSH2 0x515 JUMP JUMPDEST SWAP8 SWAP11 SWAP7 SWAP10 POP SWAP5 SWAP8 SWAP4 SWAP7 SWAP3 SWAP6 SWAP3 SWAP5 POP POP POP PUSH1 0xA0 DUP3 ADD CALLDATALOAD SWAP2 PUSH1 0xC0 ADD CALLDATALOAD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x876 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x29A DUP2 PUSH2 0x515 JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 GAS 0xAD 0x4B 0xC7 0xBC LOG1 0xAD AND LOG1 LOG3 DIV PUSH20 0x8F9F9FB1FC0D380C528FCBC9BE3C13C3F0293552 PUSH5 0x736F6C6343 STOP ADDMOD GT STOP CALLER ","sourceMap":"202:2643:6:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;133:78:5;;169:42;133:78;;;;;-1:-1:-1;;;;;178:32:12;;;160:51;;148:2;133:18;:78:5;;;;;;;;259:275:6;;;;;;:::i;:::-;491:25;259:275;;;;;;;;;;;;;1829:25:12;;;1817:2;1802:18;259:275:6;1683:177:12;626:299:5;;;;;;:::i;:::-;;:::i;1947:430:6:-;;;;;;:::i;:::-;;:::i;:::-;;;3249:14:12;;3242:22;3224:41;;3212:2;3197:18;1947:430:6;3084:187:12;306:314:5;;;;;;:::i;:::-;;:::i;540:259:6:-;;;;;;:::i;:::-;744:21;767:22;540:259;;;;;;;;;;;;;;4353:25:12;;;4409:2;4394:18;;4387:34;;;;4326:18;540:259:6;4179:248:12;1105:275:6;;;;;;:::i;805:294::-;;;;;;:::i;:::-;1044:21;1067:22;805:294;;;;;;;;;;;217:82:5;;257:42;217:82;;2383:459:6;;;;;;:::i;:::-;;:::i;626:299:5:-;762:156;;-1:-1:-1;;;762:156:5;;257:42;762:156;;;6750:34:12;830:13:5;6800:18:12;;;6793:34;-1:-1:-1;;;;;6863:15:12;;6843:18;;;6836:43;6895:18;;;6888:34;;;732:7:5;6938:19:12;;;6931:35;;;732:7:5;169:42;;762:27;;6684:19:12;;762:156:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;755:163;626:299;-1:-1:-1;;;626:299:5:o;1947:430:6:-;2237:38;;-1:-1:-1;;;2237:38:6;;-1:-1:-1;;;;;7425:32:12;;2237:38:6;;;7407:51:12;7474:18;;;7467:34;;;2185:12:6;;;;2237:4;;:12;;7380:18:12;;2237:38:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2286:84;;-1:-1:-1;;;2286:84:6;;2328:10;2286:84;;;7752:34:12;-1:-1:-1;;;;;7822:15:12;;;7802:18;;;7795:43;7854:18;;;7847:34;;;2209:66:6;;-1:-1:-1;2286:41:6;;;;;;7687:18:12;;2286:84:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2199:178;1947:430;;;;;;;;;:::o;306:314:5:-;435:178;;-1:-1:-1;;;435:178:5;;257:42;435:178;;;8261:34:12;509:13:5;8311:18:12;;;8304:34;-1:-1:-1;;;;;8374:15:12;;8354:18;;;8347:43;8406:18;;;8399:34;;;405:7:5;8449:19:12;;;8442:35;;;8514:3;8493:19;;;8486:32;8534:19;;;8527:30;;;405:7:5;169:42;;435:33;;8574:19:12;;435:178:5;;;;;;;;;;;;;;;;;;;;;;;2383:459:6;2704:38;;-1:-1:-1;;;2704:38:6;;-1:-1:-1;;;;;7425:32:12;;2704:38:6;;;7407:51:12;7474:18;;;7467:34;;;2652:12:6;;;;2704:4;;:12;;7380:18:12;;2704:38:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2753:82;;-1:-1:-1;;;2753:82:6;;-1:-1:-1;;;;;7770:15:12;;;2753:82:6;;;7752:34:12;7822:15;;;7802:18;;;7795:43;7854:18;;;7847:34;;;2676:66:6;;-1:-1:-1;2753:41:6;;;;;;7687:18:12;;2753:82:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2666:176;2383:459;;;;;;;;;;:::o;222:131:12:-;-1:-1:-1;;;;;297:31:12;;287:42;;277:70;;343:1;340;333:12;277:70;222:131;:::o;358:348::-;410:8;420:6;474:3;467:4;459:6;455:17;451:27;441:55;;492:1;489;482:12;441:55;-1:-1:-1;515:20:12;;558:18;547:30;;544:50;;;590:1;587;580:12;544:50;627:4;619:6;615:17;603:29;;679:3;672:4;663:6;655;651:19;647:30;644:39;641:59;;;696:1;693;686:12;641:59;358:348;;;;;:::o;711:967::-;827:6;835;843;851;859;867;875;928:3;916:9;907:7;903:23;899:33;896:53;;;945:1;942;935:12;896:53;984:9;971:23;1003:31;1028:5;1003:31;:::i;:::-;1053:5;-1:-1:-1;1105:2:12;1090:18;;1077:32;;-1:-1:-1;1160:2:12;1145:18;;1132:32;1187:18;1176:30;;1173:50;;;1219:1;1216;1209:12;1173:50;1258:59;1309:7;1300:6;1289:9;1285:22;1258:59;:::i;:::-;1336:8;;-1:-1:-1;1232:85:12;-1:-1:-1;;1423:2:12;1408:18;;1395:32;1436:33;1395:32;1436:33;:::i;:::-;1488:7;-1:-1:-1;1542:3:12;1527:19;;1514:33;;-1:-1:-1;1599:3:12;1584:19;;1571:33;1613;1571;1613;:::i;:::-;1665:7;1655:17;;;711:967;;;;;;;;;;:::o;1865:315::-;1933:6;1941;1994:2;1982:9;1973:7;1969:23;1965:32;1962:52;;;2010:1;2007;2000:12;1962:52;2049:9;2036:23;2068:31;2093:5;2068:31;:::i;:::-;2118:5;2170:2;2155:18;;;;2142:32;;-1:-1:-1;;;1865:315:12:o;2185:894::-;2301:6;2309;2317;2325;2333;2341;2349;2402:3;2390:9;2381:7;2377:23;2373:33;2370:53;;;2419:1;2416;2409:12;2370:53;2458:9;2445:23;2477:31;2502:5;2477:31;:::i;:::-;2527:5;-1:-1:-1;2579:2:12;2564:18;;2551:32;;-1:-1:-1;2634:2:12;2619:18;;2606:32;2661:18;2650:30;;2647:50;;;2693:1;2690;2683:12;2647:50;2732:59;2783:7;2774:6;2763:9;2759:22;2732:59;:::i;:::-;2810:8;;-1:-1:-1;2706:85:12;-1:-1:-1;;2897:2:12;2882:18;;2869:32;2910:33;2869:32;2910:33;:::i;:::-;2185:894;;;;-1:-1:-1;2185:894:12;;;;2962:7;3016:3;3001:19;;2988:33;;-1:-1:-1;3068:3:12;3053:19;;;3040:33;;2185:894;-1:-1:-1;;2185:894:12:o;3276:898::-;3383:6;3391;3399;3407;3415;3423;3476:3;3464:9;3455:7;3451:23;3447:33;3444:53;;;3493:1;3490;3483:12;3444:53;3532:9;3519:23;3551:31;3576:5;3551:31;:::i;:::-;3601:5;-1:-1:-1;3658:2:12;3643:18;;3630:32;3671:33;3630:32;3671:33;:::i;:::-;3723:7;-1:-1:-1;3777:2:12;3762:18;;3749:32;;-1:-1:-1;3832:2:12;3817:18;;3804:32;3859:18;3848:30;;3845:50;;;3891:1;3888;3881:12;3845:50;3930:59;3981:7;3972:6;3961:9;3957:22;3930:59;:::i;:::-;4008:8;;-1:-1:-1;3904:85:12;-1:-1:-1;;4095:3:12;4080:19;;4067:33;4109;4067;4109;:::i;:::-;4161:7;4151:17;;;3276:898;;;;;;;;:::o;4432:967::-;4548:6;4556;4564;4572;4580;4588;4596;4649:3;4637:9;4628:7;4624:23;4620:33;4617:53;;;4666:1;4663;4656:12;4617:53;4705:9;4692:23;4724:31;4749:5;4724:31;:::i;:::-;4774:5;-1:-1:-1;4831:2:12;4816:18;;4803:32;4844:33;4803:32;4844:33;:::i;:::-;4896:7;-1:-1:-1;4950:2:12;4935:18;;4922:32;;-1:-1:-1;5005:2:12;4990:18;;4977:32;5032:18;5021:30;;5018:50;;;5064:1;5061;5054:12;5018:50;5103:59;5154:7;5145:6;5134:9;5130:22;5103:59;:::i;:::-;5181:8;;-1:-1:-1;5077:85:12;-1:-1:-1;;5268:3:12;5253:19;;5240:33;5282;5240;5282;:::i;:::-;5334:7;5324:17;;;5388:3;5377:9;5373:19;5360:33;5350:43;;4432:967;;;;;;;;;;:::o;5404:1036::-;5529:6;5537;5545;5553;5561;5569;5577;5585;5638:3;5626:9;5617:7;5613:23;5609:33;5606:53;;;5655:1;5652;5645:12;5606:53;5694:9;5681:23;5713:31;5738:5;5713:31;:::i;:::-;5763:5;-1:-1:-1;5820:2:12;5805:18;;5792:32;5833:33;5792:32;5833:33;:::i;:::-;5885:7;-1:-1:-1;5939:2:12;5924:18;;5911:32;;-1:-1:-1;5994:2:12;5979:18;;5966:32;6021:18;6010:30;;6007:50;;;6053:1;6050;6043:12;6007:50;6092:59;6143:7;6134:6;6123:9;6119:22;6092:59;:::i;:::-;6170:8;;-1:-1:-1;6066:85:12;-1:-1:-1;;6257:3:12;6242:19;;6229:33;6271;6229;6271;:::i;:::-;5404:1036;;;;-1:-1:-1;5404:1036:12;;;;;;6323:7;;-1:-1:-1;;;6377:3:12;6362:19;;6349:33;;6429:3;6414:19;6401:33;;5404:1036::o;6977:251::-;7047:6;7100:2;7088:9;7079:7;7075:23;7071:32;7068:52;;;7116:1;7113;7106:12;7068:52;7148:9;7142:16;7167:31;7192:5;7167:31;:::i"},"gasEstimates":{"creation":{"codeDepositCost":"446200","executionCost":"480","totalCost":"446680"},"external":{"IMPLMENTATION()":"249","REGISTRY()":"206","account(address,uint256)":"infinite","breakCovalentBond(address,address,uint256,string,address,uint256,uint256)":"infinite","covalentBond(address,uint256,string,address,uint256,uint256)":"infinite","createAccount(address,uint256)":"infinite","dischargeParticle(address,address,uint256,string,address)":"infinite","dischargeParticleAmount(address,address,uint256,string,address,uint256)":"infinite","dischargeParticleForCreator(address,address,uint256,string,address,uint256)":"infinite","energizeParticle(address,uint256,string,address,uint256,address)":"infinite","releaseParticle(address,address,uint256,string,address)":"infinite","releaseParticleAmount(address,address,uint256,string,address,uint256)":"infinite"}},"methodIdentifiers":{"IMPLMENTATION()":"7fdfc7b2","REGISTRY()":"06433b1b","account(address,uint256)":"192df655","breakCovalentBond(address,address,uint256,string,address,uint256,uint256)":"fe02fb00","covalentBond(address,uint256,string,address,uint256,uint256)":"3ff956cc","createAccount(address,uint256)":"5fbfb9cf","dischargeParticle(address,address,uint256,string,address)":"621a3b70","dischargeParticleAmount(address,address,uint256,string,address,uint256)":"6697b359","dischargeParticleForCreator(address,address,uint256,string,address,uint256)":"65d20ce2","energizeParticle(address,uint256,string,address,uint256,address)":"0bdde2ca","releaseParticle(address,address,uint256,string,address)":"acab923c","releaseParticleAmount(address,address,uint256,string,address,uint256)":"a8abef47"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"IMPLMENTATION\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REGISTRY\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"account\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"basketManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"breakCovalentBond\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"basketManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"covalentBond\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"dischargeParticle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"creatorAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"}],\"name\":\"dischargeParticleAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"creatorAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"}],\"name\":\"dischargeParticleForCreator\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receiverAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"referrer\",\"type\":\"address\"}],\"name\":\"energizeParticle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"yieldTokensAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"releaseParticle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"creatorAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"}],\"name\":\"releaseParticleAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"creatorAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ChargedParticles.sol\":\"ChargedParticles\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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`.\\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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\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(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/AccountRegistryBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.13;\\n\\nimport \\\"./interfaces/IRegistry.sol\\\";\\ncontract AccountRegistryBridge {\\n address public constant REGISTRY = \\t0x02101dfB77FDE026414827Fdc604ddAF224F0921;\\n address public constant IMPLMENTATION = 0x2D25602551487C3f3354dD80D76D54383A243358;\\n\\n function createAccount(address contractAddress, uint256 tokenId)\\n external\\n returns (address)\\n {\\n return IRegistry(REGISTRY).createAccount(\\n IMPLMENTATION,\\n block.chainid,\\n contractAddress,\\n tokenId,\\n 0,\\n ''\\n );\\n }\\n\\n function account(address contractAddress, uint256 tokenId)\\n external\\n view\\n returns (address)\\n {\\n return IRegistry(REGISTRY).account(\\n IMPLMENTATION,\\n block.chainid,\\n contractAddress,\\n tokenId,\\n 0\\n );\\n }\\n}\",\"keccak256\":\"0x4536af05c6fa43a3fd532415b4d39c190c35904aee16c48ea453a3b2baf976ea\",\"license\":\"MIT\"},\"contracts/ChargedParticles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.13;\\n\\nimport \\\"./interfaces/IChargedParticles.sol\\\";\\nimport \\\"./AccountRegistryBridge.sol\\\";\\n\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\ncontract ChargedParticles is AccountRegistryBridge {\\n function energizeParticle(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount,\\n address referrer\\n ) external returns (uint256 yieldTokensAmount) {\\n \\n }\\n\\n function dischargeParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount) {\\n\\n }\\n\\n function dischargeParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount) {\\n\\n }\\n\\n function dischargeParticleForCreator(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 receiverAmount) {\\n\\n }\\n\\n function releaseParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount) {\\n\\n }\\n\\n function releaseParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount) {\\n\\n }\\n\\n function covalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success) {\\n address tokenBoundAccount = this.account(contractAddress, tokenId); \\n IERC721(nftTokenAddress).safeTransferFrom(msg.sender, tokenBoundAccount, nftTokenId);\\n }\\n\\n function breakCovalentBond(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success) {\\n address tokenBoundAccount = this.account(contractAddress, tokenId); \\n IERC721(nftTokenAddress).safeTransferFrom(tokenBoundAccount, receiver, nftTokenId);\\n }\\n\\n}\\n\",\"keccak256\":\"0xbf6d389ed4abbb2560da2a573c5c8bd4fc68cfdd259d959790d98adce40754d4\",\"license\":\"MIT\"},\"contracts/interfaces/IChargedParticles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @notice Interface for Charged Particles\\n */\\ninterface IChargedParticles {\\n\\n /***********************************|\\n | Public API |\\n |__________________________________*/\\n\\n function getStateAddress() external view returns (address stateAddress);\\n function getSettingsAddress() external view returns (address settingsAddress);\\n function getManagersAddress() external view returns (address managersAddress);\\n\\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\\n\\n /***********************************|\\n | Particle Mechanics |\\n |__________________________________*/\\n\\n function energizeParticle(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount,\\n address referrer\\n ) external returns (uint256 yieldTokensAmount);\\n\\n function dischargeParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function dischargeParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function dischargeParticleForCreator(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 receiverAmount);\\n\\n function releaseParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function releaseParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function covalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success);\\n\\n function breakCovalentBond(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success);\\n}\\n\",\"keccak256\":\"0xa825d020fbe598bb4b7a0e9dbc1fe1d3b17b161b4429a3f848eec27eab4f99d4\",\"license\":\"MIT\"},\"contracts/interfaces/IRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\ninterface IRegistry {\\n function createAccount(\\n address implementation,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId,\\n uint256 salt,\\n bytes calldata initData\\n ) external returns (address);\\n\\n function account(\\n address implementation,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId,\\n uint256 salt\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xd24999d4d474bd349b1e2e5006eff215c5d9a64a481a9ebac3293f98603fbd27\",\"license\":\"UNLICENSED\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/MinimalisticAccount.sol":{"MinimalisticAccount":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccountLocked","type":"error"},{"inputs":[],"name":"ExceedsMaxLockTime","type":"error"},{"inputs":[],"name":"InvalidInput","type":"error"},{"inputs":[],"name":"NotAuthorized","type":"error"},{"inputs":[],"name":"OwnershipCycle","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"lockedUntil","type":"uint256"}],"name":"LockUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"bytes4","name":"selector","type":"bytes4"},{"indexed":false,"internalType":"address","name":"implementation","type":"address"}],"name":"OverrideUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"bool","name":"hasPermission","type":"bool"}],"name":"PermissionUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":true,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"TransactionExecuted","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"executeCall","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"isAuthorized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lockedUntil","type":"uint256"}],"name":"lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockedUntil","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"receivedTokenId","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"permissions","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"callers","type":"address[]"},{"internalType":"bool[]","name":"_permissions","type":"bool[]"}],"name":"setPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}],"devdoc":{"kind":"dev","methods":{"executeCall(address,uint256,bytes)":{"details":"executes a low-level call against an account if the caller is authorized to make calls"},"isAuthorized(address)":{"details":"Returns the authorization status for a given caller"},"isLocked()":{"details":"returns the current lock status of the account as a boolean"},"lock(uint256)":{"details":"locks the account until a certain timestamp"},"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":{"details":"Allows ERC-1155 token batches to be received. This function can be overriden."},"onERC1155Received(address,address,uint256,uint256,bytes)":{"details":"Allows ERC-1155 tokens to be received. This function can be overriden."},"onERC721Received(address,address,uint256,bytes)":{"details":"Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle. This function can be overriden."},"owner()":{"details":"Returns the owner of the ERC-721 token which owns this account. By default, the owner of the token has full permissions on the account."},"setPermissions(address[],bool[])":{"details":"grants a given caller execution permissions"},"supportsInterface(bytes4)":{"details":"Returns true if a given interfaceId is supported by this account. This method can be extended by an override."},"token()":{"details":"Returns the EIP-155 chain ID, token contract address, and token ID for the token that owns this account."}},"stateVariables":{"lockedUntil":{"details":"timestamp at which this account will be unlocked"},"permissions":{"details":"mapping from owner => caller => has permissions"}},"title":"A smart contract account owned by a single ERC721 token","version":1},"evm":{"bytecode":{"functionDebugData":{"@_551":{"entryPoint":null,"id":551,"parameterSlots":0,"returnSlots":0}},"generatedSources":[],"linkReferences":{},"object":"608060405234801561001057600080fd5b50610fa8806100206000396000f3fe6080604052600436106100c65760003560e01c8063a4e2d6341161007f578063dd46706411610059578063dd46706414610251578063f23a6e6114610271578063fc0c546a1461029d578063fe9fbb80146102d557600080fd5b8063a4e2d634146101ea578063bc197c8114610201578063ce0617ec1461022d57600080fd5b806301ffc9a7146100d2578063039721b114610107578063150b7a02146101295780631f9838b5146101625780638da5cb5b1461019d5780639e5d4c49146101ca57600080fd5b366100cd57005b600080fd5b3480156100de57600080fd5b506100f26100ed36600461095c565b6102f5565b60405190151581526020015b60405180910390f35b34801561011357600080fd5b506101276101223660046109d9565b61035c565b005b34801561013557600080fd5b50610149610144366004610b14565b610525565b6040516001600160e01b031990911681526020016100fe565b34801561016e57600080fd5b506100f261017d366004610b80565b600160209081526000928352604080842090915290825290205460ff1681565b3480156101a957600080fd5b506101b261058d565b6040516001600160a01b0390911681526020016100fe565b6101dd6101d8366004610bb9565b610623565b6040516100fe9190610c42565b3480156101f657600080fd5b5060005442106100f2565b34801561020d57600080fd5b5061014961021c366004610d10565b63bc197c8160e01b95945050505050565b34801561023957600080fd5b5061024360005481565b6040519081526020016100fe565b34801561025d57600080fd5b5061012761026c366004610dbe565b6106c7565b34801561027d57600080fd5b5061014961028c366004610dd7565b63f23a6e6160e01b95945050505050565b3480156102a957600080fd5b506102b261078c565b604080519384526001600160a01b039092166020840152908201526060016100fe565b3480156102e157600080fd5b506100f26102f0366004610e40565b6107a4565b6000806001600160e01b031983166301ffc9a760e01b148061032757506001600160e01b03198316630271189760e51b145b8061034257506001600160e01b03198316631dfe9a6f60e31b145b905080156103535750600192915050565b50600092915050565b60005442101561037f57604051636315bfbb60e01b815260040160405180910390fd5b600061038961058d565b9050336001600160a01b038216146103b45760405163ea8e4eb560e01b815260040160405180910390fd5b838281146103d55760405163b4fa3fb360e01b815260040160405180910390fd5b60005b8181101561051c578484828181106103f2576103f2610e5d565b90506020020160208101906104079190610e73565b6001600160a01b03841660009081526001602052604081209089898581811061043257610432610e5d565b90506020020160208101906104479190610e40565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f394777a58092892d136a90c4bb7e4350c72ac50fba6a0208128677f36527dcf5838888848181106104a3576104a3610e5d565b90506020020160208101906104b89190610e40565b8787858181106104ca576104ca610e5d565b90506020020160208101906104df9190610e73565b604080516001600160a01b03948516815293909216602084015215159082015260600160405180910390a18061051481610eab565b9150506103d8565b50505050505050565b60008060008061053361088d565b925092509250468314801561055057506001600160a01b03821633145b801561055b57508581145b156105795760405163b79e3f3f60e01b815260040160405180910390fd5b50630a85bd0160e11b979650505050505050565b60008060008061059b61088d565b9250925092504683146105b2576000935050505090565b6040516331a9108f60e11b8152600481018290526001600160a01b03831690636352211e90602401602060405180830381865afa1580156105f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061b9190610ec4565b935050505090565b606061062e336107a4565b61064b5760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561066e57604051636315bfbb60e01b815260040160405180910390fd5b83856001600160a01b03167f47d99ad340f52da66535aff7e10da1ceb85a32bcbd9fa1c42314d194545e14d285856040516106aa929190610ee1565b60405180910390a36106be858585856108e0565b95945050505050565b6106cf61058d565b6001600160a01b0316336001600160a01b0316146107005760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561072357604051636315bfbb60e01b815260040160405180910390fd5b610731426301e13380610f10565b811115610751576040516301814f7d60e31b815260040160405180910390fd5b60008190556040518181527fa7b24c66dd3269a292a60b3facdbb8f3e7557d1e19e64d99e0d6ee7250be63ad9060200160405180910390a150565b600080600061079961088d565b925092509250909192565b60008060006107b161088d565b6040516331a9108f60e11b8152600481018290529194509250600091506001600160a01b03841690636352211e90602401602060405180830381865afa1580156107ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108239190610ec4565b9050806001600160a01b0316856001600160a01b03160361084957506001949350505050565b6001600160a01b0380821660009081526001602090815260408083209389168352929052205460ff161561088257506001949350505050565b506000949350505050565b604080516060808252608082019092526000918291829182919060208201818036833701905050905060ad604d60208301303c808060200190518101906108d49190610f29565b93509350935050909192565b60606000856001600160a01b03168585856040516108ff929190610f62565b60006040518083038185875af1925050503d806000811461093c576040519150601f19603f3d011682016040523d82523d6000602084013e610941565b606091505b50925090508061095357815160208301fd5b50949350505050565b60006020828403121561096e57600080fd5b81356001600160e01b03198116811461098657600080fd5b9392505050565b60008083601f84011261099f57600080fd5b50813567ffffffffffffffff8111156109b757600080fd5b6020830191508360208260051b85010111156109d257600080fd5b9250929050565b600080600080604085870312156109ef57600080fd5b843567ffffffffffffffff80821115610a0757600080fd5b610a138883890161098d565b90965094506020870135915080821115610a2c57600080fd5b50610a398782880161098d565b95989497509550505050565b6001600160a01b0381168114610a5a57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610a9c57610a9c610a5d565b604052919050565b600082601f830112610ab557600080fd5b813567ffffffffffffffff811115610acf57610acf610a5d565b610ae2601f8201601f1916602001610a73565b818152846020838601011115610af757600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215610b2a57600080fd5b8435610b3581610a45565b93506020850135610b4581610a45565b925060408501359150606085013567ffffffffffffffff811115610b6857600080fd5b610b7487828801610aa4565b91505092959194509250565b60008060408385031215610b9357600080fd5b8235610b9e81610a45565b91506020830135610bae81610a45565b809150509250929050565b60008060008060608587031215610bcf57600080fd5b8435610bda81610a45565b935060208501359250604085013567ffffffffffffffff80821115610bfe57600080fd5b818701915087601f830112610c1257600080fd5b813581811115610c2157600080fd5b886020828501011115610c3357600080fd5b95989497505060200194505050565b600060208083528351808285015260005b81811015610c6f57858101830151858201604001528201610c53565b506000604082860101526040601f19601f8301168501019250505092915050565b600082601f830112610ca157600080fd5b8135602067ffffffffffffffff821115610cbd57610cbd610a5d565b8160051b610ccc828201610a73565b9283528481018201928281019087851115610ce657600080fd5b83870192505b84831015610d0557823582529183019190830190610cec565b979650505050505050565b600080600080600060a08688031215610d2857600080fd5b8535610d3381610a45565b94506020860135610d4381610a45565b9350604086013567ffffffffffffffff80821115610d6057600080fd5b610d6c89838a01610c90565b94506060880135915080821115610d8257600080fd5b610d8e89838a01610c90565b93506080880135915080821115610da457600080fd5b50610db188828901610aa4565b9150509295509295909350565b600060208284031215610dd057600080fd5b5035919050565b600080600080600060a08688031215610def57600080fd5b8535610dfa81610a45565b94506020860135610e0a81610a45565b93506040860135925060608601359150608086013567ffffffffffffffff811115610e3457600080fd5b610db188828901610aa4565b600060208284031215610e5257600080fd5b813561098681610a45565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610e8557600080fd5b8135801515811461098657600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610ebd57610ebd610e95565b5060010190565b600060208284031215610ed657600080fd5b815161098681610a45565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b80820180821115610f2357610f23610e95565b92915050565b600080600060608486031215610f3e57600080fd5b835192506020840151610f5081610a45565b80925050604084015190509250925092565b818382376000910190815291905056fea26469706673582212208586a5aa87cff87a1d8e1dc4952c1d3b167ebfafab4c2b56ed97ed8a5ec5921664736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xFA8 DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xC6 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0xA4E2D634 GT PUSH2 0x7F JUMPI DUP1 PUSH4 0xDD467064 GT PUSH2 0x59 JUMPI DUP1 PUSH4 0xDD467064 EQ PUSH2 0x251 JUMPI DUP1 PUSH4 0xF23A6E61 EQ PUSH2 0x271 JUMPI DUP1 PUSH4 0xFC0C546A EQ PUSH2 0x29D JUMPI DUP1 PUSH4 0xFE9FBB80 EQ PUSH2 0x2D5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0xA4E2D634 EQ PUSH2 0x1EA JUMPI DUP1 PUSH4 0xBC197C81 EQ PUSH2 0x201 JUMPI DUP1 PUSH4 0xCE0617EC EQ PUSH2 0x22D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1FFC9A7 EQ PUSH2 0xD2 JUMPI DUP1 PUSH4 0x39721B1 EQ PUSH2 0x107 JUMPI DUP1 PUSH4 0x150B7A02 EQ PUSH2 0x129 JUMPI DUP1 PUSH4 0x1F9838B5 EQ PUSH2 0x162 JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x19D JUMPI DUP1 PUSH4 0x9E5D4C49 EQ PUSH2 0x1CA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST CALLDATASIZE PUSH2 0xCD JUMPI STOP JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xDE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xF2 PUSH2 0xED CALLDATASIZE PUSH1 0x4 PUSH2 0x95C JUMP JUMPDEST PUSH2 0x2F5 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x113 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x127 PUSH2 0x122 CALLDATASIZE PUSH1 0x4 PUSH2 0x9D9 JUMP JUMPDEST PUSH2 0x35C JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x135 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x149 PUSH2 0x144 CALLDATASIZE PUSH1 0x4 PUSH2 0xB14 JUMP JUMPDEST PUSH2 0x525 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xFE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x16E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xF2 PUSH2 0x17D CALLDATASIZE PUSH1 0x4 PUSH2 0xB80 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1A9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B2 PUSH2 0x58D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xFE JUMP JUMPDEST PUSH2 0x1DD PUSH2 0x1D8 CALLDATASIZE PUSH1 0x4 PUSH2 0xBB9 JUMP JUMPDEST PUSH2 0x623 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xFE SWAP2 SWAP1 PUSH2 0xC42 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1F6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x0 SLOAD TIMESTAMP LT PUSH2 0xF2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x20D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x149 PUSH2 0x21C CALLDATASIZE PUSH1 0x4 PUSH2 0xD10 JUMP JUMPDEST PUSH4 0xBC197C81 PUSH1 0xE0 SHL SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x239 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x243 PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xFE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x25D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x127 PUSH2 0x26C CALLDATASIZE PUSH1 0x4 PUSH2 0xDBE JUMP JUMPDEST PUSH2 0x6C7 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x27D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x149 PUSH2 0x28C CALLDATASIZE PUSH1 0x4 PUSH2 0xDD7 JUMP JUMPDEST PUSH4 0xF23A6E61 PUSH1 0xE0 SHL SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2A9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2B2 PUSH2 0x78C JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP4 DUP5 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE SWAP1 DUP3 ADD MSTORE PUSH1 0x60 ADD PUSH2 0xFE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2E1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xF2 PUSH2 0x2F0 CALLDATASIZE PUSH1 0x4 PUSH2 0xE40 JUMP JUMPDEST PUSH2 0x7A4 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x1FFC9A7 PUSH1 0xE0 SHL EQ DUP1 PUSH2 0x327 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x2711897 PUSH1 0xE5 SHL EQ JUMPDEST DUP1 PUSH2 0x342 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x1DFE9A6F PUSH1 0xE3 SHL EQ JUMPDEST SWAP1 POP DUP1 ISZERO PUSH2 0x353 JUMPI POP PUSH1 0x1 SWAP3 SWAP2 POP POP JUMP JUMPDEST POP PUSH1 0x0 SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x37F JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x389 PUSH2 0x58D JUMP JUMPDEST SWAP1 POP CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND EQ PUSH2 0x3B4 JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 DUP3 DUP2 EQ PUSH2 0x3D5 JUMPI PUSH1 0x40 MLOAD PUSH4 0xB4FA3FB3 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x51C JUMPI DUP5 DUP5 DUP3 DUP2 DUP2 LT PUSH2 0x3F2 JUMPI PUSH2 0x3F2 PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x407 SWAP2 SWAP1 PUSH2 0xE73 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 SWAP1 DUP10 DUP10 DUP6 DUP2 DUP2 LT PUSH2 0x432 JUMPI PUSH2 0x432 PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x447 SWAP2 SWAP1 PUSH2 0xE40 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP2 MSTORE PUSH1 0x20 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 ADD PUSH1 0x0 KECCAK256 DUP1 SLOAD PUSH1 0xFF NOT AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH32 0x394777A58092892D136A90C4BB7E4350C72AC50FBA6A0208128677F36527DCF5 DUP4 DUP9 DUP9 DUP5 DUP2 DUP2 LT PUSH2 0x4A3 JUMPI PUSH2 0x4A3 PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x4B8 SWAP2 SWAP1 PUSH2 0xE40 JUMP JUMPDEST DUP8 DUP8 DUP6 DUP2 DUP2 LT PUSH2 0x4CA JUMPI PUSH2 0x4CA PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x4DF SWAP2 SWAP1 PUSH2 0xE73 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP5 DUP6 AND DUP2 MSTORE SWAP4 SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE ISZERO ISZERO SWAP1 DUP3 ADD MSTORE PUSH1 0x60 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 DUP1 PUSH2 0x514 DUP2 PUSH2 0xEAB JUMP JUMPDEST SWAP2 POP POP PUSH2 0x3D8 JUMP JUMPDEST POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x533 PUSH2 0x88D JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP CHAINID DUP4 EQ DUP1 ISZERO PUSH2 0x550 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND CALLER EQ JUMPDEST DUP1 ISZERO PUSH2 0x55B JUMPI POP DUP6 DUP2 EQ JUMPDEST ISZERO PUSH2 0x579 JUMPI PUSH1 0x40 MLOAD PUSH4 0xB79E3F3F PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP PUSH4 0xA85BD01 PUSH1 0xE1 SHL SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x59B PUSH2 0x88D JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP CHAINID DUP4 EQ PUSH2 0x5B2 JUMPI PUSH1 0x0 SWAP4 POP POP POP POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x31A9108F PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND SWAP1 PUSH4 0x6352211E SWAP1 PUSH1 0x24 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x5F7 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x61B SWAP2 SWAP1 PUSH2 0xEC4 JUMP JUMPDEST SWAP4 POP POP POP POP SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH2 0x62E CALLER PUSH2 0x7A4 JUMP JUMPDEST PUSH2 0x64B JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x66E JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH32 0x47D99AD340F52DA66535AFF7E10DA1CEB85A32BCBD9FA1C42314D194545E14D2 DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0x6AA SWAP3 SWAP2 SWAP1 PUSH2 0xEE1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 PUSH2 0x6BE DUP6 DUP6 DUP6 DUP6 PUSH2 0x8E0 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0x6CF PUSH2 0x58D JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ PUSH2 0x700 JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x723 JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH2 0x731 TIMESTAMP PUSH4 0x1E13380 PUSH2 0xF10 JUMP JUMPDEST DUP2 GT ISZERO PUSH2 0x751 JUMPI PUSH1 0x40 MLOAD PUSH4 0x1814F7D PUSH1 0xE3 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 DUP2 SWAP1 SSTORE PUSH1 0x40 MLOAD DUP2 DUP2 MSTORE PUSH32 0xA7B24C66DD3269A292A60B3FACDBB8F3E7557D1E19E64D99E0D6EE7250BE63AD SWAP1 PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x799 PUSH2 0x88D JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP SWAP1 SWAP2 SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x7B1 PUSH2 0x88D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x31A9108F PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE SWAP2 SWAP5 POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND SWAP1 PUSH4 0x6352211E SWAP1 PUSH1 0x24 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x7FF JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x823 SWAP2 SWAP1 PUSH2 0xEC4 JUMP JUMPDEST SWAP1 POP DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SUB PUSH2 0x849 JUMPI POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP1 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP10 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x882 JUMPI POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST POP PUSH1 0x0 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 DUP1 DUP3 MSTORE PUSH1 0x80 DUP3 ADD SWAP1 SWAP3 MSTORE PUSH1 0x0 SWAP2 DUP3 SWAP2 DUP3 SWAP2 DUP3 SWAP2 SWAP1 PUSH1 0x20 DUP3 ADD DUP2 DUP1 CALLDATASIZE DUP4 CALLDATACOPY ADD SWAP1 POP POP SWAP1 POP PUSH1 0xAD PUSH1 0x4D PUSH1 0x20 DUP4 ADD ADDRESS EXTCODECOPY DUP1 DUP1 PUSH1 0x20 ADD SWAP1 MLOAD DUP2 ADD SWAP1 PUSH2 0x8D4 SWAP2 SWAP1 PUSH2 0xF29 JUMP JUMPDEST SWAP4 POP SWAP4 POP SWAP4 POP POP SWAP1 SWAP2 SWAP3 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP6 DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0x8FF SWAP3 SWAP2 SWAP1 PUSH2 0xF62 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 GAS CALL SWAP3 POP POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0x93C JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0x941 JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP3 POP SWAP1 POP DUP1 PUSH2 0x953 JUMPI DUP2 MLOAD PUSH1 0x20 DUP4 ADD REVERT JUMPDEST POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x96E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP2 AND DUP2 EQ PUSH2 0x986 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x99F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x9B7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 PUSH1 0x5 SHL DUP6 ADD ADD GT ISZERO PUSH2 0x9D2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x40 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x9EF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xA07 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xA13 DUP9 DUP4 DUP10 ADD PUSH2 0x98D JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP PUSH1 0x20 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xA2C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xA39 DUP8 DUP3 DUP9 ADD PUSH2 0x98D JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0xA5A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT AND DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0xA9C JUMPI PUSH2 0xA9C PUSH2 0xA5D JUMP JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xAB5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xACF JUMPI PUSH2 0xACF PUSH2 0xA5D JUMP JUMPDEST PUSH2 0xAE2 PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT AND PUSH1 0x20 ADD PUSH2 0xA73 JUMP JUMPDEST DUP2 DUP2 MSTORE DUP5 PUSH1 0x20 DUP4 DUP7 ADD ADD GT ISZERO PUSH2 0xAF7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 PUSH1 0x20 DUP6 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 SWAP2 DUP2 ADD PUSH1 0x20 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xB2A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xB35 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH2 0xB45 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD SWAP2 POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xB68 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xB74 DUP8 DUP3 DUP9 ADD PUSH2 0xAA4 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xB93 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH2 0xB9E DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP2 POP PUSH1 0x20 DUP4 ADD CALLDATALOAD PUSH2 0xBAE DUP2 PUSH2 0xA45 JUMP JUMPDEST DUP1 SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x60 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xBCF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xBDA DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xBFE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP8 ADD SWAP2 POP DUP8 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xC12 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP2 DUP2 GT ISZERO PUSH2 0xC21 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP9 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0xC33 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP POP PUSH1 0x20 ADD SWAP5 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 MSTORE DUP4 MLOAD DUP1 DUP3 DUP6 ADD MSTORE PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xC6F JUMPI DUP6 DUP2 ADD DUP4 ADD MLOAD DUP6 DUP3 ADD PUSH1 0x40 ADD MSTORE DUP3 ADD PUSH2 0xC53 JUMP JUMPDEST POP PUSH1 0x0 PUSH1 0x40 DUP3 DUP7 ADD ADD MSTORE PUSH1 0x40 PUSH1 0x1F NOT PUSH1 0x1F DUP4 ADD AND DUP6 ADD ADD SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xCA1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH1 0x20 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0xCBD JUMPI PUSH2 0xCBD PUSH2 0xA5D JUMP JUMPDEST DUP2 PUSH1 0x5 SHL PUSH2 0xCCC DUP3 DUP3 ADD PUSH2 0xA73 JUMP JUMPDEST SWAP3 DUP4 MSTORE DUP5 DUP2 ADD DUP3 ADD SWAP3 DUP3 DUP2 ADD SWAP1 DUP8 DUP6 GT ISZERO PUSH2 0xCE6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 DUP8 ADD SWAP3 POP JUMPDEST DUP5 DUP4 LT ISZERO PUSH2 0xD05 JUMPI DUP3 CALLDATALOAD DUP3 MSTORE SWAP2 DUP4 ADD SWAP2 SWAP1 DUP4 ADD SWAP1 PUSH2 0xCEC JUMP JUMPDEST SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xD28 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xD33 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH2 0xD43 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xD60 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD6C DUP10 DUP4 DUP11 ADD PUSH2 0xC90 JUMP JUMPDEST SWAP5 POP PUSH1 0x60 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xD82 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD8E DUP10 DUP4 DUP11 ADD PUSH2 0xC90 JUMP JUMPDEST SWAP4 POP PUSH1 0x80 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xDA4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xDB1 DUP9 DUP3 DUP10 ADD PUSH2 0xAA4 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 SWAP1 SWAP4 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xDD0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xDEF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xDFA DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH2 0xE0A DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD SWAP3 POP PUSH1 0x60 DUP7 ADD CALLDATALOAD SWAP2 POP PUSH1 0x80 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xE34 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xDB1 DUP9 DUP3 DUP10 ADD PUSH2 0xAA4 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xE52 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x986 DUP2 PUSH2 0xA45 JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x32 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xE85 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP1 ISZERO ISZERO DUP2 EQ PUSH2 0x986 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x11 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x1 DUP3 ADD PUSH2 0xEBD JUMPI PUSH2 0xEBD PUSH2 0xE95 JUMP JUMPDEST POP PUSH1 0x1 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xED6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x986 DUP2 PUSH2 0xA45 JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE DUP2 PUSH1 0x20 DUP3 ADD MSTORE DUP2 DUP4 PUSH1 0x40 DUP4 ADD CALLDATACOPY PUSH1 0x0 DUP2 DUP4 ADD PUSH1 0x40 SWAP1 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x1F SWAP1 SWAP3 ADD PUSH1 0x1F NOT AND ADD ADD SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 DUP3 ADD DUP1 DUP3 GT ISZERO PUSH2 0xF23 JUMPI PUSH2 0xF23 PUSH2 0xE95 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xF3E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 MLOAD SWAP3 POP PUSH1 0x20 DUP5 ADD MLOAD PUSH2 0xF50 DUP2 PUSH2 0xA45 JUMP JUMPDEST DUP1 SWAP3 POP POP PUSH1 0x40 DUP5 ADD MLOAD SWAP1 POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST DUP2 DUP4 DUP3 CALLDATACOPY PUSH1 0x0 SWAP2 ADD SWAP1 DUP2 MSTORE SWAP2 SWAP1 POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 DUP6 DUP7 0xA5 0xAA DUP8 0xCF 0xF8 PUSH27 0x1D8E1DC4952C1D3B167EBFAFAB4C2B56ED97ED8A5EC5921664736F PUSH13 0x63430008110033000000000000 ","sourceMap":"695:6680:7:-:0;;;1784:16;;;;;;;;;;695:6680;;;;;;"},"deployedBytecode":{"functionDebugData":{"@_556":{"entryPoint":null,"id":556,"parameterSlots":0,"returnSlots":0},"@_call_954":{"entryPoint":2272,"id":954,"parameterSlots":4,"returnSlots":1},"@executeCall_585":{"entryPoint":1571,"id":585,"parameterSlots":4,"returnSlots":1},"@isAuthorized_790":{"entryPoint":1956,"id":790,"parameterSlots":1,"returnSlots":1},"@isLocked_699":{"entryPoint":null,"id":699,"parameterSlots":0,"returnSlots":1},"@lock_687":{"entryPoint":1735,"id":687,"parameterSlots":1,"returnSlots":0},"@lockedUntil_481":{"entryPoint":null,"id":481,"parameterSlots":0,"returnSlots":0},"@onERC1155BatchReceived_922":{"entryPoint":null,"id":922,"parameterSlots":5,"returnSlots":1},"@onERC1155Received_898":{"entryPoint":null,"id":898,"parameterSlots":5,"returnSlots":1},"@onERC721Received_876":{"entryPoint":1317,"id":876,"parameterSlots":4,"returnSlots":1},"@owner_748":{"entryPoint":1421,"id":748,"parameterSlots":0,"returnSlots":1},"@permissions_488":{"entryPoint":null,"id":488,"parameterSlots":0,"returnSlots":0},"@setPermissions_658":{"entryPoint":860,"id":658,"parameterSlots":4,"returnSlots":0},"@supportsInterface_829":{"entryPoint":757,"id":829,"parameterSlots":1,"returnSlots":1},"@token_1314":{"entryPoint":2189,"id":1314,"parameterSlots":0,"returnSlots":3},"@token_714":{"entryPoint":1932,"id":714,"parameterSlots":0,"returnSlots":3},"abi_decode_array_address_dyn_calldata":{"entryPoint":2445,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_array_uint256_dyn":{"entryPoint":3216,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_bytes":{"entryPoint":2724,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_address":{"entryPoint":3648,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_address_fromMemory":{"entryPoint":3780,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_addresst_address":{"entryPoint":2944,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_tuple_t_addresst_addresst_array$_t_uint256_$dyn_memory_ptrt_array$_t_uint256_$dyn_memory_ptrt_bytes_memory_ptr":{"entryPoint":3344,"id":null,"parameterSlots":2,"returnSlots":5},"abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr":{"entryPoint":2836,"id":null,"parameterSlots":2,"returnSlots":4},"abi_decode_tuple_t_addresst_addresst_uint256t_uint256t_bytes_memory_ptr":{"entryPoint":3543,"id":null,"parameterSlots":2,"returnSlots":5},"abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptr":{"entryPoint":3001,"id":null,"parameterSlots":2,"returnSlots":4},"abi_decode_tuple_t_array$_t_address_$dyn_calldata_ptrt_array$_t_bool_$dyn_calldata_ptr":{"entryPoint":2521,"id":null,"parameterSlots":2,"returnSlots":4},"abi_decode_tuple_t_bool":{"entryPoint":3699,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_bytes4":{"entryPoint":2396,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_uint256":{"entryPoint":3518,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_uint256t_address_payablet_uint256_fromMemory":{"entryPoint":3881,"id":null,"parameterSlots":2,"returnSlots":3},"abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed":{"entryPoint":3938,"id":null,"parameterSlots":3,"returnSlots":1},"abi_encode_tuple_t_address__to_t_address__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_address_t_address_t_bool__to_t_address_t_address_t_bool__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":4,"returnSlots":1},"abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed":{"entryPoint":3809,"id":null,"parameterSlots":3,"returnSlots":1},"abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed":{"entryPoint":3138,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_uint256_t_address_t_uint256__to_t_uint256_t_address_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":4,"returnSlots":1},"allocate_memory":{"entryPoint":2675,"id":null,"parameterSlots":1,"returnSlots":1},"checked_add_t_uint256":{"entryPoint":3856,"id":null,"parameterSlots":2,"returnSlots":1},"increment_t_uint256":{"entryPoint":3755,"id":null,"parameterSlots":1,"returnSlots":1},"panic_error_0x11":{"entryPoint":3733,"id":null,"parameterSlots":0,"returnSlots":0},"panic_error_0x32":{"entryPoint":3677,"id":null,"parameterSlots":0,"returnSlots":0},"panic_error_0x41":{"entryPoint":2653,"id":null,"parameterSlots":0,"returnSlots":0},"validator_revert_address":{"entryPoint":2629,"id":null,"parameterSlots":1,"returnSlots":0}},"generatedSources":[{"ast":{"nodeType":"YulBlock","src":"0:11566:12","statements":[{"nodeType":"YulBlock","src":"6:3:12","statements":[]},{"body":{"nodeType":"YulBlock","src":"83:217:12","statements":[{"body":{"nodeType":"YulBlock","src":"129:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"138:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"141:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"131:6:12"},"nodeType":"YulFunctionCall","src":"131:12:12"},"nodeType":"YulExpressionStatement","src":"131:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"104:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"113:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"100:3:12"},"nodeType":"YulFunctionCall","src":"100:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"125:2:12","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"96:3:12"},"nodeType":"YulFunctionCall","src":"96:32:12"},"nodeType":"YulIf","src":"93:52:12"},{"nodeType":"YulVariableDeclaration","src":"154:36:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"180:9:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"167:12:12"},"nodeType":"YulFunctionCall","src":"167:23:12"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"158:5:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"254:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"263:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"266:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"256:6:12"},"nodeType":"YulFunctionCall","src":"256:12:12"},"nodeType":"YulExpressionStatement","src":"256:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"212:5:12"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"223:5:12"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"234:3:12","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"239:10:12","type":"","value":"0xffffffff"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"230:3:12"},"nodeType":"YulFunctionCall","src":"230:20:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"219:3:12"},"nodeType":"YulFunctionCall","src":"219:32:12"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"209:2:12"},"nodeType":"YulFunctionCall","src":"209:43:12"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"202:6:12"},"nodeType":"YulFunctionCall","src":"202:51:12"},"nodeType":"YulIf","src":"199:71:12"},{"nodeType":"YulAssignment","src":"279:15:12","value":{"name":"value","nodeType":"YulIdentifier","src":"289:5:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"279:6:12"}]}]},"name":"abi_decode_tuple_t_bytes4","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"49:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"60:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"72:6:12","type":""}],"src":"14:286:12"},{"body":{"nodeType":"YulBlock","src":"400:92:12","statements":[{"nodeType":"YulAssignment","src":"410:26:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"422:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"433:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"418:3:12"},"nodeType":"YulFunctionCall","src":"418:18:12"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"410:4:12"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"452:9:12"},{"arguments":[{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"477:6:12"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"470:6:12"},"nodeType":"YulFunctionCall","src":"470:14:12"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"463:6:12"},"nodeType":"YulFunctionCall","src":"463:22:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"445:6:12"},"nodeType":"YulFunctionCall","src":"445:41:12"},"nodeType":"YulExpressionStatement","src":"445:41:12"}]},"name":"abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"369:9:12","type":""},{"name":"value0","nodeType":"YulTypedName","src":"380:6:12","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"391:4:12","type":""}],"src":"305:187:12"},{"body":{"nodeType":"YulBlock","src":"581:283:12","statements":[{"body":{"nodeType":"YulBlock","src":"630:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"639:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"642:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"632:6:12"},"nodeType":"YulFunctionCall","src":"632:12:12"},"nodeType":"YulExpressionStatement","src":"632:12:12"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"609:6:12"},{"kind":"number","nodeType":"YulLiteral","src":"617:4:12","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"605:3:12"},"nodeType":"YulFunctionCall","src":"605:17:12"},{"name":"end","nodeType":"YulIdentifier","src":"624:3:12"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"601:3:12"},"nodeType":"YulFunctionCall","src":"601:27:12"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"594:6:12"},"nodeType":"YulFunctionCall","src":"594:35:12"},"nodeType":"YulIf","src":"591:55:12"},{"nodeType":"YulAssignment","src":"655:30:12","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"678:6:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"665:12:12"},"nodeType":"YulFunctionCall","src":"665:20:12"},"variableNames":[{"name":"length","nodeType":"YulIdentifier","src":"655:6:12"}]},{"body":{"nodeType":"YulBlock","src":"728:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"737:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"740:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"730:6:12"},"nodeType":"YulFunctionCall","src":"730:12:12"},"nodeType":"YulExpressionStatement","src":"730:12:12"}]},"condition":{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"700:6:12"},{"kind":"number","nodeType":"YulLiteral","src":"708:18:12","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"697:2:12"},"nodeType":"YulFunctionCall","src":"697:30:12"},"nodeType":"YulIf","src":"694:50:12"},{"nodeType":"YulAssignment","src":"753:29:12","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"769:6:12"},{"kind":"number","nodeType":"YulLiteral","src":"777:4:12","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"765:3:12"},"nodeType":"YulFunctionCall","src":"765:17:12"},"variableNames":[{"name":"arrayPos","nodeType":"YulIdentifier","src":"753:8:12"}]},{"body":{"nodeType":"YulBlock","src":"842:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"851:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"854:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"844:6:12"},"nodeType":"YulFunctionCall","src":"844:12:12"},"nodeType":"YulExpressionStatement","src":"844:12:12"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"805:6:12"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"817:1:12","type":"","value":"5"},{"name":"length","nodeType":"YulIdentifier","src":"820:6:12"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"813:3:12"},"nodeType":"YulFunctionCall","src":"813:14:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"801:3:12"},"nodeType":"YulFunctionCall","src":"801:27:12"},{"kind":"number","nodeType":"YulLiteral","src":"830:4:12","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"797:3:12"},"nodeType":"YulFunctionCall","src":"797:38:12"},{"name":"end","nodeType":"YulIdentifier","src":"837:3:12"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"794:2:12"},"nodeType":"YulFunctionCall","src":"794:47:12"},"nodeType":"YulIf","src":"791:67:12"}]},"name":"abi_decode_array_address_dyn_calldata","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"544:6:12","type":""},{"name":"end","nodeType":"YulTypedName","src":"552:3:12","type":""}],"returnVariables":[{"name":"arrayPos","nodeType":"YulTypedName","src":"560:8:12","type":""},{"name":"length","nodeType":"YulTypedName","src":"570:6:12","type":""}],"src":"497:367:12"},{"body":{"nodeType":"YulBlock","src":"1023:616:12","statements":[{"body":{"nodeType":"YulBlock","src":"1069:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1078:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1081:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1071:6:12"},"nodeType":"YulFunctionCall","src":"1071:12:12"},"nodeType":"YulExpressionStatement","src":"1071:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"1044:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"1053:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1040:3:12"},"nodeType":"YulFunctionCall","src":"1040:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"1065:2:12","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"1036:3:12"},"nodeType":"YulFunctionCall","src":"1036:32:12"},"nodeType":"YulIf","src":"1033:52:12"},{"nodeType":"YulVariableDeclaration","src":"1094:37:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1121:9:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1108:12:12"},"nodeType":"YulFunctionCall","src":"1108:23:12"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"1098:6:12","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1140:28:12","value":{"kind":"number","nodeType":"YulLiteral","src":"1150:18:12","type":"","value":"0xffffffffffffffff"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"1144:2:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"1195:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1204:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1207:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1197:6:12"},"nodeType":"YulFunctionCall","src":"1197:12:12"},"nodeType":"YulExpressionStatement","src":"1197:12:12"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"1183:6:12"},{"name":"_1","nodeType":"YulIdentifier","src":"1191:2:12"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"1180:2:12"},"nodeType":"YulFunctionCall","src":"1180:14:12"},"nodeType":"YulIf","src":"1177:34:12"},{"nodeType":"YulVariableDeclaration","src":"1220:96:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1288:9:12"},{"name":"offset","nodeType":"YulIdentifier","src":"1299:6:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1284:3:12"},"nodeType":"YulFunctionCall","src":"1284:22:12"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"1308:7:12"}],"functionName":{"name":"abi_decode_array_address_dyn_calldata","nodeType":"YulIdentifier","src":"1246:37:12"},"nodeType":"YulFunctionCall","src":"1246:70:12"},"variables":[{"name":"value0_1","nodeType":"YulTypedName","src":"1224:8:12","type":""},{"name":"value1_1","nodeType":"YulTypedName","src":"1234:8:12","type":""}]},{"nodeType":"YulAssignment","src":"1325:18:12","value":{"name":"value0_1","nodeType":"YulIdentifier","src":"1335:8:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"1325:6:12"}]},{"nodeType":"YulAssignment","src":"1352:18:12","value":{"name":"value1_1","nodeType":"YulIdentifier","src":"1362:8:12"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"1352:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"1379:48:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1412:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"1423:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1408:3:12"},"nodeType":"YulFunctionCall","src":"1408:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1395:12:12"},"nodeType":"YulFunctionCall","src":"1395:32:12"},"variables":[{"name":"offset_1","nodeType":"YulTypedName","src":"1383:8:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"1456:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1465:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1468:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1458:6:12"},"nodeType":"YulFunctionCall","src":"1458:12:12"},"nodeType":"YulExpressionStatement","src":"1458:12:12"}]},"condition":{"arguments":[{"name":"offset_1","nodeType":"YulIdentifier","src":"1442:8:12"},{"name":"_1","nodeType":"YulIdentifier","src":"1452:2:12"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"1439:2:12"},"nodeType":"YulFunctionCall","src":"1439:16:12"},"nodeType":"YulIf","src":"1436:36:12"},{"nodeType":"YulVariableDeclaration","src":"1481:98:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1549:9:12"},{"name":"offset_1","nodeType":"YulIdentifier","src":"1560:8:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1545:3:12"},"nodeType":"YulFunctionCall","src":"1545:24:12"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"1571:7:12"}],"functionName":{"name":"abi_decode_array_address_dyn_calldata","nodeType":"YulIdentifier","src":"1507:37:12"},"nodeType":"YulFunctionCall","src":"1507:72:12"},"variables":[{"name":"value2_1","nodeType":"YulTypedName","src":"1485:8:12","type":""},{"name":"value3_1","nodeType":"YulTypedName","src":"1495:8:12","type":""}]},{"nodeType":"YulAssignment","src":"1588:18:12","value":{"name":"value2_1","nodeType":"YulIdentifier","src":"1598:8:12"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"1588:6:12"}]},{"nodeType":"YulAssignment","src":"1615:18:12","value":{"name":"value3_1","nodeType":"YulIdentifier","src":"1625:8:12"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"1615:6:12"}]}]},"name":"abi_decode_tuple_t_array$_t_address_$dyn_calldata_ptrt_array$_t_bool_$dyn_calldata_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"965:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"976:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"988:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"996:6:12","type":""},{"name":"value2","nodeType":"YulTypedName","src":"1004:6:12","type":""},{"name":"value3","nodeType":"YulTypedName","src":"1012:6:12","type":""}],"src":"869:770:12"},{"body":{"nodeType":"YulBlock","src":"1689:86:12","statements":[{"body":{"nodeType":"YulBlock","src":"1753:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1762:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1765:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1755:6:12"},"nodeType":"YulFunctionCall","src":"1755:12:12"},"nodeType":"YulExpressionStatement","src":"1755:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1712:5:12"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1723:5:12"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1738:3:12","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"1743:1:12","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1734:3:12"},"nodeType":"YulFunctionCall","src":"1734:11:12"},{"kind":"number","nodeType":"YulLiteral","src":"1747:1:12","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1730:3:12"},"nodeType":"YulFunctionCall","src":"1730:19:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1719:3:12"},"nodeType":"YulFunctionCall","src":"1719:31:12"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"1709:2:12"},"nodeType":"YulFunctionCall","src":"1709:42:12"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"1702:6:12"},"nodeType":"YulFunctionCall","src":"1702:50:12"},"nodeType":"YulIf","src":"1699:70:12"}]},"name":"validator_revert_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"value","nodeType":"YulTypedName","src":"1678:5:12","type":""}],"src":"1644:131:12"},{"body":{"nodeType":"YulBlock","src":"1812:95:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1829:1:12","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1836:3:12","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"1841:10:12","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1832:3:12"},"nodeType":"YulFunctionCall","src":"1832:20:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1822:6:12"},"nodeType":"YulFunctionCall","src":"1822:31:12"},"nodeType":"YulExpressionStatement","src":"1822:31:12"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1869:1:12","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"1872:4:12","type":"","value":"0x41"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1862:6:12"},"nodeType":"YulFunctionCall","src":"1862:15:12"},"nodeType":"YulExpressionStatement","src":"1862:15:12"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1893:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1896:4:12","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1886:6:12"},"nodeType":"YulFunctionCall","src":"1886:15:12"},"nodeType":"YulExpressionStatement","src":"1886:15:12"}]},"name":"panic_error_0x41","nodeType":"YulFunctionDefinition","src":"1780:127:12"},{"body":{"nodeType":"YulBlock","src":"1957:230:12","statements":[{"nodeType":"YulAssignment","src":"1967:19:12","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1983:2:12","type":"","value":"64"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"1977:5:12"},"nodeType":"YulFunctionCall","src":"1977:9:12"},"variableNames":[{"name":"memPtr","nodeType":"YulIdentifier","src":"1967:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"1995:58:12","value":{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"2017:6:12"},{"arguments":[{"arguments":[{"name":"size","nodeType":"YulIdentifier","src":"2033:4:12"},{"kind":"number","nodeType":"YulLiteral","src":"2039:2:12","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2029:3:12"},"nodeType":"YulFunctionCall","src":"2029:13:12"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2048:2:12","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"2044:3:12"},"nodeType":"YulFunctionCall","src":"2044:7:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"2025:3:12"},"nodeType":"YulFunctionCall","src":"2025:27:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2013:3:12"},"nodeType":"YulFunctionCall","src":"2013:40:12"},"variables":[{"name":"newFreePtr","nodeType":"YulTypedName","src":"1999:10:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"2128:22:12","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"2130:16:12"},"nodeType":"YulFunctionCall","src":"2130:18:12"},"nodeType":"YulExpressionStatement","src":"2130:18:12"}]},"condition":{"arguments":[{"arguments":[{"name":"newFreePtr","nodeType":"YulIdentifier","src":"2071:10:12"},{"kind":"number","nodeType":"YulLiteral","src":"2083:18:12","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2068:2:12"},"nodeType":"YulFunctionCall","src":"2068:34:12"},{"arguments":[{"name":"newFreePtr","nodeType":"YulIdentifier","src":"2107:10:12"},{"name":"memPtr","nodeType":"YulIdentifier","src":"2119:6:12"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"2104:2:12"},"nodeType":"YulFunctionCall","src":"2104:22:12"}],"functionName":{"name":"or","nodeType":"YulIdentifier","src":"2065:2:12"},"nodeType":"YulFunctionCall","src":"2065:62:12"},"nodeType":"YulIf","src":"2062:88:12"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2166:2:12","type":"","value":"64"},{"name":"newFreePtr","nodeType":"YulIdentifier","src":"2170:10:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2159:6:12"},"nodeType":"YulFunctionCall","src":"2159:22:12"},"nodeType":"YulExpressionStatement","src":"2159:22:12"}]},"name":"allocate_memory","nodeType":"YulFunctionDefinition","parameters":[{"name":"size","nodeType":"YulTypedName","src":"1937:4:12","type":""}],"returnVariables":[{"name":"memPtr","nodeType":"YulTypedName","src":"1946:6:12","type":""}],"src":"1912:275:12"},{"body":{"nodeType":"YulBlock","src":"2244:478:12","statements":[{"body":{"nodeType":"YulBlock","src":"2293:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2302:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2305:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2295:6:12"},"nodeType":"YulFunctionCall","src":"2295:12:12"},"nodeType":"YulExpressionStatement","src":"2295:12:12"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2272:6:12"},{"kind":"number","nodeType":"YulLiteral","src":"2280:4:12","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2268:3:12"},"nodeType":"YulFunctionCall","src":"2268:17:12"},{"name":"end","nodeType":"YulIdentifier","src":"2287:3:12"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"2264:3:12"},"nodeType":"YulFunctionCall","src":"2264:27:12"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"2257:6:12"},"nodeType":"YulFunctionCall","src":"2257:35:12"},"nodeType":"YulIf","src":"2254:55:12"},{"nodeType":"YulVariableDeclaration","src":"2318:30:12","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2341:6:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2328:12:12"},"nodeType":"YulFunctionCall","src":"2328:20:12"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"2322:2:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"2387:22:12","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"2389:16:12"},"nodeType":"YulFunctionCall","src":"2389:18:12"},"nodeType":"YulExpressionStatement","src":"2389:18:12"}]},"condition":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"2363:2:12"},{"kind":"number","nodeType":"YulLiteral","src":"2367:18:12","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2360:2:12"},"nodeType":"YulFunctionCall","src":"2360:26:12"},"nodeType":"YulIf","src":"2357:52:12"},{"nodeType":"YulVariableDeclaration","src":"2418:70:12","value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"2461:2:12"},{"kind":"number","nodeType":"YulLiteral","src":"2465:4:12","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2457:3:12"},"nodeType":"YulFunctionCall","src":"2457:13:12"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2476:2:12","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"2472:3:12"},"nodeType":"YulFunctionCall","src":"2472:7:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"2453:3:12"},"nodeType":"YulFunctionCall","src":"2453:27:12"},{"kind":"number","nodeType":"YulLiteral","src":"2482:4:12","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2449:3:12"},"nodeType":"YulFunctionCall","src":"2449:38:12"}],"functionName":{"name":"allocate_memory","nodeType":"YulIdentifier","src":"2433:15:12"},"nodeType":"YulFunctionCall","src":"2433:55:12"},"variables":[{"name":"array_1","nodeType":"YulTypedName","src":"2422:7:12","type":""}]},{"expression":{"arguments":[{"name":"array_1","nodeType":"YulIdentifier","src":"2504:7:12"},{"name":"_1","nodeType":"YulIdentifier","src":"2513:2:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2497:6:12"},"nodeType":"YulFunctionCall","src":"2497:19:12"},"nodeType":"YulExpressionStatement","src":"2497:19:12"},{"body":{"nodeType":"YulBlock","src":"2564:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2573:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2576:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2566:6:12"},"nodeType":"YulFunctionCall","src":"2566:12:12"},"nodeType":"YulExpressionStatement","src":"2566:12:12"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2539:6:12"},{"name":"_1","nodeType":"YulIdentifier","src":"2547:2:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2535:3:12"},"nodeType":"YulFunctionCall","src":"2535:15:12"},{"kind":"number","nodeType":"YulLiteral","src":"2552:4:12","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2531:3:12"},"nodeType":"YulFunctionCall","src":"2531:26:12"},{"name":"end","nodeType":"YulIdentifier","src":"2559:3:12"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2528:2:12"},"nodeType":"YulFunctionCall","src":"2528:35:12"},"nodeType":"YulIf","src":"2525:55:12"},{"expression":{"arguments":[{"arguments":[{"name":"array_1","nodeType":"YulIdentifier","src":"2606:7:12"},{"kind":"number","nodeType":"YulLiteral","src":"2615:4:12","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2602:3:12"},"nodeType":"YulFunctionCall","src":"2602:18:12"},{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2626:6:12"},{"kind":"number","nodeType":"YulLiteral","src":"2634:4:12","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2622:3:12"},"nodeType":"YulFunctionCall","src":"2622:17:12"},{"name":"_1","nodeType":"YulIdentifier","src":"2641:2:12"}],"functionName":{"name":"calldatacopy","nodeType":"YulIdentifier","src":"2589:12:12"},"nodeType":"YulFunctionCall","src":"2589:55:12"},"nodeType":"YulExpressionStatement","src":"2589:55:12"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"array_1","nodeType":"YulIdentifier","src":"2668:7:12"},{"name":"_1","nodeType":"YulIdentifier","src":"2677:2:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2664:3:12"},"nodeType":"YulFunctionCall","src":"2664:16:12"},{"kind":"number","nodeType":"YulLiteral","src":"2682:4:12","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2660:3:12"},"nodeType":"YulFunctionCall","src":"2660:27:12"},{"kind":"number","nodeType":"YulLiteral","src":"2689:1:12","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2653:6:12"},"nodeType":"YulFunctionCall","src":"2653:38:12"},"nodeType":"YulExpressionStatement","src":"2653:38:12"},{"nodeType":"YulAssignment","src":"2700:16:12","value":{"name":"array_1","nodeType":"YulIdentifier","src":"2709:7:12"},"variableNames":[{"name":"array","nodeType":"YulIdentifier","src":"2700:5:12"}]}]},"name":"abi_decode_bytes","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"2218:6:12","type":""},{"name":"end","nodeType":"YulTypedName","src":"2226:3:12","type":""}],"returnVariables":[{"name":"array","nodeType":"YulTypedName","src":"2234:5:12","type":""}],"src":"2192:530:12"},{"body":{"nodeType":"YulBlock","src":"2857:535:12","statements":[{"body":{"nodeType":"YulBlock","src":"2904:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2913:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2916:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2906:6:12"},"nodeType":"YulFunctionCall","src":"2906:12:12"},"nodeType":"YulExpressionStatement","src":"2906:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"2878:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"2887:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"2874:3:12"},"nodeType":"YulFunctionCall","src":"2874:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"2899:3:12","type":"","value":"128"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"2870:3:12"},"nodeType":"YulFunctionCall","src":"2870:33:12"},"nodeType":"YulIf","src":"2867:53:12"},{"nodeType":"YulVariableDeclaration","src":"2929:36:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2955:9:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2942:12:12"},"nodeType":"YulFunctionCall","src":"2942:23:12"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"2933:5:12","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"2999:5:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"2974:24:12"},"nodeType":"YulFunctionCall","src":"2974:31:12"},"nodeType":"YulExpressionStatement","src":"2974:31:12"},{"nodeType":"YulAssignment","src":"3014:15:12","value":{"name":"value","nodeType":"YulIdentifier","src":"3024:5:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"3014:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"3038:47:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3070:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"3081:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3066:3:12"},"nodeType":"YulFunctionCall","src":"3066:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3053:12:12"},"nodeType":"YulFunctionCall","src":"3053:32:12"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"3042:7:12","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"3119:7:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"3094:24:12"},"nodeType":"YulFunctionCall","src":"3094:33:12"},"nodeType":"YulExpressionStatement","src":"3094:33:12"},{"nodeType":"YulAssignment","src":"3136:17:12","value":{"name":"value_1","nodeType":"YulIdentifier","src":"3146:7:12"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"3136:6:12"}]},{"nodeType":"YulAssignment","src":"3162:42:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3189:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"3200:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3185:3:12"},"nodeType":"YulFunctionCall","src":"3185:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3172:12:12"},"nodeType":"YulFunctionCall","src":"3172:32:12"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"3162:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"3213:46:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3244:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"3255:2:12","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3240:3:12"},"nodeType":"YulFunctionCall","src":"3240:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3227:12:12"},"nodeType":"YulFunctionCall","src":"3227:32:12"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"3217:6:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"3302:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3311:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3314:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3304:6:12"},"nodeType":"YulFunctionCall","src":"3304:12:12"},"nodeType":"YulExpressionStatement","src":"3304:12:12"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"3274:6:12"},{"kind":"number","nodeType":"YulLiteral","src":"3282:18:12","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"3271:2:12"},"nodeType":"YulFunctionCall","src":"3271:30:12"},"nodeType":"YulIf","src":"3268:50:12"},{"nodeType":"YulAssignment","src":"3327:59:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3358:9:12"},{"name":"offset","nodeType":"YulIdentifier","src":"3369:6:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3354:3:12"},"nodeType":"YulFunctionCall","src":"3354:22:12"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"3378:7:12"}],"functionName":{"name":"abi_decode_bytes","nodeType":"YulIdentifier","src":"3337:16:12"},"nodeType":"YulFunctionCall","src":"3337:49:12"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"3327:6:12"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"2799:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"2810:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"2822:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"2830:6:12","type":""},{"name":"value2","nodeType":"YulTypedName","src":"2838:6:12","type":""},{"name":"value3","nodeType":"YulTypedName","src":"2846:6:12","type":""}],"src":"2727:665:12"},{"body":{"nodeType":"YulBlock","src":"3496:103:12","statements":[{"nodeType":"YulAssignment","src":"3506:26:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3518:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"3529:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3514:3:12"},"nodeType":"YulFunctionCall","src":"3514:18:12"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"3506:4:12"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3548:9:12"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"3563:6:12"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3575:3:12","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"3580:10:12","type":"","value":"0xffffffff"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"3571:3:12"},"nodeType":"YulFunctionCall","src":"3571:20:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"3559:3:12"},"nodeType":"YulFunctionCall","src":"3559:33:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"3541:6:12"},"nodeType":"YulFunctionCall","src":"3541:52:12"},"nodeType":"YulExpressionStatement","src":"3541:52:12"}]},"name":"abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"3465:9:12","type":""},{"name":"value0","nodeType":"YulTypedName","src":"3476:6:12","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"3487:4:12","type":""}],"src":"3397:202:12"},{"body":{"nodeType":"YulBlock","src":"3691:301:12","statements":[{"body":{"nodeType":"YulBlock","src":"3737:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3746:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3749:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3739:6:12"},"nodeType":"YulFunctionCall","src":"3739:12:12"},"nodeType":"YulExpressionStatement","src":"3739:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"3712:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"3721:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"3708:3:12"},"nodeType":"YulFunctionCall","src":"3708:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"3733:2:12","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"3704:3:12"},"nodeType":"YulFunctionCall","src":"3704:32:12"},"nodeType":"YulIf","src":"3701:52:12"},{"nodeType":"YulVariableDeclaration","src":"3762:36:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3788:9:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3775:12:12"},"nodeType":"YulFunctionCall","src":"3775:23:12"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"3766:5:12","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"3832:5:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"3807:24:12"},"nodeType":"YulFunctionCall","src":"3807:31:12"},"nodeType":"YulExpressionStatement","src":"3807:31:12"},{"nodeType":"YulAssignment","src":"3847:15:12","value":{"name":"value","nodeType":"YulIdentifier","src":"3857:5:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"3847:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"3871:47:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3903:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"3914:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3899:3:12"},"nodeType":"YulFunctionCall","src":"3899:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3886:12:12"},"nodeType":"YulFunctionCall","src":"3886:32:12"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"3875:7:12","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"3952:7:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"3927:24:12"},"nodeType":"YulFunctionCall","src":"3927:33:12"},"nodeType":"YulExpressionStatement","src":"3927:33:12"},{"nodeType":"YulAssignment","src":"3969:17:12","value":{"name":"value_1","nodeType":"YulIdentifier","src":"3979:7:12"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"3969:6:12"}]}]},"name":"abi_decode_tuple_t_addresst_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"3649:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"3660:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"3672:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"3680:6:12","type":""}],"src":"3604:388:12"},{"body":{"nodeType":"YulBlock","src":"4098:102:12","statements":[{"nodeType":"YulAssignment","src":"4108:26:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4120:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"4131:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4116:3:12"},"nodeType":"YulFunctionCall","src":"4116:18:12"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"4108:4:12"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4150:9:12"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"4165:6:12"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4181:3:12","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"4186:1:12","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"4177:3:12"},"nodeType":"YulFunctionCall","src":"4177:11:12"},{"kind":"number","nodeType":"YulLiteral","src":"4190:1:12","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"4173:3:12"},"nodeType":"YulFunctionCall","src":"4173:19:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"4161:3:12"},"nodeType":"YulFunctionCall","src":"4161:32:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"4143:6:12"},"nodeType":"YulFunctionCall","src":"4143:51:12"},"nodeType":"YulExpressionStatement","src":"4143:51:12"}]},"name":"abi_encode_tuple_t_address__to_t_address__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"4067:9:12","type":""},{"name":"value0","nodeType":"YulTypedName","src":"4078:6:12","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"4089:4:12","type":""}],"src":"3997:203:12"},{"body":{"nodeType":"YulBlock","src":"4328:671:12","statements":[{"body":{"nodeType":"YulBlock","src":"4374:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4383:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4386:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4376:6:12"},"nodeType":"YulFunctionCall","src":"4376:12:12"},"nodeType":"YulExpressionStatement","src":"4376:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"4349:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"4358:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"4345:3:12"},"nodeType":"YulFunctionCall","src":"4345:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"4370:2:12","type":"","value":"96"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"4341:3:12"},"nodeType":"YulFunctionCall","src":"4341:32:12"},"nodeType":"YulIf","src":"4338:52:12"},{"nodeType":"YulVariableDeclaration","src":"4399:36:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4425:9:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4412:12:12"},"nodeType":"YulFunctionCall","src":"4412:23:12"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"4403:5:12","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"4469:5:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"4444:24:12"},"nodeType":"YulFunctionCall","src":"4444:31:12"},"nodeType":"YulExpressionStatement","src":"4444:31:12"},{"nodeType":"YulAssignment","src":"4484:15:12","value":{"name":"value","nodeType":"YulIdentifier","src":"4494:5:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"4484:6:12"}]},{"nodeType":"YulAssignment","src":"4508:42:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4535:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"4546:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4531:3:12"},"nodeType":"YulFunctionCall","src":"4531:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4518:12:12"},"nodeType":"YulFunctionCall","src":"4518:32:12"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"4508:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"4559:46:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4590:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"4601:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4586:3:12"},"nodeType":"YulFunctionCall","src":"4586:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4573:12:12"},"nodeType":"YulFunctionCall","src":"4573:32:12"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"4563:6:12","type":""}]},{"nodeType":"YulVariableDeclaration","src":"4614:28:12","value":{"kind":"number","nodeType":"YulLiteral","src":"4624:18:12","type":"","value":"0xffffffffffffffff"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"4618:2:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"4669:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4678:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4681:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4671:6:12"},"nodeType":"YulFunctionCall","src":"4671:12:12"},"nodeType":"YulExpressionStatement","src":"4671:12:12"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"4657:6:12"},{"name":"_1","nodeType":"YulIdentifier","src":"4665:2:12"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"4654:2:12"},"nodeType":"YulFunctionCall","src":"4654:14:12"},"nodeType":"YulIf","src":"4651:34:12"},{"nodeType":"YulVariableDeclaration","src":"4694:32:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4708:9:12"},{"name":"offset","nodeType":"YulIdentifier","src":"4719:6:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4704:3:12"},"nodeType":"YulFunctionCall","src":"4704:22:12"},"variables":[{"name":"_2","nodeType":"YulTypedName","src":"4698:2:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"4774:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4783:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4786:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4776:6:12"},"nodeType":"YulFunctionCall","src":"4776:12:12"},"nodeType":"YulExpressionStatement","src":"4776:12:12"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"4753:2:12"},{"kind":"number","nodeType":"YulLiteral","src":"4757:4:12","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4749:3:12"},"nodeType":"YulFunctionCall","src":"4749:13:12"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"4764:7:12"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"4745:3:12"},"nodeType":"YulFunctionCall","src":"4745:27:12"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"4738:6:12"},"nodeType":"YulFunctionCall","src":"4738:35:12"},"nodeType":"YulIf","src":"4735:55:12"},{"nodeType":"YulVariableDeclaration","src":"4799:30:12","value":{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"4826:2:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4813:12:12"},"nodeType":"YulFunctionCall","src":"4813:16:12"},"variables":[{"name":"length","nodeType":"YulTypedName","src":"4803:6:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"4856:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4865:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4868:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4858:6:12"},"nodeType":"YulFunctionCall","src":"4858:12:12"},"nodeType":"YulExpressionStatement","src":"4858:12:12"}]},"condition":{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"4844:6:12"},{"name":"_1","nodeType":"YulIdentifier","src":"4852:2:12"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"4841:2:12"},"nodeType":"YulFunctionCall","src":"4841:14:12"},"nodeType":"YulIf","src":"4838:34:12"},{"body":{"nodeType":"YulBlock","src":"4922:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4931:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4934:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4924:6:12"},"nodeType":"YulFunctionCall","src":"4924:12:12"},"nodeType":"YulExpressionStatement","src":"4924:12:12"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"4895:2:12"},{"name":"length","nodeType":"YulIdentifier","src":"4899:6:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4891:3:12"},"nodeType":"YulFunctionCall","src":"4891:15:12"},{"kind":"number","nodeType":"YulLiteral","src":"4908:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4887:3:12"},"nodeType":"YulFunctionCall","src":"4887:24:12"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"4913:7:12"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"4884:2:12"},"nodeType":"YulFunctionCall","src":"4884:37:12"},"nodeType":"YulIf","src":"4881:57:12"},{"nodeType":"YulAssignment","src":"4947:21:12","value":{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"4961:2:12"},{"kind":"number","nodeType":"YulLiteral","src":"4965:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4957:3:12"},"nodeType":"YulFunctionCall","src":"4957:11:12"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"4947:6:12"}]},{"nodeType":"YulAssignment","src":"4977:16:12","value":{"name":"length","nodeType":"YulIdentifier","src":"4987:6:12"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"4977:6:12"}]}]},"name":"abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"4270:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"4281:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"4293:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"4301:6:12","type":""},{"name":"value2","nodeType":"YulTypedName","src":"4309:6:12","type":""},{"name":"value3","nodeType":"YulTypedName","src":"4317:6:12","type":""}],"src":"4205:794:12"},{"body":{"nodeType":"YulBlock","src":"5123:427:12","statements":[{"nodeType":"YulVariableDeclaration","src":"5133:12:12","value":{"kind":"number","nodeType":"YulLiteral","src":"5143:2:12","type":"","value":"32"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"5137:2:12","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5161:9:12"},{"name":"_1","nodeType":"YulIdentifier","src":"5172:2:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5154:6:12"},"nodeType":"YulFunctionCall","src":"5154:21:12"},"nodeType":"YulExpressionStatement","src":"5154:21:12"},{"nodeType":"YulVariableDeclaration","src":"5184:27:12","value":{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"5204:6:12"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"5198:5:12"},"nodeType":"YulFunctionCall","src":"5198:13:12"},"variables":[{"name":"length","nodeType":"YulTypedName","src":"5188:6:12","type":""}]},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5231:9:12"},{"name":"_1","nodeType":"YulIdentifier","src":"5242:2:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5227:3:12"},"nodeType":"YulFunctionCall","src":"5227:18:12"},{"name":"length","nodeType":"YulIdentifier","src":"5247:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5220:6:12"},"nodeType":"YulFunctionCall","src":"5220:34:12"},"nodeType":"YulExpressionStatement","src":"5220:34:12"},{"nodeType":"YulVariableDeclaration","src":"5263:10:12","value":{"kind":"number","nodeType":"YulLiteral","src":"5272:1:12","type":"","value":"0"},"variables":[{"name":"i","nodeType":"YulTypedName","src":"5267:1:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"5332:90:12","statements":[{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5361:9:12"},{"name":"i","nodeType":"YulIdentifier","src":"5372:1:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5357:3:12"},"nodeType":"YulFunctionCall","src":"5357:17:12"},{"kind":"number","nodeType":"YulLiteral","src":"5376:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5353:3:12"},"nodeType":"YulFunctionCall","src":"5353:26:12"},{"arguments":[{"arguments":[{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"5395:6:12"},{"name":"i","nodeType":"YulIdentifier","src":"5403:1:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5391:3:12"},"nodeType":"YulFunctionCall","src":"5391:14:12"},{"name":"_1","nodeType":"YulIdentifier","src":"5407:2:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5387:3:12"},"nodeType":"YulFunctionCall","src":"5387:23:12"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"5381:5:12"},"nodeType":"YulFunctionCall","src":"5381:30:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5346:6:12"},"nodeType":"YulFunctionCall","src":"5346:66:12"},"nodeType":"YulExpressionStatement","src":"5346:66:12"}]},"condition":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"5293:1:12"},{"name":"length","nodeType":"YulIdentifier","src":"5296:6:12"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"5290:2:12"},"nodeType":"YulFunctionCall","src":"5290:13:12"},"nodeType":"YulForLoop","post":{"nodeType":"YulBlock","src":"5304:19:12","statements":[{"nodeType":"YulAssignment","src":"5306:15:12","value":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"5315:1:12"},{"name":"_1","nodeType":"YulIdentifier","src":"5318:2:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5311:3:12"},"nodeType":"YulFunctionCall","src":"5311:10:12"},"variableNames":[{"name":"i","nodeType":"YulIdentifier","src":"5306:1:12"}]}]},"pre":{"nodeType":"YulBlock","src":"5286:3:12","statements":[]},"src":"5282:140:12"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5446:9:12"},{"name":"length","nodeType":"YulIdentifier","src":"5457:6:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5442:3:12"},"nodeType":"YulFunctionCall","src":"5442:22:12"},{"kind":"number","nodeType":"YulLiteral","src":"5466:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5438:3:12"},"nodeType":"YulFunctionCall","src":"5438:31:12"},{"kind":"number","nodeType":"YulLiteral","src":"5471:1:12","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5431:6:12"},"nodeType":"YulFunctionCall","src":"5431:42:12"},"nodeType":"YulExpressionStatement","src":"5431:42:12"},{"nodeType":"YulAssignment","src":"5482:62:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5498:9:12"},{"arguments":[{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"5517:6:12"},{"kind":"number","nodeType":"YulLiteral","src":"5525:2:12","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5513:3:12"},"nodeType":"YulFunctionCall","src":"5513:15:12"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5534:2:12","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"5530:3:12"},"nodeType":"YulFunctionCall","src":"5530:7:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"5509:3:12"},"nodeType":"YulFunctionCall","src":"5509:29:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5494:3:12"},"nodeType":"YulFunctionCall","src":"5494:45:12"},{"kind":"number","nodeType":"YulLiteral","src":"5541:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5490:3:12"},"nodeType":"YulFunctionCall","src":"5490:54:12"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"5482:4:12"}]}]},"name":"abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"5092:9:12","type":""},{"name":"value0","nodeType":"YulTypedName","src":"5103:6:12","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"5114:4:12","type":""}],"src":"5004:546:12"},{"body":{"nodeType":"YulBlock","src":"5619:648:12","statements":[{"body":{"nodeType":"YulBlock","src":"5668:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5677:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"5680:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"5670:6:12"},"nodeType":"YulFunctionCall","src":"5670:12:12"},"nodeType":"YulExpressionStatement","src":"5670:12:12"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"5647:6:12"},{"kind":"number","nodeType":"YulLiteral","src":"5655:4:12","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5643:3:12"},"nodeType":"YulFunctionCall","src":"5643:17:12"},{"name":"end","nodeType":"YulIdentifier","src":"5662:3:12"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"5639:3:12"},"nodeType":"YulFunctionCall","src":"5639:27:12"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"5632:6:12"},"nodeType":"YulFunctionCall","src":"5632:35:12"},"nodeType":"YulIf","src":"5629:55:12"},{"nodeType":"YulVariableDeclaration","src":"5693:30:12","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"5716:6:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5703:12:12"},"nodeType":"YulFunctionCall","src":"5703:20:12"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"5697:2:12","type":""}]},{"nodeType":"YulVariableDeclaration","src":"5732:14:12","value":{"kind":"number","nodeType":"YulLiteral","src":"5742:4:12","type":"","value":"0x20"},"variables":[{"name":"_2","nodeType":"YulTypedName","src":"5736:2:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"5785:22:12","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"5787:16:12"},"nodeType":"YulFunctionCall","src":"5787:18:12"},"nodeType":"YulExpressionStatement","src":"5787:18:12"}]},"condition":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"5761:2:12"},{"kind":"number","nodeType":"YulLiteral","src":"5765:18:12","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"5758:2:12"},"nodeType":"YulFunctionCall","src":"5758:26:12"},"nodeType":"YulIf","src":"5755:52:12"},{"nodeType":"YulVariableDeclaration","src":"5816:20:12","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5830:1:12","type":"","value":"5"},{"name":"_1","nodeType":"YulIdentifier","src":"5833:2:12"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"5826:3:12"},"nodeType":"YulFunctionCall","src":"5826:10:12"},"variables":[{"name":"_3","nodeType":"YulTypedName","src":"5820:2:12","type":""}]},{"nodeType":"YulVariableDeclaration","src":"5845:39:12","value":{"arguments":[{"arguments":[{"name":"_3","nodeType":"YulIdentifier","src":"5876:2:12"},{"name":"_2","nodeType":"YulIdentifier","src":"5880:2:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5872:3:12"},"nodeType":"YulFunctionCall","src":"5872:11:12"}],"functionName":{"name":"allocate_memory","nodeType":"YulIdentifier","src":"5856:15:12"},"nodeType":"YulFunctionCall","src":"5856:28:12"},"variables":[{"name":"dst","nodeType":"YulTypedName","src":"5849:3:12","type":""}]},{"nodeType":"YulVariableDeclaration","src":"5893:16:12","value":{"name":"dst","nodeType":"YulIdentifier","src":"5906:3:12"},"variables":[{"name":"dst_1","nodeType":"YulTypedName","src":"5897:5:12","type":""}]},{"expression":{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"5925:3:12"},{"name":"_1","nodeType":"YulIdentifier","src":"5930:2:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5918:6:12"},"nodeType":"YulFunctionCall","src":"5918:15:12"},"nodeType":"YulExpressionStatement","src":"5918:15:12"},{"nodeType":"YulAssignment","src":"5942:19:12","value":{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"5953:3:12"},{"name":"_2","nodeType":"YulIdentifier","src":"5958:2:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5949:3:12"},"nodeType":"YulFunctionCall","src":"5949:12:12"},"variableNames":[{"name":"dst","nodeType":"YulIdentifier","src":"5942:3:12"}]},{"nodeType":"YulVariableDeclaration","src":"5970:38:12","value":{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"5992:6:12"},{"name":"_3","nodeType":"YulIdentifier","src":"6000:2:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5988:3:12"},"nodeType":"YulFunctionCall","src":"5988:15:12"},{"name":"_2","nodeType":"YulIdentifier","src":"6005:2:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5984:3:12"},"nodeType":"YulFunctionCall","src":"5984:24:12"},"variables":[{"name":"srcEnd","nodeType":"YulTypedName","src":"5974:6:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"6036:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6045:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"6048:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"6038:6:12"},"nodeType":"YulFunctionCall","src":"6038:12:12"},"nodeType":"YulExpressionStatement","src":"6038:12:12"}]},"condition":{"arguments":[{"name":"srcEnd","nodeType":"YulIdentifier","src":"6023:6:12"},{"name":"end","nodeType":"YulIdentifier","src":"6031:3:12"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"6020:2:12"},"nodeType":"YulFunctionCall","src":"6020:15:12"},"nodeType":"YulIf","src":"6017:35:12"},{"nodeType":"YulVariableDeclaration","src":"6061:26:12","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"6076:6:12"},{"name":"_2","nodeType":"YulIdentifier","src":"6084:2:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6072:3:12"},"nodeType":"YulFunctionCall","src":"6072:15:12"},"variables":[{"name":"src","nodeType":"YulTypedName","src":"6065:3:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"6152:86:12","statements":[{"expression":{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"6173:3:12"},{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"6191:3:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6178:12:12"},"nodeType":"YulFunctionCall","src":"6178:17:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6166:6:12"},"nodeType":"YulFunctionCall","src":"6166:30:12"},"nodeType":"YulExpressionStatement","src":"6166:30:12"},{"nodeType":"YulAssignment","src":"6209:19:12","value":{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"6220:3:12"},{"name":"_2","nodeType":"YulIdentifier","src":"6225:2:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6216:3:12"},"nodeType":"YulFunctionCall","src":"6216:12:12"},"variableNames":[{"name":"dst","nodeType":"YulIdentifier","src":"6209:3:12"}]}]},"condition":{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"6107:3:12"},{"name":"srcEnd","nodeType":"YulIdentifier","src":"6112:6:12"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"6104:2:12"},"nodeType":"YulFunctionCall","src":"6104:15:12"},"nodeType":"YulForLoop","post":{"nodeType":"YulBlock","src":"6120:23:12","statements":[{"nodeType":"YulAssignment","src":"6122:19:12","value":{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"6133:3:12"},{"name":"_2","nodeType":"YulIdentifier","src":"6138:2:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6129:3:12"},"nodeType":"YulFunctionCall","src":"6129:12:12"},"variableNames":[{"name":"src","nodeType":"YulIdentifier","src":"6122:3:12"}]}]},"pre":{"nodeType":"YulBlock","src":"6100:3:12","statements":[]},"src":"6096:142:12"},{"nodeType":"YulAssignment","src":"6247:14:12","value":{"name":"dst_1","nodeType":"YulIdentifier","src":"6256:5:12"},"variableNames":[{"name":"array","nodeType":"YulIdentifier","src":"6247:5:12"}]}]},"name":"abi_decode_array_uint256_dyn","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"5593:6:12","type":""},{"name":"end","nodeType":"YulTypedName","src":"5601:3:12","type":""}],"returnVariables":[{"name":"array","nodeType":"YulTypedName","src":"5609:5:12","type":""}],"src":"5555:712:12"},{"body":{"nodeType":"YulBlock","src":"6469:874:12","statements":[{"body":{"nodeType":"YulBlock","src":"6516:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6525:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"6528:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"6518:6:12"},"nodeType":"YulFunctionCall","src":"6518:12:12"},"nodeType":"YulExpressionStatement","src":"6518:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"6490:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"6499:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"6486:3:12"},"nodeType":"YulFunctionCall","src":"6486:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"6511:3:12","type":"","value":"160"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"6482:3:12"},"nodeType":"YulFunctionCall","src":"6482:33:12"},"nodeType":"YulIf","src":"6479:53:12"},{"nodeType":"YulVariableDeclaration","src":"6541:36:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6567:9:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6554:12:12"},"nodeType":"YulFunctionCall","src":"6554:23:12"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"6545:5:12","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"6611:5:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"6586:24:12"},"nodeType":"YulFunctionCall","src":"6586:31:12"},"nodeType":"YulExpressionStatement","src":"6586:31:12"},{"nodeType":"YulAssignment","src":"6626:15:12","value":{"name":"value","nodeType":"YulIdentifier","src":"6636:5:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"6626:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"6650:47:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6682:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"6693:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6678:3:12"},"nodeType":"YulFunctionCall","src":"6678:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6665:12:12"},"nodeType":"YulFunctionCall","src":"6665:32:12"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"6654:7:12","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"6731:7:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"6706:24:12"},"nodeType":"YulFunctionCall","src":"6706:33:12"},"nodeType":"YulExpressionStatement","src":"6706:33:12"},{"nodeType":"YulAssignment","src":"6748:17:12","value":{"name":"value_1","nodeType":"YulIdentifier","src":"6758:7:12"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"6748:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"6774:46:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6805:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"6816:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6801:3:12"},"nodeType":"YulFunctionCall","src":"6801:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6788:12:12"},"nodeType":"YulFunctionCall","src":"6788:32:12"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"6778:6:12","type":""}]},{"nodeType":"YulVariableDeclaration","src":"6829:28:12","value":{"kind":"number","nodeType":"YulLiteral","src":"6839:18:12","type":"","value":"0xffffffffffffffff"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"6833:2:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"6884:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6893:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"6896:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"6886:6:12"},"nodeType":"YulFunctionCall","src":"6886:12:12"},"nodeType":"YulExpressionStatement","src":"6886:12:12"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"6872:6:12"},{"name":"_1","nodeType":"YulIdentifier","src":"6880:2:12"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"6869:2:12"},"nodeType":"YulFunctionCall","src":"6869:14:12"},"nodeType":"YulIf","src":"6866:34:12"},{"nodeType":"YulAssignment","src":"6909:71:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6952:9:12"},{"name":"offset","nodeType":"YulIdentifier","src":"6963:6:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6948:3:12"},"nodeType":"YulFunctionCall","src":"6948:22:12"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"6972:7:12"}],"functionName":{"name":"abi_decode_array_uint256_dyn","nodeType":"YulIdentifier","src":"6919:28:12"},"nodeType":"YulFunctionCall","src":"6919:61:12"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"6909:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"6989:48:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7022:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"7033:2:12","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7018:3:12"},"nodeType":"YulFunctionCall","src":"7018:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7005:12:12"},"nodeType":"YulFunctionCall","src":"7005:32:12"},"variables":[{"name":"offset_1","nodeType":"YulTypedName","src":"6993:8:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"7066:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7075:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"7078:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7068:6:12"},"nodeType":"YulFunctionCall","src":"7068:12:12"},"nodeType":"YulExpressionStatement","src":"7068:12:12"}]},"condition":{"arguments":[{"name":"offset_1","nodeType":"YulIdentifier","src":"7052:8:12"},{"name":"_1","nodeType":"YulIdentifier","src":"7062:2:12"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"7049:2:12"},"nodeType":"YulFunctionCall","src":"7049:16:12"},"nodeType":"YulIf","src":"7046:36:12"},{"nodeType":"YulAssignment","src":"7091:73:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7134:9:12"},{"name":"offset_1","nodeType":"YulIdentifier","src":"7145:8:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7130:3:12"},"nodeType":"YulFunctionCall","src":"7130:24:12"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"7156:7:12"}],"functionName":{"name":"abi_decode_array_uint256_dyn","nodeType":"YulIdentifier","src":"7101:28:12"},"nodeType":"YulFunctionCall","src":"7101:63:12"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"7091:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"7173:49:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7206:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"7217:3:12","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7202:3:12"},"nodeType":"YulFunctionCall","src":"7202:19:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7189:12:12"},"nodeType":"YulFunctionCall","src":"7189:33:12"},"variables":[{"name":"offset_2","nodeType":"YulTypedName","src":"7177:8:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"7251:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7260:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"7263:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7253:6:12"},"nodeType":"YulFunctionCall","src":"7253:12:12"},"nodeType":"YulExpressionStatement","src":"7253:12:12"}]},"condition":{"arguments":[{"name":"offset_2","nodeType":"YulIdentifier","src":"7237:8:12"},{"name":"_1","nodeType":"YulIdentifier","src":"7247:2:12"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"7234:2:12"},"nodeType":"YulFunctionCall","src":"7234:16:12"},"nodeType":"YulIf","src":"7231:36:12"},{"nodeType":"YulAssignment","src":"7276:61:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7307:9:12"},{"name":"offset_2","nodeType":"YulIdentifier","src":"7318:8:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7303:3:12"},"nodeType":"YulFunctionCall","src":"7303:24:12"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"7329:7:12"}],"functionName":{"name":"abi_decode_bytes","nodeType":"YulIdentifier","src":"7286:16:12"},"nodeType":"YulFunctionCall","src":"7286:51:12"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"7276:6:12"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_array$_t_uint256_$dyn_memory_ptrt_array$_t_uint256_$dyn_memory_ptrt_bytes_memory_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"6403:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"6414:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"6426:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"6434:6:12","type":""},{"name":"value2","nodeType":"YulTypedName","src":"6442:6:12","type":""},{"name":"value3","nodeType":"YulTypedName","src":"6450:6:12","type":""},{"name":"value4","nodeType":"YulTypedName","src":"6458:6:12","type":""}],"src":"6272:1071:12"},{"body":{"nodeType":"YulBlock","src":"7449:76:12","statements":[{"nodeType":"YulAssignment","src":"7459:26:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7471:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"7482:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7467:3:12"},"nodeType":"YulFunctionCall","src":"7467:18:12"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"7459:4:12"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7501:9:12"},{"name":"value0","nodeType":"YulIdentifier","src":"7512:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7494:6:12"},"nodeType":"YulFunctionCall","src":"7494:25:12"},"nodeType":"YulExpressionStatement","src":"7494:25:12"}]},"name":"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"7418:9:12","type":""},{"name":"value0","nodeType":"YulTypedName","src":"7429:6:12","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"7440:4:12","type":""}],"src":"7348:177:12"},{"body":{"nodeType":"YulBlock","src":"7600:110:12","statements":[{"body":{"nodeType":"YulBlock","src":"7646:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7655:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"7658:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7648:6:12"},"nodeType":"YulFunctionCall","src":"7648:12:12"},"nodeType":"YulExpressionStatement","src":"7648:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"7621:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"7630:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"7617:3:12"},"nodeType":"YulFunctionCall","src":"7617:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"7642:2:12","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"7613:3:12"},"nodeType":"YulFunctionCall","src":"7613:32:12"},"nodeType":"YulIf","src":"7610:52:12"},{"nodeType":"YulAssignment","src":"7671:33:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7694:9:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7681:12:12"},"nodeType":"YulFunctionCall","src":"7681:23:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"7671:6:12"}]}]},"name":"abi_decode_tuple_t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"7566:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"7577:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"7589:6:12","type":""}],"src":"7530:180:12"},{"body":{"nodeType":"YulBlock","src":"7862:587:12","statements":[{"body":{"nodeType":"YulBlock","src":"7909:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7918:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"7921:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7911:6:12"},"nodeType":"YulFunctionCall","src":"7911:12:12"},"nodeType":"YulExpressionStatement","src":"7911:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"7883:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"7892:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"7879:3:12"},"nodeType":"YulFunctionCall","src":"7879:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"7904:3:12","type":"","value":"160"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"7875:3:12"},"nodeType":"YulFunctionCall","src":"7875:33:12"},"nodeType":"YulIf","src":"7872:53:12"},{"nodeType":"YulVariableDeclaration","src":"7934:36:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7960:9:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7947:12:12"},"nodeType":"YulFunctionCall","src":"7947:23:12"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"7938:5:12","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"8004:5:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"7979:24:12"},"nodeType":"YulFunctionCall","src":"7979:31:12"},"nodeType":"YulExpressionStatement","src":"7979:31:12"},{"nodeType":"YulAssignment","src":"8019:15:12","value":{"name":"value","nodeType":"YulIdentifier","src":"8029:5:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"8019:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"8043:47:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8075:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"8086:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8071:3:12"},"nodeType":"YulFunctionCall","src":"8071:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8058:12:12"},"nodeType":"YulFunctionCall","src":"8058:32:12"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"8047:7:12","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"8124:7:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"8099:24:12"},"nodeType":"YulFunctionCall","src":"8099:33:12"},"nodeType":"YulExpressionStatement","src":"8099:33:12"},{"nodeType":"YulAssignment","src":"8141:17:12","value":{"name":"value_1","nodeType":"YulIdentifier","src":"8151:7:12"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"8141:6:12"}]},{"nodeType":"YulAssignment","src":"8167:42:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8194:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"8205:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8190:3:12"},"nodeType":"YulFunctionCall","src":"8190:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8177:12:12"},"nodeType":"YulFunctionCall","src":"8177:32:12"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"8167:6:12"}]},{"nodeType":"YulAssignment","src":"8218:42:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8245:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"8256:2:12","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8241:3:12"},"nodeType":"YulFunctionCall","src":"8241:18:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8228:12:12"},"nodeType":"YulFunctionCall","src":"8228:32:12"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"8218:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"8269:47:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8300:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"8311:3:12","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8296:3:12"},"nodeType":"YulFunctionCall","src":"8296:19:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8283:12:12"},"nodeType":"YulFunctionCall","src":"8283:33:12"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"8273:6:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"8359:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"8368:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"8371:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"8361:6:12"},"nodeType":"YulFunctionCall","src":"8361:12:12"},"nodeType":"YulExpressionStatement","src":"8361:12:12"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"8331:6:12"},{"kind":"number","nodeType":"YulLiteral","src":"8339:18:12","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"8328:2:12"},"nodeType":"YulFunctionCall","src":"8328:30:12"},"nodeType":"YulIf","src":"8325:50:12"},{"nodeType":"YulAssignment","src":"8384:59:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8415:9:12"},{"name":"offset","nodeType":"YulIdentifier","src":"8426:6:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8411:3:12"},"nodeType":"YulFunctionCall","src":"8411:22:12"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"8435:7:12"}],"functionName":{"name":"abi_decode_bytes","nodeType":"YulIdentifier","src":"8394:16:12"},"nodeType":"YulFunctionCall","src":"8394:49:12"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"8384:6:12"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256t_uint256t_bytes_memory_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"7796:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"7807:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"7819:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"7827:6:12","type":""},{"name":"value2","nodeType":"YulTypedName","src":"7835:6:12","type":""},{"name":"value3","nodeType":"YulTypedName","src":"7843:6:12","type":""},{"name":"value4","nodeType":"YulTypedName","src":"7851:6:12","type":""}],"src":"7715:734:12"},{"body":{"nodeType":"YulBlock","src":"8611:188:12","statements":[{"nodeType":"YulAssignment","src":"8621:26:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8633:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"8644:2:12","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8629:3:12"},"nodeType":"YulFunctionCall","src":"8629:18:12"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"8621:4:12"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8663:9:12"},{"name":"value0","nodeType":"YulIdentifier","src":"8674:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8656:6:12"},"nodeType":"YulFunctionCall","src":"8656:25:12"},"nodeType":"YulExpressionStatement","src":"8656:25:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8701:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"8712:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8697:3:12"},"nodeType":"YulFunctionCall","src":"8697:18:12"},{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"8721:6:12"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"8737:3:12","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"8742:1:12","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"8733:3:12"},"nodeType":"YulFunctionCall","src":"8733:11:12"},{"kind":"number","nodeType":"YulLiteral","src":"8746:1:12","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"8729:3:12"},"nodeType":"YulFunctionCall","src":"8729:19:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"8717:3:12"},"nodeType":"YulFunctionCall","src":"8717:32:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8690:6:12"},"nodeType":"YulFunctionCall","src":"8690:60:12"},"nodeType":"YulExpressionStatement","src":"8690:60:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8770:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"8781:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8766:3:12"},"nodeType":"YulFunctionCall","src":"8766:18:12"},{"name":"value2","nodeType":"YulIdentifier","src":"8786:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8759:6:12"},"nodeType":"YulFunctionCall","src":"8759:34:12"},"nodeType":"YulExpressionStatement","src":"8759:34:12"}]},"name":"abi_encode_tuple_t_uint256_t_address_t_uint256__to_t_uint256_t_address_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"8564:9:12","type":""},{"name":"value2","nodeType":"YulTypedName","src":"8575:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"8583:6:12","type":""},{"name":"value0","nodeType":"YulTypedName","src":"8591:6:12","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"8602:4:12","type":""}],"src":"8454:345:12"},{"body":{"nodeType":"YulBlock","src":"8874:177:12","statements":[{"body":{"nodeType":"YulBlock","src":"8920:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"8929:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"8932:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"8922:6:12"},"nodeType":"YulFunctionCall","src":"8922:12:12"},"nodeType":"YulExpressionStatement","src":"8922:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"8895:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"8904:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"8891:3:12"},"nodeType":"YulFunctionCall","src":"8891:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"8916:2:12","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"8887:3:12"},"nodeType":"YulFunctionCall","src":"8887:32:12"},"nodeType":"YulIf","src":"8884:52:12"},{"nodeType":"YulVariableDeclaration","src":"8945:36:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8971:9:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8958:12:12"},"nodeType":"YulFunctionCall","src":"8958:23:12"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"8949:5:12","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"9015:5:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"8990:24:12"},"nodeType":"YulFunctionCall","src":"8990:31:12"},"nodeType":"YulExpressionStatement","src":"8990:31:12"},{"nodeType":"YulAssignment","src":"9030:15:12","value":{"name":"value","nodeType":"YulIdentifier","src":"9040:5:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"9030:6:12"}]}]},"name":"abi_decode_tuple_t_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"8840:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"8851:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"8863:6:12","type":""}],"src":"8804:247:12"},{"body":{"nodeType":"YulBlock","src":"9088:95:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9105:1:12","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9112:3:12","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"9117:10:12","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"9108:3:12"},"nodeType":"YulFunctionCall","src":"9108:20:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9098:6:12"},"nodeType":"YulFunctionCall","src":"9098:31:12"},"nodeType":"YulExpressionStatement","src":"9098:31:12"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9145:1:12","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"9148:4:12","type":"","value":"0x32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9138:6:12"},"nodeType":"YulFunctionCall","src":"9138:15:12"},"nodeType":"YulExpressionStatement","src":"9138:15:12"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9169:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"9172:4:12","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"9162:6:12"},"nodeType":"YulFunctionCall","src":"9162:15:12"},"nodeType":"YulExpressionStatement","src":"9162:15:12"}]},"name":"panic_error_0x32","nodeType":"YulFunctionDefinition","src":"9056:127:12"},{"body":{"nodeType":"YulBlock","src":"9255:206:12","statements":[{"body":{"nodeType":"YulBlock","src":"9301:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9310:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"9313:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"9303:6:12"},"nodeType":"YulFunctionCall","src":"9303:12:12"},"nodeType":"YulExpressionStatement","src":"9303:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"9276:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"9285:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"9272:3:12"},"nodeType":"YulFunctionCall","src":"9272:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"9297:2:12","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"9268:3:12"},"nodeType":"YulFunctionCall","src":"9268:32:12"},"nodeType":"YulIf","src":"9265:52:12"},{"nodeType":"YulVariableDeclaration","src":"9326:36:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9352:9:12"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"9339:12:12"},"nodeType":"YulFunctionCall","src":"9339:23:12"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"9330:5:12","type":""}]},{"body":{"nodeType":"YulBlock","src":"9415:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9424:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"9427:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"9417:6:12"},"nodeType":"YulFunctionCall","src":"9417:12:12"},"nodeType":"YulExpressionStatement","src":"9417:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"9384:5:12"},{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"9405:5:12"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"9398:6:12"},"nodeType":"YulFunctionCall","src":"9398:13:12"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"9391:6:12"},"nodeType":"YulFunctionCall","src":"9391:21:12"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"9381:2:12"},"nodeType":"YulFunctionCall","src":"9381:32:12"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"9374:6:12"},"nodeType":"YulFunctionCall","src":"9374:40:12"},"nodeType":"YulIf","src":"9371:60:12"},{"nodeType":"YulAssignment","src":"9440:15:12","value":{"name":"value","nodeType":"YulIdentifier","src":"9450:5:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"9440:6:12"}]}]},"name":"abi_decode_tuple_t_bool","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"9221:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"9232:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"9244:6:12","type":""}],"src":"9188:273:12"},{"body":{"nodeType":"YulBlock","src":"9617:234:12","statements":[{"nodeType":"YulAssignment","src":"9627:26:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9639:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"9650:2:12","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9635:3:12"},"nodeType":"YulFunctionCall","src":"9635:18:12"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"9627:4:12"}]},{"nodeType":"YulVariableDeclaration","src":"9662:29:12","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9680:3:12","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"9685:1:12","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"9676:3:12"},"nodeType":"YulFunctionCall","src":"9676:11:12"},{"kind":"number","nodeType":"YulLiteral","src":"9689:1:12","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"9672:3:12"},"nodeType":"YulFunctionCall","src":"9672:19:12"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"9666:2:12","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9707:9:12"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"9722:6:12"},{"name":"_1","nodeType":"YulIdentifier","src":"9730:2:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"9718:3:12"},"nodeType":"YulFunctionCall","src":"9718:15:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9700:6:12"},"nodeType":"YulFunctionCall","src":"9700:34:12"},"nodeType":"YulExpressionStatement","src":"9700:34:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9754:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"9765:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9750:3:12"},"nodeType":"YulFunctionCall","src":"9750:18:12"},{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"9774:6:12"},{"name":"_1","nodeType":"YulIdentifier","src":"9782:2:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"9770:3:12"},"nodeType":"YulFunctionCall","src":"9770:15:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9743:6:12"},"nodeType":"YulFunctionCall","src":"9743:43:12"},"nodeType":"YulExpressionStatement","src":"9743:43:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9806:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"9817:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9802:3:12"},"nodeType":"YulFunctionCall","src":"9802:18:12"},{"arguments":[{"arguments":[{"name":"value2","nodeType":"YulIdentifier","src":"9836:6:12"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"9829:6:12"},"nodeType":"YulFunctionCall","src":"9829:14:12"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"9822:6:12"},"nodeType":"YulFunctionCall","src":"9822:22:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9795:6:12"},"nodeType":"YulFunctionCall","src":"9795:50:12"},"nodeType":"YulExpressionStatement","src":"9795:50:12"}]},"name":"abi_encode_tuple_t_address_t_address_t_bool__to_t_address_t_address_t_bool__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"9570:9:12","type":""},{"name":"value2","nodeType":"YulTypedName","src":"9581:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"9589:6:12","type":""},{"name":"value0","nodeType":"YulTypedName","src":"9597:6:12","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"9608:4:12","type":""}],"src":"9466:385:12"},{"body":{"nodeType":"YulBlock","src":"9888:95:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9905:1:12","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9912:3:12","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"9917:10:12","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"9908:3:12"},"nodeType":"YulFunctionCall","src":"9908:20:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9898:6:12"},"nodeType":"YulFunctionCall","src":"9898:31:12"},"nodeType":"YulExpressionStatement","src":"9898:31:12"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9945:1:12","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"9948:4:12","type":"","value":"0x11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9938:6:12"},"nodeType":"YulFunctionCall","src":"9938:15:12"},"nodeType":"YulExpressionStatement","src":"9938:15:12"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9969:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"9972:4:12","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"9962:6:12"},"nodeType":"YulFunctionCall","src":"9962:15:12"},"nodeType":"YulExpressionStatement","src":"9962:15:12"}]},"name":"panic_error_0x11","nodeType":"YulFunctionDefinition","src":"9856:127:12"},{"body":{"nodeType":"YulBlock","src":"10035:88:12","statements":[{"body":{"nodeType":"YulBlock","src":"10066:22:12","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x11","nodeType":"YulIdentifier","src":"10068:16:12"},"nodeType":"YulFunctionCall","src":"10068:18:12"},"nodeType":"YulExpressionStatement","src":"10068:18:12"}]},"condition":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"10051:5:12"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10062:1:12","type":"","value":"0"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"10058:3:12"},"nodeType":"YulFunctionCall","src":"10058:6:12"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"10048:2:12"},"nodeType":"YulFunctionCall","src":"10048:17:12"},"nodeType":"YulIf","src":"10045:43:12"},{"nodeType":"YulAssignment","src":"10097:20:12","value":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"10108:5:12"},{"kind":"number","nodeType":"YulLiteral","src":"10115:1:12","type":"","value":"1"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10104:3:12"},"nodeType":"YulFunctionCall","src":"10104:13:12"},"variableNames":[{"name":"ret","nodeType":"YulIdentifier","src":"10097:3:12"}]}]},"name":"increment_t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"value","nodeType":"YulTypedName","src":"10017:5:12","type":""}],"returnVariables":[{"name":"ret","nodeType":"YulTypedName","src":"10027:3:12","type":""}],"src":"9988:135:12"},{"body":{"nodeType":"YulBlock","src":"10209:170:12","statements":[{"body":{"nodeType":"YulBlock","src":"10255:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10264:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"10267:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"10257:6:12"},"nodeType":"YulFunctionCall","src":"10257:12:12"},"nodeType":"YulExpressionStatement","src":"10257:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"10230:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"10239:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"10226:3:12"},"nodeType":"YulFunctionCall","src":"10226:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"10251:2:12","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"10222:3:12"},"nodeType":"YulFunctionCall","src":"10222:32:12"},"nodeType":"YulIf","src":"10219:52:12"},{"nodeType":"YulVariableDeclaration","src":"10280:29:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10299:9:12"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"10293:5:12"},"nodeType":"YulFunctionCall","src":"10293:16:12"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"10284:5:12","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"10343:5:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"10318:24:12"},"nodeType":"YulFunctionCall","src":"10318:31:12"},"nodeType":"YulExpressionStatement","src":"10318:31:12"},{"nodeType":"YulAssignment","src":"10358:15:12","value":{"name":"value","nodeType":"YulIdentifier","src":"10368:5:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"10358:6:12"}]}]},"name":"abi_decode_tuple_t_address_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"10175:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"10186:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"10198:6:12","type":""}],"src":"10128:251:12"},{"body":{"nodeType":"YulBlock","src":"10513:259:12","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10530:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"10541:2:12","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10523:6:12"},"nodeType":"YulFunctionCall","src":"10523:21:12"},"nodeType":"YulExpressionStatement","src":"10523:21:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10564:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"10575:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10560:3:12"},"nodeType":"YulFunctionCall","src":"10560:18:12"},{"name":"value1","nodeType":"YulIdentifier","src":"10580:6:12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10553:6:12"},"nodeType":"YulFunctionCall","src":"10553:34:12"},"nodeType":"YulExpressionStatement","src":"10553:34:12"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10613:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"10624:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10609:3:12"},"nodeType":"YulFunctionCall","src":"10609:18:12"},{"name":"value0","nodeType":"YulIdentifier","src":"10629:6:12"},{"name":"value1","nodeType":"YulIdentifier","src":"10637:6:12"}],"functionName":{"name":"calldatacopy","nodeType":"YulIdentifier","src":"10596:12:12"},"nodeType":"YulFunctionCall","src":"10596:48:12"},"nodeType":"YulExpressionStatement","src":"10596:48:12"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10668:9:12"},{"name":"value1","nodeType":"YulIdentifier","src":"10679:6:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10664:3:12"},"nodeType":"YulFunctionCall","src":"10664:22:12"},{"kind":"number","nodeType":"YulLiteral","src":"10688:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10660:3:12"},"nodeType":"YulFunctionCall","src":"10660:31:12"},{"kind":"number","nodeType":"YulLiteral","src":"10693:1:12","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10653:6:12"},"nodeType":"YulFunctionCall","src":"10653:42:12"},"nodeType":"YulExpressionStatement","src":"10653:42:12"},{"nodeType":"YulAssignment","src":"10704:62:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10720:9:12"},{"arguments":[{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"10739:6:12"},{"kind":"number","nodeType":"YulLiteral","src":"10747:2:12","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10735:3:12"},"nodeType":"YulFunctionCall","src":"10735:15:12"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10756:2:12","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"10752:3:12"},"nodeType":"YulFunctionCall","src":"10752:7:12"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"10731:3:12"},"nodeType":"YulFunctionCall","src":"10731:29:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10716:3:12"},"nodeType":"YulFunctionCall","src":"10716:45:12"},{"kind":"number","nodeType":"YulLiteral","src":"10763:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10712:3:12"},"nodeType":"YulFunctionCall","src":"10712:54:12"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"10704:4:12"}]}]},"name":"abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"10474:9:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"10485:6:12","type":""},{"name":"value0","nodeType":"YulTypedName","src":"10493:6:12","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"10504:4:12","type":""}],"src":"10384:388:12"},{"body":{"nodeType":"YulBlock","src":"10825:77:12","statements":[{"nodeType":"YulAssignment","src":"10835:16:12","value":{"arguments":[{"name":"x","nodeType":"YulIdentifier","src":"10846:1:12"},{"name":"y","nodeType":"YulIdentifier","src":"10849:1:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10842:3:12"},"nodeType":"YulFunctionCall","src":"10842:9:12"},"variableNames":[{"name":"sum","nodeType":"YulIdentifier","src":"10835:3:12"}]},{"body":{"nodeType":"YulBlock","src":"10874:22:12","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x11","nodeType":"YulIdentifier","src":"10876:16:12"},"nodeType":"YulFunctionCall","src":"10876:18:12"},"nodeType":"YulExpressionStatement","src":"10876:18:12"}]},"condition":{"arguments":[{"name":"x","nodeType":"YulIdentifier","src":"10866:1:12"},{"name":"sum","nodeType":"YulIdentifier","src":"10869:3:12"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"10863:2:12"},"nodeType":"YulFunctionCall","src":"10863:10:12"},"nodeType":"YulIf","src":"10860:36:12"}]},"name":"checked_add_t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"x","nodeType":"YulTypedName","src":"10808:1:12","type":""},{"name":"y","nodeType":"YulTypedName","src":"10811:1:12","type":""}],"returnVariables":[{"name":"sum","nodeType":"YulTypedName","src":"10817:3:12","type":""}],"src":"10777:125:12"},{"body":{"nodeType":"YulBlock","src":"11030:258:12","statements":[{"body":{"nodeType":"YulBlock","src":"11076:16:12","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"11085:1:12","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"11088:1:12","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"11078:6:12"},"nodeType":"YulFunctionCall","src":"11078:12:12"},"nodeType":"YulExpressionStatement","src":"11078:12:12"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"11051:7:12"},{"name":"headStart","nodeType":"YulIdentifier","src":"11060:9:12"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"11047:3:12"},"nodeType":"YulFunctionCall","src":"11047:23:12"},{"kind":"number","nodeType":"YulLiteral","src":"11072:2:12","type":"","value":"96"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"11043:3:12"},"nodeType":"YulFunctionCall","src":"11043:32:12"},"nodeType":"YulIf","src":"11040:52:12"},{"nodeType":"YulAssignment","src":"11101:26:12","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11117:9:12"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"11111:5:12"},"nodeType":"YulFunctionCall","src":"11111:16:12"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"11101:6:12"}]},{"nodeType":"YulVariableDeclaration","src":"11136:38:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11159:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"11170:2:12","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11155:3:12"},"nodeType":"YulFunctionCall","src":"11155:18:12"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"11149:5:12"},"nodeType":"YulFunctionCall","src":"11149:25:12"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"11140:5:12","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"11208:5:12"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"11183:24:12"},"nodeType":"YulFunctionCall","src":"11183:31:12"},"nodeType":"YulExpressionStatement","src":"11183:31:12"},{"nodeType":"YulAssignment","src":"11223:15:12","value":{"name":"value","nodeType":"YulIdentifier","src":"11233:5:12"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"11223:6:12"}]},{"nodeType":"YulAssignment","src":"11247:35:12","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11267:9:12"},{"kind":"number","nodeType":"YulLiteral","src":"11278:2:12","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11263:3:12"},"nodeType":"YulFunctionCall","src":"11263:18:12"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"11257:5:12"},"nodeType":"YulFunctionCall","src":"11257:25:12"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"11247:6:12"}]}]},"name":"abi_decode_tuple_t_uint256t_address_payablet_uint256_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"10980:9:12","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"10991:7:12","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"11003:6:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"11011:6:12","type":""},{"name":"value2","nodeType":"YulTypedName","src":"11019:6:12","type":""}],"src":"10907:381:12"},{"body":{"nodeType":"YulBlock","src":"11440:124:12","statements":[{"expression":{"arguments":[{"name":"pos","nodeType":"YulIdentifier","src":"11463:3:12"},{"name":"value0","nodeType":"YulIdentifier","src":"11468:6:12"},{"name":"value1","nodeType":"YulIdentifier","src":"11476:6:12"}],"functionName":{"name":"calldatacopy","nodeType":"YulIdentifier","src":"11450:12:12"},"nodeType":"YulFunctionCall","src":"11450:33:12"},"nodeType":"YulExpressionStatement","src":"11450:33:12"},{"nodeType":"YulVariableDeclaration","src":"11492:26:12","value":{"arguments":[{"name":"pos","nodeType":"YulIdentifier","src":"11506:3:12"},{"name":"value1","nodeType":"YulIdentifier","src":"11511:6:12"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11502:3:12"},"nodeType":"YulFunctionCall","src":"11502:16:12"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"11496:2:12","type":""}]},{"expression":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"11534:2:12"},{"kind":"number","nodeType":"YulLiteral","src":"11538:1:12","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"11527:6:12"},"nodeType":"YulFunctionCall","src":"11527:13:12"},"nodeType":"YulExpressionStatement","src":"11527:13:12"},{"nodeType":"YulAssignment","src":"11549:9:12","value":{"name":"_1","nodeType":"YulIdentifier","src":"11556:2:12"},"variableNames":[{"name":"end","nodeType":"YulIdentifier","src":"11549:3:12"}]}]},"name":"abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"pos","nodeType":"YulTypedName","src":"11408:3:12","type":""},{"name":"value1","nodeType":"YulTypedName","src":"11413:6:12","type":""},{"name":"value0","nodeType":"YulTypedName","src":"11421:6:12","type":""}],"returnVariables":[{"name":"end","nodeType":"YulTypedName","src":"11432:3:12","type":""}],"src":"11293:271:12"}]},"contents":"{\n { }\n function abi_decode_tuple_t_bytes4(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := calldataload(headStart)\n if iszero(eq(value, and(value, shl(224, 0xffffffff)))) { revert(0, 0) }\n value0 := value\n }\n function abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, iszero(iszero(value0)))\n }\n function abi_decode_array_address_dyn_calldata(offset, end) -> arrayPos, length\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n length := calldataload(offset)\n if gt(length, 0xffffffffffffffff) { revert(0, 0) }\n arrayPos := add(offset, 0x20)\n if gt(add(add(offset, shl(5, length)), 0x20), end) { revert(0, 0) }\n }\n function abi_decode_tuple_t_array$_t_address_$dyn_calldata_ptrt_array$_t_bool_$dyn_calldata_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n let offset := calldataload(headStart)\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n let value0_1, value1_1 := abi_decode_array_address_dyn_calldata(add(headStart, offset), dataEnd)\n value0 := value0_1\n value1 := value1_1\n let offset_1 := calldataload(add(headStart, 32))\n if gt(offset_1, _1) { revert(0, 0) }\n let value2_1, value3_1 := abi_decode_array_address_dyn_calldata(add(headStart, offset_1), dataEnd)\n value2 := value2_1\n value3 := value3_1\n }\n function validator_revert_address(value)\n {\n if iszero(eq(value, and(value, sub(shl(160, 1), 1)))) { revert(0, 0) }\n }\n function panic_error_0x41()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x41)\n revert(0, 0x24)\n }\n function allocate_memory(size) -> memPtr\n {\n memPtr := mload(64)\n let newFreePtr := add(memPtr, and(add(size, 31), not(31)))\n if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n mstore(64, newFreePtr)\n }\n function abi_decode_bytes(offset, end) -> array\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n let _1 := calldataload(offset)\n if gt(_1, 0xffffffffffffffff) { panic_error_0x41() }\n let array_1 := allocate_memory(add(and(add(_1, 0x1f), not(31)), 0x20))\n mstore(array_1, _1)\n if gt(add(add(offset, _1), 0x20), end) { revert(0, 0) }\n calldatacopy(add(array_1, 0x20), add(offset, 0x20), _1)\n mstore(add(add(array_1, _1), 0x20), 0)\n array := array_1\n }\n function abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 128) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n value2 := calldataload(add(headStart, 64))\n let offset := calldataload(add(headStart, 96))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n value3 := abi_decode_bytes(add(headStart, offset), dataEnd)\n }\n function abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, shl(224, 0xffffffff)))\n }\n function abi_decode_tuple_t_addresst_address(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n }\n function abi_encode_tuple_t_address__to_t_address__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, sub(shl(160, 1), 1)))\n }\n function abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 96) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n value1 := calldataload(add(headStart, 32))\n let offset := calldataload(add(headStart, 64))\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n let _2 := add(headStart, offset)\n if iszero(slt(add(_2, 0x1f), dataEnd)) { revert(0, 0) }\n let length := calldataload(_2)\n if gt(length, _1) { revert(0, 0) }\n if gt(add(add(_2, length), 32), dataEnd) { revert(0, 0) }\n value2 := add(_2, 32)\n value3 := length\n }\n function abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value0) -> tail\n {\n let _1 := 32\n mstore(headStart, _1)\n let length := mload(value0)\n mstore(add(headStart, _1), length)\n let i := 0\n for { } lt(i, length) { i := add(i, _1) }\n {\n mstore(add(add(headStart, i), 64), mload(add(add(value0, i), _1)))\n }\n mstore(add(add(headStart, length), 64), 0)\n tail := add(add(headStart, and(add(length, 31), not(31))), 64)\n }\n function abi_decode_array_uint256_dyn(offset, end) -> array\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n let _1 := calldataload(offset)\n let _2 := 0x20\n if gt(_1, 0xffffffffffffffff) { panic_error_0x41() }\n let _3 := shl(5, _1)\n let dst := allocate_memory(add(_3, _2))\n let dst_1 := dst\n mstore(dst, _1)\n dst := add(dst, _2)\n let srcEnd := add(add(offset, _3), _2)\n if gt(srcEnd, end) { revert(0, 0) }\n let src := add(offset, _2)\n for { } lt(src, srcEnd) { src := add(src, _2) }\n {\n mstore(dst, calldataload(src))\n dst := add(dst, _2)\n }\n array := dst_1\n }\n function abi_decode_tuple_t_addresst_addresst_array$_t_uint256_$dyn_memory_ptrt_array$_t_uint256_$dyn_memory_ptrt_bytes_memory_ptr(headStart, dataEnd) -> value0, value1, value2, value3, value4\n {\n if slt(sub(dataEnd, headStart), 160) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n let offset := calldataload(add(headStart, 64))\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n value2 := abi_decode_array_uint256_dyn(add(headStart, offset), dataEnd)\n let offset_1 := calldataload(add(headStart, 96))\n if gt(offset_1, _1) { revert(0, 0) }\n value3 := abi_decode_array_uint256_dyn(add(headStart, offset_1), dataEnd)\n let offset_2 := calldataload(add(headStart, 128))\n if gt(offset_2, _1) { revert(0, 0) }\n value4 := abi_decode_bytes(add(headStart, offset_2), dataEnd)\n }\n function abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, value0)\n }\n function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n value0 := calldataload(headStart)\n }\n function abi_decode_tuple_t_addresst_addresst_uint256t_uint256t_bytes_memory_ptr(headStart, dataEnd) -> value0, value1, value2, value3, value4\n {\n if slt(sub(dataEnd, headStart), 160) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n value2 := calldataload(add(headStart, 64))\n value3 := calldataload(add(headStart, 96))\n let offset := calldataload(add(headStart, 128))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n value4 := abi_decode_bytes(add(headStart, offset), dataEnd)\n }\n function abi_encode_tuple_t_uint256_t_address_t_uint256__to_t_uint256_t_address_t_uint256__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n tail := add(headStart, 96)\n mstore(headStart, value0)\n mstore(add(headStart, 32), and(value1, sub(shl(160, 1), 1)))\n mstore(add(headStart, 64), value2)\n }\n function abi_decode_tuple_t_address(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n }\n function panic_error_0x32()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x32)\n revert(0, 0x24)\n }\n function abi_decode_tuple_t_bool(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := calldataload(headStart)\n if iszero(eq(value, iszero(iszero(value)))) { revert(0, 0) }\n value0 := value\n }\n function abi_encode_tuple_t_address_t_address_t_bool__to_t_address_t_address_t_bool__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n tail := add(headStart, 96)\n let _1 := sub(shl(160, 1), 1)\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), and(value1, _1))\n mstore(add(headStart, 64), iszero(iszero(value2)))\n }\n function panic_error_0x11()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x11)\n revert(0, 0x24)\n }\n function increment_t_uint256(value) -> ret\n {\n if eq(value, not(0)) { panic_error_0x11() }\n ret := add(value, 1)\n }\n function abi_decode_tuple_t_address_fromMemory(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := mload(headStart)\n validator_revert_address(value)\n value0 := value\n }\n function abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value1, value0) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), value1)\n calldatacopy(add(headStart, 64), value0, value1)\n mstore(add(add(headStart, value1), 64), 0)\n tail := add(add(headStart, and(add(value1, 31), not(31))), 64)\n }\n function checked_add_t_uint256(x, y) -> sum\n {\n sum := add(x, y)\n if gt(x, sum) { panic_error_0x11() }\n }\n function abi_decode_tuple_t_uint256t_address_payablet_uint256_fromMemory(headStart, dataEnd) -> value0, value1, value2\n {\n if slt(sub(dataEnd, headStart), 96) { revert(0, 0) }\n value0 := mload(headStart)\n let value := mload(add(headStart, 32))\n validator_revert_address(value)\n value1 := value\n value2 := mload(add(headStart, 64))\n }\n function abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed(pos, value1, value0) -> end\n {\n calldatacopy(pos, value0, value1)\n let _1 := add(pos, value1)\n mstore(_1, 0)\n end := _1\n }\n}","id":12,"language":"Yul","name":"#utility.yul"}],"immutableReferences":{},"linkReferences":{},"object":"6080604052600436106100c65760003560e01c8063a4e2d6341161007f578063dd46706411610059578063dd46706414610251578063f23a6e6114610271578063fc0c546a1461029d578063fe9fbb80146102d557600080fd5b8063a4e2d634146101ea578063bc197c8114610201578063ce0617ec1461022d57600080fd5b806301ffc9a7146100d2578063039721b114610107578063150b7a02146101295780631f9838b5146101625780638da5cb5b1461019d5780639e5d4c49146101ca57600080fd5b366100cd57005b600080fd5b3480156100de57600080fd5b506100f26100ed36600461095c565b6102f5565b60405190151581526020015b60405180910390f35b34801561011357600080fd5b506101276101223660046109d9565b61035c565b005b34801561013557600080fd5b50610149610144366004610b14565b610525565b6040516001600160e01b031990911681526020016100fe565b34801561016e57600080fd5b506100f261017d366004610b80565b600160209081526000928352604080842090915290825290205460ff1681565b3480156101a957600080fd5b506101b261058d565b6040516001600160a01b0390911681526020016100fe565b6101dd6101d8366004610bb9565b610623565b6040516100fe9190610c42565b3480156101f657600080fd5b5060005442106100f2565b34801561020d57600080fd5b5061014961021c366004610d10565b63bc197c8160e01b95945050505050565b34801561023957600080fd5b5061024360005481565b6040519081526020016100fe565b34801561025d57600080fd5b5061012761026c366004610dbe565b6106c7565b34801561027d57600080fd5b5061014961028c366004610dd7565b63f23a6e6160e01b95945050505050565b3480156102a957600080fd5b506102b261078c565b604080519384526001600160a01b039092166020840152908201526060016100fe565b3480156102e157600080fd5b506100f26102f0366004610e40565b6107a4565b6000806001600160e01b031983166301ffc9a760e01b148061032757506001600160e01b03198316630271189760e51b145b8061034257506001600160e01b03198316631dfe9a6f60e31b145b905080156103535750600192915050565b50600092915050565b60005442101561037f57604051636315bfbb60e01b815260040160405180910390fd5b600061038961058d565b9050336001600160a01b038216146103b45760405163ea8e4eb560e01b815260040160405180910390fd5b838281146103d55760405163b4fa3fb360e01b815260040160405180910390fd5b60005b8181101561051c578484828181106103f2576103f2610e5d565b90506020020160208101906104079190610e73565b6001600160a01b03841660009081526001602052604081209089898581811061043257610432610e5d565b90506020020160208101906104479190610e40565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f394777a58092892d136a90c4bb7e4350c72ac50fba6a0208128677f36527dcf5838888848181106104a3576104a3610e5d565b90506020020160208101906104b89190610e40565b8787858181106104ca576104ca610e5d565b90506020020160208101906104df9190610e73565b604080516001600160a01b03948516815293909216602084015215159082015260600160405180910390a18061051481610eab565b9150506103d8565b50505050505050565b60008060008061053361088d565b925092509250468314801561055057506001600160a01b03821633145b801561055b57508581145b156105795760405163b79e3f3f60e01b815260040160405180910390fd5b50630a85bd0160e11b979650505050505050565b60008060008061059b61088d565b9250925092504683146105b2576000935050505090565b6040516331a9108f60e11b8152600481018290526001600160a01b03831690636352211e90602401602060405180830381865afa1580156105f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061b9190610ec4565b935050505090565b606061062e336107a4565b61064b5760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561066e57604051636315bfbb60e01b815260040160405180910390fd5b83856001600160a01b03167f47d99ad340f52da66535aff7e10da1ceb85a32bcbd9fa1c42314d194545e14d285856040516106aa929190610ee1565b60405180910390a36106be858585856108e0565b95945050505050565b6106cf61058d565b6001600160a01b0316336001600160a01b0316146107005760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561072357604051636315bfbb60e01b815260040160405180910390fd5b610731426301e13380610f10565b811115610751576040516301814f7d60e31b815260040160405180910390fd5b60008190556040518181527fa7b24c66dd3269a292a60b3facdbb8f3e7557d1e19e64d99e0d6ee7250be63ad9060200160405180910390a150565b600080600061079961088d565b925092509250909192565b60008060006107b161088d565b6040516331a9108f60e11b8152600481018290529194509250600091506001600160a01b03841690636352211e90602401602060405180830381865afa1580156107ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108239190610ec4565b9050806001600160a01b0316856001600160a01b03160361084957506001949350505050565b6001600160a01b0380821660009081526001602090815260408083209389168352929052205460ff161561088257506001949350505050565b506000949350505050565b604080516060808252608082019092526000918291829182919060208201818036833701905050905060ad604d60208301303c808060200190518101906108d49190610f29565b93509350935050909192565b60606000856001600160a01b03168585856040516108ff929190610f62565b60006040518083038185875af1925050503d806000811461093c576040519150601f19603f3d011682016040523d82523d6000602084013e610941565b606091505b50925090508061095357815160208301fd5b50949350505050565b60006020828403121561096e57600080fd5b81356001600160e01b03198116811461098657600080fd5b9392505050565b60008083601f84011261099f57600080fd5b50813567ffffffffffffffff8111156109b757600080fd5b6020830191508360208260051b85010111156109d257600080fd5b9250929050565b600080600080604085870312156109ef57600080fd5b843567ffffffffffffffff80821115610a0757600080fd5b610a138883890161098d565b90965094506020870135915080821115610a2c57600080fd5b50610a398782880161098d565b95989497509550505050565b6001600160a01b0381168114610a5a57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610a9c57610a9c610a5d565b604052919050565b600082601f830112610ab557600080fd5b813567ffffffffffffffff811115610acf57610acf610a5d565b610ae2601f8201601f1916602001610a73565b818152846020838601011115610af757600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215610b2a57600080fd5b8435610b3581610a45565b93506020850135610b4581610a45565b925060408501359150606085013567ffffffffffffffff811115610b6857600080fd5b610b7487828801610aa4565b91505092959194509250565b60008060408385031215610b9357600080fd5b8235610b9e81610a45565b91506020830135610bae81610a45565b809150509250929050565b60008060008060608587031215610bcf57600080fd5b8435610bda81610a45565b935060208501359250604085013567ffffffffffffffff80821115610bfe57600080fd5b818701915087601f830112610c1257600080fd5b813581811115610c2157600080fd5b886020828501011115610c3357600080fd5b95989497505060200194505050565b600060208083528351808285015260005b81811015610c6f57858101830151858201604001528201610c53565b506000604082860101526040601f19601f8301168501019250505092915050565b600082601f830112610ca157600080fd5b8135602067ffffffffffffffff821115610cbd57610cbd610a5d565b8160051b610ccc828201610a73565b9283528481018201928281019087851115610ce657600080fd5b83870192505b84831015610d0557823582529183019190830190610cec565b979650505050505050565b600080600080600060a08688031215610d2857600080fd5b8535610d3381610a45565b94506020860135610d4381610a45565b9350604086013567ffffffffffffffff80821115610d6057600080fd5b610d6c89838a01610c90565b94506060880135915080821115610d8257600080fd5b610d8e89838a01610c90565b93506080880135915080821115610da457600080fd5b50610db188828901610aa4565b9150509295509295909350565b600060208284031215610dd057600080fd5b5035919050565b600080600080600060a08688031215610def57600080fd5b8535610dfa81610a45565b94506020860135610e0a81610a45565b93506040860135925060608601359150608086013567ffffffffffffffff811115610e3457600080fd5b610db188828901610aa4565b600060208284031215610e5257600080fd5b813561098681610a45565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610e8557600080fd5b8135801515811461098657600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610ebd57610ebd610e95565b5060010190565b600060208284031215610ed657600080fd5b815161098681610a45565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b80820180821115610f2357610f23610e95565b92915050565b600080600060608486031215610f3e57600080fd5b835192506020840151610f5081610a45565b80925050604084015190509250925092565b818382376000910190815291905056fea26469706673582212208586a5aa87cff87a1d8e1dc4952c1d3b167ebfafab4c2b56ed97ed8a5ec5921664736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xC6 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0xA4E2D634 GT PUSH2 0x7F JUMPI DUP1 PUSH4 0xDD467064 GT PUSH2 0x59 JUMPI DUP1 PUSH4 0xDD467064 EQ PUSH2 0x251 JUMPI DUP1 PUSH4 0xF23A6E61 EQ PUSH2 0x271 JUMPI DUP1 PUSH4 0xFC0C546A EQ PUSH2 0x29D JUMPI DUP1 PUSH4 0xFE9FBB80 EQ PUSH2 0x2D5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0xA4E2D634 EQ PUSH2 0x1EA JUMPI DUP1 PUSH4 0xBC197C81 EQ PUSH2 0x201 JUMPI DUP1 PUSH4 0xCE0617EC EQ PUSH2 0x22D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1FFC9A7 EQ PUSH2 0xD2 JUMPI DUP1 PUSH4 0x39721B1 EQ PUSH2 0x107 JUMPI DUP1 PUSH4 0x150B7A02 EQ PUSH2 0x129 JUMPI DUP1 PUSH4 0x1F9838B5 EQ PUSH2 0x162 JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x19D JUMPI DUP1 PUSH4 0x9E5D4C49 EQ PUSH2 0x1CA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST CALLDATASIZE PUSH2 0xCD JUMPI STOP JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xDE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xF2 PUSH2 0xED CALLDATASIZE PUSH1 0x4 PUSH2 0x95C JUMP JUMPDEST PUSH2 0x2F5 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x113 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x127 PUSH2 0x122 CALLDATASIZE PUSH1 0x4 PUSH2 0x9D9 JUMP JUMPDEST PUSH2 0x35C JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x135 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x149 PUSH2 0x144 CALLDATASIZE PUSH1 0x4 PUSH2 0xB14 JUMP JUMPDEST PUSH2 0x525 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xFE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x16E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xF2 PUSH2 0x17D CALLDATASIZE PUSH1 0x4 PUSH2 0xB80 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1A9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B2 PUSH2 0x58D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xFE JUMP JUMPDEST PUSH2 0x1DD PUSH2 0x1D8 CALLDATASIZE PUSH1 0x4 PUSH2 0xBB9 JUMP JUMPDEST PUSH2 0x623 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xFE SWAP2 SWAP1 PUSH2 0xC42 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1F6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x0 SLOAD TIMESTAMP LT PUSH2 0xF2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x20D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x149 PUSH2 0x21C CALLDATASIZE PUSH1 0x4 PUSH2 0xD10 JUMP JUMPDEST PUSH4 0xBC197C81 PUSH1 0xE0 SHL SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x239 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x243 PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xFE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x25D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x127 PUSH2 0x26C CALLDATASIZE PUSH1 0x4 PUSH2 0xDBE JUMP JUMPDEST PUSH2 0x6C7 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x27D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x149 PUSH2 0x28C CALLDATASIZE PUSH1 0x4 PUSH2 0xDD7 JUMP JUMPDEST PUSH4 0xF23A6E61 PUSH1 0xE0 SHL SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2A9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2B2 PUSH2 0x78C JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP4 DUP5 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE SWAP1 DUP3 ADD MSTORE PUSH1 0x60 ADD PUSH2 0xFE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2E1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xF2 PUSH2 0x2F0 CALLDATASIZE PUSH1 0x4 PUSH2 0xE40 JUMP JUMPDEST PUSH2 0x7A4 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x1FFC9A7 PUSH1 0xE0 SHL EQ DUP1 PUSH2 0x327 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x2711897 PUSH1 0xE5 SHL EQ JUMPDEST DUP1 PUSH2 0x342 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x1DFE9A6F PUSH1 0xE3 SHL EQ JUMPDEST SWAP1 POP DUP1 ISZERO PUSH2 0x353 JUMPI POP PUSH1 0x1 SWAP3 SWAP2 POP POP JUMP JUMPDEST POP PUSH1 0x0 SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x37F JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x389 PUSH2 0x58D JUMP JUMPDEST SWAP1 POP CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND EQ PUSH2 0x3B4 JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 DUP3 DUP2 EQ PUSH2 0x3D5 JUMPI PUSH1 0x40 MLOAD PUSH4 0xB4FA3FB3 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x51C JUMPI DUP5 DUP5 DUP3 DUP2 DUP2 LT PUSH2 0x3F2 JUMPI PUSH2 0x3F2 PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x407 SWAP2 SWAP1 PUSH2 0xE73 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 SWAP1 DUP10 DUP10 DUP6 DUP2 DUP2 LT PUSH2 0x432 JUMPI PUSH2 0x432 PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x447 SWAP2 SWAP1 PUSH2 0xE40 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP2 MSTORE PUSH1 0x20 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 ADD PUSH1 0x0 KECCAK256 DUP1 SLOAD PUSH1 0xFF NOT AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH32 0x394777A58092892D136A90C4BB7E4350C72AC50FBA6A0208128677F36527DCF5 DUP4 DUP9 DUP9 DUP5 DUP2 DUP2 LT PUSH2 0x4A3 JUMPI PUSH2 0x4A3 PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x4B8 SWAP2 SWAP1 PUSH2 0xE40 JUMP JUMPDEST DUP8 DUP8 DUP6 DUP2 DUP2 LT PUSH2 0x4CA JUMPI PUSH2 0x4CA PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x4DF SWAP2 SWAP1 PUSH2 0xE73 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP5 DUP6 AND DUP2 MSTORE SWAP4 SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE ISZERO ISZERO SWAP1 DUP3 ADD MSTORE PUSH1 0x60 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 DUP1 PUSH2 0x514 DUP2 PUSH2 0xEAB JUMP JUMPDEST SWAP2 POP POP PUSH2 0x3D8 JUMP JUMPDEST POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x533 PUSH2 0x88D JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP CHAINID DUP4 EQ DUP1 ISZERO PUSH2 0x550 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND CALLER EQ JUMPDEST DUP1 ISZERO PUSH2 0x55B JUMPI POP DUP6 DUP2 EQ JUMPDEST ISZERO PUSH2 0x579 JUMPI PUSH1 0x40 MLOAD PUSH4 0xB79E3F3F PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP PUSH4 0xA85BD01 PUSH1 0xE1 SHL SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x59B PUSH2 0x88D JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP CHAINID DUP4 EQ PUSH2 0x5B2 JUMPI PUSH1 0x0 SWAP4 POP POP POP POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x31A9108F PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND SWAP1 PUSH4 0x6352211E SWAP1 PUSH1 0x24 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x5F7 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x61B SWAP2 SWAP1 PUSH2 0xEC4 JUMP JUMPDEST SWAP4 POP POP POP POP SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH2 0x62E CALLER PUSH2 0x7A4 JUMP JUMPDEST PUSH2 0x64B JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x66E JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH32 0x47D99AD340F52DA66535AFF7E10DA1CEB85A32BCBD9FA1C42314D194545E14D2 DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0x6AA SWAP3 SWAP2 SWAP1 PUSH2 0xEE1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 PUSH2 0x6BE DUP6 DUP6 DUP6 DUP6 PUSH2 0x8E0 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0x6CF PUSH2 0x58D JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ PUSH2 0x700 JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x723 JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH2 0x731 TIMESTAMP PUSH4 0x1E13380 PUSH2 0xF10 JUMP JUMPDEST DUP2 GT ISZERO PUSH2 0x751 JUMPI PUSH1 0x40 MLOAD PUSH4 0x1814F7D PUSH1 0xE3 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 DUP2 SWAP1 SSTORE PUSH1 0x40 MLOAD DUP2 DUP2 MSTORE PUSH32 0xA7B24C66DD3269A292A60B3FACDBB8F3E7557D1E19E64D99E0D6EE7250BE63AD SWAP1 PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x799 PUSH2 0x88D JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP SWAP1 SWAP2 SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x7B1 PUSH2 0x88D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x31A9108F PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE SWAP2 SWAP5 POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND SWAP1 PUSH4 0x6352211E SWAP1 PUSH1 0x24 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x7FF JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x823 SWAP2 SWAP1 PUSH2 0xEC4 JUMP JUMPDEST SWAP1 POP DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SUB PUSH2 0x849 JUMPI POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP1 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP10 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x882 JUMPI POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST POP PUSH1 0x0 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 DUP1 DUP3 MSTORE PUSH1 0x80 DUP3 ADD SWAP1 SWAP3 MSTORE PUSH1 0x0 SWAP2 DUP3 SWAP2 DUP3 SWAP2 DUP3 SWAP2 SWAP1 PUSH1 0x20 DUP3 ADD DUP2 DUP1 CALLDATASIZE DUP4 CALLDATACOPY ADD SWAP1 POP POP SWAP1 POP PUSH1 0xAD PUSH1 0x4D PUSH1 0x20 DUP4 ADD ADDRESS EXTCODECOPY DUP1 DUP1 PUSH1 0x20 ADD SWAP1 MLOAD DUP2 ADD SWAP1 PUSH2 0x8D4 SWAP2 SWAP1 PUSH2 0xF29 JUMP JUMPDEST SWAP4 POP SWAP4 POP SWAP4 POP POP SWAP1 SWAP2 SWAP3 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP6 DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0x8FF SWAP3 SWAP2 SWAP1 PUSH2 0xF62 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 GAS CALL SWAP3 POP POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0x93C JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0x941 JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP3 POP SWAP1 POP DUP1 PUSH2 0x953 JUMPI DUP2 MLOAD PUSH1 0x20 DUP4 ADD REVERT JUMPDEST POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x96E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP2 AND DUP2 EQ PUSH2 0x986 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x99F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x9B7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 PUSH1 0x5 SHL DUP6 ADD ADD GT ISZERO PUSH2 0x9D2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x40 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x9EF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xA07 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xA13 DUP9 DUP4 DUP10 ADD PUSH2 0x98D JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP PUSH1 0x20 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xA2C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xA39 DUP8 DUP3 DUP9 ADD PUSH2 0x98D JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0xA5A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT AND DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0xA9C JUMPI PUSH2 0xA9C PUSH2 0xA5D JUMP JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xAB5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xACF JUMPI PUSH2 0xACF PUSH2 0xA5D JUMP JUMPDEST PUSH2 0xAE2 PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT AND PUSH1 0x20 ADD PUSH2 0xA73 JUMP JUMPDEST DUP2 DUP2 MSTORE DUP5 PUSH1 0x20 DUP4 DUP7 ADD ADD GT ISZERO PUSH2 0xAF7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 PUSH1 0x20 DUP6 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 SWAP2 DUP2 ADD PUSH1 0x20 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xB2A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xB35 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH2 0xB45 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD SWAP2 POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xB68 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xB74 DUP8 DUP3 DUP9 ADD PUSH2 0xAA4 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xB93 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH2 0xB9E DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP2 POP PUSH1 0x20 DUP4 ADD CALLDATALOAD PUSH2 0xBAE DUP2 PUSH2 0xA45 JUMP JUMPDEST DUP1 SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x60 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xBCF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xBDA DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xBFE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP8 ADD SWAP2 POP DUP8 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xC12 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP2 DUP2 GT ISZERO PUSH2 0xC21 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP9 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0xC33 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP POP PUSH1 0x20 ADD SWAP5 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 MSTORE DUP4 MLOAD DUP1 DUP3 DUP6 ADD MSTORE PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xC6F JUMPI DUP6 DUP2 ADD DUP4 ADD MLOAD DUP6 DUP3 ADD PUSH1 0x40 ADD MSTORE DUP3 ADD PUSH2 0xC53 JUMP JUMPDEST POP PUSH1 0x0 PUSH1 0x40 DUP3 DUP7 ADD ADD MSTORE PUSH1 0x40 PUSH1 0x1F NOT PUSH1 0x1F DUP4 ADD AND DUP6 ADD ADD SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xCA1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH1 0x20 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0xCBD JUMPI PUSH2 0xCBD PUSH2 0xA5D JUMP JUMPDEST DUP2 PUSH1 0x5 SHL PUSH2 0xCCC DUP3 DUP3 ADD PUSH2 0xA73 JUMP JUMPDEST SWAP3 DUP4 MSTORE DUP5 DUP2 ADD DUP3 ADD SWAP3 DUP3 DUP2 ADD SWAP1 DUP8 DUP6 GT ISZERO PUSH2 0xCE6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 DUP8 ADD SWAP3 POP JUMPDEST DUP5 DUP4 LT ISZERO PUSH2 0xD05 JUMPI DUP3 CALLDATALOAD DUP3 MSTORE SWAP2 DUP4 ADD SWAP2 SWAP1 DUP4 ADD SWAP1 PUSH2 0xCEC JUMP JUMPDEST SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xD28 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xD33 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH2 0xD43 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xD60 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD6C DUP10 DUP4 DUP11 ADD PUSH2 0xC90 JUMP JUMPDEST SWAP5 POP PUSH1 0x60 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xD82 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD8E DUP10 DUP4 DUP11 ADD PUSH2 0xC90 JUMP JUMPDEST SWAP4 POP PUSH1 0x80 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xDA4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xDB1 DUP9 DUP3 DUP10 ADD PUSH2 0xAA4 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 SWAP1 SWAP4 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xDD0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xDEF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xDFA DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH2 0xE0A DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD SWAP3 POP PUSH1 0x60 DUP7 ADD CALLDATALOAD SWAP2 POP PUSH1 0x80 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xE34 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xDB1 DUP9 DUP3 DUP10 ADD PUSH2 0xAA4 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xE52 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x986 DUP2 PUSH2 0xA45 JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x32 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xE85 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP1 ISZERO ISZERO DUP2 EQ PUSH2 0x986 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x11 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x1 DUP3 ADD PUSH2 0xEBD JUMPI PUSH2 0xEBD PUSH2 0xE95 JUMP JUMPDEST POP PUSH1 0x1 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xED6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x986 DUP2 PUSH2 0xA45 JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE DUP2 PUSH1 0x20 DUP3 ADD MSTORE DUP2 DUP4 PUSH1 0x40 DUP4 ADD CALLDATACOPY PUSH1 0x0 DUP2 DUP4 ADD PUSH1 0x40 SWAP1 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x1F SWAP1 SWAP3 ADD PUSH1 0x1F NOT AND ADD ADD SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 DUP3 ADD DUP1 DUP3 GT ISZERO PUSH2 0xF23 JUMPI PUSH2 0xF23 PUSH2 0xE95 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xF3E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 MLOAD SWAP3 POP PUSH1 0x20 DUP5 ADD MLOAD PUSH2 0xF50 DUP2 PUSH2 0xA45 JUMP JUMPDEST DUP1 SWAP3 POP POP PUSH1 0x40 DUP5 ADD MLOAD SWAP1 POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST DUP2 DUP4 DUP3 CALLDATACOPY PUSH1 0x0 SWAP2 ADD SWAP1 DUP2 MSTORE SWAP2 SWAP1 POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 DUP6 DUP7 0xA5 0xAA DUP8 0xCF 0xF8 PUSH27 0x1D8E1DC4952C1D3B167EBFAFAB4C2B56ED97ED8A5EC5921664736F PUSH13 0x63430008110033000000000000 ","sourceMap":"695:6680:7:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4889:393;;;;;;;;;;-1:-1:-1;4889:393:7;;;;;:::i;:::-;;:::i;:::-;;;470:14:12;;463:22;445:41;;433:2;418:18;4889:393:7;;;;;;;;2357:528;;;;;;;;;;-1:-1:-1;2357:528:7;;;;;:::i;:::-;;:::i;:::-;;5427:526;;;;;;;;;;-1:-1:-1;5427:526:7;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;;3559:33:12;;;3541:52;;3529:2;3514:18;5427:526:7;3397:202:12;965:63:7;;;;;;;;;;-1:-1:-1;965:63:7;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;3891:310;;;;;;;;;;;;;:::i;:::-;;;-1:-1:-1;;;;;4161:32:12;;;4143:51;;4131:2;4116:18;3891:310:7;3997:203:12;2029:265:7;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;3276:100::-;;;;;;;;;;-1:-1:-1;3317:4:7;3340:11;3354:15;-1:-1:-1;3276:100:7;;6356:244;;;;;;;;;;-1:-1:-1;6356:244:7;;;;;:::i;:::-;-1:-1:-1;;;6356:244:7;;;;;;;;871:26;;;;;;;;;;;;;;;;;;;7494:25:12;;;7482:2;7467:18;871:26:7;7348:177:12;2948:249:7;;;;;;;;;;-1:-1:-1;2948:249:7;;;;;:::i;:::-;;:::i;6043:216::-;;;;;;;;;;-1:-1:-1;6043:216:7;;;;;:::i;:::-;-1:-1:-1;;;6043:216:7;;;;;;;;3508:220;;;;;;;;;;;;;:::i;:::-;;;;8656:25:12;;;-1:-1:-1;;;;;8717:32:12;;;8712:2;8697:18;;8690:60;8766:18;;;8759:34;8644:2;8629:18;3508:220:7;8454:345:12;4272:480:7;;;;;;;;;;-1:-1:-1;4272:480:7;;;;;:::i;:::-;;:::i;4889:393::-;4999:4;;-1:-1:-1;;;;;;5041:40:7;;-1:-1:-1;;;5041:40:7;;:105;;-1:-1:-1;;;;;;;5097:49:7;;-1:-1:-1;;;5097:49:7;5041:105;:169;;;-1:-1:-1;;;;;;;5162:48:7;;-1:-1:-1;;;5162:48:7;5041:169;5019:191;;5225:14;5221:31;;;-1:-1:-1;5248:4:7;;4889:393;-1:-1:-1;;4889:393:7:o;5221:31::-;-1:-1:-1;5270:5:7;;4889:393;-1:-1:-1;;4889:393:7:o;2357:528::-;3317:4;3340:11;3354:15;-1:-1:-1;1722:38:7;;;1745:15;;-1:-1:-1;;;1745:15:7;;;;;;;;;;;1722:38;2493:14:::1;2510:7;:5;:7::i;:::-;2493:24:::0;-1:-1:-1;2531:10:7::1;-1:-1:-1::0;;;;;2531:20:7;::::1;;2527:48;;2560:15;;-1:-1:-1::0;;;2560:15:7::1;;;;;;;;;;;2527:48;2603:7:::0;2632:29;;::::1;2628:56;;2670:14;;-1:-1:-1::0;;;2670:14:7::1;;;;;;;;;;;2628:56;2700:9;2695:184;2719:6;2715:1;:10;2695:184;;;2780:12;;2793:1;2780:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;2746:19:7;::::1;;::::0;;;:11:::1;:19;::::0;;;;;2766:7;;2774:1;2766:10;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;2746:31:7::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;2746:31:7;:49;;-1:-1:-1;;2746:49:7::1;::::0;::::1;;::::0;;;::::1;::::0;;2814:54:::1;2832:6:::0;2840:7;;2848:1;2840:10;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;2852:12;;2865:1;2852:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;2814:54;::::0;;-1:-1:-1;;;;;9718:15:12;;;9700:34;;9770:15;;;;9765:2;9750:18;;9743:43;9829:14;9822:22;9802:18;;;9795:50;9650:2;9635:18;2814:54:7::1;;;;;;;2727:3:::0;::::1;::::0;::::1;:::i;:::-;;;;2695:184;;;;2483:402;;2357:528:::0;;;;:::o;5427:526::-;5578:6;5610:15;5639:21;5674:15;5702:25;:23;:25::i;:::-;5596:131;;;;;;5766:13;5755:7;:24;:67;;;;-1:-1:-1;;;;;;5795:27:7;;5812:10;5795:27;5755:67;:109;;;;;5849:15;5838:7;:26;5755:109;5738:160;;;5882:16;;-1:-1:-1;;;5882:16:7;;;;;;;;;;;5738:160;-1:-1:-1;;;;5916:30:7;5427:526;-1:-1:-1;;;;;;;5427:526:7:o;3891:310::-;3929:7;3962:15;3991:21;4026:15;4054:25;:23;:25::i;:::-;3948:131;;;;;;4105:13;4094:7;:24;4090:47;;4135:1;4120:17;;;;;3891:310;:::o;4090:47::-;4155:39;;-1:-1:-1;;;4155:39:7;;;;;7494:25:12;;;-1:-1:-1;;;;;4155:30:7;;;;;7467:18:12;;4155:39:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4148:46;;;;;3891:310;:::o;2029:265::-;2182:12;1559:24;1572:10;1559:12;:24::i;:::-;1554:53;;1592:15;;-1:-1:-1;;;1592:15:7;;;;;;;;;;;1554:53;3317:4;3340:11;3354:15;-1:-1:-1;1722:38:7::1;;;1745:15;;-1:-1:-1::0;;;1745:15:7::1;;;;;;;;;;;1722:38;2235:5:::2;2231:2;-1:-1:-1::0;;;;;2211:36:7::2;;2242:4;;2211:36;;;;;;;:::i;:::-;;;;;;;;2265:22;2271:2;2275:5;2282:4;;2265:5;:22::i;:::-;2258:29:::0;2029:265;-1:-1:-1;;;;;2029:265:7:o;2948:249::-;1387:7;:5;:7::i;:::-;-1:-1:-1;;;;;1373:21:7;:10;-1:-1:-1;;;;;1373:21:7;;1369:49;;1403:15;;-1:-1:-1;;;1403:15:7;;;;;;;;;;;1369:49;3317:4;3340:11;3354:15;-1:-1:-1;1722:38:7::1;;;1745:15;;-1:-1:-1::0;;;1745:15:7::1;;;;;;;;;;;1722:38;3045:26:::2;:15;3063:8;3045:26;:::i;:::-;3030:12;:41;3026:86;;;3092:20;;-1:-1:-1::0;;;3092:20:7::2;;;;;;;;;;;3026:86;3123:11;:26:::0;;;3165:25:::2;::::0;7494::12;;;3165::7::2;::::0;7482:2:12;7467:18;3165:25:7::2;;;;;;;2948:249:::0;:::o;3508:220::-;3585:15;3614:21;3649:15;3696:25;:23;:25::i;:::-;3689:32;;;;;;3508:220;;;:::o;4272:480::-;4331:4;4375:21;4410:15;4438:25;:23;:25::i;:::-;4490:39;;-1:-1:-1;;;4490:39:7;;;;;7494:25:12;;;4347:116:7;;-1:-1:-1;4347:116:7;-1:-1:-1;4473:14:7;;-1:-1:-1;;;;;;4490:30:7;;;;;7467:18:12;;4490:39:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4473:56;;4587:6;-1:-1:-1;;;;;4577:16:7;:6;-1:-1:-1;;;;;4577:16:7;;4573:33;;-1:-1:-1;4602:4:7;;4272:480;-1:-1:-1;;;;4272:480:7:o;4573:33::-;-1:-1:-1;;;;;4682:19:7;;;;;;;:11;:19;;;;;;;;:27;;;;;;;;;;;;4678:44;;;-1:-1:-1;4718:4:7;;4272:480;-1:-1:-1;;;;4272:480:7:o;4678:44::-;-1:-1:-1;4740:5:7;;4272:480;-1:-1:-1;;;;4272:480:7:o;90:406:11:-;263:15;;;273:4;263:15;;;;;;;;;167:7;;;;;;;;263:15;;;;;;;;;;;-1:-1:-1;263:15:11;241:37;;410:4;404;397;389:6;385:17;374:9;362:53;453:6;442:47;;;;;;;;;;;;:::i;:::-;435:54;;;;;;;90:406;;;:::o;6645:345:7:-;6756:19;6787:12;6829:2;-1:-1:-1;;;;;6829:7:7;6844:5;6851:4;;6829:27;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6809:47:7;-1:-1:-1;6809:47:7;-1:-1:-1;6809:47:7;6867:117;;6952:6;6946:13;6941:2;6933:6;6929:15;6922:38;6867:117;6777:213;6645:345;;;;;;:::o;14:286:12:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:12;;209:43;;199:71;;266:1;263;256:12;199:71;289:5;14:286;-1:-1:-1;;;14:286:12:o;497:367::-;560:8;570:6;624:3;617:4;609:6;605:17;601:27;591:55;;642:1;639;632:12;591:55;-1:-1:-1;665:20:12;;708:18;697:30;;694:50;;;740:1;737;730:12;694:50;777:4;769:6;765:17;753:29;;837:3;830:4;820:6;817:1;813:14;805:6;801:27;797:38;794:47;791:67;;;854:1;851;844:12;791:67;497:367;;;;;:::o;869:770::-;988:6;996;1004;1012;1065:2;1053:9;1044:7;1040:23;1036:32;1033:52;;;1081:1;1078;1071:12;1033:52;1121:9;1108:23;1150:18;1191:2;1183:6;1180:14;1177:34;;;1207:1;1204;1197:12;1177:34;1246:70;1308:7;1299:6;1288:9;1284:22;1246:70;:::i;:::-;1335:8;;-1:-1:-1;1220:96:12;-1:-1:-1;1423:2:12;1408:18;;1395:32;;-1:-1:-1;1439:16:12;;;1436:36;;;1468:1;1465;1458:12;1436:36;;1507:72;1571:7;1560:8;1549:9;1545:24;1507:72;:::i;:::-;869:770;;;;-1:-1:-1;1598:8:12;-1:-1:-1;;;;869:770:12:o;1644:131::-;-1:-1:-1;;;;;1719:31:12;;1709:42;;1699:70;;1765:1;1762;1755:12;1699:70;1644:131;:::o;1780:127::-;1841:10;1836:3;1832:20;1829:1;1822:31;1872:4;1869:1;1862:15;1896:4;1893:1;1886:15;1912:275;1983:2;1977:9;2048:2;2029:13;;-1:-1:-1;;2025:27:12;2013:40;;2083:18;2068:34;;2104:22;;;2065:62;2062:88;;;2130:18;;:::i;:::-;2166:2;2159:22;1912:275;;-1:-1:-1;1912:275:12:o;2192:530::-;2234:5;2287:3;2280:4;2272:6;2268:17;2264:27;2254:55;;2305:1;2302;2295:12;2254:55;2341:6;2328:20;2367:18;2363:2;2360:26;2357:52;;;2389:18;;:::i;:::-;2433:55;2476:2;2457:13;;-1:-1:-1;;2453:27:12;2482:4;2449:38;2433:55;:::i;:::-;2513:2;2504:7;2497:19;2559:3;2552:4;2547:2;2539:6;2535:15;2531:26;2528:35;2525:55;;;2576:1;2573;2566:12;2525:55;2641:2;2634:4;2626:6;2622:17;2615:4;2606:7;2602:18;2589:55;2689:1;2664:16;;;2682:4;2660:27;2653:38;;;;2668:7;2192:530;-1:-1:-1;;;2192:530:12:o;2727:665::-;2822:6;2830;2838;2846;2899:3;2887:9;2878:7;2874:23;2870:33;2867:53;;;2916:1;2913;2906:12;2867:53;2955:9;2942:23;2974:31;2999:5;2974:31;:::i;:::-;3024:5;-1:-1:-1;3081:2:12;3066:18;;3053:32;3094:33;3053:32;3094:33;:::i;:::-;3146:7;-1:-1:-1;3200:2:12;3185:18;;3172:32;;-1:-1:-1;3255:2:12;3240:18;;3227:32;3282:18;3271:30;;3268:50;;;3314:1;3311;3304:12;3268:50;3337:49;3378:7;3369:6;3358:9;3354:22;3337:49;:::i;:::-;3327:59;;;2727:665;;;;;;;:::o;3604:388::-;3672:6;3680;3733:2;3721:9;3712:7;3708:23;3704:32;3701:52;;;3749:1;3746;3739:12;3701:52;3788:9;3775:23;3807:31;3832:5;3807:31;:::i;:::-;3857:5;-1:-1:-1;3914:2:12;3899:18;;3886:32;3927:33;3886:32;3927:33;:::i;:::-;3979:7;3969:17;;;3604:388;;;;;:::o;4205:794::-;4293:6;4301;4309;4317;4370:2;4358:9;4349:7;4345:23;4341:32;4338:52;;;4386:1;4383;4376:12;4338:52;4425:9;4412:23;4444:31;4469:5;4444:31;:::i;:::-;4494:5;-1:-1:-1;4546:2:12;4531:18;;4518:32;;-1:-1:-1;4601:2:12;4586:18;;4573:32;4624:18;4654:14;;;4651:34;;;4681:1;4678;4671:12;4651:34;4719:6;4708:9;4704:22;4694:32;;4764:7;4757:4;4753:2;4749:13;4745:27;4735:55;;4786:1;4783;4776:12;4735:55;4826:2;4813:16;4852:2;4844:6;4841:14;4838:34;;;4868:1;4865;4858:12;4838:34;4913:7;4908:2;4899:6;4895:2;4891:15;4887:24;4884:37;4881:57;;;4934:1;4931;4924:12;4881:57;4205:794;;;;-1:-1:-1;;4965:2:12;4957:11;;-1:-1:-1;;;4205:794:12:o;5004:546::-;5114:4;5143:2;5172;5161:9;5154:21;5204:6;5198:13;5247:6;5242:2;5231:9;5227:18;5220:34;5272:1;5282:140;5296:6;5293:1;5290:13;5282:140;;;5391:14;;;5387:23;;5381:30;5357:17;;;5376:2;5353:26;5346:66;5311:10;;5282:140;;;5286:3;5471:1;5466:2;5457:6;5446:9;5442:22;5438:31;5431:42;5541:2;5534;5530:7;5525:2;5517:6;5513:15;5509:29;5498:9;5494:45;5490:54;5482:62;;;;5004:546;;;;:::o;5555:712::-;5609:5;5662:3;5655:4;5647:6;5643:17;5639:27;5629:55;;5680:1;5677;5670:12;5629:55;5716:6;5703:20;5742:4;5765:18;5761:2;5758:26;5755:52;;;5787:18;;:::i;:::-;5833:2;5830:1;5826:10;5856:28;5880:2;5876;5872:11;5856:28;:::i;:::-;5918:15;;;5988;;;5984:24;;;5949:12;;;;6020:15;;;6017:35;;;6048:1;6045;6038:12;6017:35;6084:2;6076:6;6072:15;6061:26;;6096:142;6112:6;6107:3;6104:15;6096:142;;;6178:17;;6166:30;;6129:12;;;;6216;;;;6096:142;;;6256:5;5555:712;-1:-1:-1;;;;;;;5555:712:12:o;6272:1071::-;6426:6;6434;6442;6450;6458;6511:3;6499:9;6490:7;6486:23;6482:33;6479:53;;;6528:1;6525;6518:12;6479:53;6567:9;6554:23;6586:31;6611:5;6586:31;:::i;:::-;6636:5;-1:-1:-1;6693:2:12;6678:18;;6665:32;6706:33;6665:32;6706:33;:::i;:::-;6758:7;-1:-1:-1;6816:2:12;6801:18;;6788:32;6839:18;6869:14;;;6866:34;;;6896:1;6893;6886:12;6866:34;6919:61;6972:7;6963:6;6952:9;6948:22;6919:61;:::i;:::-;6909:71;;7033:2;7022:9;7018:18;7005:32;6989:48;;7062:2;7052:8;7049:16;7046:36;;;7078:1;7075;7068:12;7046:36;7101:63;7156:7;7145:8;7134:9;7130:24;7101:63;:::i;:::-;7091:73;;7217:3;7206:9;7202:19;7189:33;7173:49;;7247:2;7237:8;7234:16;7231:36;;;7263:1;7260;7253:12;7231:36;;7286:51;7329:7;7318:8;7307:9;7303:24;7286:51;:::i;:::-;7276:61;;;6272:1071;;;;;;;;:::o;7530:180::-;7589:6;7642:2;7630:9;7621:7;7617:23;7613:32;7610:52;;;7658:1;7655;7648:12;7610:52;-1:-1:-1;7681:23:12;;7530:180;-1:-1:-1;7530:180:12:o;7715:734::-;7819:6;7827;7835;7843;7851;7904:3;7892:9;7883:7;7879:23;7875:33;7872:53;;;7921:1;7918;7911:12;7872:53;7960:9;7947:23;7979:31;8004:5;7979:31;:::i;:::-;8029:5;-1:-1:-1;8086:2:12;8071:18;;8058:32;8099:33;8058:32;8099:33;:::i;:::-;8151:7;-1:-1:-1;8205:2:12;8190:18;;8177:32;;-1:-1:-1;8256:2:12;8241:18;;8228:32;;-1:-1:-1;8311:3:12;8296:19;;8283:33;8339:18;8328:30;;8325:50;;;8371:1;8368;8361:12;8325:50;8394:49;8435:7;8426:6;8415:9;8411:22;8394:49;:::i;8804:247::-;8863:6;8916:2;8904:9;8895:7;8891:23;8887:32;8884:52;;;8932:1;8929;8922:12;8884:52;8971:9;8958:23;8990:31;9015:5;8990:31;:::i;9056:127::-;9117:10;9112:3;9108:20;9105:1;9098:31;9148:4;9145:1;9138:15;9172:4;9169:1;9162:15;9188:273;9244:6;9297:2;9285:9;9276:7;9272:23;9268:32;9265:52;;;9313:1;9310;9303:12;9265:52;9352:9;9339:23;9405:5;9398:13;9391:21;9384:5;9381:32;9371:60;;9427:1;9424;9417:12;9856:127;9917:10;9912:3;9908:20;9905:1;9898:31;9948:4;9945:1;9938:15;9972:4;9969:1;9962:15;9988:135;10027:3;10048:17;;;10045:43;;10068:18;;:::i;:::-;-1:-1:-1;10115:1:12;10104:13;;9988:135::o;10128:251::-;10198:6;10251:2;10239:9;10230:7;10226:23;10222:32;10219:52;;;10267:1;10264;10257:12;10219:52;10299:9;10293:16;10318:31;10343:5;10318:31;:::i;10384:388::-;10541:2;10530:9;10523:21;10580:6;10575:2;10564:9;10560:18;10553:34;10637:6;10629;10624:2;10613:9;10609:18;10596:48;10693:1;10664:22;;;10688:2;10660:31;;;10653:42;;;;10756:2;10735:15;;;-1:-1:-1;;10731:29:12;10716:45;10712:54;;10384:388;-1:-1:-1;10384:388:12:o;10777:125::-;10842:9;;;10863:10;;;10860:36;;;10876:18;;:::i;:::-;10777:125;;;;:::o;10907:381::-;11003:6;11011;11019;11072:2;11060:9;11051:7;11047:23;11043:32;11040:52;;;11088:1;11085;11078:12;11040:52;11117:9;11111:16;11101:26;;11170:2;11159:9;11155:18;11149:25;11183:31;11208:5;11183:31;:::i;:::-;11233:5;11223:15;;;11278:2;11267:9;11263:18;11257:25;11247:35;;10907:381;;;;;:::o;11293:271::-;11476:6;11468;11463:3;11450:33;11432:3;11502:16;;11527:13;;;11502:16;11293:271;-1:-1:-1;11293:271:12:o"},"gasEstimates":{"creation":{"codeDepositCost":"801600","executionCost":"838","totalCost":"802438"},"external":{"executeCall(address,uint256,bytes)":"infinite","isAuthorized(address)":"infinite","isLocked()":"2315","lock(uint256)":"infinite","lockedUntil()":"2362","onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":"infinite","onERC1155Received(address,address,uint256,uint256,bytes)":"infinite","onERC721Received(address,address,uint256,bytes)":"infinite","owner()":"infinite","permissions(address,address)":"infinite","setPermissions(address[],bool[])":"infinite","supportsInterface(bytes4)":"515","token()":"infinite"},"internal":{"_call(address,uint256,bytes calldata)":"infinite","_callStatic(address,bytes calldata)":"infinite"}},"methodIdentifiers":{"executeCall(address,uint256,bytes)":"9e5d4c49","isAuthorized(address)":"fe9fbb80","isLocked()":"a4e2d634","lock(uint256)":"dd467064","lockedUntil()":"ce0617ec","onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":"bc197c81","onERC1155Received(address,address,uint256,uint256,bytes)":"f23a6e61","onERC721Received(address,address,uint256,bytes)":"150b7a02","owner()":"8da5cb5b","permissions(address,address)":"1f9838b5","setPermissions(address[],bool[])":"039721b1","supportsInterface(bytes4)":"01ffc9a7","token()":"fc0c546a"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccountLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExceedsMaxLockTime\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInput\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAuthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnershipCycle\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lockedUntil\",\"type\":\"uint256\"}],\"name\":\"LockUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"OverrideUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"hasPermission\",\"type\":\"bool\"}],\"name\":\"PermissionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"TransactionExecuted\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"executeCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"isAuthorized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isLocked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_lockedUntil\",\"type\":\"uint256\"}],\"name\":\"lock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lockedUntil\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"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\":\"receivedTokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"permissions\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"callers\",\"type\":\"address[]\"},{\"internalType\":\"bool[]\",\"name\":\"_permissions\",\"type\":\"bool[]\"}],\"name\":\"setPermissions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"executeCall(address,uint256,bytes)\":{\"details\":\"executes a low-level call against an account if the caller is authorized to make calls\"},\"isAuthorized(address)\":{\"details\":\"Returns the authorization status for a given caller\"},\"isLocked()\":{\"details\":\"returns the current lock status of the account as a boolean\"},\"lock(uint256)\":{\"details\":\"locks the account until a certain timestamp\"},\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"details\":\"Allows ERC-1155 token batches to be received. This function can be overriden.\"},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"details\":\"Allows ERC-1155 tokens to be received. This function can be overriden.\"},\"onERC721Received(address,address,uint256,bytes)\":{\"details\":\"Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle. This function can be overriden.\"},\"owner()\":{\"details\":\"Returns the owner of the ERC-721 token which owns this account. By default, the owner of the token has full permissions on the account.\"},\"setPermissions(address[],bool[])\":{\"details\":\"grants a given caller execution permissions\"},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if a given interfaceId is supported by this account. This method can be extended by an override.\"},\"token()\":{\"details\":\"Returns the EIP-155 chain ID, token contract address, and token ID for the token that owns this account.\"}},\"stateVariables\":{\"lockedUntil\":{\"details\":\"timestamp at which this account will be unlocked\"},\"permissions\":{\"details\":\"mapping from owner => caller => has permissions\"}},\"title\":\"A smart contract account owned by a single ERC721 token\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/MinimalisticAccount.sol\":\"MinimalisticAccount\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (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 *\\n * NOTE: 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 *\\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.\\n *\\n * NOTE: 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 *\\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\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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`.\\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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\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(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface 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 `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/MinimalisticAccount.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\nimport \\\"./interfaces/IERC6551Account.sol\\\";\\nimport \\\"./lib/ERC6551AccountLib.sol\\\";\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/interfaces/IERC1271.sol\\\";\\n\\nerror NotAuthorized();\\nerror InvalidInput();\\nerror AccountLocked();\\nerror ExceedsMaxLockTime();\\nerror UntrustedImplementation();\\nerror OwnershipCycle();\\n\\n/**\\n * @title A smart contract account owned by a single ERC721 token\\n */\\ncontract MinimalisticAccount is\\n IERC165,\\n IERC6551Account,\\n IERC721Receiver,\\n IERC1155Receiver\\n{\\n /// @dev timestamp at which this account will be unlocked\\n uint256 public lockedUntil;\\n\\n /// @dev mapping from owner => caller => has permissions\\n mapping(address => mapping(address => bool)) public permissions;\\n\\n event OverrideUpdated(\\n address owner,\\n bytes4 selector,\\n address implementation\\n );\\n\\n event PermissionUpdated(address owner, address caller, bool hasPermission);\\n\\n event LockUpdated(uint256 lockedUntil);\\n\\n /// @dev reverts if caller is not the owner of the account\\n modifier onlyOwner() {\\n if (msg.sender != owner()) revert NotAuthorized();\\n _;\\n }\\n\\n /// @dev reverts if caller is not authorized to execute on this account\\n modifier onlyAuthorized() {\\n if (!isAuthorized(msg.sender)) revert NotAuthorized();\\n _;\\n }\\n\\n /// @dev reverts if this account is currently locked\\n modifier onlyUnlocked() {\\n if (isLocked()) revert AccountLocked();\\n _;\\n }\\n\\n constructor() {}\\n\\n /// @dev allows eth transfers by default, but allows account owner to override\\n receive() external payable {\\n }\\n\\n /// @dev executes a low-level call against an account if the caller is authorized to make calls\\n function executeCall(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) external payable onlyAuthorized onlyUnlocked returns (bytes memory) {\\n emit TransactionExecuted(to, value, data);\\n\\n return _call(to, value, data);\\n }\\n\\n /// @dev grants a given caller execution permissions\\n function setPermissions(\\n address[] calldata callers,\\n bool[] calldata _permissions\\n ) external onlyUnlocked {\\n address _owner = owner();\\n if (msg.sender != _owner) revert NotAuthorized();\\n\\n uint256 length = callers.length;\\n\\n if (_permissions.length != length) revert InvalidInput();\\n\\n for (uint256 i = 0; i < length; i++) {\\n permissions[_owner][callers[i]] = _permissions[i];\\n emit PermissionUpdated(_owner, callers[i], _permissions[i]);\\n }\\n }\\n\\n /// @dev locks the account until a certain timestamp\\n function lock(uint256 _lockedUntil) external onlyOwner onlyUnlocked {\\n if (_lockedUntil > block.timestamp + 365 days)\\n revert ExceedsMaxLockTime();\\n\\n lockedUntil = _lockedUntil;\\n\\n emit LockUpdated(_lockedUntil);\\n }\\n\\n /// @dev returns the current lock status of the account as a boolean\\n function isLocked() public view returns (bool) {\\n return lockedUntil > block.timestamp;\\n }\\n\\n /// @dev Returns the EIP-155 chain ID, token contract address, and token ID for the token that\\n /// owns this account.\\n function token()\\n external\\n view\\n returns (\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n )\\n {\\n return ERC6551AccountLib.token();\\n }\\n\\n /// @dev Returns the owner of the ERC-721 token which owns this account. By default, the owner\\n /// of the token has full permissions on the account.\\n function owner() public view returns (address) {\\n (\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) = ERC6551AccountLib.token();\\n\\n if (chainId != block.chainid) return address(0);\\n\\n return IERC721(tokenContract).ownerOf(tokenId);\\n }\\n\\n /// @dev Returns the authorization status for a given caller\\n function isAuthorized(address caller) public view returns (bool) {\\n (\\n ,\\n address tokenContract,\\n uint256 tokenId\\n ) = ERC6551AccountLib.token();\\n address _owner = IERC721(tokenContract).ownerOf(tokenId);\\n\\n // authorize token owner\\n if (caller == _owner) return true;\\n\\n // authorize caller if owner has granted permissions\\n if (permissions[_owner][caller]) return true;\\n\\n return false;\\n }\\n\\n /// @dev Returns true if a given interfaceId is supported by this account. This method can be\\n /// extended by an override.\\n function supportsInterface(bytes4 interfaceId)\\n public\\n pure \\n override\\n returns (bool)\\n {\\n bool defaultSupport = interfaceId == type(IERC165).interfaceId ||\\n interfaceId == type(IERC1155Receiver).interfaceId ||\\n interfaceId == type(IERC6551Account).interfaceId;\\n\\n if (defaultSupport) return true;\\n\\n return false;\\n }\\n\\n /// @dev Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle.\\n /// This function can be overriden.\\n function onERC721Received(\\n address,\\n address,\\n uint256 receivedTokenId,\\n bytes memory\\n ) public view override returns (bytes4) {\\n (\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) = ERC6551AccountLib.token();\\n\\n if (\\n chainId == block.chainid &&\\n tokenContract == msg.sender &&\\n tokenId == receivedTokenId\\n ) revert OwnershipCycle();\\n\\n return this.onERC721Received.selector;\\n }\\n\\n /// @dev Allows ERC-1155 tokens to be received. This function can be overriden.\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes memory\\n ) public pure override returns (bytes4) {\\n return this.onERC1155Received.selector;\\n }\\n\\n /// @dev Allows ERC-1155 token batches to be received. This function can be overriden.\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] memory,\\n uint256[] memory,\\n bytes memory\\n ) public pure override returns (bytes4) {\\n return this.onERC1155BatchReceived.selector;\\n }\\n\\n /// @dev Executes a low-level call\\n function _call(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) internal returns (bytes memory result) {\\n bool success;\\n (success, result) = to.call{value: value}(data);\\n\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /// @dev Executes a low-level static call\\n function _callStatic(address to, bytes calldata data)\\n internal\\n view\\n returns (bytes memory result)\\n {\\n bool success;\\n (success, result) = to.staticcall(data);\\n\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xed537db66c8c88618b283b038ec6e1b55b56c1ad4006658a1fef0fe8e60fb528\",\"license\":\"UNLICENSED\"},\"contracts/interfaces/IERC6551Account.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\ninterface IERC6551AccountProxy {\\n function implementation() external view returns (address);\\n}\\n\\n/// @dev the ERC-165 identifier for this interface is `0xeff4d378`\\ninterface IERC6551Account {\\n event TransactionExecuted(address indexed target, uint256 indexed value, bytes data);\\n\\n receive() external payable;\\n\\n function executeCall(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) external payable returns (bytes memory);\\n\\n function token()\\n external\\n view\\n returns (uint256 chainId, address tokenContract, uint256 tokenId);\\n\\n function owner() external view returns (address);\\n}\\n\",\"keccak256\":\"0x5fe2dca745f8e753d414778980a0846c1bbcbb26a09d7cd7fb712c7db7939582\",\"license\":\"UNLICENSED\"},\"contracts/lib/ERC6551AccountLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.13;\\n\\nlibrary ERC6551AccountLib {\\n function token()\\n internal\\n view\\n returns (\\n uint256,\\n address,\\n uint256\\n )\\n {\\n bytes memory footer = new bytes(0x60);\\n\\n assembly {\\n // copy 0x60 bytes from end of footer\\n extcodecopy(address(), add(footer, 0x20), 0x4d, 0xad)\\n }\\n\\n return abi.decode(footer, (uint256, address, uint256));\\n }\\n\\n function salt() internal view returns (uint256) {\\n bytes memory footer = new bytes(0x20);\\n\\n assembly {\\n // copy 0x20 bytes from beginning of footer\\n extcodecopy(address(), add(footer, 0x20), 0x2d, 0x4d)\\n }\\n\\n return abi.decode(footer, (uint256));\\n }\\n}\\n\",\"keccak256\":\"0xf7a8eb3b4fb63068eb8ed2a1a129e4676af842541f43c1a1dc96a9f295060c45\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[{"astId":481,"contract":"contracts/MinimalisticAccount.sol:MinimalisticAccount","label":"lockedUntil","offset":0,"slot":"0","type":"t_uint256"},{"astId":488,"contract":"contracts/MinimalisticAccount.sol:MinimalisticAccount","label":"permissions","offset":0,"slot":"1","type":"t_mapping(t_address,t_mapping(t_address,t_bool))"}],"types":{"t_address":{"encoding":"inplace","label":"address","numberOfBytes":"20"},"t_bool":{"encoding":"inplace","label":"bool","numberOfBytes":"1"},"t_mapping(t_address,t_bool)":{"encoding":"mapping","key":"t_address","label":"mapping(address => bool)","numberOfBytes":"32","value":"t_bool"},"t_mapping(t_address,t_mapping(t_address,t_bool))":{"encoding":"mapping","key":"t_address","label":"mapping(address => mapping(address => bool))","numberOfBytes":"32","value":"t_mapping(t_address,t_bool)"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/interfaces/IChargedParticles.sol":{"IChargedParticles":{"abi":[{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"}],"name":"baseParticleMass","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"basketManagerId","type":"string"},{"internalType":"address","name":"nftTokenAddress","type":"address"},{"internalType":"uint256","name":"nftTokenId","type":"uint256"},{"internalType":"uint256","name":"nftTokenAmount","type":"uint256"}],"name":"breakCovalentBond","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"basketManagerId","type":"string"},{"internalType":"address","name":"nftTokenAddress","type":"address"},{"internalType":"uint256","name":"nftTokenId","type":"uint256"},{"internalType":"uint256","name":"nftTokenAmount","type":"uint256"}],"name":"covalentBond","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"}],"name":"currentParticleCharge","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"basketManagerId","type":"string"}],"name":"currentParticleCovalentBonds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"}],"name":"currentParticleKinetics","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"}],"name":"dischargeParticle","outputs":[{"internalType":"uint256","name":"creatorAmount","type":"uint256"},{"internalType":"uint256","name":"receiverAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"},{"internalType":"uint256","name":"assetAmount","type":"uint256"}],"name":"dischargeParticleAmount","outputs":[{"internalType":"uint256","name":"creatorAmount","type":"uint256"},{"internalType":"uint256","name":"receiverAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"},{"internalType":"uint256","name":"assetAmount","type":"uint256"}],"name":"dischargeParticleForCreator","outputs":[{"internalType":"uint256","name":"receiverAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"},{"internalType":"uint256","name":"assetAmount","type":"uint256"},{"internalType":"address","name":"referrer","type":"address"}],"name":"energizeParticle","outputs":[{"internalType":"uint256","name":"yieldTokensAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assetAmount","type":"uint256"}],"name":"getFeesForDeposit","outputs":[{"internalType":"uint256","name":"protocolFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getManagersAddress","outputs":[{"internalType":"address","name":"managersAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSettingsAddress","outputs":[{"internalType":"address","name":"settingsAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStateAddress","outputs":[{"internalType":"address","name":"stateAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"}],"name":"releaseParticle","outputs":[{"internalType":"uint256","name":"creatorAmount","type":"uint256"},{"internalType":"uint256","name":"receiverAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"},{"internalType":"uint256","name":"assetAmount","type":"uint256"}],"name":"releaseParticleAmount","outputs":[{"internalType":"uint256","name":"creatorAmount","type":"uint256"},{"internalType":"uint256","name":"receiverAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"baseParticleMass(address,uint256,string,address)":"e6ea6ce7","breakCovalentBond(address,address,uint256,string,address,uint256,uint256)":"fe02fb00","covalentBond(address,uint256,string,address,uint256,uint256)":"3ff956cc","currentParticleCharge(address,uint256,string,address)":"99fa4c73","currentParticleCovalentBonds(address,uint256,string)":"a13eafd5","currentParticleKinetics(address,uint256,string,address)":"ca92acd0","dischargeParticle(address,address,uint256,string,address)":"621a3b70","dischargeParticleAmount(address,address,uint256,string,address,uint256)":"6697b359","dischargeParticleForCreator(address,address,uint256,string,address,uint256)":"65d20ce2","energizeParticle(address,uint256,string,address,uint256,address)":"0bdde2ca","getFeesForDeposit(uint256)":"ee895623","getManagersAddress()":"8742f168","getSettingsAddress()":"d00999fe","getStateAddress()":"31969e57","releaseParticle(address,address,uint256,string,address)":"acab923c","releaseParticleAmount(address,address,uint256,string,address,uint256)":"a8abef47"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"baseParticleMass\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"basketManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"breakCovalentBond\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"basketManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"covalentBond\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"currentParticleCharge\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"basketManagerId\",\"type\":\"string\"}],\"name\":\"currentParticleCovalentBonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"currentParticleKinetics\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"dischargeParticle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"creatorAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"}],\"name\":\"dischargeParticleAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"creatorAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"}],\"name\":\"dischargeParticleForCreator\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receiverAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"referrer\",\"type\":\"address\"}],\"name\":\"energizeParticle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"yieldTokensAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"}],\"name\":\"getFeesForDeposit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getManagersAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"managersAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSettingsAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"settingsAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStateAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"stateAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"releaseParticle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"creatorAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"}],\"name\":\"releaseParticleAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"creatorAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Interface for Charged Particles\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/interfaces/IChargedParticles.sol\":\"IChargedParticles\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interfaces/IChargedParticles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @notice Interface for Charged Particles\\n */\\ninterface IChargedParticles {\\n\\n /***********************************|\\n | Public API |\\n |__________________________________*/\\n\\n function getStateAddress() external view returns (address stateAddress);\\n function getSettingsAddress() external view returns (address settingsAddress);\\n function getManagersAddress() external view returns (address managersAddress);\\n\\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\\n\\n /***********************************|\\n | Particle Mechanics |\\n |__________________________________*/\\n\\n function energizeParticle(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount,\\n address referrer\\n ) external returns (uint256 yieldTokensAmount);\\n\\n function dischargeParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function dischargeParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function dischargeParticleForCreator(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 receiverAmount);\\n\\n function releaseParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function releaseParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function covalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success);\\n\\n function breakCovalentBond(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success);\\n}\\n\",\"keccak256\":\"0xa825d020fbe598bb4b7a0e9dbc1fe1d3b17b161b4429a3f848eec27eab4f99d4\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"notice":"Interface for Charged Particles","version":1}}},"contracts/interfaces/IERC6551Account.sol":{"IERC6551Account":{"abi":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":true,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"TransactionExecuted","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"executeCall","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}],"devdoc":{"details":"the ERC-165 identifier for this interface is `0xeff4d378`","kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"executeCall(address,uint256,bytes)":"9e5d4c49","owner()":"8da5cb5b","token()":"fc0c546a"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"TransactionExecuted\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"executeCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"the ERC-165 identifier for this interface is `0xeff4d378`\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/interfaces/IERC6551Account.sol\":\"IERC6551Account\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interfaces/IERC6551Account.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\ninterface IERC6551AccountProxy {\\n function implementation() external view returns (address);\\n}\\n\\n/// @dev the ERC-165 identifier for this interface is `0xeff4d378`\\ninterface IERC6551Account {\\n event TransactionExecuted(address indexed target, uint256 indexed value, bytes data);\\n\\n receive() external payable;\\n\\n function executeCall(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) external payable returns (bytes memory);\\n\\n function token()\\n external\\n view\\n returns (uint256 chainId, address tokenContract, uint256 tokenId);\\n\\n function owner() external view returns (address);\\n}\\n\",\"keccak256\":\"0x5fe2dca745f8e753d414778980a0846c1bbcbb26a09d7cd7fb712c7db7939582\",\"license\":\"UNLICENSED\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}},"IERC6551AccountProxy":{"abi":[{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"implementation()":"5c60da1b"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/interfaces/IERC6551Account.sol\":\"IERC6551AccountProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interfaces/IERC6551Account.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\ninterface IERC6551AccountProxy {\\n function implementation() external view returns (address);\\n}\\n\\n/// @dev the ERC-165 identifier for this interface is `0xeff4d378`\\ninterface IERC6551Account {\\n event TransactionExecuted(address indexed target, uint256 indexed value, bytes data);\\n\\n receive() external payable;\\n\\n function executeCall(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) external payable returns (bytes memory);\\n\\n function token()\\n external\\n view\\n returns (uint256 chainId, address tokenContract, uint256 tokenId);\\n\\n function owner() external view returns (address);\\n}\\n\",\"keccak256\":\"0x5fe2dca745f8e753d414778980a0846c1bbcbb26a09d7cd7fb712c7db7939582\",\"license\":\"UNLICENSED\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/interfaces/IRegistry.sol":{"IRegistry":{"abi":[{"inputs":[{"internalType":"address","name":"implementation","type":"address"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"}],"name":"account","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"implementation","type":"address"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"initData","type":"bytes"}],"name":"createAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"account(address,uint256,address,uint256,uint256)":"5e9bc536","createAccount(address,uint256,address,uint256,uint256,bytes)":"da7323b3"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"salt\",\"type\":\"uint256\"}],\"name\":\"account\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"salt\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initData\",\"type\":\"bytes\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/interfaces/IRegistry.sol\":\"IRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interfaces/IRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\ninterface IRegistry {\\n function createAccount(\\n address implementation,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId,\\n uint256 salt,\\n bytes calldata initData\\n ) external returns (address);\\n\\n function account(\\n address implementation,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId,\\n uint256 salt\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xd24999d4d474bd349b1e2e5006eff215c5d9a64a481a9ebac3293f98603fbd27\",\"license\":\"UNLICENSED\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/lib/ERC6551AccountLib.sol":{"ERC6551AccountLib":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220507d1af45fff54535180cd2db9c0244503eb6a3f2538827633938e9a22f0be7564736f6c63430008110033","opcodes":"PUSH1 0x56 PUSH1 0x37 PUSH1 0xB DUP3 DUP3 DUP3 CODECOPY DUP1 MLOAD PUSH1 0x0 BYTE PUSH1 0x73 EQ PUSH1 0x2A JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x0 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST ADDRESS PUSH1 0x0 MSTORE PUSH1 0x73 DUP2 MSTORE8 DUP3 DUP2 RETURN INVALID PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 POP PUSH30 0x1AF45FFF54535180CD2DB9C0244503EB6A3F2538827633938E9A22F0BE75 PUSH5 0x736F6C6343 STOP ADDMOD GT STOP CALLER ","sourceMap":"58:747:11:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;58:747:11;;;;;;;;;;;;;;;;;"},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220507d1af45fff54535180cd2db9c0244503eb6a3f2538827633938e9a22f0be7564736f6c63430008110033","opcodes":"PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 POP PUSH30 0x1AF45FFF54535180CD2DB9C0244503EB6A3F2538827633938E9A22F0BE75 PUSH5 0x736F6C6343 STOP ADDMOD GT STOP CALLER ","sourceMap":"58:747:11:-:0;;;;;;;;"},"gasEstimates":{"creation":{"codeDepositCost":"17200","executionCost":"103","totalCost":"17303"},"internal":{"salt()":"infinite","token()":"infinite"}},"methodIdentifiers":{}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/lib/ERC6551AccountLib.sol\":\"ERC6551AccountLib\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/lib/ERC6551AccountLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.13;\\n\\nlibrary ERC6551AccountLib {\\n function token()\\n internal\\n view\\n returns (\\n uint256,\\n address,\\n uint256\\n )\\n {\\n bytes memory footer = new bytes(0x60);\\n\\n assembly {\\n // copy 0x60 bytes from end of footer\\n extcodecopy(address(), add(footer, 0x20), 0x4d, 0xad)\\n }\\n\\n return abi.decode(footer, (uint256, address, uint256));\\n }\\n\\n function salt() internal view returns (uint256) {\\n bytes memory footer = new bytes(0x20);\\n\\n assembly {\\n // copy 0x20 bytes from beginning of footer\\n extcodecopy(address(), add(footer, 0x20), 0x2d, 0x4d)\\n }\\n\\n return abi.decode(footer, (uint256));\\n }\\n}\\n\",\"keccak256\":\"0xf7a8eb3b4fb63068eb8ed2a1a129e4676af842541f43c1a1dc96a9f295060c45\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}}}}} \ No newline at end of file diff --git a/build/contracts/build-info/2976796d46a1fc41934566b3e04b2516.json b/build/contracts/build-info/2976796d46a1fc41934566b3e04b2516.json deleted file mode 100644 index 31f8f93..0000000 --- a/build/contracts/build-info/2976796d46a1fc41934566b3e04b2516.json +++ /dev/null @@ -1 +0,0 @@ -{"id":"2976796d46a1fc41934566b3e04b2516","_format":"hh-sol-build-info-1","solcVersion":"0.8.17","solcLongVersion":"0.8.17+commit.8df45f5f","input":{"language":"Solidity","sources":{"@openzeppelin/contracts/interfaces/IERC1271.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n"},"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (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 *\n * NOTE: 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 *\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.\n *\n * NOTE: 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 *\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/token/ERC721/IERC721.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (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`.\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(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\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(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"},"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface 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 `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"},"@openzeppelin/contracts/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"},"contracts/AccountRegistryBridge.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.13;\n\nimport \"./interfaces/IRegistry.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\ncontract AccountRegistryBridge {\n address public constant REGISTRY = \t0x02101dfB77FDE026414827Fdc604ddAF224F0921;\n address public constant IMPLEMENTATION = 0x2D25602551487C3f3354dD80D76D54383A243358;\n\n function createAccount(\n address contractAddress,\n uint256 tokenId\n ) external returns (address) {\n return IRegistry(REGISTRY).createAccount(\n IMPLEMENTATION,\n block.chainid,\n contractAddress,\n tokenId,\n 0,\n ''\n );\n }\n\n function account(\n address contractAddress,\n uint256 tokenId\n ) external view returns (address) {\n return IRegistry(REGISTRY).account(\n IMPLEMENTATION,\n block.chainid,\n contractAddress,\n tokenId,\n 0\n );\n }\n}"},"contracts/ChargedParticlesAccount.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\nimport \"./MinimalisticAccount.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\n\ncontract ChargedParticlesAccount is MinimalisticAccount {\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success) {\n // Check permission\n\n // Transfer to self\n }\n}"},"contracts/interfaces/IERC6551Account.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\ninterface IERC6551AccountProxy {\n function implementation() external view returns (address);\n}\n\n/// @dev the ERC-165 identifier for this interface is `0xeff4d378`\ninterface IERC6551Account {\n event TransactionExecuted(address indexed target, uint256 indexed value, bytes data);\n\n receive() external payable;\n\n function executeCall(\n address to,\n uint256 value,\n bytes calldata data\n ) external payable returns (bytes memory);\n\n function token()\n external\n view\n returns (uint256 chainId, address tokenContract, uint256 tokenId);\n\n function owner() external view returns (address);\n}\n"},"contracts/interfaces/IRegistry.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\ninterface IRegistry {\n function createAccount(\n address implementation,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId,\n uint256 salt,\n bytes calldata initData\n ) external returns (address);\n\n function account(\n address implementation,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId,\n uint256 salt\n ) external view returns (address);\n}\n"},"contracts/lib/ERC6551AccountLib.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\nlibrary ERC6551AccountLib {\n function token()\n internal\n view\n returns (\n uint256,\n address,\n uint256\n )\n {\n bytes memory footer = new bytes(0x60);\n\n assembly {\n // copy 0x60 bytes from end of footer\n extcodecopy(address(), add(footer, 0x20), 0x4d, 0xad)\n }\n\n return abi.decode(footer, (uint256, address, uint256));\n }\n\n function salt() internal view returns (uint256) {\n bytes memory footer = new bytes(0x20);\n\n assembly {\n // copy 0x20 bytes from beginning of footer\n extcodecopy(address(), add(footer, 0x20), 0x2d, 0x4d)\n }\n\n return abi.decode(footer, (uint256));\n }\n}\n"},"contracts/MinimalisticAccount.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\nimport \"./interfaces/IERC6551Account.sol\";\nimport \"./lib/ERC6551AccountLib.sol\";\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC1271.sol\";\n\nerror NotAuthorized();\nerror InvalidInput();\nerror AccountLocked();\nerror ExceedsMaxLockTime();\nerror UntrustedImplementation();\nerror OwnershipCycle();\n\n/**\n * @title A smart contract account owned by a single ERC721 token\n */\ncontract MinimalisticAccount is\n IERC165,\n IERC6551Account,\n IERC721Receiver,\n IERC1155Receiver\n{\n /// @dev timestamp at which this account will be unlocked\n uint256 public lockedUntil;\n\n /// @dev mapping from owner => caller => has permissions\n mapping(address => mapping(address => bool)) public permissions;\n\n event OverrideUpdated(\n address owner,\n bytes4 selector,\n address implementation\n );\n\n event PermissionUpdated(address owner, address caller, bool hasPermission);\n\n event LockUpdated(uint256 lockedUntil);\n\n /// @dev reverts if caller is not the owner of the account\n modifier onlyOwner() {\n if (msg.sender != owner()) revert NotAuthorized();\n _;\n }\n\n /// @dev reverts if caller is not authorized to execute on this account\n modifier onlyAuthorized() {\n if (!isAuthorized(msg.sender)) revert NotAuthorized();\n _;\n }\n\n /// @dev reverts if this account is currently locked\n modifier onlyUnlocked() {\n if (isLocked()) revert AccountLocked();\n _;\n }\n\n constructor() {}\n\n /// @dev allows eth transfers by default, but allows account owner to override\n receive() external payable {\n }\n\n /// @dev executes a low-level call against an account if the caller is authorized to make calls\n function executeCall(\n address to,\n uint256 value,\n bytes calldata data\n ) external payable onlyAuthorized onlyUnlocked returns (bytes memory) {\n emit TransactionExecuted(to, value, data);\n\n return _call(to, value, data);\n }\n\n /// @dev grants a given caller execution permissions\n function setPermissions(\n address[] calldata callers,\n bool[] calldata _permissions\n ) external onlyUnlocked {\n address _owner = owner();\n if (msg.sender != _owner) revert NotAuthorized();\n\n uint256 length = callers.length;\n\n if (_permissions.length != length) revert InvalidInput();\n\n for (uint256 i = 0; i < length; i++) {\n permissions[_owner][callers[i]] = _permissions[i];\n emit PermissionUpdated(_owner, callers[i], _permissions[i]);\n }\n }\n\n /// @dev locks the account until a certain timestamp\n function lock(uint256 _lockedUntil) external onlyOwner onlyUnlocked {\n if (_lockedUntil > block.timestamp + 365 days)\n revert ExceedsMaxLockTime();\n\n lockedUntil = _lockedUntil;\n\n emit LockUpdated(_lockedUntil);\n }\n\n /// @dev returns the current lock status of the account as a boolean\n function isLocked() public view returns (bool) {\n return lockedUntil > block.timestamp;\n }\n\n /// @dev Returns the EIP-155 chain ID, token contract address, and token ID for the token that\n /// owns this account.\n function token()\n external\n view\n returns (\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n )\n {\n return ERC6551AccountLib.token();\n }\n\n /// @dev Returns the owner of the ERC-721 token which owns this account. By default, the owner\n /// of the token has full permissions on the account.\n function owner() public view returns (address) {\n (\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) = ERC6551AccountLib.token();\n\n if (chainId != block.chainid) return address(0);\n\n return IERC721(tokenContract).ownerOf(tokenId);\n }\n\n /// @dev Returns the authorization status for a given caller\n function isAuthorized(address caller) public view returns (bool) {\n (\n ,\n address tokenContract,\n uint256 tokenId\n ) = ERC6551AccountLib.token();\n address _owner = IERC721(tokenContract).ownerOf(tokenId);\n\n // authorize token owner\n if (caller == _owner) return true;\n\n // authorize caller if owner has granted permissions\n if (permissions[_owner][caller]) return true;\n\n return false;\n }\n\n /// @dev Returns true if a given interfaceId is supported by this account. This method can be\n /// extended by an override.\n function supportsInterface(bytes4 interfaceId)\n public\n pure \n override\n returns (bool)\n {\n bool defaultSupport = interfaceId == type(IERC165).interfaceId ||\n interfaceId == type(IERC1155Receiver).interfaceId ||\n interfaceId == type(IERC6551Account).interfaceId;\n\n if (defaultSupport) return true;\n\n return false;\n }\n\n /// @dev Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle.\n /// This function can be overriden.\n function onERC721Received(\n address,\n address,\n uint256 receivedTokenId,\n bytes memory\n ) public view override returns (bytes4) {\n (\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) = ERC6551AccountLib.token();\n\n if (\n chainId == block.chainid &&\n tokenContract == msg.sender &&\n tokenId == receivedTokenId\n ) revert OwnershipCycle();\n\n return this.onERC721Received.selector;\n }\n\n /// @dev Allows ERC-1155 tokens to be received. This function can be overriden.\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes memory\n ) public pure override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n /// @dev Allows ERC-1155 token batches to be received. This function can be overriden.\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] memory,\n uint256[] memory,\n bytes memory\n ) public pure override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n\n /// @dev Executes a low-level call\n function _call(\n address to,\n uint256 value,\n bytes calldata data\n ) internal returns (bytes memory result) {\n bool success;\n (success, result) = to.call{value: value}(data);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /// @dev Executes a low-level static call\n function _callStatic(address to, bytes calldata data)\n internal\n view\n returns (bytes memory result)\n {\n bool success;\n (success, result) = to.staticcall(data);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n}\n"}},"settings":{"optimizer":{"enabled":true,"runs":200},"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata","devdoc","userdoc","storageLayout","evm.gasEstimates"],"":["ast"]}},"metadata":{"useLiteralContent":true}}},"output":{"sources":{"@openzeppelin/contracts/interfaces/IERC1271.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/interfaces/IERC1271.sol","exportedSymbols":{"IERC1271":[13]},"id":14,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":1,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"92:23:0"},{"abstract":false,"baseContracts":[],"canonicalName":"IERC1271","contractDependencies":[],"contractKind":"interface","documentation":{"id":2,"nodeType":"StructuredDocumentation","src":"117:189:0","text":" @dev Interface of the ERC1271 standard signature validation method for\n contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n _Available since v4.1._"},"fullyImplemented":false,"id":13,"linearizedBaseContracts":[13],"name":"IERC1271","nameLocation":"317:8:0","nodeType":"ContractDefinition","nodes":[{"documentation":{"id":3,"nodeType":"StructuredDocumentation","src":"332:220:0","text":" @dev Should return whether the signature provided is valid for the provided data\n @param hash Hash of the data to be signed\n @param signature Signature byte array associated with _data"},"functionSelector":"1626ba7e","id":12,"implemented":false,"kind":"function","modifiers":[],"name":"isValidSignature","nameLocation":"566:16:0","nodeType":"FunctionDefinition","parameters":{"id":8,"nodeType":"ParameterList","parameters":[{"constant":false,"id":5,"mutability":"mutable","name":"hash","nameLocation":"591:4:0","nodeType":"VariableDeclaration","scope":12,"src":"583:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"},"typeName":{"id":4,"name":"bytes32","nodeType":"ElementaryTypeName","src":"583:7:0","typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}},"visibility":"internal"},{"constant":false,"id":7,"mutability":"mutable","name":"signature","nameLocation":"610:9:0","nodeType":"VariableDeclaration","scope":12,"src":"597:22:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":6,"name":"bytes","nodeType":"ElementaryTypeName","src":"597:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"582:38:0"},"returnParameters":{"id":11,"nodeType":"ParameterList","parameters":[{"constant":false,"id":10,"mutability":"mutable","name":"magicValue","nameLocation":"651:10:0","nodeType":"VariableDeclaration","scope":12,"src":"644:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":9,"name":"bytes4","nodeType":"ElementaryTypeName","src":"644:6:0","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"643:19:0"},"scope":13,"src":"557:106:0","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":14,"src":"307:358:0","usedErrors":[]}],"src":"92:574:0"},"id":0},"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol","exportedSymbols":{"IERC1155Receiver":[54],"IERC165":[200]},"id":55,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":15,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"118:23:1"},{"absolutePath":"@openzeppelin/contracts/utils/introspection/IERC165.sol","file":"../../utils/introspection/IERC165.sol","id":16,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":55,"sourceUnit":201,"src":"143:47:1","symbolAliases":[],"unitAlias":""},{"abstract":false,"baseContracts":[{"baseName":{"id":18,"name":"IERC165","nameLocations":["262:7:1"],"nodeType":"IdentifierPath","referencedDeclaration":200,"src":"262:7:1"},"id":19,"nodeType":"InheritanceSpecifier","src":"262:7:1"}],"canonicalName":"IERC1155Receiver","contractDependencies":[],"contractKind":"interface","documentation":{"id":17,"nodeType":"StructuredDocumentation","src":"192:39:1","text":" @dev _Available since v3.1._"},"fullyImplemented":false,"id":54,"linearizedBaseContracts":[54,200],"name":"IERC1155Receiver","nameLocation":"242:16:1","nodeType":"ContractDefinition","nodes":[{"documentation":{"id":20,"nodeType":"StructuredDocumentation","src":"276:826:1","text":" @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 NOTE: 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"},"functionSelector":"f23a6e61","id":35,"implemented":false,"kind":"function","modifiers":[],"name":"onERC1155Received","nameLocation":"1116:17:1","nodeType":"FunctionDefinition","parameters":{"id":31,"nodeType":"ParameterList","parameters":[{"constant":false,"id":22,"mutability":"mutable","name":"operator","nameLocation":"1151:8:1","nodeType":"VariableDeclaration","scope":35,"src":"1143:16:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":21,"name":"address","nodeType":"ElementaryTypeName","src":"1143:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":24,"mutability":"mutable","name":"from","nameLocation":"1177:4:1","nodeType":"VariableDeclaration","scope":35,"src":"1169:12:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":23,"name":"address","nodeType":"ElementaryTypeName","src":"1169:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":26,"mutability":"mutable","name":"id","nameLocation":"1199:2:1","nodeType":"VariableDeclaration","scope":35,"src":"1191:10:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":25,"name":"uint256","nodeType":"ElementaryTypeName","src":"1191:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":28,"mutability":"mutable","name":"value","nameLocation":"1219:5:1","nodeType":"VariableDeclaration","scope":35,"src":"1211:13:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":27,"name":"uint256","nodeType":"ElementaryTypeName","src":"1211:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":30,"mutability":"mutable","name":"data","nameLocation":"1249:4:1","nodeType":"VariableDeclaration","scope":35,"src":"1234:19:1","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":29,"name":"bytes","nodeType":"ElementaryTypeName","src":"1234:5:1","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1133:126:1"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[{"constant":false,"id":33,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":35,"src":"1278:6:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":32,"name":"bytes4","nodeType":"ElementaryTypeName","src":"1278:6:1","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"1277:8:1"},"scope":54,"src":"1107:179:1","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":36,"nodeType":"StructuredDocumentation","src":"1292:994:1","text":" @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.\n NOTE: 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"},"functionSelector":"bc197c81","id":53,"implemented":false,"kind":"function","modifiers":[],"name":"onERC1155BatchReceived","nameLocation":"2300:22:1","nodeType":"FunctionDefinition","parameters":{"id":49,"nodeType":"ParameterList","parameters":[{"constant":false,"id":38,"mutability":"mutable","name":"operator","nameLocation":"2340:8:1","nodeType":"VariableDeclaration","scope":53,"src":"2332:16:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":37,"name":"address","nodeType":"ElementaryTypeName","src":"2332:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":40,"mutability":"mutable","name":"from","nameLocation":"2366:4:1","nodeType":"VariableDeclaration","scope":53,"src":"2358:12:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":39,"name":"address","nodeType":"ElementaryTypeName","src":"2358:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":43,"mutability":"mutable","name":"ids","nameLocation":"2399:3:1","nodeType":"VariableDeclaration","scope":53,"src":"2380:22:1","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_calldata_ptr","typeString":"uint256[]"},"typeName":{"baseType":{"id":41,"name":"uint256","nodeType":"ElementaryTypeName","src":"2380:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":42,"nodeType":"ArrayTypeName","src":"2380:9:1","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_storage_ptr","typeString":"uint256[]"}},"visibility":"internal"},{"constant":false,"id":46,"mutability":"mutable","name":"values","nameLocation":"2431:6:1","nodeType":"VariableDeclaration","scope":53,"src":"2412:25:1","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_calldata_ptr","typeString":"uint256[]"},"typeName":{"baseType":{"id":44,"name":"uint256","nodeType":"ElementaryTypeName","src":"2412:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":45,"nodeType":"ArrayTypeName","src":"2412:9:1","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_storage_ptr","typeString":"uint256[]"}},"visibility":"internal"},{"constant":false,"id":48,"mutability":"mutable","name":"data","nameLocation":"2462:4:1","nodeType":"VariableDeclaration","scope":53,"src":"2447:19:1","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":47,"name":"bytes","nodeType":"ElementaryTypeName","src":"2447:5:1","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"2322:150:1"},"returnParameters":{"id":52,"nodeType":"ParameterList","parameters":[{"constant":false,"id":51,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":53,"src":"2491:6:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":50,"name":"bytes4","nodeType":"ElementaryTypeName","src":"2491:6:1","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"2490:8:1"},"scope":54,"src":"2291:208:1","stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"scope":55,"src":"232:2269:1","usedErrors":[]}],"src":"118:2384:1"},"id":1},"@openzeppelin/contracts/token/ERC721/IERC721.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721.sol","exportedSymbols":{"IERC165":[200],"IERC721":[170]},"id":171,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":56,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"108:23:2"},{"absolutePath":"@openzeppelin/contracts/utils/introspection/IERC165.sol","file":"../../utils/introspection/IERC165.sol","id":57,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":171,"sourceUnit":201,"src":"133:47:2","symbolAliases":[],"unitAlias":""},{"abstract":false,"baseContracts":[{"baseName":{"id":59,"name":"IERC165","nameLocations":["271:7:2"],"nodeType":"IdentifierPath","referencedDeclaration":200,"src":"271:7:2"},"id":60,"nodeType":"InheritanceSpecifier","src":"271:7:2"}],"canonicalName":"IERC721","contractDependencies":[],"contractKind":"interface","documentation":{"id":58,"nodeType":"StructuredDocumentation","src":"182:67:2","text":" @dev Required interface of an ERC721 compliant contract."},"fullyImplemented":false,"id":170,"linearizedBaseContracts":[170,200],"name":"IERC721","nameLocation":"260:7:2","nodeType":"ContractDefinition","nodes":[{"anonymous":false,"documentation":{"id":61,"nodeType":"StructuredDocumentation","src":"285:88:2","text":" @dev Emitted when `tokenId` token is transferred from `from` to `to`."},"eventSelector":"ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","id":69,"name":"Transfer","nameLocation":"384:8:2","nodeType":"EventDefinition","parameters":{"id":68,"nodeType":"ParameterList","parameters":[{"constant":false,"id":63,"indexed":true,"mutability":"mutable","name":"from","nameLocation":"409:4:2","nodeType":"VariableDeclaration","scope":69,"src":"393:20:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":62,"name":"address","nodeType":"ElementaryTypeName","src":"393:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":65,"indexed":true,"mutability":"mutable","name":"to","nameLocation":"431:2:2","nodeType":"VariableDeclaration","scope":69,"src":"415:18:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":64,"name":"address","nodeType":"ElementaryTypeName","src":"415:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":67,"indexed":true,"mutability":"mutable","name":"tokenId","nameLocation":"451:7:2","nodeType":"VariableDeclaration","scope":69,"src":"435:23:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":66,"name":"uint256","nodeType":"ElementaryTypeName","src":"435:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"392:67:2"},"src":"378:82:2"},{"anonymous":false,"documentation":{"id":70,"nodeType":"StructuredDocumentation","src":"466:94:2","text":" @dev Emitted when `owner` enables `approved` to manage the `tokenId` token."},"eventSelector":"8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925","id":78,"name":"Approval","nameLocation":"571:8:2","nodeType":"EventDefinition","parameters":{"id":77,"nodeType":"ParameterList","parameters":[{"constant":false,"id":72,"indexed":true,"mutability":"mutable","name":"owner","nameLocation":"596:5:2","nodeType":"VariableDeclaration","scope":78,"src":"580:21:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":71,"name":"address","nodeType":"ElementaryTypeName","src":"580:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":74,"indexed":true,"mutability":"mutable","name":"approved","nameLocation":"619:8:2","nodeType":"VariableDeclaration","scope":78,"src":"603:24:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":73,"name":"address","nodeType":"ElementaryTypeName","src":"603:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":76,"indexed":true,"mutability":"mutable","name":"tokenId","nameLocation":"645:7:2","nodeType":"VariableDeclaration","scope":78,"src":"629:23:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":75,"name":"uint256","nodeType":"ElementaryTypeName","src":"629:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"579:74:2"},"src":"565:89:2"},{"anonymous":false,"documentation":{"id":79,"nodeType":"StructuredDocumentation","src":"660:117:2","text":" @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets."},"eventSelector":"17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31","id":87,"name":"ApprovalForAll","nameLocation":"788:14:2","nodeType":"EventDefinition","parameters":{"id":86,"nodeType":"ParameterList","parameters":[{"constant":false,"id":81,"indexed":true,"mutability":"mutable","name":"owner","nameLocation":"819:5:2","nodeType":"VariableDeclaration","scope":87,"src":"803:21:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":80,"name":"address","nodeType":"ElementaryTypeName","src":"803:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":83,"indexed":true,"mutability":"mutable","name":"operator","nameLocation":"842:8:2","nodeType":"VariableDeclaration","scope":87,"src":"826:24:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":82,"name":"address","nodeType":"ElementaryTypeName","src":"826:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":85,"indexed":false,"mutability":"mutable","name":"approved","nameLocation":"857:8:2","nodeType":"VariableDeclaration","scope":87,"src":"852:13:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":84,"name":"bool","nodeType":"ElementaryTypeName","src":"852:4:2","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"802:64:2"},"src":"782:85:2"},{"documentation":{"id":88,"nodeType":"StructuredDocumentation","src":"873:76:2","text":" @dev Returns the number of tokens in ``owner``'s account."},"functionSelector":"70a08231","id":95,"implemented":false,"kind":"function","modifiers":[],"name":"balanceOf","nameLocation":"963:9:2","nodeType":"FunctionDefinition","parameters":{"id":91,"nodeType":"ParameterList","parameters":[{"constant":false,"id":90,"mutability":"mutable","name":"owner","nameLocation":"981:5:2","nodeType":"VariableDeclaration","scope":95,"src":"973:13:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":89,"name":"address","nodeType":"ElementaryTypeName","src":"973:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"972:15:2"},"returnParameters":{"id":94,"nodeType":"ParameterList","parameters":[{"constant":false,"id":93,"mutability":"mutable","name":"balance","nameLocation":"1019:7:2","nodeType":"VariableDeclaration","scope":95,"src":"1011:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":92,"name":"uint256","nodeType":"ElementaryTypeName","src":"1011:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1010:17:2"},"scope":170,"src":"954:74:2","stateMutability":"view","virtual":false,"visibility":"external"},{"documentation":{"id":96,"nodeType":"StructuredDocumentation","src":"1034:131:2","text":" @dev Returns the owner of the `tokenId` token.\n Requirements:\n - `tokenId` must exist."},"functionSelector":"6352211e","id":103,"implemented":false,"kind":"function","modifiers":[],"name":"ownerOf","nameLocation":"1179:7:2","nodeType":"FunctionDefinition","parameters":{"id":99,"nodeType":"ParameterList","parameters":[{"constant":false,"id":98,"mutability":"mutable","name":"tokenId","nameLocation":"1195:7:2","nodeType":"VariableDeclaration","scope":103,"src":"1187:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":97,"name":"uint256","nodeType":"ElementaryTypeName","src":"1187:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1186:17:2"},"returnParameters":{"id":102,"nodeType":"ParameterList","parameters":[{"constant":false,"id":101,"mutability":"mutable","name":"owner","nameLocation":"1235:5:2","nodeType":"VariableDeclaration","scope":103,"src":"1227:13:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":100,"name":"address","nodeType":"ElementaryTypeName","src":"1227:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1226:15:2"},"scope":170,"src":"1170:72:2","stateMutability":"view","virtual":false,"visibility":"external"},{"documentation":{"id":104,"nodeType":"StructuredDocumentation","src":"1248:556:2","text":" @dev Safely transfers `tokenId` token from `from` to `to`.\n Requirements:\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 Emits a {Transfer} event."},"functionSelector":"b88d4fde","id":115,"implemented":false,"kind":"function","modifiers":[],"name":"safeTransferFrom","nameLocation":"1818:16:2","nodeType":"FunctionDefinition","parameters":{"id":113,"nodeType":"ParameterList","parameters":[{"constant":false,"id":106,"mutability":"mutable","name":"from","nameLocation":"1843:4:2","nodeType":"VariableDeclaration","scope":115,"src":"1835:12:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":105,"name":"address","nodeType":"ElementaryTypeName","src":"1835:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":108,"mutability":"mutable","name":"to","nameLocation":"1857:2:2","nodeType":"VariableDeclaration","scope":115,"src":"1849:10:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":107,"name":"address","nodeType":"ElementaryTypeName","src":"1849:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":110,"mutability":"mutable","name":"tokenId","nameLocation":"1869:7:2","nodeType":"VariableDeclaration","scope":115,"src":"1861:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":109,"name":"uint256","nodeType":"ElementaryTypeName","src":"1861:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":112,"mutability":"mutable","name":"data","nameLocation":"1893:4:2","nodeType":"VariableDeclaration","scope":115,"src":"1878:19:2","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":111,"name":"bytes","nodeType":"ElementaryTypeName","src":"1878:5:2","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1834:64:2"},"returnParameters":{"id":114,"nodeType":"ParameterList","parameters":[],"src":"1907:0:2"},"scope":170,"src":"1809:99:2","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":116,"nodeType":"StructuredDocumentation","src":"1914:687:2","text":" @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 Requirements:\n - `from` cannot be the zero address.\n - `to` cannot be the zero address.\n - `tokenId` token must exist and be owned by `from`.\n - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n Emits a {Transfer} event."},"functionSelector":"42842e0e","id":125,"implemented":false,"kind":"function","modifiers":[],"name":"safeTransferFrom","nameLocation":"2615:16:2","nodeType":"FunctionDefinition","parameters":{"id":123,"nodeType":"ParameterList","parameters":[{"constant":false,"id":118,"mutability":"mutable","name":"from","nameLocation":"2640:4:2","nodeType":"VariableDeclaration","scope":125,"src":"2632:12:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":117,"name":"address","nodeType":"ElementaryTypeName","src":"2632:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":120,"mutability":"mutable","name":"to","nameLocation":"2654:2:2","nodeType":"VariableDeclaration","scope":125,"src":"2646:10:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":119,"name":"address","nodeType":"ElementaryTypeName","src":"2646:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":122,"mutability":"mutable","name":"tokenId","nameLocation":"2666:7:2","nodeType":"VariableDeclaration","scope":125,"src":"2658:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":121,"name":"uint256","nodeType":"ElementaryTypeName","src":"2658:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2631:43:2"},"returnParameters":{"id":124,"nodeType":"ParameterList","parameters":[],"src":"2683:0:2"},"scope":170,"src":"2606:78:2","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":126,"nodeType":"StructuredDocumentation","src":"2690:732:2","text":" @dev Transfers `tokenId` token from `from` to `to`.\n WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n understand this adds an external call which potentially creates a reentrancy vulnerability.\n Requirements:\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 Emits a {Transfer} event."},"functionSelector":"23b872dd","id":135,"implemented":false,"kind":"function","modifiers":[],"name":"transferFrom","nameLocation":"3436:12:2","nodeType":"FunctionDefinition","parameters":{"id":133,"nodeType":"ParameterList","parameters":[{"constant":false,"id":128,"mutability":"mutable","name":"from","nameLocation":"3457:4:2","nodeType":"VariableDeclaration","scope":135,"src":"3449:12:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":127,"name":"address","nodeType":"ElementaryTypeName","src":"3449:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":130,"mutability":"mutable","name":"to","nameLocation":"3471:2:2","nodeType":"VariableDeclaration","scope":135,"src":"3463:10:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":129,"name":"address","nodeType":"ElementaryTypeName","src":"3463:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":132,"mutability":"mutable","name":"tokenId","nameLocation":"3483:7:2","nodeType":"VariableDeclaration","scope":135,"src":"3475:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":131,"name":"uint256","nodeType":"ElementaryTypeName","src":"3475:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3448:43:2"},"returnParameters":{"id":134,"nodeType":"ParameterList","parameters":[],"src":"3500:0:2"},"scope":170,"src":"3427:74:2","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":136,"nodeType":"StructuredDocumentation","src":"3507:452:2","text":" @dev Gives permission to `to` to transfer `tokenId` token to another account.\n The approval is cleared when the token is transferred.\n Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n Requirements:\n - The caller must own the token or be an approved operator.\n - `tokenId` must exist.\n Emits an {Approval} event."},"functionSelector":"095ea7b3","id":143,"implemented":false,"kind":"function","modifiers":[],"name":"approve","nameLocation":"3973:7:2","nodeType":"FunctionDefinition","parameters":{"id":141,"nodeType":"ParameterList","parameters":[{"constant":false,"id":138,"mutability":"mutable","name":"to","nameLocation":"3989:2:2","nodeType":"VariableDeclaration","scope":143,"src":"3981:10:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":137,"name":"address","nodeType":"ElementaryTypeName","src":"3981:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":140,"mutability":"mutable","name":"tokenId","nameLocation":"4001:7:2","nodeType":"VariableDeclaration","scope":143,"src":"3993:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":139,"name":"uint256","nodeType":"ElementaryTypeName","src":"3993:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3980:29:2"},"returnParameters":{"id":142,"nodeType":"ParameterList","parameters":[],"src":"4018:0:2"},"scope":170,"src":"3964:55:2","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":144,"nodeType":"StructuredDocumentation","src":"4025:309:2","text":" @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 Requirements:\n - The `operator` cannot be the caller.\n Emits an {ApprovalForAll} event."},"functionSelector":"a22cb465","id":151,"implemented":false,"kind":"function","modifiers":[],"name":"setApprovalForAll","nameLocation":"4348:17:2","nodeType":"FunctionDefinition","parameters":{"id":149,"nodeType":"ParameterList","parameters":[{"constant":false,"id":146,"mutability":"mutable","name":"operator","nameLocation":"4374:8:2","nodeType":"VariableDeclaration","scope":151,"src":"4366:16:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":145,"name":"address","nodeType":"ElementaryTypeName","src":"4366:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":148,"mutability":"mutable","name":"approved","nameLocation":"4389:8:2","nodeType":"VariableDeclaration","scope":151,"src":"4384:13:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":147,"name":"bool","nodeType":"ElementaryTypeName","src":"4384:4:2","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"4365:33:2"},"returnParameters":{"id":150,"nodeType":"ParameterList","parameters":[],"src":"4407:0:2"},"scope":170,"src":"4339:69:2","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":152,"nodeType":"StructuredDocumentation","src":"4414:139:2","text":" @dev Returns the account approved for `tokenId` token.\n Requirements:\n - `tokenId` must exist."},"functionSelector":"081812fc","id":159,"implemented":false,"kind":"function","modifiers":[],"name":"getApproved","nameLocation":"4567:11:2","nodeType":"FunctionDefinition","parameters":{"id":155,"nodeType":"ParameterList","parameters":[{"constant":false,"id":154,"mutability":"mutable","name":"tokenId","nameLocation":"4587:7:2","nodeType":"VariableDeclaration","scope":159,"src":"4579:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":153,"name":"uint256","nodeType":"ElementaryTypeName","src":"4579:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"4578:17:2"},"returnParameters":{"id":158,"nodeType":"ParameterList","parameters":[{"constant":false,"id":157,"mutability":"mutable","name":"operator","nameLocation":"4627:8:2","nodeType":"VariableDeclaration","scope":159,"src":"4619:16:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":156,"name":"address","nodeType":"ElementaryTypeName","src":"4619:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"4618:18:2"},"scope":170,"src":"4558:79:2","stateMutability":"view","virtual":false,"visibility":"external"},{"documentation":{"id":160,"nodeType":"StructuredDocumentation","src":"4643:138:2","text":" @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n See {setApprovalForAll}"},"functionSelector":"e985e9c5","id":169,"implemented":false,"kind":"function","modifiers":[],"name":"isApprovedForAll","nameLocation":"4795:16:2","nodeType":"FunctionDefinition","parameters":{"id":165,"nodeType":"ParameterList","parameters":[{"constant":false,"id":162,"mutability":"mutable","name":"owner","nameLocation":"4820:5:2","nodeType":"VariableDeclaration","scope":169,"src":"4812:13:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":161,"name":"address","nodeType":"ElementaryTypeName","src":"4812:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":164,"mutability":"mutable","name":"operator","nameLocation":"4835:8:2","nodeType":"VariableDeclaration","scope":169,"src":"4827:16:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":163,"name":"address","nodeType":"ElementaryTypeName","src":"4827:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"4811:33:2"},"returnParameters":{"id":168,"nodeType":"ParameterList","parameters":[{"constant":false,"id":167,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":169,"src":"4868:4:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":166,"name":"bool","nodeType":"ElementaryTypeName","src":"4868:4:2","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"4867:6:2"},"scope":170,"src":"4786:88:2","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":171,"src":"250:4626:2","usedErrors":[]}],"src":"108:4769:2"},"id":2},"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol","exportedSymbols":{"IERC721Receiver":[188]},"id":189,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":172,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"116:23:3"},{"abstract":false,"baseContracts":[],"canonicalName":"IERC721Receiver","contractDependencies":[],"contractKind":"interface","documentation":{"id":173,"nodeType":"StructuredDocumentation","src":"141:152:3","text":" @title ERC721 token receiver interface\n @dev Interface for any contract that wants to support safeTransfers\n from ERC721 asset contracts."},"fullyImplemented":false,"id":188,"linearizedBaseContracts":[188],"name":"IERC721Receiver","nameLocation":"304:15:3","nodeType":"ContractDefinition","nodes":[{"documentation":{"id":174,"nodeType":"StructuredDocumentation","src":"326:493:3","text":" @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n by `operator` from `from`, this function is called.\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 The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`."},"functionSelector":"150b7a02","id":187,"implemented":false,"kind":"function","modifiers":[],"name":"onERC721Received","nameLocation":"833:16:3","nodeType":"FunctionDefinition","parameters":{"id":183,"nodeType":"ParameterList","parameters":[{"constant":false,"id":176,"mutability":"mutable","name":"operator","nameLocation":"867:8:3","nodeType":"VariableDeclaration","scope":187,"src":"859:16:3","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":175,"name":"address","nodeType":"ElementaryTypeName","src":"859:7:3","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":178,"mutability":"mutable","name":"from","nameLocation":"893:4:3","nodeType":"VariableDeclaration","scope":187,"src":"885:12:3","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":177,"name":"address","nodeType":"ElementaryTypeName","src":"885:7:3","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":180,"mutability":"mutable","name":"tokenId","nameLocation":"915:7:3","nodeType":"VariableDeclaration","scope":187,"src":"907:15:3","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":179,"name":"uint256","nodeType":"ElementaryTypeName","src":"907:7:3","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":182,"mutability":"mutable","name":"data","nameLocation":"947:4:3","nodeType":"VariableDeclaration","scope":187,"src":"932:19:3","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":181,"name":"bytes","nodeType":"ElementaryTypeName","src":"932:5:3","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"849:108:3"},"returnParameters":{"id":186,"nodeType":"ParameterList","parameters":[{"constant":false,"id":185,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":187,"src":"976:6:3","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":184,"name":"bytes4","nodeType":"ElementaryTypeName","src":"976:6:3","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"975:8:3"},"scope":188,"src":"824:160:3","stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"scope":189,"src":"294:692:3","usedErrors":[]}],"src":"116:871:3"},"id":3},"@openzeppelin/contracts/utils/introspection/IERC165.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/utils/introspection/IERC165.sol","exportedSymbols":{"IERC165":[200]},"id":201,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":190,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"100:23:4"},{"abstract":false,"baseContracts":[],"canonicalName":"IERC165","contractDependencies":[],"contractKind":"interface","documentation":{"id":191,"nodeType":"StructuredDocumentation","src":"125:279:4","text":" @dev Interface of the ERC165 standard, as defined in the\n https://eips.ethereum.org/EIPS/eip-165[EIP].\n Implementers can declare support of contract interfaces, which can then be\n queried by others ({ERC165Checker}).\n For an implementation, see {ERC165}."},"fullyImplemented":false,"id":200,"linearizedBaseContracts":[200],"name":"IERC165","nameLocation":"415:7:4","nodeType":"ContractDefinition","nodes":[{"documentation":{"id":192,"nodeType":"StructuredDocumentation","src":"429:340:4","text":" @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 This function call must use less than 30 000 gas."},"functionSelector":"01ffc9a7","id":199,"implemented":false,"kind":"function","modifiers":[],"name":"supportsInterface","nameLocation":"783:17:4","nodeType":"FunctionDefinition","parameters":{"id":195,"nodeType":"ParameterList","parameters":[{"constant":false,"id":194,"mutability":"mutable","name":"interfaceId","nameLocation":"808:11:4","nodeType":"VariableDeclaration","scope":199,"src":"801:18:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":193,"name":"bytes4","nodeType":"ElementaryTypeName","src":"801:6:4","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"800:20:4"},"returnParameters":{"id":198,"nodeType":"ParameterList","parameters":[{"constant":false,"id":197,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":199,"src":"844:4:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":196,"name":"bool","nodeType":"ElementaryTypeName","src":"844:4:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"843:6:4"},"scope":200,"src":"774:76:4","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":201,"src":"405:447:4","usedErrors":[]}],"src":"100:753:4"},"id":4},"contracts/AccountRegistryBridge.sol":{"ast":{"absolutePath":"contracts/AccountRegistryBridge.sol","exportedSymbols":{"AccountRegistryBridge":[256],"IERC165":[200],"IRegistry":[897]},"id":257,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":202,"literals":["solidity","^","0.8",".13"],"nodeType":"PragmaDirective","src":"33:24:5"},{"absolutePath":"contracts/interfaces/IRegistry.sol","file":"./interfaces/IRegistry.sol","id":203,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":257,"sourceUnit":898,"src":"59:36:5","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/utils/introspection/IERC165.sol","file":"@openzeppelin/contracts/utils/introspection/IERC165.sol","id":204,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":257,"sourceUnit":201,"src":"96:65:5","symbolAliases":[],"unitAlias":""},{"abstract":false,"baseContracts":[],"canonicalName":"AccountRegistryBridge","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"id":256,"linearizedBaseContracts":[256],"name":"AccountRegistryBridge","nameLocation":"172:21:5","nodeType":"ContractDefinition","nodes":[{"constant":true,"functionSelector":"06433b1b","id":207,"mutability":"constant","name":"REGISTRY","nameLocation":"224:8:5","nodeType":"VariableDeclaration","scope":256,"src":"200:78:5","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":205,"name":"address","nodeType":"ElementaryTypeName","src":"200:7:5","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"hexValue":"307830323130316466423737464445303236343134383237466463363034646441463232344630393231","id":206,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"236:42:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x02101dfB77FDE026414827Fdc604ddAF224F0921"},"visibility":"public"},{"constant":true,"functionSelector":"3a4741bd","id":210,"mutability":"constant","name":"IMPLEMENTATION","nameLocation":"308:14:5","nodeType":"VariableDeclaration","scope":256,"src":"284:83:5","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":208,"name":"address","nodeType":"ElementaryTypeName","src":"284:7:5","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"hexValue":"307832443235363032353531343837433366333335346444383044373644353433383341323433333538","id":209,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"325:42:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x2D25602551487C3f3354dD80D76D54383A243358"},"visibility":"public"},{"body":{"id":232,"nodeType":"Block","src":"488:203:5","statements":[{"expression":{"arguments":[{"id":223,"name":"IMPLEMENTATION","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":210,"src":"552:14:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"expression":{"id":224,"name":"block","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-4,"src":"580:5:5","typeDescriptions":{"typeIdentifier":"t_magic_block","typeString":"block"}},"id":225,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"586:7:5","memberName":"chainid","nodeType":"MemberAccess","src":"580:13:5","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":226,"name":"contractAddress","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":212,"src":"607:15:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":227,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":214,"src":"636:7:5","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"hexValue":"30","id":228,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"657:1:5","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},{"hexValue":"","id":229,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"672:2:5","typeDescriptions":{"typeIdentifier":"t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","typeString":"literal_string \"\""},"value":""}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},{"typeIdentifier":"t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","typeString":"literal_string \"\""}],"expression":{"arguments":[{"id":220,"name":"REGISTRY","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":207,"src":"515:8:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":219,"name":"IRegistry","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":897,"src":"505:9:5","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IRegistry_$897_$","typeString":"type(contract IRegistry)"}},"id":221,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"505:19:5","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_IRegistry_$897","typeString":"contract IRegistry"}},"id":222,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"525:13:5","memberName":"createAccount","nodeType":"MemberAccess","referencedDeclaration":881,"src":"505:33:5","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$_t_uint256_$_t_address_$_t_uint256_$_t_uint256_$_t_bytes_memory_ptr_$returns$_t_address_$","typeString":"function (address,uint256,address,uint256,uint256,bytes memory) external returns (address)"}},"id":230,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"505:179:5","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"functionReturnParameters":218,"id":231,"nodeType":"Return","src":"498:186:5"}]},"functionSelector":"5fbfb9cf","id":233,"implemented":true,"kind":"function","modifiers":[],"name":"createAccount","nameLocation":"383:13:5","nodeType":"FunctionDefinition","parameters":{"id":215,"nodeType":"ParameterList","parameters":[{"constant":false,"id":212,"mutability":"mutable","name":"contractAddress","nameLocation":"414:15:5","nodeType":"VariableDeclaration","scope":233,"src":"406:23:5","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":211,"name":"address","nodeType":"ElementaryTypeName","src":"406:7:5","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":214,"mutability":"mutable","name":"tokenId","nameLocation":"447:7:5","nodeType":"VariableDeclaration","scope":233,"src":"439:15:5","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":213,"name":"uint256","nodeType":"ElementaryTypeName","src":"439:7:5","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"396:64:5"},"returnParameters":{"id":218,"nodeType":"ParameterList","parameters":[{"constant":false,"id":217,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":233,"src":"479:7:5","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":216,"name":"address","nodeType":"ElementaryTypeName","src":"479:7:5","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"478:9:5"},"scope":256,"src":"374:317:5","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":254,"nodeType":"Block","src":"810:181:5","statements":[{"expression":{"arguments":[{"id":246,"name":"IMPLEMENTATION","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":210,"src":"868:14:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"expression":{"id":247,"name":"block","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-4,"src":"896:5:5","typeDescriptions":{"typeIdentifier":"t_magic_block","typeString":"block"}},"id":248,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"902:7:5","memberName":"chainid","nodeType":"MemberAccess","src":"896:13:5","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":249,"name":"contractAddress","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":235,"src":"923:15:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":250,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":237,"src":"952:7:5","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"hexValue":"30","id":251,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"973:1:5","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"expression":{"arguments":[{"id":243,"name":"REGISTRY","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":207,"src":"837:8:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":242,"name":"IRegistry","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":897,"src":"827:9:5","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IRegistry_$897_$","typeString":"type(contract IRegistry)"}},"id":244,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"827:19:5","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_IRegistry_$897","typeString":"contract IRegistry"}},"id":245,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"847:7:5","memberName":"account","nodeType":"MemberAccess","referencedDeclaration":896,"src":"827:27:5","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$_t_uint256_$_t_address_$_t_uint256_$_t_uint256_$returns$_t_address_$","typeString":"function (address,uint256,address,uint256,uint256) view external returns (address)"}},"id":252,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"827:157:5","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"functionReturnParameters":241,"id":253,"nodeType":"Return","src":"820:164:5"}]},"functionSelector":"192df655","id":255,"implemented":true,"kind":"function","modifiers":[],"name":"account","nameLocation":"706:7:5","nodeType":"FunctionDefinition","parameters":{"id":238,"nodeType":"ParameterList","parameters":[{"constant":false,"id":235,"mutability":"mutable","name":"contractAddress","nameLocation":"731:15:5","nodeType":"VariableDeclaration","scope":255,"src":"723:23:5","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":234,"name":"address","nodeType":"ElementaryTypeName","src":"723:7:5","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":237,"mutability":"mutable","name":"tokenId","nameLocation":"764:7:5","nodeType":"VariableDeclaration","scope":255,"src":"756:15:5","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":236,"name":"uint256","nodeType":"ElementaryTypeName","src":"756:7:5","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"713:64:5"},"returnParameters":{"id":241,"nodeType":"ParameterList","parameters":[{"constant":false,"id":240,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":255,"src":"801:7:5","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":239,"name":"address","nodeType":"ElementaryTypeName","src":"801:7:5","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"800:9:5"},"scope":256,"src":"697:294:5","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":257,"src":"163:830:5","usedErrors":[]}],"src":"33:960:5"},"id":5},"contracts/ChargedParticlesAccount.sol":{"ast":{"absolutePath":"contracts/ChargedParticlesAccount.sol","exportedSymbols":{"AccountLocked":[296],"ChargedParticlesAccount":[281],"ERC6551AccountLib":[952],"ExceedsMaxLockTime":[298],"IERC1155Receiver":[54],"IERC1271":[13],"IERC165":[200],"IERC6551Account":[862],"IERC6551AccountProxy":[824],"IERC721":[170],"IERC721Receiver":[188],"InvalidInput":[294],"MinimalisticAccount":[816],"NotAuthorized":[292],"OwnershipCycle":[302],"UntrustedImplementation":[300]},"id":282,"license":"UNLICENSED","nodeType":"SourceUnit","nodes":[{"id":258,"literals":["solidity","^","0.8",".13"],"nodeType":"PragmaDirective","src":"39:24:6"},{"absolutePath":"contracts/MinimalisticAccount.sol","file":"./MinimalisticAccount.sol","id":259,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":282,"sourceUnit":817,"src":"65:35:6","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721.sol","file":"@openzeppelin/contracts/token/ERC721/IERC721.sol","id":260,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":282,"sourceUnit":171,"src":"101:58:6","symbolAliases":[],"unitAlias":""},{"abstract":false,"baseContracts":[{"baseName":{"id":261,"name":"MinimalisticAccount","nameLocations":["197:19:6"],"nodeType":"IdentifierPath","referencedDeclaration":816,"src":"197:19:6"},"id":262,"nodeType":"InheritanceSpecifier","src":"197:19:6"}],"canonicalName":"ChargedParticlesAccount","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"id":281,"linearizedBaseContracts":[281,816,54,188,862,200],"name":"ChargedParticlesAccount","nameLocation":"170:23:6","nodeType":"ContractDefinition","nodes":[{"body":{"id":279,"nodeType":"Block","src":"447:56:6","statements":[]},"functionSelector":"3ff956cc","id":280,"implemented":true,"kind":"function","modifiers":[],"name":"covalentBond","nameLocation":"230:12:6","nodeType":"FunctionDefinition","parameters":{"id":275,"nodeType":"ParameterList","parameters":[{"constant":false,"id":264,"mutability":"mutable","name":"contractAddress","nameLocation":"256:15:6","nodeType":"VariableDeclaration","scope":280,"src":"248:23:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":263,"name":"address","nodeType":"ElementaryTypeName","src":"248:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":266,"mutability":"mutable","name":"tokenId","nameLocation":"285:7:6","nodeType":"VariableDeclaration","scope":280,"src":"277:15:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":265,"name":"uint256","nodeType":"ElementaryTypeName","src":"277:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":268,"mutability":"mutable","name":"basketManagerId","nameLocation":"314:15:6","nodeType":"VariableDeclaration","scope":280,"src":"298:31:6","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":267,"name":"string","nodeType":"ElementaryTypeName","src":"298:6:6","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":270,"mutability":"mutable","name":"nftTokenAddress","nameLocation":"343:15:6","nodeType":"VariableDeclaration","scope":280,"src":"335:23:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":269,"name":"address","nodeType":"ElementaryTypeName","src":"335:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":272,"mutability":"mutable","name":"nftTokenId","nameLocation":"372:10:6","nodeType":"VariableDeclaration","scope":280,"src":"364:18:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":271,"name":"uint256","nodeType":"ElementaryTypeName","src":"364:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":274,"mutability":"mutable","name":"nftTokenAmount","nameLocation":"396:14:6","nodeType":"VariableDeclaration","scope":280,"src":"388:22:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":273,"name":"uint256","nodeType":"ElementaryTypeName","src":"388:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"242:172:6"},"returnParameters":{"id":278,"nodeType":"ParameterList","parameters":[{"constant":false,"id":277,"mutability":"mutable","name":"success","nameLocation":"438:7:6","nodeType":"VariableDeclaration","scope":280,"src":"433:12:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":276,"name":"bool","nodeType":"ElementaryTypeName","src":"433:4:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"432:14:6"},"scope":281,"src":"221:282:6","stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"scope":282,"src":"161:344:6","usedErrors":[292,294,296,298,302]}],"src":"39:466:6"},"id":6},"contracts/MinimalisticAccount.sol":{"ast":{"absolutePath":"contracts/MinimalisticAccount.sol","exportedSymbols":{"AccountLocked":[296],"ERC6551AccountLib":[952],"ExceedsMaxLockTime":[298],"IERC1155Receiver":[54],"IERC1271":[13],"IERC165":[200],"IERC6551Account":[862],"IERC6551AccountProxy":[824],"IERC721":[170],"IERC721Receiver":[188],"InvalidInput":[294],"MinimalisticAccount":[816],"NotAuthorized":[292],"OwnershipCycle":[302],"UntrustedImplementation":[300]},"id":817,"license":"UNLICENSED","nodeType":"SourceUnit","nodes":[{"id":283,"literals":["solidity","^","0.8",".13"],"nodeType":"PragmaDirective","src":"39:24:7"},{"absolutePath":"contracts/interfaces/IERC6551Account.sol","file":"./interfaces/IERC6551Account.sol","id":284,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":817,"sourceUnit":863,"src":"65:42:7","symbolAliases":[],"unitAlias":""},{"absolutePath":"contracts/lib/ERC6551AccountLib.sol","file":"./lib/ERC6551AccountLib.sol","id":285,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":817,"sourceUnit":953,"src":"108:37:7","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/utils/introspection/IERC165.sol","file":"@openzeppelin/contracts/utils/introspection/IERC165.sol","id":286,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":817,"sourceUnit":201,"src":"147:65:7","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721.sol","file":"@openzeppelin/contracts/token/ERC721/IERC721.sol","id":287,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":817,"sourceUnit":171,"src":"213:58:7","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol","file":"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol","id":288,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":817,"sourceUnit":189,"src":"272:66:7","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol","file":"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol","id":289,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":817,"sourceUnit":55,"src":"339:68:7","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/interfaces/IERC1271.sol","file":"@openzeppelin/contracts/interfaces/IERC1271.sol","id":290,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":817,"sourceUnit":14,"src":"408:57:7","symbolAliases":[],"unitAlias":""},{"errorSelector":"ea8e4eb5","id":292,"name":"NotAuthorized","nameLocation":"473:13:7","nodeType":"ErrorDefinition","parameters":{"id":291,"nodeType":"ParameterList","parameters":[],"src":"486:2:7"},"src":"467:22:7"},{"errorSelector":"b4fa3fb3","id":294,"name":"InvalidInput","nameLocation":"496:12:7","nodeType":"ErrorDefinition","parameters":{"id":293,"nodeType":"ParameterList","parameters":[],"src":"508:2:7"},"src":"490:21:7"},{"errorSelector":"6315bfbb","id":296,"name":"AccountLocked","nameLocation":"518:13:7","nodeType":"ErrorDefinition","parameters":{"id":295,"nodeType":"ParameterList","parameters":[],"src":"531:2:7"},"src":"512:22:7"},{"errorSelector":"0c0a7be8","id":298,"name":"ExceedsMaxLockTime","nameLocation":"541:18:7","nodeType":"ErrorDefinition","parameters":{"id":297,"nodeType":"ParameterList","parameters":[],"src":"559:2:7"},"src":"535:27:7"},{"errorSelector":"b57d5a5e","id":300,"name":"UntrustedImplementation","nameLocation":"569:23:7","nodeType":"ErrorDefinition","parameters":{"id":299,"nodeType":"ParameterList","parameters":[],"src":"592:2:7"},"src":"563:32:7"},{"errorSelector":"b79e3f3f","id":302,"name":"OwnershipCycle","nameLocation":"602:14:7","nodeType":"ErrorDefinition","parameters":{"id":301,"nodeType":"ParameterList","parameters":[],"src":"616:2:7"},"src":"596:23:7"},{"abstract":false,"baseContracts":[{"baseName":{"id":304,"name":"IERC165","nameLocations":["731:7:7"],"nodeType":"IdentifierPath","referencedDeclaration":200,"src":"731:7:7"},"id":305,"nodeType":"InheritanceSpecifier","src":"731:7:7"},{"baseName":{"id":306,"name":"IERC6551Account","nameLocations":["744:15:7"],"nodeType":"IdentifierPath","referencedDeclaration":862,"src":"744:15:7"},"id":307,"nodeType":"InheritanceSpecifier","src":"744:15:7"},{"baseName":{"id":308,"name":"IERC721Receiver","nameLocations":["765:15:7"],"nodeType":"IdentifierPath","referencedDeclaration":188,"src":"765:15:7"},"id":309,"nodeType":"InheritanceSpecifier","src":"765:15:7"},{"baseName":{"id":310,"name":"IERC1155Receiver","nameLocations":["786:16:7"],"nodeType":"IdentifierPath","referencedDeclaration":54,"src":"786:16:7"},"id":311,"nodeType":"InheritanceSpecifier","src":"786:16:7"}],"canonicalName":"MinimalisticAccount","contractDependencies":[],"contractKind":"contract","documentation":{"id":303,"nodeType":"StructuredDocumentation","src":"621:73:7","text":" @title A smart contract account owned by a single ERC721 token"},"fullyImplemented":true,"id":816,"linearizedBaseContracts":[816,54,188,862,200],"name":"MinimalisticAccount","nameLocation":"704:19:7","nodeType":"ContractDefinition","nodes":[{"constant":false,"documentation":{"id":312,"nodeType":"StructuredDocumentation","src":"809:57:7","text":"@dev timestamp at which this account will be unlocked"},"functionSelector":"ce0617ec","id":314,"mutability":"mutable","name":"lockedUntil","nameLocation":"886:11:7","nodeType":"VariableDeclaration","scope":816,"src":"871:26:7","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":313,"name":"uint256","nodeType":"ElementaryTypeName","src":"871:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"constant":false,"documentation":{"id":315,"nodeType":"StructuredDocumentation","src":"904:56:7","text":"@dev mapping from owner => caller => has permissions"},"functionSelector":"1f9838b5","id":321,"mutability":"mutable","name":"permissions","nameLocation":"1017:11:7","nodeType":"VariableDeclaration","scope":816,"src":"965:63:7","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_mapping$_t_address_$_t_bool_$_$","typeString":"mapping(address => mapping(address => bool))"},"typeName":{"id":320,"keyType":{"id":316,"name":"address","nodeType":"ElementaryTypeName","src":"973:7:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"Mapping","src":"965:44:7","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_mapping$_t_address_$_t_bool_$_$","typeString":"mapping(address => mapping(address => bool))"},"valueType":{"id":319,"keyType":{"id":317,"name":"address","nodeType":"ElementaryTypeName","src":"992:7:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"Mapping","src":"984:24:7","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_bool_$","typeString":"mapping(address => bool)"},"valueType":{"id":318,"name":"bool","nodeType":"ElementaryTypeName","src":"1003:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}}},"visibility":"public"},{"anonymous":false,"eventSelector":"2c722487e90aca38ec1b074c3403210bd2bfb769b4da7f12f7bf0b9e37517c18","id":329,"name":"OverrideUpdated","nameLocation":"1041:15:7","nodeType":"EventDefinition","parameters":{"id":328,"nodeType":"ParameterList","parameters":[{"constant":false,"id":323,"indexed":false,"mutability":"mutable","name":"owner","nameLocation":"1074:5:7","nodeType":"VariableDeclaration","scope":329,"src":"1066:13:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":322,"name":"address","nodeType":"ElementaryTypeName","src":"1066:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":325,"indexed":false,"mutability":"mutable","name":"selector","nameLocation":"1096:8:7","nodeType":"VariableDeclaration","scope":329,"src":"1089:15:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":324,"name":"bytes4","nodeType":"ElementaryTypeName","src":"1089:6:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"},{"constant":false,"id":327,"indexed":false,"mutability":"mutable","name":"implementation","nameLocation":"1122:14:7","nodeType":"VariableDeclaration","scope":329,"src":"1114:22:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":326,"name":"address","nodeType":"ElementaryTypeName","src":"1114:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1056:86:7"},"src":"1035:108:7"},{"anonymous":false,"eventSelector":"394777a58092892d136a90c4bb7e4350c72ac50fba6a0208128677f36527dcf5","id":337,"name":"PermissionUpdated","nameLocation":"1155:17:7","nodeType":"EventDefinition","parameters":{"id":336,"nodeType":"ParameterList","parameters":[{"constant":false,"id":331,"indexed":false,"mutability":"mutable","name":"owner","nameLocation":"1181:5:7","nodeType":"VariableDeclaration","scope":337,"src":"1173:13:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":330,"name":"address","nodeType":"ElementaryTypeName","src":"1173:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":333,"indexed":false,"mutability":"mutable","name":"caller","nameLocation":"1196:6:7","nodeType":"VariableDeclaration","scope":337,"src":"1188:14:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":332,"name":"address","nodeType":"ElementaryTypeName","src":"1188:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":335,"indexed":false,"mutability":"mutable","name":"hasPermission","nameLocation":"1209:13:7","nodeType":"VariableDeclaration","scope":337,"src":"1204:18:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":334,"name":"bool","nodeType":"ElementaryTypeName","src":"1204:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1172:51:7"},"src":"1149:75:7"},{"anonymous":false,"eventSelector":"a7b24c66dd3269a292a60b3facdbb8f3e7557d1e19e64d99e0d6ee7250be63ad","id":341,"name":"LockUpdated","nameLocation":"1236:11:7","nodeType":"EventDefinition","parameters":{"id":340,"nodeType":"ParameterList","parameters":[{"constant":false,"id":339,"indexed":false,"mutability":"mutable","name":"lockedUntil","nameLocation":"1256:11:7","nodeType":"VariableDeclaration","scope":341,"src":"1248:19:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":338,"name":"uint256","nodeType":"ElementaryTypeName","src":"1248:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1247:21:7"},"src":"1230:39:7"},{"body":{"id":354,"nodeType":"Block","src":"1359:77:7","statements":[{"condition":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":348,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"expression":{"id":344,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"1373:3:7","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":345,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"1377:6:7","memberName":"sender","nodeType":"MemberAccess","src":"1373:10:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"!=","rightExpression":{"arguments":[],"expression":{"argumentTypes":[],"id":346,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":581,"src":"1387:5:7","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_address_$","typeString":"function () view returns (address)"}},"id":347,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1387:7:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"1373:21:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":352,"nodeType":"IfStatement","src":"1369:49:7","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":349,"name":"NotAuthorized","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":292,"src":"1403:13:7","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":350,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1403:15:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":351,"nodeType":"RevertStatement","src":"1396:22:7"}},{"id":353,"nodeType":"PlaceholderStatement","src":"1428:1:7"}]},"documentation":{"id":342,"nodeType":"StructuredDocumentation","src":"1275:58:7","text":"@dev reverts if caller is not the owner of the account"},"id":355,"name":"onlyOwner","nameLocation":"1347:9:7","nodeType":"ModifierDefinition","parameters":{"id":343,"nodeType":"ParameterList","parameters":[],"src":"1356:2:7"},"src":"1338:98:7","virtual":false,"visibility":"internal"},{"body":{"id":368,"nodeType":"Block","src":"1544:81:7","statements":[{"condition":{"id":362,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"!","prefix":true,"src":"1558:25:7","subExpression":{"arguments":[{"expression":{"id":359,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"1572:3:7","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":360,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"1576:6:7","memberName":"sender","nodeType":"MemberAccess","src":"1572:10:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":358,"name":"isAuthorized","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":623,"src":"1559:12:7","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_address_$returns$_t_bool_$","typeString":"function (address) view returns (bool)"}},"id":361,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1559:24:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":366,"nodeType":"IfStatement","src":"1554:53:7","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":363,"name":"NotAuthorized","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":292,"src":"1592:13:7","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":364,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1592:15:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":365,"nodeType":"RevertStatement","src":"1585:22:7"}},{"id":367,"nodeType":"PlaceholderStatement","src":"1617:1:7"}]},"documentation":{"id":356,"nodeType":"StructuredDocumentation","src":"1442:71:7","text":"@dev reverts if caller is not authorized to execute on this account"},"id":369,"name":"onlyAuthorized","nameLocation":"1527:14:7","nodeType":"ModifierDefinition","parameters":{"id":357,"nodeType":"ParameterList","parameters":[],"src":"1541:2:7"},"src":"1518:107:7","virtual":false,"visibility":"internal"},{"body":{"id":379,"nodeType":"Block","src":"1712:66:7","statements":[{"condition":{"arguments":[],"expression":{"argumentTypes":[],"id":372,"name":"isLocked","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":532,"src":"1726:8:7","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_bool_$","typeString":"function () view returns (bool)"}},"id":373,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1726:10:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":377,"nodeType":"IfStatement","src":"1722:38:7","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":374,"name":"AccountLocked","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":296,"src":"1745:13:7","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":375,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1745:15:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":376,"nodeType":"RevertStatement","src":"1738:22:7"}},{"id":378,"nodeType":"PlaceholderStatement","src":"1770:1:7"}]},"documentation":{"id":370,"nodeType":"StructuredDocumentation","src":"1631:52:7","text":"@dev reverts if this account is currently locked"},"id":380,"name":"onlyUnlocked","nameLocation":"1697:12:7","nodeType":"ModifierDefinition","parameters":{"id":371,"nodeType":"ParameterList","parameters":[],"src":"1709:2:7"},"src":"1688:90:7","virtual":false,"visibility":"internal"},{"body":{"id":383,"nodeType":"Block","src":"1798:2:7","statements":[]},"id":384,"implemented":true,"kind":"constructor","modifiers":[],"name":"","nameLocation":"-1:-1:-1","nodeType":"FunctionDefinition","parameters":{"id":381,"nodeType":"ParameterList","parameters":[],"src":"1795:2:7"},"returnParameters":{"id":382,"nodeType":"ParameterList","parameters":[],"src":"1798:0:7"},"scope":816,"src":"1784:16:7","stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"baseFunctions":[836],"body":{"id":388,"nodeType":"Block","src":"1916:7:7","statements":[]},"documentation":{"id":385,"nodeType":"StructuredDocumentation","src":"1806:78:7","text":"@dev allows eth transfers by default, but allows account owner to override"},"id":389,"implemented":true,"kind":"receive","modifiers":[],"name":"","nameLocation":"-1:-1:-1","nodeType":"FunctionDefinition","parameters":{"id":386,"nodeType":"ParameterList","parameters":[],"src":"1896:2:7"},"returnParameters":{"id":387,"nodeType":"ParameterList","parameters":[],"src":"1916:0:7"},"scope":816,"src":"1889:34:7","stateMutability":"payable","virtual":false,"visibility":"external"},{"baseFunctions":[847],"body":{"id":417,"nodeType":"Block","src":"2196:98:7","statements":[{"eventCall":{"arguments":[{"id":406,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":392,"src":"2231:2:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":407,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":394,"src":"2235:5:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":408,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":396,"src":"2242:4:7","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}],"id":405,"name":"TransactionExecuted","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":833,"src":"2211:19:7","typeDescriptions":{"typeIdentifier":"t_function_event_nonpayable$_t_address_$_t_uint256_$_t_bytes_memory_ptr_$returns$__$","typeString":"function (address,uint256,bytes memory)"}},"id":409,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2211:36:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":410,"nodeType":"EmitStatement","src":"2206:41:7"},{"expression":{"arguments":[{"id":412,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":392,"src":"2271:2:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":413,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":394,"src":"2275:5:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":414,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":396,"src":"2282:4:7","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}],"id":411,"name":"_call","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":787,"src":"2265:5:7","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_uint256_$_t_bytes_calldata_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (address,uint256,bytes calldata) returns (bytes memory)"}},"id":415,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2265:22:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"functionReturnParameters":404,"id":416,"nodeType":"Return","src":"2258:29:7"}]},"documentation":{"id":390,"nodeType":"StructuredDocumentation","src":"1929:95:7","text":"@dev executes a low-level call against an account if the caller is authorized to make calls"},"functionSelector":"9e5d4c49","id":418,"implemented":true,"kind":"function","modifiers":[{"id":399,"kind":"modifierInvocation","modifierName":{"id":398,"name":"onlyAuthorized","nameLocations":["2145:14:7"],"nodeType":"IdentifierPath","referencedDeclaration":369,"src":"2145:14:7"},"nodeType":"ModifierInvocation","src":"2145:14:7"},{"id":401,"kind":"modifierInvocation","modifierName":{"id":400,"name":"onlyUnlocked","nameLocations":["2160:12:7"],"nodeType":"IdentifierPath","referencedDeclaration":380,"src":"2160:12:7"},"nodeType":"ModifierInvocation","src":"2160:12:7"}],"name":"executeCall","nameLocation":"2038:11:7","nodeType":"FunctionDefinition","parameters":{"id":397,"nodeType":"ParameterList","parameters":[{"constant":false,"id":392,"mutability":"mutable","name":"to","nameLocation":"2067:2:7","nodeType":"VariableDeclaration","scope":418,"src":"2059:10:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":391,"name":"address","nodeType":"ElementaryTypeName","src":"2059:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":394,"mutability":"mutable","name":"value","nameLocation":"2087:5:7","nodeType":"VariableDeclaration","scope":418,"src":"2079:13:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":393,"name":"uint256","nodeType":"ElementaryTypeName","src":"2079:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":396,"mutability":"mutable","name":"data","nameLocation":"2117:4:7","nodeType":"VariableDeclaration","scope":418,"src":"2102:19:7","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":395,"name":"bytes","nodeType":"ElementaryTypeName","src":"2102:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"2049:78:7"},"returnParameters":{"id":404,"nodeType":"ParameterList","parameters":[{"constant":false,"id":403,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":418,"src":"2182:12:7","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":402,"name":"bytes","nodeType":"ElementaryTypeName","src":"2182:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"2181:14:7"},"scope":816,"src":"2029:265:7","stateMutability":"payable","virtual":false,"visibility":"external"},{"body":{"id":490,"nodeType":"Block","src":"2483:402:7","statements":[{"assignments":[431],"declarations":[{"constant":false,"id":431,"mutability":"mutable","name":"_owner","nameLocation":"2501:6:7","nodeType":"VariableDeclaration","scope":490,"src":"2493:14:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":430,"name":"address","nodeType":"ElementaryTypeName","src":"2493:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":434,"initialValue":{"arguments":[],"expression":{"argumentTypes":[],"id":432,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":581,"src":"2510:5:7","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_address_$","typeString":"function () view returns (address)"}},"id":433,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2510:7:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"2493:24:7"},{"condition":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":438,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"expression":{"id":435,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"2531:3:7","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":436,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"2535:6:7","memberName":"sender","nodeType":"MemberAccess","src":"2531:10:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"!=","rightExpression":{"id":437,"name":"_owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":431,"src":"2545:6:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"2531:20:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":442,"nodeType":"IfStatement","src":"2527:48:7","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":439,"name":"NotAuthorized","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":292,"src":"2560:13:7","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":440,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2560:15:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":441,"nodeType":"RevertStatement","src":"2553:22:7"}},{"assignments":[444],"declarations":[{"constant":false,"id":444,"mutability":"mutable","name":"length","nameLocation":"2594:6:7","nodeType":"VariableDeclaration","scope":490,"src":"2586:14:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":443,"name":"uint256","nodeType":"ElementaryTypeName","src":"2586:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":447,"initialValue":{"expression":{"id":445,"name":"callers","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":422,"src":"2603:7:7","typeDescriptions":{"typeIdentifier":"t_array$_t_address_$dyn_calldata_ptr","typeString":"address[] calldata"}},"id":446,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"2611:6:7","memberName":"length","nodeType":"MemberAccess","src":"2603:14:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"2586:31:7"},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":451,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"expression":{"id":448,"name":"_permissions","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":425,"src":"2632:12:7","typeDescriptions":{"typeIdentifier":"t_array$_t_bool_$dyn_calldata_ptr","typeString":"bool[] calldata"}},"id":449,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"2645:6:7","memberName":"length","nodeType":"MemberAccess","src":"2632:19:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"!=","rightExpression":{"id":450,"name":"length","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":444,"src":"2655:6:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"2632:29:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":455,"nodeType":"IfStatement","src":"2628:56:7","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":452,"name":"InvalidInput","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":294,"src":"2670:12:7","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":453,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2670:14:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":454,"nodeType":"RevertStatement","src":"2663:21:7"}},{"body":{"id":488,"nodeType":"Block","src":"2732:147:7","statements":[{"expression":{"id":476,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"baseExpression":{"baseExpression":{"id":466,"name":"permissions","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":321,"src":"2746:11:7","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_mapping$_t_address_$_t_bool_$_$","typeString":"mapping(address => mapping(address => bool))"}},"id":471,"indexExpression":{"id":467,"name":"_owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":431,"src":"2758:6:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"2746:19:7","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_bool_$","typeString":"mapping(address => bool)"}},"id":472,"indexExpression":{"baseExpression":{"id":468,"name":"callers","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":422,"src":"2766:7:7","typeDescriptions":{"typeIdentifier":"t_array$_t_address_$dyn_calldata_ptr","typeString":"address[] calldata"}},"id":470,"indexExpression":{"id":469,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":457,"src":"2774:1:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"2766:10:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"IndexAccess","src":"2746:31:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"baseExpression":{"id":473,"name":"_permissions","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":425,"src":"2780:12:7","typeDescriptions":{"typeIdentifier":"t_array$_t_bool_$dyn_calldata_ptr","typeString":"bool[] calldata"}},"id":475,"indexExpression":{"id":474,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":457,"src":"2793:1:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"2780:15:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"2746:49:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":477,"nodeType":"ExpressionStatement","src":"2746:49:7"},{"eventCall":{"arguments":[{"id":479,"name":"_owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":431,"src":"2832:6:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"baseExpression":{"id":480,"name":"callers","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":422,"src":"2840:7:7","typeDescriptions":{"typeIdentifier":"t_array$_t_address_$dyn_calldata_ptr","typeString":"address[] calldata"}},"id":482,"indexExpression":{"id":481,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":457,"src":"2848:1:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"2840:10:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"baseExpression":{"id":483,"name":"_permissions","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":425,"src":"2852:12:7","typeDescriptions":{"typeIdentifier":"t_array$_t_bool_$dyn_calldata_ptr","typeString":"bool[] calldata"}},"id":485,"indexExpression":{"id":484,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":457,"src":"2865:1:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"2852:15:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_bool","typeString":"bool"}],"id":478,"name":"PermissionUpdated","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":337,"src":"2814:17:7","typeDescriptions":{"typeIdentifier":"t_function_event_nonpayable$_t_address_$_t_address_$_t_bool_$returns$__$","typeString":"function (address,address,bool)"}},"id":486,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2814:54:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":487,"nodeType":"EmitStatement","src":"2809:59:7"}]},"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":462,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":460,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":457,"src":"2715:1:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"<","rightExpression":{"id":461,"name":"length","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":444,"src":"2719:6:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"2715:10:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":489,"initializationExpression":{"assignments":[457],"declarations":[{"constant":false,"id":457,"mutability":"mutable","name":"i","nameLocation":"2708:1:7","nodeType":"VariableDeclaration","scope":489,"src":"2700:9:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":456,"name":"uint256","nodeType":"ElementaryTypeName","src":"2700:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":459,"initialValue":{"hexValue":"30","id":458,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"2712:1:7","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"nodeType":"VariableDeclarationStatement","src":"2700:13:7"},"loopExpression":{"expression":{"id":464,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"2727:3:7","subExpression":{"id":463,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":457,"src":"2727:1:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":465,"nodeType":"ExpressionStatement","src":"2727:3:7"},"nodeType":"ForStatement","src":"2695:184:7"}]},"documentation":{"id":419,"nodeType":"StructuredDocumentation","src":"2300:52:7","text":"@dev grants a given caller execution permissions"},"functionSelector":"039721b1","id":491,"implemented":true,"kind":"function","modifiers":[{"id":428,"kind":"modifierInvocation","modifierName":{"id":427,"name":"onlyUnlocked","nameLocations":["2470:12:7"],"nodeType":"IdentifierPath","referencedDeclaration":380,"src":"2470:12:7"},"nodeType":"ModifierInvocation","src":"2470:12:7"}],"name":"setPermissions","nameLocation":"2366:14:7","nodeType":"FunctionDefinition","parameters":{"id":426,"nodeType":"ParameterList","parameters":[{"constant":false,"id":422,"mutability":"mutable","name":"callers","nameLocation":"2409:7:7","nodeType":"VariableDeclaration","scope":491,"src":"2390:26:7","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_array$_t_address_$dyn_calldata_ptr","typeString":"address[]"},"typeName":{"baseType":{"id":420,"name":"address","nodeType":"ElementaryTypeName","src":"2390:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":421,"nodeType":"ArrayTypeName","src":"2390:9:7","typeDescriptions":{"typeIdentifier":"t_array$_t_address_$dyn_storage_ptr","typeString":"address[]"}},"visibility":"internal"},{"constant":false,"id":425,"mutability":"mutable","name":"_permissions","nameLocation":"2442:12:7","nodeType":"VariableDeclaration","scope":491,"src":"2426:28:7","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_array$_t_bool_$dyn_calldata_ptr","typeString":"bool[]"},"typeName":{"baseType":{"id":423,"name":"bool","nodeType":"ElementaryTypeName","src":"2426:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":424,"nodeType":"ArrayTypeName","src":"2426:6:7","typeDescriptions":{"typeIdentifier":"t_array$_t_bool_$dyn_storage_ptr","typeString":"bool[]"}},"visibility":"internal"}],"src":"2380:80:7"},"returnParameters":{"id":429,"nodeType":"ParameterList","parameters":[],"src":"2483:0:7"},"scope":816,"src":"2357:528:7","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":519,"nodeType":"Block","src":"3016:181:7","statements":[{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":506,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":501,"name":"_lockedUntil","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":494,"src":"3030:12:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":505,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"expression":{"id":502,"name":"block","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-4,"src":"3045:5:7","typeDescriptions":{"typeIdentifier":"t_magic_block","typeString":"block"}},"id":503,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"3051:9:7","memberName":"timestamp","nodeType":"MemberAccess","src":"3045:15:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"hexValue":"333635","id":504,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3063:8:7","subdenomination":"days","typeDescriptions":{"typeIdentifier":"t_rational_31536000_by_1","typeString":"int_const 31536000"},"value":"365"},"src":"3045:26:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"3030:41:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":510,"nodeType":"IfStatement","src":"3026:86:7","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":507,"name":"ExceedsMaxLockTime","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":298,"src":"3092:18:7","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":508,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3092:20:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":509,"nodeType":"RevertStatement","src":"3085:27:7"}},{"expression":{"id":513,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":511,"name":"lockedUntil","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":314,"src":"3123:11:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":512,"name":"_lockedUntil","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":494,"src":"3137:12:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"3123:26:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":514,"nodeType":"ExpressionStatement","src":"3123:26:7"},{"eventCall":{"arguments":[{"id":516,"name":"_lockedUntil","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":494,"src":"3177:12:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":515,"name":"LockUpdated","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":341,"src":"3165:11:7","typeDescriptions":{"typeIdentifier":"t_function_event_nonpayable$_t_uint256_$returns$__$","typeString":"function (uint256)"}},"id":517,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3165:25:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":518,"nodeType":"EmitStatement","src":"3160:30:7"}]},"documentation":{"id":492,"nodeType":"StructuredDocumentation","src":"2891:52:7","text":"@dev locks the account until a certain timestamp"},"functionSelector":"dd467064","id":520,"implemented":true,"kind":"function","modifiers":[{"id":497,"kind":"modifierInvocation","modifierName":{"id":496,"name":"onlyOwner","nameLocations":["2993:9:7"],"nodeType":"IdentifierPath","referencedDeclaration":355,"src":"2993:9:7"},"nodeType":"ModifierInvocation","src":"2993:9:7"},{"id":499,"kind":"modifierInvocation","modifierName":{"id":498,"name":"onlyUnlocked","nameLocations":["3003:12:7"],"nodeType":"IdentifierPath","referencedDeclaration":380,"src":"3003:12:7"},"nodeType":"ModifierInvocation","src":"3003:12:7"}],"name":"lock","nameLocation":"2957:4:7","nodeType":"FunctionDefinition","parameters":{"id":495,"nodeType":"ParameterList","parameters":[{"constant":false,"id":494,"mutability":"mutable","name":"_lockedUntil","nameLocation":"2970:12:7","nodeType":"VariableDeclaration","scope":520,"src":"2962:20:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":493,"name":"uint256","nodeType":"ElementaryTypeName","src":"2962:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2961:22:7"},"returnParameters":{"id":500,"nodeType":"ParameterList","parameters":[],"src":"3016:0:7"},"scope":816,"src":"2948:249:7","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":531,"nodeType":"Block","src":"3323:53:7","statements":[{"expression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":529,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":526,"name":"lockedUntil","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":314,"src":"3340:11:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"expression":{"id":527,"name":"block","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-4,"src":"3354:5:7","typeDescriptions":{"typeIdentifier":"t_magic_block","typeString":"block"}},"id":528,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"3360:9:7","memberName":"timestamp","nodeType":"MemberAccess","src":"3354:15:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"3340:29:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"functionReturnParameters":525,"id":530,"nodeType":"Return","src":"3333:36:7"}]},"documentation":{"id":521,"nodeType":"StructuredDocumentation","src":"3203:68:7","text":"@dev returns the current lock status of the account as a boolean"},"functionSelector":"a4e2d634","id":532,"implemented":true,"kind":"function","modifiers":[],"name":"isLocked","nameLocation":"3285:8:7","nodeType":"FunctionDefinition","parameters":{"id":522,"nodeType":"ParameterList","parameters":[],"src":"3293:2:7"},"returnParameters":{"id":525,"nodeType":"ParameterList","parameters":[{"constant":false,"id":524,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":532,"src":"3317:4:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":523,"name":"bool","nodeType":"ElementaryTypeName","src":"3317:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"3316:6:7"},"scope":816,"src":"3276:100:7","stateMutability":"view","virtual":false,"visibility":"public"},{"baseFunctions":[856],"body":{"id":546,"nodeType":"Block","src":"3679:49:7","statements":[{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":542,"name":"ERC6551AccountLib","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":952,"src":"3696:17:7","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_ERC6551AccountLib_$952_$","typeString":"type(library ERC6551AccountLib)"}},"id":543,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"3714:5:7","memberName":"token","nodeType":"MemberAccess","referencedDeclaration":929,"src":"3696:23:7","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_uint256_$_t_address_$_t_uint256_$","typeString":"function () view returns (uint256,address,uint256)"}},"id":544,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3696:25:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_uint256_$_t_address_$_t_uint256_$","typeString":"tuple(uint256,address,uint256)"}},"functionReturnParameters":541,"id":545,"nodeType":"Return","src":"3689:32:7"}]},"documentation":{"id":533,"nodeType":"StructuredDocumentation","src":"3382:121:7","text":"@dev Returns the EIP-155 chain ID, token contract address, and token ID for the token that\n owns this account."},"functionSelector":"fc0c546a","id":547,"implemented":true,"kind":"function","modifiers":[],"name":"token","nameLocation":"3517:5:7","nodeType":"FunctionDefinition","parameters":{"id":534,"nodeType":"ParameterList","parameters":[],"src":"3522:2:7"},"returnParameters":{"id":541,"nodeType":"ParameterList","parameters":[{"constant":false,"id":536,"mutability":"mutable","name":"chainId","nameLocation":"3593:7:7","nodeType":"VariableDeclaration","scope":547,"src":"3585:15:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":535,"name":"uint256","nodeType":"ElementaryTypeName","src":"3585:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":538,"mutability":"mutable","name":"tokenContract","nameLocation":"3622:13:7","nodeType":"VariableDeclaration","scope":547,"src":"3614:21:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":537,"name":"address","nodeType":"ElementaryTypeName","src":"3614:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":540,"mutability":"mutable","name":"tokenId","nameLocation":"3657:7:7","nodeType":"VariableDeclaration","scope":547,"src":"3649:15:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":539,"name":"uint256","nodeType":"ElementaryTypeName","src":"3649:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3571:103:7"},"scope":816,"src":"3508:220:7","stateMutability":"view","virtual":false,"visibility":"external"},{"baseFunctions":[861],"body":{"id":580,"nodeType":"Block","src":"3938:263:7","statements":[{"assignments":[554,556,558],"declarations":[{"constant":false,"id":554,"mutability":"mutable","name":"chainId","nameLocation":"3970:7:7","nodeType":"VariableDeclaration","scope":580,"src":"3962:15:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":553,"name":"uint256","nodeType":"ElementaryTypeName","src":"3962:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":556,"mutability":"mutable","name":"tokenContract","nameLocation":"3999:13:7","nodeType":"VariableDeclaration","scope":580,"src":"3991:21:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":555,"name":"address","nodeType":"ElementaryTypeName","src":"3991:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":558,"mutability":"mutable","name":"tokenId","nameLocation":"4034:7:7","nodeType":"VariableDeclaration","scope":580,"src":"4026:15:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":557,"name":"uint256","nodeType":"ElementaryTypeName","src":"4026:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":562,"initialValue":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":559,"name":"ERC6551AccountLib","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":952,"src":"4054:17:7","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_ERC6551AccountLib_$952_$","typeString":"type(library ERC6551AccountLib)"}},"id":560,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"4072:5:7","memberName":"token","nodeType":"MemberAccess","referencedDeclaration":929,"src":"4054:23:7","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_uint256_$_t_address_$_t_uint256_$","typeString":"function () view returns (uint256,address,uint256)"}},"id":561,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4054:25:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_uint256_$_t_address_$_t_uint256_$","typeString":"tuple(uint256,address,uint256)"}},"nodeType":"VariableDeclarationStatement","src":"3948:131:7"},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":566,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":563,"name":"chainId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":554,"src":"4094:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"!=","rightExpression":{"expression":{"id":564,"name":"block","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-4,"src":"4105:5:7","typeDescriptions":{"typeIdentifier":"t_magic_block","typeString":"block"}},"id":565,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"4111:7:7","memberName":"chainid","nodeType":"MemberAccess","src":"4105:13:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"4094:24:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":572,"nodeType":"IfStatement","src":"4090:47:7","trueBody":{"expression":{"arguments":[{"hexValue":"30","id":569,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4135:1:7","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"id":568,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4127:7:7","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":567,"name":"address","nodeType":"ElementaryTypeName","src":"4127:7:7","typeDescriptions":{}}},"id":570,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4127:10:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"functionReturnParameters":552,"id":571,"nodeType":"Return","src":"4120:17:7"}},{"expression":{"arguments":[{"id":577,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":558,"src":"4186:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"arguments":[{"id":574,"name":"tokenContract","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":556,"src":"4163:13:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":573,"name":"IERC721","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":170,"src":"4155:7:7","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC721_$170_$","typeString":"type(contract IERC721)"}},"id":575,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4155:22:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_IERC721_$170","typeString":"contract IERC721"}},"id":576,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"4178:7:7","memberName":"ownerOf","nodeType":"MemberAccess","referencedDeclaration":103,"src":"4155:30:7","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_uint256_$returns$_t_address_$","typeString":"function (uint256) view external returns (address)"}},"id":578,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4155:39:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"functionReturnParameters":552,"id":579,"nodeType":"Return","src":"4148:46:7"}]},"documentation":{"id":548,"nodeType":"StructuredDocumentation","src":"3734:152:7","text":"@dev Returns the owner of the ERC-721 token which owns this account. By default, the owner\n of the token has full permissions on the account."},"functionSelector":"8da5cb5b","id":581,"implemented":true,"kind":"function","modifiers":[],"name":"owner","nameLocation":"3900:5:7","nodeType":"FunctionDefinition","parameters":{"id":549,"nodeType":"ParameterList","parameters":[],"src":"3905:2:7"},"returnParameters":{"id":552,"nodeType":"ParameterList","parameters":[{"constant":false,"id":551,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":581,"src":"3929:7:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":550,"name":"address","nodeType":"ElementaryTypeName","src":"3929:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"3928:9:7"},"scope":816,"src":"3891:310:7","stateMutability":"view","virtual":false,"visibility":"public"},{"body":{"id":622,"nodeType":"Block","src":"4337:415:7","statements":[{"assignments":[null,590,592],"declarations":[null,{"constant":false,"id":590,"mutability":"mutable","name":"tokenContract","nameLocation":"4383:13:7","nodeType":"VariableDeclaration","scope":622,"src":"4375:21:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":589,"name":"address","nodeType":"ElementaryTypeName","src":"4375:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":592,"mutability":"mutable","name":"tokenId","nameLocation":"4418:7:7","nodeType":"VariableDeclaration","scope":622,"src":"4410:15:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":591,"name":"uint256","nodeType":"ElementaryTypeName","src":"4410:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":596,"initialValue":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":593,"name":"ERC6551AccountLib","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":952,"src":"4438:17:7","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_ERC6551AccountLib_$952_$","typeString":"type(library ERC6551AccountLib)"}},"id":594,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"4456:5:7","memberName":"token","nodeType":"MemberAccess","referencedDeclaration":929,"src":"4438:23:7","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_uint256_$_t_address_$_t_uint256_$","typeString":"function () view returns (uint256,address,uint256)"}},"id":595,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4438:25:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_uint256_$_t_address_$_t_uint256_$","typeString":"tuple(uint256,address,uint256)"}},"nodeType":"VariableDeclarationStatement","src":"4347:116:7"},{"assignments":[598],"declarations":[{"constant":false,"id":598,"mutability":"mutable","name":"_owner","nameLocation":"4481:6:7","nodeType":"VariableDeclaration","scope":622,"src":"4473:14:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":597,"name":"address","nodeType":"ElementaryTypeName","src":"4473:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":605,"initialValue":{"arguments":[{"id":603,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":592,"src":"4521:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"arguments":[{"id":600,"name":"tokenContract","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":590,"src":"4498:13:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":599,"name":"IERC721","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":170,"src":"4490:7:7","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC721_$170_$","typeString":"type(contract IERC721)"}},"id":601,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4490:22:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_IERC721_$170","typeString":"contract IERC721"}},"id":602,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"4513:7:7","memberName":"ownerOf","nodeType":"MemberAccess","referencedDeclaration":103,"src":"4490:30:7","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_uint256_$returns$_t_address_$","typeString":"function (uint256) view external returns (address)"}},"id":604,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4490:39:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"4473:56:7"},{"condition":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":608,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":606,"name":"caller","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":584,"src":"4577:6:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"id":607,"name":"_owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":598,"src":"4587:6:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"4577:16:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":611,"nodeType":"IfStatement","src":"4573:33:7","trueBody":{"expression":{"hexValue":"74727565","id":609,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"4602:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"true"},"functionReturnParameters":588,"id":610,"nodeType":"Return","src":"4595:11:7"}},{"condition":{"baseExpression":{"baseExpression":{"id":612,"name":"permissions","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":321,"src":"4682:11:7","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_mapping$_t_address_$_t_bool_$_$","typeString":"mapping(address => mapping(address => bool))"}},"id":614,"indexExpression":{"id":613,"name":"_owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":598,"src":"4694:6:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"4682:19:7","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_bool_$","typeString":"mapping(address => bool)"}},"id":616,"indexExpression":{"id":615,"name":"caller","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":584,"src":"4702:6:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"4682:27:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":619,"nodeType":"IfStatement","src":"4678:44:7","trueBody":{"expression":{"hexValue":"74727565","id":617,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"4718:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"true"},"functionReturnParameters":588,"id":618,"nodeType":"Return","src":"4711:11:7"}},{"expression":{"hexValue":"66616c7365","id":620,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"4740:5:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"},"functionReturnParameters":588,"id":621,"nodeType":"Return","src":"4733:12:7"}]},"documentation":{"id":582,"nodeType":"StructuredDocumentation","src":"4207:60:7","text":"@dev Returns the authorization status for a given caller"},"functionSelector":"fe9fbb80","id":623,"implemented":true,"kind":"function","modifiers":[],"name":"isAuthorized","nameLocation":"4281:12:7","nodeType":"FunctionDefinition","parameters":{"id":585,"nodeType":"ParameterList","parameters":[{"constant":false,"id":584,"mutability":"mutable","name":"caller","nameLocation":"4302:6:7","nodeType":"VariableDeclaration","scope":623,"src":"4294:14:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":583,"name":"address","nodeType":"ElementaryTypeName","src":"4294:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"4293:16:7"},"returnParameters":{"id":588,"nodeType":"ParameterList","parameters":[{"constant":false,"id":587,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":623,"src":"4331:4:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":586,"name":"bool","nodeType":"ElementaryTypeName","src":"4331:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"4330:6:7"},"scope":816,"src":"4272:480:7","stateMutability":"view","virtual":false,"visibility":"public"},{"baseFunctions":[199],"body":{"id":661,"nodeType":"Block","src":"5009:273:7","statements":[{"assignments":[633],"declarations":[{"constant":false,"id":633,"mutability":"mutable","name":"defaultSupport","nameLocation":"5024:14:7","nodeType":"VariableDeclaration","scope":661,"src":"5019:19:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":632,"name":"bool","nodeType":"ElementaryTypeName","src":"5019:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":654,"initialValue":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":653,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":646,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"id":639,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":634,"name":"interfaceId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":626,"src":"5041:11:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"arguments":[{"id":636,"name":"IERC165","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":200,"src":"5061:7:7","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC165_$200_$","typeString":"type(contract IERC165)"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_type$_t_contract$_IERC165_$200_$","typeString":"type(contract IERC165)"}],"id":635,"name":"type","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-27,"src":"5056:4:7","typeDescriptions":{"typeIdentifier":"t_function_metatype_pure$__$returns$__$","typeString":"function () pure"}},"id":637,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5056:13:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_magic_meta_type_t_contract$_IERC165_$200","typeString":"type(contract IERC165)"}},"id":638,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"5070:11:7","memberName":"interfaceId","nodeType":"MemberAccess","src":"5056:25:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"src":"5041:40:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"||","rightExpression":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"id":645,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":640,"name":"interfaceId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":626,"src":"5097:11:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"arguments":[{"id":642,"name":"IERC1155Receiver","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":54,"src":"5117:16:7","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC1155Receiver_$54_$","typeString":"type(contract IERC1155Receiver)"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_type$_t_contract$_IERC1155Receiver_$54_$","typeString":"type(contract IERC1155Receiver)"}],"id":641,"name":"type","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-27,"src":"5112:4:7","typeDescriptions":{"typeIdentifier":"t_function_metatype_pure$__$returns$__$","typeString":"function () pure"}},"id":643,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5112:22:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_magic_meta_type_t_contract$_IERC1155Receiver_$54","typeString":"type(contract IERC1155Receiver)"}},"id":644,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"5135:11:7","memberName":"interfaceId","nodeType":"MemberAccess","src":"5112:34:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"src":"5097:49:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"5041:105:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"||","rightExpression":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"id":652,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":647,"name":"interfaceId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":626,"src":"5162:11:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"arguments":[{"id":649,"name":"IERC6551Account","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":862,"src":"5182:15:7","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC6551Account_$862_$","typeString":"type(contract IERC6551Account)"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_type$_t_contract$_IERC6551Account_$862_$","typeString":"type(contract IERC6551Account)"}],"id":648,"name":"type","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-27,"src":"5177:4:7","typeDescriptions":{"typeIdentifier":"t_function_metatype_pure$__$returns$__$","typeString":"function () pure"}},"id":650,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5177:21:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_magic_meta_type_t_contract$_IERC6551Account_$862","typeString":"type(contract IERC6551Account)"}},"id":651,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"5199:11:7","memberName":"interfaceId","nodeType":"MemberAccess","src":"5177:33:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"src":"5162:48:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"5041:169:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"5019:191:7"},{"condition":{"id":655,"name":"defaultSupport","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":633,"src":"5225:14:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":658,"nodeType":"IfStatement","src":"5221:31:7","trueBody":{"expression":{"hexValue":"74727565","id":656,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"5248:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"true"},"functionReturnParameters":631,"id":657,"nodeType":"Return","src":"5241:11:7"}},{"expression":{"hexValue":"66616c7365","id":659,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"5270:5:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"},"functionReturnParameters":631,"id":660,"nodeType":"Return","src":"5263:12:7"}]},"documentation":{"id":624,"nodeType":"StructuredDocumentation","src":"4758:126:7","text":"@dev Returns true if a given interfaceId is supported by this account. This method can be\n extended by an override."},"functionSelector":"01ffc9a7","id":662,"implemented":true,"kind":"function","modifiers":[],"name":"supportsInterface","nameLocation":"4898:17:7","nodeType":"FunctionDefinition","overrides":{"id":628,"nodeType":"OverrideSpecifier","overrides":[],"src":"4973:8:7"},"parameters":{"id":627,"nodeType":"ParameterList","parameters":[{"constant":false,"id":626,"mutability":"mutable","name":"interfaceId","nameLocation":"4923:11:7","nodeType":"VariableDeclaration","scope":662,"src":"4916:18:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":625,"name":"bytes4","nodeType":"ElementaryTypeName","src":"4916:6:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"4915:20:7"},"returnParameters":{"id":631,"nodeType":"ParameterList","parameters":[{"constant":false,"id":630,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":662,"src":"4999:4:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":629,"name":"bool","nodeType":"ElementaryTypeName","src":"4999:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"4998:6:7"},"scope":816,"src":"4889:393:7","stateMutability":"pure","virtual":false,"visibility":"public"},{"baseFunctions":[187],"body":{"id":708,"nodeType":"Block","src":"5586:367:7","statements":[{"assignments":[678,680,682],"declarations":[{"constant":false,"id":678,"mutability":"mutable","name":"chainId","nameLocation":"5618:7:7","nodeType":"VariableDeclaration","scope":708,"src":"5610:15:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":677,"name":"uint256","nodeType":"ElementaryTypeName","src":"5610:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":680,"mutability":"mutable","name":"tokenContract","nameLocation":"5647:13:7","nodeType":"VariableDeclaration","scope":708,"src":"5639:21:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":679,"name":"address","nodeType":"ElementaryTypeName","src":"5639:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":682,"mutability":"mutable","name":"tokenId","nameLocation":"5682:7:7","nodeType":"VariableDeclaration","scope":708,"src":"5674:15:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":681,"name":"uint256","nodeType":"ElementaryTypeName","src":"5674:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":686,"initialValue":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":683,"name":"ERC6551AccountLib","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":952,"src":"5702:17:7","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_ERC6551AccountLib_$952_$","typeString":"type(library ERC6551AccountLib)"}},"id":684,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"5720:5:7","memberName":"token","nodeType":"MemberAccess","referencedDeclaration":929,"src":"5702:23:7","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_uint256_$_t_address_$_t_uint256_$","typeString":"function () view returns (uint256,address,uint256)"}},"id":685,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5702:25:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_uint256_$_t_address_$_t_uint256_$","typeString":"tuple(uint256,address,uint256)"}},"nodeType":"VariableDeclarationStatement","src":"5596:131:7"},{"condition":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":699,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":695,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":690,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":687,"name":"chainId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":678,"src":"5755:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"id":688,"name":"block","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-4,"src":"5766:5:7","typeDescriptions":{"typeIdentifier":"t_magic_block","typeString":"block"}},"id":689,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"5772:7:7","memberName":"chainid","nodeType":"MemberAccess","src":"5766:13:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5755:24:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"&&","rightExpression":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":694,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":691,"name":"tokenContract","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":680,"src":"5795:13:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"id":692,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"5812:3:7","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":693,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"5816:6:7","memberName":"sender","nodeType":"MemberAccess","src":"5812:10:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"5795:27:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"5755:67:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"&&","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":698,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":696,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":682,"src":"5838:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"id":697,"name":"receivedTokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":669,"src":"5849:15:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5838:26:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"5755:109:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":703,"nodeType":"IfStatement","src":"5738:160:7","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":700,"name":"OwnershipCycle","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":302,"src":"5882:14:7","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":701,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5882:16:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":702,"nodeType":"RevertStatement","src":"5875:23:7"}},{"expression":{"expression":{"expression":{"id":704,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"5916:4:7","typeDescriptions":{"typeIdentifier":"t_contract$_MinimalisticAccount_$816","typeString":"contract MinimalisticAccount"}},"id":705,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"5921:16:7","memberName":"onERC721Received","nodeType":"MemberAccess","referencedDeclaration":709,"src":"5916:21:7","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$_t_address_$_t_uint256_$_t_bytes_memory_ptr_$returns$_t_bytes4_$","typeString":"function (address,address,uint256,bytes memory) view external returns (bytes4)"}},"id":706,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"5938:8:7","memberName":"selector","nodeType":"MemberAccess","src":"5916:30:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"functionReturnParameters":676,"id":707,"nodeType":"Return","src":"5909:37:7"}]},"documentation":{"id":663,"nodeType":"StructuredDocumentation","src":"5288:134:7","text":"@dev Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle.\n This function can be overriden."},"functionSelector":"150b7a02","id":709,"implemented":true,"kind":"function","modifiers":[],"name":"onERC721Received","nameLocation":"5436:16:7","nodeType":"FunctionDefinition","overrides":{"id":673,"nodeType":"OverrideSpecifier","overrides":[],"src":"5560:8:7"},"parameters":{"id":672,"nodeType":"ParameterList","parameters":[{"constant":false,"id":665,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":709,"src":"5462:7:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":664,"name":"address","nodeType":"ElementaryTypeName","src":"5462:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":667,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":709,"src":"5479:7:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":666,"name":"address","nodeType":"ElementaryTypeName","src":"5479:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":669,"mutability":"mutable","name":"receivedTokenId","nameLocation":"5504:15:7","nodeType":"VariableDeclaration","scope":709,"src":"5496:23:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":668,"name":"uint256","nodeType":"ElementaryTypeName","src":"5496:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":671,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":709,"src":"5529:12:7","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":670,"name":"bytes","nodeType":"ElementaryTypeName","src":"5529:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"5452:95:7"},"returnParameters":{"id":676,"nodeType":"ParameterList","parameters":[{"constant":false,"id":675,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":709,"src":"5578:6:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":674,"name":"bytes4","nodeType":"ElementaryTypeName","src":"5578:6:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"5577:8:7"},"scope":816,"src":"5427:526:7","stateMutability":"view","virtual":false,"visibility":"public"},{"baseFunctions":[35],"body":{"id":730,"nodeType":"Block","src":"6204:55:7","statements":[{"expression":{"expression":{"expression":{"id":726,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"6221:4:7","typeDescriptions":{"typeIdentifier":"t_contract$_MinimalisticAccount_$816","typeString":"contract MinimalisticAccount"}},"id":727,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"6226:17:7","memberName":"onERC1155Received","nodeType":"MemberAccess","referencedDeclaration":731,"src":"6221:22:7","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_address_$_t_address_$_t_uint256_$_t_uint256_$_t_bytes_memory_ptr_$returns$_t_bytes4_$","typeString":"function (address,address,uint256,uint256,bytes memory) pure external returns (bytes4)"}},"id":728,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"6244:8:7","memberName":"selector","nodeType":"MemberAccess","src":"6221:31:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"functionReturnParameters":725,"id":729,"nodeType":"Return","src":"6214:38:7"}]},"documentation":{"id":710,"nodeType":"StructuredDocumentation","src":"5959:79:7","text":"@dev Allows ERC-1155 tokens to be received. This function can be overriden."},"functionSelector":"f23a6e61","id":731,"implemented":true,"kind":"function","modifiers":[],"name":"onERC1155Received","nameLocation":"6052:17:7","nodeType":"FunctionDefinition","overrides":{"id":722,"nodeType":"OverrideSpecifier","overrides":[],"src":"6178:8:7"},"parameters":{"id":721,"nodeType":"ParameterList","parameters":[{"constant":false,"id":712,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":731,"src":"6079:7:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":711,"name":"address","nodeType":"ElementaryTypeName","src":"6079:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":714,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":731,"src":"6096:7:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":713,"name":"address","nodeType":"ElementaryTypeName","src":"6096:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":716,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":731,"src":"6113:7:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":715,"name":"uint256","nodeType":"ElementaryTypeName","src":"6113:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":718,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":731,"src":"6130:7:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":717,"name":"uint256","nodeType":"ElementaryTypeName","src":"6130:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":720,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":731,"src":"6147:12:7","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":719,"name":"bytes","nodeType":"ElementaryTypeName","src":"6147:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"6069:96:7"},"returnParameters":{"id":725,"nodeType":"ParameterList","parameters":[{"constant":false,"id":724,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":731,"src":"6196:6:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":723,"name":"bytes4","nodeType":"ElementaryTypeName","src":"6196:6:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"6195:8:7"},"scope":816,"src":"6043:216:7","stateMutability":"pure","virtual":false,"visibility":"public"},{"baseFunctions":[53],"body":{"id":754,"nodeType":"Block","src":"6540:60:7","statements":[{"expression":{"expression":{"expression":{"id":750,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"6557:4:7","typeDescriptions":{"typeIdentifier":"t_contract$_MinimalisticAccount_$816","typeString":"contract MinimalisticAccount"}},"id":751,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"6562:22:7","memberName":"onERC1155BatchReceived","nodeType":"MemberAccess","referencedDeclaration":755,"src":"6557:27:7","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_address_$_t_address_$_t_array$_t_uint256_$dyn_memory_ptr_$_t_array$_t_uint256_$dyn_memory_ptr_$_t_bytes_memory_ptr_$returns$_t_bytes4_$","typeString":"function (address,address,uint256[] memory,uint256[] memory,bytes memory) pure external returns (bytes4)"}},"id":752,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"6585:8:7","memberName":"selector","nodeType":"MemberAccess","src":"6557:36:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"functionReturnParameters":749,"id":753,"nodeType":"Return","src":"6550:43:7"}]},"documentation":{"id":732,"nodeType":"StructuredDocumentation","src":"6265:86:7","text":"@dev Allows ERC-1155 token batches to be received. This function can be overriden."},"functionSelector":"bc197c81","id":755,"implemented":true,"kind":"function","modifiers":[],"name":"onERC1155BatchReceived","nameLocation":"6365:22:7","nodeType":"FunctionDefinition","overrides":{"id":746,"nodeType":"OverrideSpecifier","overrides":[],"src":"6514:8:7"},"parameters":{"id":745,"nodeType":"ParameterList","parameters":[{"constant":false,"id":734,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":755,"src":"6397:7:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":733,"name":"address","nodeType":"ElementaryTypeName","src":"6397:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":736,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":755,"src":"6414:7:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":735,"name":"address","nodeType":"ElementaryTypeName","src":"6414:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":739,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":755,"src":"6431:16:7","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_memory_ptr","typeString":"uint256[]"},"typeName":{"baseType":{"id":737,"name":"uint256","nodeType":"ElementaryTypeName","src":"6431:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":738,"nodeType":"ArrayTypeName","src":"6431:9:7","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_storage_ptr","typeString":"uint256[]"}},"visibility":"internal"},{"constant":false,"id":742,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":755,"src":"6457:16:7","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_memory_ptr","typeString":"uint256[]"},"typeName":{"baseType":{"id":740,"name":"uint256","nodeType":"ElementaryTypeName","src":"6457:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":741,"nodeType":"ArrayTypeName","src":"6457:9:7","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_storage_ptr","typeString":"uint256[]"}},"visibility":"internal"},{"constant":false,"id":744,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":755,"src":"6483:12:7","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":743,"name":"bytes","nodeType":"ElementaryTypeName","src":"6483:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"6387:114:7"},"returnParameters":{"id":749,"nodeType":"ParameterList","parameters":[{"constant":false,"id":748,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":755,"src":"6532:6:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":747,"name":"bytes4","nodeType":"ElementaryTypeName","src":"6532:6:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"6531:8:7"},"scope":816,"src":"6356:244:7","stateMutability":"pure","virtual":false,"visibility":"public"},{"body":{"id":786,"nodeType":"Block","src":"6777:213:7","statements":[{"assignments":[768],"declarations":[{"constant":false,"id":768,"mutability":"mutable","name":"success","nameLocation":"6792:7:7","nodeType":"VariableDeclaration","scope":786,"src":"6787:12:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":767,"name":"bool","nodeType":"ElementaryTypeName","src":"6787:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":769,"nodeType":"VariableDeclarationStatement","src":"6787:12:7"},{"expression":{"id":779,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"components":[{"id":770,"name":"success","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":768,"src":"6810:7:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"id":771,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":765,"src":"6819:6:7","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"id":772,"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"TupleExpression","src":"6809:17:7","typeDescriptions":{"typeIdentifier":"t_tuple$_t_bool_$_t_bytes_memory_ptr_$","typeString":"tuple(bool,bytes memory)"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"arguments":[{"id":777,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":762,"src":"6851:4:7","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}],"expression":{"id":773,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":758,"src":"6829:2:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":774,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"6832:4:7","memberName":"call","nodeType":"MemberAccess","src":"6829:7:7","typeDescriptions":{"typeIdentifier":"t_function_barecall_payable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$","typeString":"function (bytes memory) payable returns (bool,bytes memory)"}},"id":776,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"names":["value"],"nodeType":"FunctionCallOptions","options":[{"id":775,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":760,"src":"6844:5:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"src":"6829:21:7","typeDescriptions":{"typeIdentifier":"t_function_barecall_payable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$value","typeString":"function (bytes memory) payable returns (bool,bytes memory)"}},"id":778,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"6829:27:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_bool_$_t_bytes_memory_ptr_$","typeString":"tuple(bool,bytes memory)"}},"src":"6809:47:7","typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":780,"nodeType":"ExpressionStatement","src":"6809:47:7"},{"condition":{"id":782,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"!","prefix":true,"src":"6871:8:7","subExpression":{"id":781,"name":"success","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":768,"src":"6872:7:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":785,"nodeType":"IfStatement","src":"6867:117:7","trueBody":{"id":784,"nodeType":"Block","src":"6881:103:7","statements":[{"AST":{"nodeType":"YulBlock","src":"6904:70:7","statements":[{"expression":{"arguments":[{"arguments":[{"name":"result","nodeType":"YulIdentifier","src":"6933:6:7"},{"kind":"number","nodeType":"YulLiteral","src":"6941:2:7","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6929:3:7"},"nodeType":"YulFunctionCall","src":"6929:15:7"},{"arguments":[{"name":"result","nodeType":"YulIdentifier","src":"6952:6:7"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"6946:5:7"},"nodeType":"YulFunctionCall","src":"6946:13:7"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"6922:6:7"},"nodeType":"YulFunctionCall","src":"6922:38:7"},"nodeType":"YulExpressionStatement","src":"6922:38:7"}]},"evmVersion":"london","externalReferences":[{"declaration":765,"isOffset":false,"isSlot":false,"src":"6933:6:7","valueSize":1},{"declaration":765,"isOffset":false,"isSlot":false,"src":"6952:6:7","valueSize":1}],"id":783,"nodeType":"InlineAssembly","src":"6895:79:7"}]}}]},"documentation":{"id":756,"nodeType":"StructuredDocumentation","src":"6606:34:7","text":"@dev Executes a low-level call"},"id":787,"implemented":true,"kind":"function","modifiers":[],"name":"_call","nameLocation":"6654:5:7","nodeType":"FunctionDefinition","parameters":{"id":763,"nodeType":"ParameterList","parameters":[{"constant":false,"id":758,"mutability":"mutable","name":"to","nameLocation":"6677:2:7","nodeType":"VariableDeclaration","scope":787,"src":"6669:10:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":757,"name":"address","nodeType":"ElementaryTypeName","src":"6669:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":760,"mutability":"mutable","name":"value","nameLocation":"6697:5:7","nodeType":"VariableDeclaration","scope":787,"src":"6689:13:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":759,"name":"uint256","nodeType":"ElementaryTypeName","src":"6689:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":762,"mutability":"mutable","name":"data","nameLocation":"6727:4:7","nodeType":"VariableDeclaration","scope":787,"src":"6712:19:7","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":761,"name":"bytes","nodeType":"ElementaryTypeName","src":"6712:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"6659:78:7"},"returnParameters":{"id":766,"nodeType":"ParameterList","parameters":[{"constant":false,"id":765,"mutability":"mutable","name":"result","nameLocation":"6769:6:7","nodeType":"VariableDeclaration","scope":787,"src":"6756:19:7","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":764,"name":"bytes","nodeType":"ElementaryTypeName","src":"6756:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"6755:21:7"},"scope":816,"src":"6645:345:7","stateMutability":"nonpayable","virtual":false,"visibility":"internal"},{"body":{"id":814,"nodeType":"Block","src":"7168:205:7","statements":[{"assignments":[798],"declarations":[{"constant":false,"id":798,"mutability":"mutable","name":"success","nameLocation":"7183:7:7","nodeType":"VariableDeclaration","scope":814,"src":"7178:12:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":797,"name":"bool","nodeType":"ElementaryTypeName","src":"7178:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":799,"nodeType":"VariableDeclarationStatement","src":"7178:12:7"},{"expression":{"id":807,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"components":[{"id":800,"name":"success","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":798,"src":"7201:7:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"id":801,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":795,"src":"7210:6:7","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"id":802,"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"TupleExpression","src":"7200:17:7","typeDescriptions":{"typeIdentifier":"t_tuple$_t_bool_$_t_bytes_memory_ptr_$","typeString":"tuple(bool,bytes memory)"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"arguments":[{"id":805,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":792,"src":"7234:4:7","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}],"expression":{"id":803,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":790,"src":"7220:2:7","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":804,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"7223:10:7","memberName":"staticcall","nodeType":"MemberAccess","src":"7220:13:7","typeDescriptions":{"typeIdentifier":"t_function_barestaticcall_view$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$","typeString":"function (bytes memory) view returns (bool,bytes memory)"}},"id":806,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"7220:19:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_bool_$_t_bytes_memory_ptr_$","typeString":"tuple(bool,bytes memory)"}},"src":"7200:39:7","typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":808,"nodeType":"ExpressionStatement","src":"7200:39:7"},{"condition":{"id":810,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"!","prefix":true,"src":"7254:8:7","subExpression":{"id":809,"name":"success","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":798,"src":"7255:7:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":813,"nodeType":"IfStatement","src":"7250:117:7","trueBody":{"id":812,"nodeType":"Block","src":"7264:103:7","statements":[{"AST":{"nodeType":"YulBlock","src":"7287:70:7","statements":[{"expression":{"arguments":[{"arguments":[{"name":"result","nodeType":"YulIdentifier","src":"7316:6:7"},{"kind":"number","nodeType":"YulLiteral","src":"7324:2:7","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7312:3:7"},"nodeType":"YulFunctionCall","src":"7312:15:7"},{"arguments":[{"name":"result","nodeType":"YulIdentifier","src":"7335:6:7"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"7329:5:7"},"nodeType":"YulFunctionCall","src":"7329:13:7"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7305:6:7"},"nodeType":"YulFunctionCall","src":"7305:38:7"},"nodeType":"YulExpressionStatement","src":"7305:38:7"}]},"evmVersion":"london","externalReferences":[{"declaration":795,"isOffset":false,"isSlot":false,"src":"7316:6:7","valueSize":1},{"declaration":795,"isOffset":false,"isSlot":false,"src":"7335:6:7","valueSize":1}],"id":811,"nodeType":"InlineAssembly","src":"7278:79:7"}]}}]},"documentation":{"id":788,"nodeType":"StructuredDocumentation","src":"6996:41:7","text":"@dev Executes a low-level static call"},"id":815,"implemented":true,"kind":"function","modifiers":[],"name":"_callStatic","nameLocation":"7051:11:7","nodeType":"FunctionDefinition","parameters":{"id":793,"nodeType":"ParameterList","parameters":[{"constant":false,"id":790,"mutability":"mutable","name":"to","nameLocation":"7071:2:7","nodeType":"VariableDeclaration","scope":815,"src":"7063:10:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":789,"name":"address","nodeType":"ElementaryTypeName","src":"7063:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":792,"mutability":"mutable","name":"data","nameLocation":"7090:4:7","nodeType":"VariableDeclaration","scope":815,"src":"7075:19:7","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":791,"name":"bytes","nodeType":"ElementaryTypeName","src":"7075:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"7062:33:7"},"returnParameters":{"id":796,"nodeType":"ParameterList","parameters":[{"constant":false,"id":795,"mutability":"mutable","name":"result","nameLocation":"7156:6:7","nodeType":"VariableDeclaration","scope":815,"src":"7143:19:7","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":794,"name":"bytes","nodeType":"ElementaryTypeName","src":"7143:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"7142:21:7"},"scope":816,"src":"7042:331:7","stateMutability":"view","virtual":false,"visibility":"internal"}],"scope":817,"src":"695:6680:7","usedErrors":[292,294,296,298,302]}],"src":"39:7337:7"},"id":7},"contracts/interfaces/IERC6551Account.sol":{"ast":{"absolutePath":"contracts/interfaces/IERC6551Account.sol","exportedSymbols":{"IERC6551Account":[862],"IERC6551AccountProxy":[824]},"id":863,"license":"UNLICENSED","nodeType":"SourceUnit","nodes":[{"id":818,"literals":["solidity","^","0.8",".13"],"nodeType":"PragmaDirective","src":"39:24:8"},{"abstract":false,"baseContracts":[],"canonicalName":"IERC6551AccountProxy","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"id":824,"linearizedBaseContracts":[824],"name":"IERC6551AccountProxy","nameLocation":"75:20:8","nodeType":"ContractDefinition","nodes":[{"functionSelector":"5c60da1b","id":823,"implemented":false,"kind":"function","modifiers":[],"name":"implementation","nameLocation":"111:14:8","nodeType":"FunctionDefinition","parameters":{"id":819,"nodeType":"ParameterList","parameters":[],"src":"125:2:8"},"returnParameters":{"id":822,"nodeType":"ParameterList","parameters":[{"constant":false,"id":821,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":823,"src":"151:7:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":820,"name":"address","nodeType":"ElementaryTypeName","src":"151:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"150:9:8"},"scope":824,"src":"102:58:8","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":863,"src":"65:97:8","usedErrors":[]},{"abstract":false,"baseContracts":[],"canonicalName":"IERC6551Account","contractDependencies":[],"contractKind":"interface","documentation":{"id":825,"nodeType":"StructuredDocumentation","src":"164:67:8","text":"@dev the ERC-165 identifier for this interface is `0xeff4d378`"},"fullyImplemented":false,"id":862,"linearizedBaseContracts":[862],"name":"IERC6551Account","nameLocation":"241:15:8","nodeType":"ContractDefinition","nodes":[{"anonymous":false,"eventSelector":"47d99ad340f52da66535aff7e10da1ceb85a32bcbd9fa1c42314d194545e14d2","id":833,"name":"TransactionExecuted","nameLocation":"269:19:8","nodeType":"EventDefinition","parameters":{"id":832,"nodeType":"ParameterList","parameters":[{"constant":false,"id":827,"indexed":true,"mutability":"mutable","name":"target","nameLocation":"305:6:8","nodeType":"VariableDeclaration","scope":833,"src":"289:22:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":826,"name":"address","nodeType":"ElementaryTypeName","src":"289:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":829,"indexed":true,"mutability":"mutable","name":"value","nameLocation":"329:5:8","nodeType":"VariableDeclaration","scope":833,"src":"313:21:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":828,"name":"uint256","nodeType":"ElementaryTypeName","src":"313:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":831,"indexed":false,"mutability":"mutable","name":"data","nameLocation":"342:4:8","nodeType":"VariableDeclaration","scope":833,"src":"336:10:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":830,"name":"bytes","nodeType":"ElementaryTypeName","src":"336:5:8","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"288:59:8"},"src":"263:85:8"},{"id":836,"implemented":false,"kind":"receive","modifiers":[],"name":"","nameLocation":"-1:-1:-1","nodeType":"FunctionDefinition","parameters":{"id":834,"nodeType":"ParameterList","parameters":[],"src":"361:2:8"},"returnParameters":{"id":835,"nodeType":"ParameterList","parameters":[],"src":"380:0:8"},"scope":862,"src":"354:27:8","stateMutability":"payable","virtual":false,"visibility":"external"},{"functionSelector":"9e5d4c49","id":847,"implemented":false,"kind":"function","modifiers":[],"name":"executeCall","nameLocation":"396:11:8","nodeType":"FunctionDefinition","parameters":{"id":843,"nodeType":"ParameterList","parameters":[{"constant":false,"id":838,"mutability":"mutable","name":"to","nameLocation":"425:2:8","nodeType":"VariableDeclaration","scope":847,"src":"417:10:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":837,"name":"address","nodeType":"ElementaryTypeName","src":"417:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":840,"mutability":"mutable","name":"value","nameLocation":"445:5:8","nodeType":"VariableDeclaration","scope":847,"src":"437:13:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":839,"name":"uint256","nodeType":"ElementaryTypeName","src":"437:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":842,"mutability":"mutable","name":"data","nameLocation":"475:4:8","nodeType":"VariableDeclaration","scope":847,"src":"460:19:8","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":841,"name":"bytes","nodeType":"ElementaryTypeName","src":"460:5:8","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"407:78:8"},"returnParameters":{"id":846,"nodeType":"ParameterList","parameters":[{"constant":false,"id":845,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":847,"src":"512:12:8","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":844,"name":"bytes","nodeType":"ElementaryTypeName","src":"512:5:8","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"511:14:8"},"scope":862,"src":"387:139:8","stateMutability":"payable","virtual":false,"visibility":"external"},{"functionSelector":"fc0c546a","id":856,"implemented":false,"kind":"function","modifiers":[],"name":"token","nameLocation":"541:5:8","nodeType":"FunctionDefinition","parameters":{"id":848,"nodeType":"ParameterList","parameters":[],"src":"546:2:8"},"returnParameters":{"id":855,"nodeType":"ParameterList","parameters":[{"constant":false,"id":850,"mutability":"mutable","name":"chainId","nameLocation":"604:7:8","nodeType":"VariableDeclaration","scope":856,"src":"596:15:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":849,"name":"uint256","nodeType":"ElementaryTypeName","src":"596:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":852,"mutability":"mutable","name":"tokenContract","nameLocation":"621:13:8","nodeType":"VariableDeclaration","scope":856,"src":"613:21:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":851,"name":"address","nodeType":"ElementaryTypeName","src":"613:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":854,"mutability":"mutable","name":"tokenId","nameLocation":"644:7:8","nodeType":"VariableDeclaration","scope":856,"src":"636:15:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":853,"name":"uint256","nodeType":"ElementaryTypeName","src":"636:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"595:57:8"},"scope":862,"src":"532:121:8","stateMutability":"view","virtual":false,"visibility":"external"},{"functionSelector":"8da5cb5b","id":861,"implemented":false,"kind":"function","modifiers":[],"name":"owner","nameLocation":"668:5:8","nodeType":"FunctionDefinition","parameters":{"id":857,"nodeType":"ParameterList","parameters":[],"src":"673:2:8"},"returnParameters":{"id":860,"nodeType":"ParameterList","parameters":[{"constant":false,"id":859,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":861,"src":"699:7:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":858,"name":"address","nodeType":"ElementaryTypeName","src":"699:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"698:9:8"},"scope":862,"src":"659:49:8","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":863,"src":"231:479:8","usedErrors":[]}],"src":"39:672:8"},"id":8},"contracts/interfaces/IRegistry.sol":{"ast":{"absolutePath":"contracts/interfaces/IRegistry.sol","exportedSymbols":{"IRegistry":[897]},"id":898,"license":"UNLICENSED","nodeType":"SourceUnit","nodes":[{"id":864,"literals":["solidity","^","0.8",".13"],"nodeType":"PragmaDirective","src":"39:24:9"},{"abstract":false,"baseContracts":[],"canonicalName":"IRegistry","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"id":897,"linearizedBaseContracts":[897],"name":"IRegistry","nameLocation":"75:9:9","nodeType":"ContractDefinition","nodes":[{"functionSelector":"da7323b3","id":881,"implemented":false,"kind":"function","modifiers":[],"name":"createAccount","nameLocation":"100:13:9","nodeType":"FunctionDefinition","parameters":{"id":877,"nodeType":"ParameterList","parameters":[{"constant":false,"id":866,"mutability":"mutable","name":"implementation","nameLocation":"131:14:9","nodeType":"VariableDeclaration","scope":881,"src":"123:22:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":865,"name":"address","nodeType":"ElementaryTypeName","src":"123:7:9","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":868,"mutability":"mutable","name":"chainId","nameLocation":"163:7:9","nodeType":"VariableDeclaration","scope":881,"src":"155:15:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":867,"name":"uint256","nodeType":"ElementaryTypeName","src":"155:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":870,"mutability":"mutable","name":"tokenContract","nameLocation":"188:13:9","nodeType":"VariableDeclaration","scope":881,"src":"180:21:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":869,"name":"address","nodeType":"ElementaryTypeName","src":"180:7:9","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":872,"mutability":"mutable","name":"tokenId","nameLocation":"219:7:9","nodeType":"VariableDeclaration","scope":881,"src":"211:15:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":871,"name":"uint256","nodeType":"ElementaryTypeName","src":"211:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":874,"mutability":"mutable","name":"salt","nameLocation":"244:4:9","nodeType":"VariableDeclaration","scope":881,"src":"236:12:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":873,"name":"uint256","nodeType":"ElementaryTypeName","src":"236:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":876,"mutability":"mutable","name":"initData","nameLocation":"273:8:9","nodeType":"VariableDeclaration","scope":881,"src":"258:23:9","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":875,"name":"bytes","nodeType":"ElementaryTypeName","src":"258:5:9","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"113:174:9"},"returnParameters":{"id":880,"nodeType":"ParameterList","parameters":[{"constant":false,"id":879,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":881,"src":"306:7:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":878,"name":"address","nodeType":"ElementaryTypeName","src":"306:7:9","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"305:9:9"},"scope":897,"src":"91:224:9","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"5e9bc536","id":896,"implemented":false,"kind":"function","modifiers":[],"name":"account","nameLocation":"330:7:9","nodeType":"FunctionDefinition","parameters":{"id":892,"nodeType":"ParameterList","parameters":[{"constant":false,"id":883,"mutability":"mutable","name":"implementation","nameLocation":"355:14:9","nodeType":"VariableDeclaration","scope":896,"src":"347:22:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":882,"name":"address","nodeType":"ElementaryTypeName","src":"347:7:9","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":885,"mutability":"mutable","name":"chainId","nameLocation":"387:7:9","nodeType":"VariableDeclaration","scope":896,"src":"379:15:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":884,"name":"uint256","nodeType":"ElementaryTypeName","src":"379:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":887,"mutability":"mutable","name":"tokenContract","nameLocation":"412:13:9","nodeType":"VariableDeclaration","scope":896,"src":"404:21:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":886,"name":"address","nodeType":"ElementaryTypeName","src":"404:7:9","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":889,"mutability":"mutable","name":"tokenId","nameLocation":"443:7:9","nodeType":"VariableDeclaration","scope":896,"src":"435:15:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":888,"name":"uint256","nodeType":"ElementaryTypeName","src":"435:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":891,"mutability":"mutable","name":"salt","nameLocation":"468:4:9","nodeType":"VariableDeclaration","scope":896,"src":"460:12:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":890,"name":"uint256","nodeType":"ElementaryTypeName","src":"460:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"337:141:9"},"returnParameters":{"id":895,"nodeType":"ParameterList","parameters":[{"constant":false,"id":894,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":896,"src":"502:7:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":893,"name":"address","nodeType":"ElementaryTypeName","src":"502:7:9","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"501:9:9"},"scope":897,"src":"321:190:9","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":898,"src":"65:448:9","usedErrors":[]}],"src":"39:475:9"},"id":9},"contracts/lib/ERC6551AccountLib.sol":{"ast":{"absolutePath":"contracts/lib/ERC6551AccountLib.sol","exportedSymbols":{"ERC6551AccountLib":[952]},"id":953,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":899,"literals":["solidity","^","0.8",".13"],"nodeType":"PragmaDirective","src":"32:24:10"},{"abstract":false,"baseContracts":[],"canonicalName":"ERC6551AccountLib","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"id":952,"linearizedBaseContracts":[952],"name":"ERC6551AccountLib","nameLocation":"66:17:10","nodeType":"ContractDefinition","nodes":[{"body":{"id":928,"nodeType":"Block","src":"231:265:10","statements":[{"assignments":[909],"declarations":[{"constant":false,"id":909,"mutability":"mutable","name":"footer","nameLocation":"254:6:10","nodeType":"VariableDeclaration","scope":928,"src":"241:19:10","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":908,"name":"bytes","nodeType":"ElementaryTypeName","src":"241:5:10","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"id":914,"initialValue":{"arguments":[{"hexValue":"30783630","id":912,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"273:4:10","typeDescriptions":{"typeIdentifier":"t_rational_96_by_1","typeString":"int_const 96"},"value":"0x60"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_96_by_1","typeString":"int_const 96"}],"id":911,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"NewExpression","src":"263:9:10","typeDescriptions":{"typeIdentifier":"t_function_objectcreation_pure$_t_uint256_$returns$_t_bytes_memory_ptr_$","typeString":"function (uint256) pure returns (bytes memory)"},"typeName":{"id":910,"name":"bytes","nodeType":"ElementaryTypeName","src":"267:5:10","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}}},"id":913,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"263:15:10","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"nodeType":"VariableDeclarationStatement","src":"241:37:10"},{"AST":{"nodeType":"YulBlock","src":"298:127:10","statements":[{"expression":{"arguments":[{"arguments":[],"functionName":{"name":"address","nodeType":"YulIdentifier","src":"374:7:10"},"nodeType":"YulFunctionCall","src":"374:9:10"},{"arguments":[{"name":"footer","nodeType":"YulIdentifier","src":"389:6:10"},{"kind":"number","nodeType":"YulLiteral","src":"397:4:10","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"385:3:10"},"nodeType":"YulFunctionCall","src":"385:17:10"},{"kind":"number","nodeType":"YulLiteral","src":"404:4:10","type":"","value":"0x4d"},{"kind":"number","nodeType":"YulLiteral","src":"410:4:10","type":"","value":"0xad"}],"functionName":{"name":"extcodecopy","nodeType":"YulIdentifier","src":"362:11:10"},"nodeType":"YulFunctionCall","src":"362:53:10"},"nodeType":"YulExpressionStatement","src":"362:53:10"}]},"evmVersion":"london","externalReferences":[{"declaration":909,"isOffset":false,"isSlot":false,"src":"389:6:10","valueSize":1}],"id":915,"nodeType":"InlineAssembly","src":"289:136:10"},{"expression":{"arguments":[{"id":918,"name":"footer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":909,"src":"453:6:10","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},{"components":[{"id":920,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"462:7:10","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":919,"name":"uint256","nodeType":"ElementaryTypeName","src":"462:7:10","typeDescriptions":{}}},{"id":922,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"471:7:10","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":921,"name":"address","nodeType":"ElementaryTypeName","src":"471:7:10","typeDescriptions":{}}},{"id":924,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"480:7:10","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":923,"name":"uint256","nodeType":"ElementaryTypeName","src":"480:7:10","typeDescriptions":{}}}],"id":925,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"TupleExpression","src":"461:27:10","typeDescriptions":{"typeIdentifier":"t_tuple$_t_type$_t_uint256_$_$_t_type$_t_address_$_$_t_type$_t_uint256_$_$","typeString":"tuple(type(uint256),type(address),type(uint256))"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"},{"typeIdentifier":"t_tuple$_t_type$_t_uint256_$_$_t_type$_t_address_$_$_t_type$_t_uint256_$_$","typeString":"tuple(type(uint256),type(address),type(uint256))"}],"expression":{"id":916,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"442:3:10","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":917,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"446:6:10","memberName":"decode","nodeType":"MemberAccess","src":"442:10:10","typeDescriptions":{"typeIdentifier":"t_function_abidecode_pure$__$returns$__$","typeString":"function () pure"}},"id":926,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"442:47:10","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_uint256_$_t_address_payable_$_t_uint256_$","typeString":"tuple(uint256,address payable,uint256)"}},"functionReturnParameters":907,"id":927,"nodeType":"Return","src":"435:54:10"}]},"id":929,"implemented":true,"kind":"function","modifiers":[],"name":"token","nameLocation":"99:5:10","nodeType":"FunctionDefinition","parameters":{"id":900,"nodeType":"ParameterList","parameters":[],"src":"104:2:10"},"returnParameters":{"id":907,"nodeType":"ParameterList","parameters":[{"constant":false,"id":902,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":929,"src":"167:7:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":901,"name":"uint256","nodeType":"ElementaryTypeName","src":"167:7:10","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":904,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":929,"src":"188:7:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":903,"name":"address","nodeType":"ElementaryTypeName","src":"188:7:10","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":906,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":929,"src":"209:7:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":905,"name":"uint256","nodeType":"ElementaryTypeName","src":"209:7:10","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"153:73:10"},"scope":952,"src":"90:406:10","stateMutability":"view","virtual":false,"visibility":"internal"},{"body":{"id":950,"nodeType":"Block","src":"550:253:10","statements":[{"assignments":[935],"declarations":[{"constant":false,"id":935,"mutability":"mutable","name":"footer","nameLocation":"573:6:10","nodeType":"VariableDeclaration","scope":950,"src":"560:19:10","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":934,"name":"bytes","nodeType":"ElementaryTypeName","src":"560:5:10","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"id":940,"initialValue":{"arguments":[{"hexValue":"30783230","id":938,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"592:4:10","typeDescriptions":{"typeIdentifier":"t_rational_32_by_1","typeString":"int_const 32"},"value":"0x20"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_32_by_1","typeString":"int_const 32"}],"id":937,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"NewExpression","src":"582:9:10","typeDescriptions":{"typeIdentifier":"t_function_objectcreation_pure$_t_uint256_$returns$_t_bytes_memory_ptr_$","typeString":"function (uint256) pure returns (bytes memory)"},"typeName":{"id":936,"name":"bytes","nodeType":"ElementaryTypeName","src":"586:5:10","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}}},"id":939,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"582:15:10","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"nodeType":"VariableDeclarationStatement","src":"560:37:10"},{"AST":{"nodeType":"YulBlock","src":"617:133:10","statements":[{"expression":{"arguments":[{"arguments":[],"functionName":{"name":"address","nodeType":"YulIdentifier","src":"699:7:10"},"nodeType":"YulFunctionCall","src":"699:9:10"},{"arguments":[{"name":"footer","nodeType":"YulIdentifier","src":"714:6:10"},{"kind":"number","nodeType":"YulLiteral","src":"722:4:10","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"710:3:10"},"nodeType":"YulFunctionCall","src":"710:17:10"},{"kind":"number","nodeType":"YulLiteral","src":"729:4:10","type":"","value":"0x2d"},{"kind":"number","nodeType":"YulLiteral","src":"735:4:10","type":"","value":"0x4d"}],"functionName":{"name":"extcodecopy","nodeType":"YulIdentifier","src":"687:11:10"},"nodeType":"YulFunctionCall","src":"687:53:10"},"nodeType":"YulExpressionStatement","src":"687:53:10"}]},"evmVersion":"london","externalReferences":[{"declaration":935,"isOffset":false,"isSlot":false,"src":"714:6:10","valueSize":1}],"id":941,"nodeType":"InlineAssembly","src":"608:142:10"},{"expression":{"arguments":[{"id":944,"name":"footer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":935,"src":"778:6:10","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},{"components":[{"id":946,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"787:7:10","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":945,"name":"uint256","nodeType":"ElementaryTypeName","src":"787:7:10","typeDescriptions":{}}}],"id":947,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"TupleExpression","src":"786:9:10","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"},{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"}],"expression":{"id":942,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"767:3:10","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":943,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"771:6:10","memberName":"decode","nodeType":"MemberAccess","src":"767:10:10","typeDescriptions":{"typeIdentifier":"t_function_abidecode_pure$__$returns$__$","typeString":"function () pure"}},"id":948,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"767:29:10","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"functionReturnParameters":933,"id":949,"nodeType":"Return","src":"760:36:10"}]},"id":951,"implemented":true,"kind":"function","modifiers":[],"name":"salt","nameLocation":"511:4:10","nodeType":"FunctionDefinition","parameters":{"id":930,"nodeType":"ParameterList","parameters":[],"src":"515:2:10"},"returnParameters":{"id":933,"nodeType":"ParameterList","parameters":[{"constant":false,"id":932,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":951,"src":"541:7:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":931,"name":"uint256","nodeType":"ElementaryTypeName","src":"541:7:10","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"540:9:10"},"scope":952,"src":"502:301:10","stateMutability":"view","virtual":false,"visibility":"internal"}],"scope":953,"src":"58:747:10","usedErrors":[]}],"src":"32:774:10"},"id":10}},"contracts":{"@openzeppelin/contracts/interfaces/IERC1271.sol":{"IERC1271":{"abi":[{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"magicValue","type":"bytes4"}],"stateMutability":"view","type":"function"}],"devdoc":{"details":"Interface of the ERC1271 standard signature validation method for contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271]. _Available since v4.1._","kind":"dev","methods":{"isValidSignature(bytes32,bytes)":{"details":"Should return whether the signature provided is valid for the provided data","params":{"hash":"Hash of the data to be signed","signature":"Signature byte array associated with _data"}}},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"isValidSignature(bytes32,bytes)":"1626ba7e"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Interface of the ERC1271 standard signature validation method for contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271]. _Available since v4.1._\",\"kind\":\"dev\",\"methods\":{\"isValidSignature(bytes32,bytes)\":{\"details\":\"Should return whether the signature provided is valid for the provided data\",\"params\":{\"hash\":\"Hash of the data to be signed\",\"signature\":\"Signature byte array associated with _data\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":\"IERC1271\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol":{"IERC1155Receiver":{"abi":[{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}],"devdoc":{"details":"_Available since v3.1._","kind":"dev","methods":{"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":{"details":"Handles the receipt of a multiple ERC1155 token types. This function is called at the end of a `safeBatchTransferFrom` after the balances have been updated. NOTE: To accept the transfer(s), this must return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` (i.e. 0xbc197c81, or its own function selector).","params":{"data":"Additional data with no specified format","from":"The address which previously owned the token","ids":"An array containing ids of each token being transferred (order and length must match values array)","operator":"The address which initiated the batch transfer (i.e. msg.sender)","values":"An array containing amounts of each token being transferred (order and length must match ids array)"},"returns":{"_0":"`bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed"}},"onERC1155Received(address,address,uint256,uint256,bytes)":{"details":"Handles the receipt of a single ERC1155 token type. This function is called at the end of a `safeTransferFrom` after the balance has been updated. NOTE: To accept the transfer, this must return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` (i.e. 0xf23a6e61, or its own function selector).","params":{"data":"Additional data with no specified format","from":"The address which previously owned the token","id":"The ID of the token being transferred","operator":"The address which initiated the transfer (i.e. msg.sender)","value":"The amount of tokens being transferred"},"returns":{"_0":"`bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed"}},"supportsInterface(bytes4)":{"details":"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas."}},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":"bc197c81","onERC1155Received(address,address,uint256,uint256,bytes)":"f23a6e61","supportsInterface(bytes4)":"01ffc9a7"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onERC1155BatchReceived\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onERC1155Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"_Available since v3.1._\",\"kind\":\"dev\",\"methods\":{\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"details\":\"Handles the receipt of a multiple ERC1155 token types. This function is called at the end of a `safeBatchTransferFrom` after the balances have been updated. NOTE: To accept the transfer(s), this must return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` (i.e. 0xbc197c81, or its own function selector).\",\"params\":{\"data\":\"Additional data with no specified format\",\"from\":\"The address which previously owned the token\",\"ids\":\"An array containing ids of each token being transferred (order and length must match values array)\",\"operator\":\"The address which initiated the batch transfer (i.e. msg.sender)\",\"values\":\"An array containing amounts of each token being transferred (order and length must match ids array)\"},\"returns\":{\"_0\":\"`bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\"}},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"details\":\"Handles the receipt of a single ERC1155 token type. This function is called at the end of a `safeTransferFrom` after the balance has been updated. NOTE: To accept the transfer, this must return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` (i.e. 0xf23a6e61, or its own function selector).\",\"params\":{\"data\":\"Additional data with no specified format\",\"from\":\"The address which previously owned the token\",\"id\":\"The ID of the token being transferred\",\"operator\":\"The address which initiated the transfer (i.e. msg.sender)\",\"value\":\"The amount of tokens being transferred\"},\"returns\":{\"_0\":\"`bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\"}},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":\"IERC1155Receiver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (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 *\\n * NOTE: 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 *\\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.\\n *\\n * NOTE: 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 *\\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\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/token/ERC721/IERC721.sol":{"IERC721":{"abi":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"operator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"details":"Required interface of an ERC721 compliant contract.","events":{"Approval(address,address,uint256)":{"details":"Emitted when `owner` enables `approved` to manage the `tokenId` token."},"ApprovalForAll(address,address,bool)":{"details":"Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets."},"Transfer(address,address,uint256)":{"details":"Emitted when `tokenId` token is transferred from `from` to `to`."}},"kind":"dev","methods":{"approve(address,uint256)":{"details":"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event."},"balanceOf(address)":{"details":"Returns the number of tokens in ``owner``'s account."},"getApproved(uint256)":{"details":"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist."},"isApprovedForAll(address,address)":{"details":"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}"},"ownerOf(uint256)":{"details":"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist."},"safeTransferFrom(address,address,uint256)":{"details":"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event."},"safeTransferFrom(address,address,uint256,bytes)":{"details":"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event."},"setApprovalForAll(address,bool)":{"details":"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the caller. Emits an {ApprovalForAll} event."},"supportsInterface(bytes4)":{"details":"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas."},"transferFrom(address,address,uint256)":{"details":"Transfers `tokenId` token from `from` to `to`. WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event."}},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"approve(address,uint256)":"095ea7b3","balanceOf(address)":"70a08231","getApproved(uint256)":"081812fc","isApprovedForAll(address,address)":"e985e9c5","ownerOf(uint256)":"6352211e","safeTransferFrom(address,address,uint256)":"42842e0e","safeTransferFrom(address,address,uint256,bytes)":"b88d4fde","setApprovalForAll(address,bool)":"a22cb465","supportsInterface(bytes4)":"01ffc9a7","transferFrom(address,address,uint256)":"23b872dd"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Required interface of an ERC721 compliant contract.\",\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when `owner` enables `approved` to manage the `tokenId` token.\"},\"ApprovalForAll(address,address,bool)\":{\"details\":\"Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\"},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `tokenId` token is transferred from `from` to `to`.\"}},\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"details\":\"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event.\"},\"balanceOf(address)\":{\"details\":\"Returns the number of tokens in ``owner``'s account.\"},\"getApproved(uint256)\":{\"details\":\"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist.\"},\"isApprovedForAll(address,address)\":{\"details\":\"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}\"},\"ownerOf(uint256)\":{\"details\":\"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the caller. Emits an {ApprovalForAll} event.\"},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"Transfers `tokenId` token from `from` to `to`. WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":\"IERC721\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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`.\\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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\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(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol":{"IERC721Receiver":{"abi":[{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"details":"Interface for any contract that wants to support safeTransfers from ERC721 asset contracts.","kind":"dev","methods":{"onERC721Received(address,address,uint256,bytes)":{"details":"Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} by `operator` from `from`, this function is called. It must return its Solidity selector to confirm the token transfer. If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`."}},"title":"ERC721 token receiver interface","version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"onERC721Received(address,address,uint256,bytes)":"150b7a02"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Interface for any contract that wants to support safeTransfers from ERC721 asset contracts.\",\"kind\":\"dev\",\"methods\":{\"onERC721Received(address,address,uint256,bytes)\":{\"details\":\"Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} by `operator` from `from`, this function is called. It must return its Solidity selector to confirm the token transfer. If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\"}},\"title\":\"ERC721 token receiver interface\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":\"IERC721Receiver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface 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 `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/utils/introspection/IERC165.sol":{"IERC165":{"abi":[{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}],"devdoc":{"details":"Interface of the ERC165 standard, as defined in the https://eips.ethereum.org/EIPS/eip-165[EIP]. Implementers can declare support of contract interfaces, which can then be queried by others ({ERC165Checker}). For an implementation, see {ERC165}.","kind":"dev","methods":{"supportsInterface(bytes4)":{"details":"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas."}},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"supportsInterface(bytes4)":"01ffc9a7"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Interface of the ERC165 standard, as defined in the https://eips.ethereum.org/EIPS/eip-165[EIP]. Implementers can declare support of contract interfaces, which can then be queried by others ({ERC165Checker}). For an implementation, see {ERC165}.\",\"kind\":\"dev\",\"methods\":{\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":\"IERC165\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/AccountRegistryBridge.sol":{"AccountRegistryBridge":{"abi":[{"inputs":[],"name":"IMPLEMENTATION","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REGISTRY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"account","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"createAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"608060405234801561001057600080fd5b506102ad806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806306433b1b14610051578063192df655146100885780633a4741bd1461009b5780635fbfb9cf146100b6575b600080fd5b61006c7302101dfb77fde026414827fdc604ddaf224f092181565b6040516001600160a01b03909116815260200160405180910390f35b61006c61009636600461022e565b6100c9565b61006c732d25602551487c3f3354dd80d76d54383a24335881565b61006c6100c436600461022e565b61017d565b604051632f4de29b60e11b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b038316604482015260648101829052600060848201819052907302101dfb77fde026414827fdc604ddaf224f092190635e9bc5369060a401602060405180830381865afa158015610152573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610176919061025a565b9392505050565b60405163da7323b360e01b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b03831660448201526064810182905260006084820181905260c060a483015260c48201819052907302101dfb77fde026414827fdc604ddaf224f09219063da7323b39060e4016020604051808303816000875af1158015610152573d6000803e3d6000fd5b6001600160a01b038116811461022b57600080fd5b50565b6000806040838503121561024157600080fd5b823561024c81610216565b946020939093013593505050565b60006020828403121561026c57600080fd5b81516101768161021656fea26469706673582212200b4836e18ca9294f39a0f67787d9af3a81bbfd3510dceb2abf00f235aa0e1ecf64736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2AD DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x4C JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x6433B1B EQ PUSH2 0x51 JUMPI DUP1 PUSH4 0x192DF655 EQ PUSH2 0x88 JUMPI DUP1 PUSH4 0x3A4741BD EQ PUSH2 0x9B JUMPI DUP1 PUSH4 0x5FBFB9CF EQ PUSH2 0xB6 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x6C PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x6C PUSH2 0x96 CALLDATASIZE PUSH1 0x4 PUSH2 0x22E JUMP JUMPDEST PUSH2 0xC9 JUMP JUMPDEST PUSH2 0x6C PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 DUP2 JUMP JUMPDEST PUSH2 0x6C PUSH2 0xC4 CALLDATASIZE PUSH1 0x4 PUSH2 0x22E JUMP JUMPDEST PUSH2 0x17D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x2F4DE29B PUSH1 0xE1 SHL DUP2 MSTORE PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 PUSH1 0x4 DUP3 ADD MSTORE CHAINID PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 PUSH1 0x84 DUP3 ADD DUP2 SWAP1 MSTORE SWAP1 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 SWAP1 PUSH4 0x5E9BC536 SWAP1 PUSH1 0xA4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x152 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x176 SWAP2 SWAP1 PUSH2 0x25A JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0xDA7323B3 PUSH1 0xE0 SHL DUP2 MSTORE PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 PUSH1 0x4 DUP3 ADD MSTORE CHAINID PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 PUSH1 0x84 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0xC0 PUSH1 0xA4 DUP4 ADD MSTORE PUSH1 0xC4 DUP3 ADD DUP2 SWAP1 MSTORE SWAP1 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 SWAP1 PUSH4 0xDA7323B3 SWAP1 PUSH1 0xE4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x152 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0x22B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x241 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH2 0x24C DUP2 PUSH2 0x216 JUMP JUMPDEST SWAP5 PUSH1 0x20 SWAP4 SWAP1 SWAP4 ADD CALLDATALOAD SWAP4 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x26C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x176 DUP2 PUSH2 0x216 JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 SIGNEXTEND BASEFEE CALLDATASIZE 0xE1 DUP13 0xA9 0x29 0x4F CODECOPY LOG0 0xF6 PUSH24 0x87D9AF3A81BBFD3510DCEB2ABF00F235AA0E1ECF64736F6C PUSH4 0x43000811 STOP CALLER ","sourceMap":"163:830:5:-:0;;;;;;;;;;;;;;;;;;;"},"deployedBytecode":{"functionDebugData":{"@IMPLEMENTATION_210":{"entryPoint":null,"id":210,"parameterSlots":0,"returnSlots":0},"@REGISTRY_207":{"entryPoint":null,"id":207,"parameterSlots":0,"returnSlots":0},"@account_255":{"entryPoint":201,"id":255,"parameterSlots":2,"returnSlots":1},"@createAccount_233":{"entryPoint":381,"id":233,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_address_fromMemory":{"entryPoint":602,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_addresst_uint256":{"entryPoint":558,"id":null,"parameterSlots":2,"returnSlots":2},"abi_encode_tuple_t_address__to_t_address__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1__to_t_address_t_uint256_t_address_t_uint256_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":6,"returnSlots":1},"abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470__to_t_address_t_uint256_t_address_t_uint256_t_uint256_t_bytes_memory_ptr__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":6,"returnSlots":1},"validator_revert_address":{"entryPoint":534,"id":null,"parameterSlots":1,"returnSlots":0}},"generatedSources":[{"ast":{"nodeType":"YulBlock","src":"0:2175:11","statements":[{"nodeType":"YulBlock","src":"6:3:11","statements":[]},{"body":{"nodeType":"YulBlock","src":"115:102:11","statements":[{"nodeType":"YulAssignment","src":"125:26:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"137:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"148:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"133:3:11"},"nodeType":"YulFunctionCall","src":"133:18:11"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"125:4:11"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"167:9:11"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"182:6:11"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"198:3:11","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"203:1:11","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"194:3:11"},"nodeType":"YulFunctionCall","src":"194:11:11"},{"kind":"number","nodeType":"YulLiteral","src":"207:1:11","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"190:3:11"},"nodeType":"YulFunctionCall","src":"190:19:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"178:3:11"},"nodeType":"YulFunctionCall","src":"178:32:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"160:6:11"},"nodeType":"YulFunctionCall","src":"160:51:11"},"nodeType":"YulExpressionStatement","src":"160:51:11"}]},"name":"abi_encode_tuple_t_address__to_t_address__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"84:9:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"95:6:11","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"106:4:11","type":""}],"src":"14:203:11"},{"body":{"nodeType":"YulBlock","src":"267:86:11","statements":[{"body":{"nodeType":"YulBlock","src":"331:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"340:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"343:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"333:6:11"},"nodeType":"YulFunctionCall","src":"333:12:11"},"nodeType":"YulExpressionStatement","src":"333:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"290:5:11"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"301:5:11"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"316:3:11","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"321:1:11","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"312:3:11"},"nodeType":"YulFunctionCall","src":"312:11:11"},{"kind":"number","nodeType":"YulLiteral","src":"325:1:11","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"308:3:11"},"nodeType":"YulFunctionCall","src":"308:19:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"297:3:11"},"nodeType":"YulFunctionCall","src":"297:31:11"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"287:2:11"},"nodeType":"YulFunctionCall","src":"287:42:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"280:6:11"},"nodeType":"YulFunctionCall","src":"280:50:11"},"nodeType":"YulIf","src":"277:70:11"}]},"name":"validator_revert_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"value","nodeType":"YulTypedName","src":"256:5:11","type":""}],"src":"222:131:11"},{"body":{"nodeType":"YulBlock","src":"445:228:11","statements":[{"body":{"nodeType":"YulBlock","src":"491:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"500:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"503:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"493:6:11"},"nodeType":"YulFunctionCall","src":"493:12:11"},"nodeType":"YulExpressionStatement","src":"493:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"466:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"475:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"462:3:11"},"nodeType":"YulFunctionCall","src":"462:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"487:2:11","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"458:3:11"},"nodeType":"YulFunctionCall","src":"458:32:11"},"nodeType":"YulIf","src":"455:52:11"},{"nodeType":"YulVariableDeclaration","src":"516:36:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"542:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"529:12:11"},"nodeType":"YulFunctionCall","src":"529:23:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"520:5:11","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"586:5:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"561:24:11"},"nodeType":"YulFunctionCall","src":"561:31:11"},"nodeType":"YulExpressionStatement","src":"561:31:11"},{"nodeType":"YulAssignment","src":"601:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"611:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"601:6:11"}]},{"nodeType":"YulAssignment","src":"625:42:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"652:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"663:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"648:3:11"},"nodeType":"YulFunctionCall","src":"648:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"635:12:11"},"nodeType":"YulFunctionCall","src":"635:32:11"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"625:6:11"}]}]},"name":"abi_decode_tuple_t_addresst_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"403:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"414:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"426:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"434:6:11","type":""}],"src":"358:315:11"},{"body":{"nodeType":"YulBlock","src":"899:306:11","statements":[{"nodeType":"YulAssignment","src":"909:27:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"921:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"932:3:11","type":"","value":"160"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"917:3:11"},"nodeType":"YulFunctionCall","src":"917:19:11"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"909:4:11"}]},{"nodeType":"YulVariableDeclaration","src":"945:29:11","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"963:3:11","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"968:1:11","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"959:3:11"},"nodeType":"YulFunctionCall","src":"959:11:11"},{"kind":"number","nodeType":"YulLiteral","src":"972:1:11","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"955:3:11"},"nodeType":"YulFunctionCall","src":"955:19:11"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"949:2:11","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"990:9:11"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"1005:6:11"},{"name":"_1","nodeType":"YulIdentifier","src":"1013:2:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1001:3:11"},"nodeType":"YulFunctionCall","src":"1001:15:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"983:6:11"},"nodeType":"YulFunctionCall","src":"983:34:11"},"nodeType":"YulExpressionStatement","src":"983:34:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1037:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"1048:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1033:3:11"},"nodeType":"YulFunctionCall","src":"1033:18:11"},{"name":"value1","nodeType":"YulIdentifier","src":"1053:6:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1026:6:11"},"nodeType":"YulFunctionCall","src":"1026:34:11"},"nodeType":"YulExpressionStatement","src":"1026:34:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1080:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"1091:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1076:3:11"},"nodeType":"YulFunctionCall","src":"1076:18:11"},{"arguments":[{"name":"value2","nodeType":"YulIdentifier","src":"1100:6:11"},{"name":"_1","nodeType":"YulIdentifier","src":"1108:2:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1096:3:11"},"nodeType":"YulFunctionCall","src":"1096:15:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1069:6:11"},"nodeType":"YulFunctionCall","src":"1069:43:11"},"nodeType":"YulExpressionStatement","src":"1069:43:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1132:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"1143:2:11","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1128:3:11"},"nodeType":"YulFunctionCall","src":"1128:18:11"},{"name":"value3","nodeType":"YulIdentifier","src":"1148:6:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1121:6:11"},"nodeType":"YulFunctionCall","src":"1121:34:11"},"nodeType":"YulExpressionStatement","src":"1121:34:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1175:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"1186:3:11","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1171:3:11"},"nodeType":"YulFunctionCall","src":"1171:19:11"},{"name":"value4","nodeType":"YulIdentifier","src":"1192:6:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1164:6:11"},"nodeType":"YulFunctionCall","src":"1164:35:11"},"nodeType":"YulExpressionStatement","src":"1164:35:11"}]},"name":"abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1__to_t_address_t_uint256_t_address_t_uint256_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"836:9:11","type":""},{"name":"value4","nodeType":"YulTypedName","src":"847:6:11","type":""},{"name":"value3","nodeType":"YulTypedName","src":"855:6:11","type":""},{"name":"value2","nodeType":"YulTypedName","src":"863:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"871:6:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"879:6:11","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"890:4:11","type":""}],"src":"678:527:11"},{"body":{"nodeType":"YulBlock","src":"1291:170:11","statements":[{"body":{"nodeType":"YulBlock","src":"1337:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1346:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1349:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1339:6:11"},"nodeType":"YulFunctionCall","src":"1339:12:11"},"nodeType":"YulExpressionStatement","src":"1339:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"1312:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"1321:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1308:3:11"},"nodeType":"YulFunctionCall","src":"1308:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"1333:2:11","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"1304:3:11"},"nodeType":"YulFunctionCall","src":"1304:32:11"},"nodeType":"YulIf","src":"1301:52:11"},{"nodeType":"YulVariableDeclaration","src":"1362:29:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1381:9:11"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"1375:5:11"},"nodeType":"YulFunctionCall","src":"1375:16:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"1366:5:11","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1425:5:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"1400:24:11"},"nodeType":"YulFunctionCall","src":"1400:31:11"},"nodeType":"YulExpressionStatement","src":"1400:31:11"},{"nodeType":"YulAssignment","src":"1440:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"1450:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"1440:6:11"}]}]},"name":"abi_decode_tuple_t_address_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"1257:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"1268:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"1280:6:11","type":""}],"src":"1210:251:11"},{"body":{"nodeType":"YulBlock","src":"1787:386:11","statements":[{"nodeType":"YulVariableDeclaration","src":"1797:29:11","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1815:3:11","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"1820:1:11","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1811:3:11"},"nodeType":"YulFunctionCall","src":"1811:11:11"},{"kind":"number","nodeType":"YulLiteral","src":"1824:1:11","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1807:3:11"},"nodeType":"YulFunctionCall","src":"1807:19:11"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"1801:2:11","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1842:9:11"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"1857:6:11"},{"name":"_1","nodeType":"YulIdentifier","src":"1865:2:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1853:3:11"},"nodeType":"YulFunctionCall","src":"1853:15:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1835:6:11"},"nodeType":"YulFunctionCall","src":"1835:34:11"},"nodeType":"YulExpressionStatement","src":"1835:34:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1889:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"1900:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1885:3:11"},"nodeType":"YulFunctionCall","src":"1885:18:11"},{"name":"value1","nodeType":"YulIdentifier","src":"1905:6:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1878:6:11"},"nodeType":"YulFunctionCall","src":"1878:34:11"},"nodeType":"YulExpressionStatement","src":"1878:34:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1932:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"1943:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1928:3:11"},"nodeType":"YulFunctionCall","src":"1928:18:11"},{"arguments":[{"name":"value2","nodeType":"YulIdentifier","src":"1952:6:11"},{"name":"_1","nodeType":"YulIdentifier","src":"1960:2:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1948:3:11"},"nodeType":"YulFunctionCall","src":"1948:15:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1921:6:11"},"nodeType":"YulFunctionCall","src":"1921:43:11"},"nodeType":"YulExpressionStatement","src":"1921:43:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1984:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"1995:2:11","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1980:3:11"},"nodeType":"YulFunctionCall","src":"1980:18:11"},{"name":"value3","nodeType":"YulIdentifier","src":"2000:6:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1973:6:11"},"nodeType":"YulFunctionCall","src":"1973:34:11"},"nodeType":"YulExpressionStatement","src":"1973:34:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2027:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"2038:3:11","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2023:3:11"},"nodeType":"YulFunctionCall","src":"2023:19:11"},{"name":"value4","nodeType":"YulIdentifier","src":"2044:6:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2016:6:11"},"nodeType":"YulFunctionCall","src":"2016:35:11"},"nodeType":"YulExpressionStatement","src":"2016:35:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2071:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"2082:3:11","type":"","value":"160"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2067:3:11"},"nodeType":"YulFunctionCall","src":"2067:19:11"},{"kind":"number","nodeType":"YulLiteral","src":"2088:3:11","type":"","value":"192"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2060:6:11"},"nodeType":"YulFunctionCall","src":"2060:32:11"},"nodeType":"YulExpressionStatement","src":"2060:32:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2112:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"2123:3:11","type":"","value":"192"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2108:3:11"},"nodeType":"YulFunctionCall","src":"2108:19:11"},{"kind":"number","nodeType":"YulLiteral","src":"2129:1:11","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2101:6:11"},"nodeType":"YulFunctionCall","src":"2101:30:11"},"nodeType":"YulExpressionStatement","src":"2101:30:11"},{"nodeType":"YulAssignment","src":"2140:27:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2152:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"2163:3:11","type":"","value":"224"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2148:3:11"},"nodeType":"YulFunctionCall","src":"2148:19:11"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"2140:4:11"}]}]},"name":"abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470__to_t_address_t_uint256_t_address_t_uint256_t_uint256_t_bytes_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"1724:9:11","type":""},{"name":"value4","nodeType":"YulTypedName","src":"1735:6:11","type":""},{"name":"value3","nodeType":"YulTypedName","src":"1743:6:11","type":""},{"name":"value2","nodeType":"YulTypedName","src":"1751:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"1759:6:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"1767:6:11","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"1778:4:11","type":""}],"src":"1466:707:11"}]},"contents":"{\n { }\n function abi_encode_tuple_t_address__to_t_address__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, sub(shl(160, 1), 1)))\n }\n function validator_revert_address(value)\n {\n if iszero(eq(value, and(value, sub(shl(160, 1), 1)))) { revert(0, 0) }\n }\n function abi_decode_tuple_t_addresst_uint256(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n value1 := calldataload(add(headStart, 32))\n }\n function abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1__to_t_address_t_uint256_t_address_t_uint256_t_uint256__fromStack_reversed(headStart, value4, value3, value2, value1, value0) -> tail\n {\n tail := add(headStart, 160)\n let _1 := sub(shl(160, 1), 1)\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), value1)\n mstore(add(headStart, 64), and(value2, _1))\n mstore(add(headStart, 96), value3)\n mstore(add(headStart, 128), value4)\n }\n function abi_decode_tuple_t_address_fromMemory(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := mload(headStart)\n validator_revert_address(value)\n value0 := value\n }\n function abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470__to_t_address_t_uint256_t_address_t_uint256_t_uint256_t_bytes_memory_ptr__fromStack_reversed(headStart, value4, value3, value2, value1, value0) -> tail\n {\n let _1 := sub(shl(160, 1), 1)\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), value1)\n mstore(add(headStart, 64), and(value2, _1))\n mstore(add(headStart, 96), value3)\n mstore(add(headStart, 128), value4)\n mstore(add(headStart, 160), 192)\n mstore(add(headStart, 192), 0)\n tail := add(headStart, 224)\n }\n}","id":11,"language":"Yul","name":"#utility.yul"}],"immutableReferences":{},"linkReferences":{},"object":"608060405234801561001057600080fd5b506004361061004c5760003560e01c806306433b1b14610051578063192df655146100885780633a4741bd1461009b5780635fbfb9cf146100b6575b600080fd5b61006c7302101dfb77fde026414827fdc604ddaf224f092181565b6040516001600160a01b03909116815260200160405180910390f35b61006c61009636600461022e565b6100c9565b61006c732d25602551487c3f3354dd80d76d54383a24335881565b61006c6100c436600461022e565b61017d565b604051632f4de29b60e11b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b038316604482015260648101829052600060848201819052907302101dfb77fde026414827fdc604ddaf224f092190635e9bc5369060a401602060405180830381865afa158015610152573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610176919061025a565b9392505050565b60405163da7323b360e01b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b03831660448201526064810182905260006084820181905260c060a483015260c48201819052907302101dfb77fde026414827fdc604ddaf224f09219063da7323b39060e4016020604051808303816000875af1158015610152573d6000803e3d6000fd5b6001600160a01b038116811461022b57600080fd5b50565b6000806040838503121561024157600080fd5b823561024c81610216565b946020939093013593505050565b60006020828403121561026c57600080fd5b81516101768161021656fea26469706673582212200b4836e18ca9294f39a0f67787d9af3a81bbfd3510dceb2abf00f235aa0e1ecf64736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x4C JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x6433B1B EQ PUSH2 0x51 JUMPI DUP1 PUSH4 0x192DF655 EQ PUSH2 0x88 JUMPI DUP1 PUSH4 0x3A4741BD EQ PUSH2 0x9B JUMPI DUP1 PUSH4 0x5FBFB9CF EQ PUSH2 0xB6 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x6C PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x6C PUSH2 0x96 CALLDATASIZE PUSH1 0x4 PUSH2 0x22E JUMP JUMPDEST PUSH2 0xC9 JUMP JUMPDEST PUSH2 0x6C PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 DUP2 JUMP JUMPDEST PUSH2 0x6C PUSH2 0xC4 CALLDATASIZE PUSH1 0x4 PUSH2 0x22E JUMP JUMPDEST PUSH2 0x17D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x2F4DE29B PUSH1 0xE1 SHL DUP2 MSTORE PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 PUSH1 0x4 DUP3 ADD MSTORE CHAINID PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 PUSH1 0x84 DUP3 ADD DUP2 SWAP1 MSTORE SWAP1 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 SWAP1 PUSH4 0x5E9BC536 SWAP1 PUSH1 0xA4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x152 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x176 SWAP2 SWAP1 PUSH2 0x25A JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0xDA7323B3 PUSH1 0xE0 SHL DUP2 MSTORE PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 PUSH1 0x4 DUP3 ADD MSTORE CHAINID PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 PUSH1 0x84 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0xC0 PUSH1 0xA4 DUP4 ADD MSTORE PUSH1 0xC4 DUP3 ADD DUP2 SWAP1 MSTORE SWAP1 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 SWAP1 PUSH4 0xDA7323B3 SWAP1 PUSH1 0xE4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x152 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0x22B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x241 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH2 0x24C DUP2 PUSH2 0x216 JUMP JUMPDEST SWAP5 PUSH1 0x20 SWAP4 SWAP1 SWAP4 ADD CALLDATALOAD SWAP4 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x26C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x176 DUP2 PUSH2 0x216 JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 SIGNEXTEND BASEFEE CALLDATASIZE 0xE1 DUP13 0xA9 0x29 0x4F CODECOPY LOG0 0xF6 PUSH24 0x87D9AF3A81BBFD3510DCEB2ABF00F235AA0E1ECF64736F6C PUSH4 0x43000811 STOP CALLER ","sourceMap":"163:830:5:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;200:78;;236:42;200:78;;;;;-1:-1:-1;;;;;178:32:11;;;160:51;;148:2;133:18;200:78:5;;;;;;;697:294;;;;;;:::i;:::-;;:::i;284:83::-;;325:42;284:83;;374:317;;;;;;:::i;:::-;;:::i;697:294::-;827:157;;-1:-1:-1;;;827:157:5;;325:42;827:157;;;983:34:11;896:13:5;1033:18:11;;;1026:34;-1:-1:-1;;;;;1096:15:11;;1076:18;;;1069:43;1128:18;;;1121:34;;;801:7:5;1171:19:11;;;1164:35;;;801:7:5;236:42;;827:27;;917:19:11;;827:157:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;820:164;697:294;-1:-1:-1;;;697:294:5:o;374:317::-;505:179;;-1:-1:-1;;;505:179:5;;325:42;505:179;;;1835:34:11;580:13:5;1885:18:11;;;1878:34;-1:-1:-1;;;;;1948:15:11;;1928:18;;;1921:43;1980:18;;;1973:34;;;479:7:5;2023:19:11;;;2016:35;;;2088:3;2067:19;;;2060:32;2108:19;;;2101:30;;;479:7:5;236:42;;505:33;;2148:19:11;;505:179:5;;;;;;;;;;;;;;;;;;;;;;;222:131:11;-1:-1:-1;;;;;297:31:11;;287:42;;277:70;;343:1;340;333:12;277:70;222:131;:::o;358:315::-;426:6;434;487:2;475:9;466:7;462:23;458:32;455:52;;;503:1;500;493:12;455:52;542:9;529:23;561:31;586:5;561:31;:::i;:::-;611:5;663:2;648:18;;;;635:32;;-1:-1:-1;;;358:315:11:o;1210:251::-;1280:6;1333:2;1321:9;1312:7;1308:23;1304:32;1301:52;;;1349:1;1346;1339:12;1301:52;1381:9;1375:16;1400:31;1425:5;1400:31;:::i"},"gasEstimates":{"creation":{"codeDepositCost":"137000","executionCost":"183","totalCost":"137183"},"external":{"IMPLEMENTATION()":"226","REGISTRY()":"182","account(address,uint256)":"infinite","createAccount(address,uint256)":"infinite"}},"methodIdentifiers":{"IMPLEMENTATION()":"3a4741bd","REGISTRY()":"06433b1b","account(address,uint256)":"192df655","createAccount(address,uint256)":"5fbfb9cf"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"IMPLEMENTATION\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REGISTRY\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"account\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/AccountRegistryBridge.sol\":\"AccountRegistryBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/AccountRegistryBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.13;\\n\\nimport \\\"./interfaces/IRegistry.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\n\\ncontract AccountRegistryBridge {\\n address public constant REGISTRY = \\t0x02101dfB77FDE026414827Fdc604ddAF224F0921;\\n address public constant IMPLEMENTATION = 0x2D25602551487C3f3354dD80D76D54383A243358;\\n\\n function createAccount(\\n address contractAddress,\\n uint256 tokenId\\n ) external returns (address) {\\n return IRegistry(REGISTRY).createAccount(\\n IMPLEMENTATION,\\n block.chainid,\\n contractAddress,\\n tokenId,\\n 0,\\n ''\\n );\\n }\\n\\n function account(\\n address contractAddress,\\n uint256 tokenId\\n ) external view returns (address) {\\n return IRegistry(REGISTRY).account(\\n IMPLEMENTATION,\\n block.chainid,\\n contractAddress,\\n tokenId,\\n 0\\n );\\n }\\n}\",\"keccak256\":\"0x263ac1c6e56edaab1925063387b0fcd8ba33f875f3b5a2afeffdc4424ac2189a\",\"license\":\"MIT\"},\"contracts/interfaces/IRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\ninterface IRegistry {\\n function createAccount(\\n address implementation,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId,\\n uint256 salt,\\n bytes calldata initData\\n ) external returns (address);\\n\\n function account(\\n address implementation,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId,\\n uint256 salt\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xd24999d4d474bd349b1e2e5006eff215c5d9a64a481a9ebac3293f98603fbd27\",\"license\":\"UNLICENSED\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/ChargedParticlesAccount.sol":{"ChargedParticlesAccount":{"abi":[{"inputs":[],"name":"AccountLocked","type":"error"},{"inputs":[],"name":"ExceedsMaxLockTime","type":"error"},{"inputs":[],"name":"InvalidInput","type":"error"},{"inputs":[],"name":"NotAuthorized","type":"error"},{"inputs":[],"name":"OwnershipCycle","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"lockedUntil","type":"uint256"}],"name":"LockUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"bytes4","name":"selector","type":"bytes4"},{"indexed":false,"internalType":"address","name":"implementation","type":"address"}],"name":"OverrideUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"bool","name":"hasPermission","type":"bool"}],"name":"PermissionUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":true,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"TransactionExecuted","type":"event"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"basketManagerId","type":"string"},{"internalType":"address","name":"nftTokenAddress","type":"address"},{"internalType":"uint256","name":"nftTokenId","type":"uint256"},{"internalType":"uint256","name":"nftTokenAmount","type":"uint256"}],"name":"covalentBond","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"executeCall","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"isAuthorized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lockedUntil","type":"uint256"}],"name":"lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockedUntil","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"receivedTokenId","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"permissions","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"callers","type":"address[]"},{"internalType":"bool[]","name":"_permissions","type":"bool[]"}],"name":"setPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}],"devdoc":{"kind":"dev","methods":{"executeCall(address,uint256,bytes)":{"details":"executes a low-level call against an account if the caller is authorized to make calls"},"isAuthorized(address)":{"details":"Returns the authorization status for a given caller"},"isLocked()":{"details":"returns the current lock status of the account as a boolean"},"lock(uint256)":{"details":"locks the account until a certain timestamp"},"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":{"details":"Allows ERC-1155 token batches to be received. This function can be overriden."},"onERC1155Received(address,address,uint256,uint256,bytes)":{"details":"Allows ERC-1155 tokens to be received. This function can be overriden."},"onERC721Received(address,address,uint256,bytes)":{"details":"Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle. This function can be overriden."},"owner()":{"details":"Returns the owner of the ERC-721 token which owns this account. By default, the owner of the token has full permissions on the account."},"setPermissions(address[],bool[])":{"details":"grants a given caller execution permissions"},"supportsInterface(bytes4)":{"details":"Returns true if a given interfaceId is supported by this account. This method can be extended by an override."},"token()":{"details":"Returns the EIP-155 chain ID, token contract address, and token ID for the token that owns this account."}},"version":1},"evm":{"bytecode":{"functionDebugData":{"@_384":{"entryPoint":null,"id":384,"parameterSlots":0,"returnSlots":0}},"generatedSources":[],"linkReferences":{},"object":"608060405234801561001057600080fd5b5061107a806100206000396000f3fe6080604052600436106100e15760003560e01c8063a4e2d6341161007f578063dd46706411610059578063dd46706414610294578063f23a6e61146102b4578063fc0c546a146102e0578063fe9fbb801461031857600080fd5b8063a4e2d6341461022d578063bc197c8114610244578063ce0617ec1461027057600080fd5b80631f9838b5116100bb5780631f9838b51461017d5780633ff956cc146101b85780638da5cb5b146101e05780639e5d4c491461020d57600080fd5b806301ffc9a7146100ed578063039721b114610122578063150b7a021461014457600080fd5b366100e857005b600080fd5b3480156100f957600080fd5b5061010d61010836600461099f565b610338565b60405190151581526020015b60405180910390f35b34801561012e57600080fd5b5061014261013d366004610a1c565b61039f565b005b34801561015057600080fd5b5061016461015f366004610b57565b610568565b6040516001600160e01b03199091168152602001610119565b34801561018957600080fd5b5061010d610198366004610bc3565b600160209081526000928352604080842090915290825290205460ff1681565b3480156101c457600080fd5b5061010d6101d3366004610c3e565b6000979650505050505050565b3480156101ec57600080fd5b506101f56105d0565b6040516001600160a01b039091168152602001610119565b61022061021b366004610cc4565b610666565b6040516101199190610d14565b34801561023957600080fd5b50600054421061010d565b34801561025057600080fd5b5061016461025f366004610de2565b63bc197c8160e01b95945050505050565b34801561027c57600080fd5b5061028660005481565b604051908152602001610119565b3480156102a057600080fd5b506101426102af366004610e90565b61070a565b3480156102c057600080fd5b506101646102cf366004610ea9565b63f23a6e6160e01b95945050505050565b3480156102ec57600080fd5b506102f56107cf565b604080519384526001600160a01b03909216602084015290820152606001610119565b34801561032457600080fd5b5061010d610333366004610f12565b6107e7565b6000806001600160e01b031983166301ffc9a760e01b148061036a57506001600160e01b03198316630271189760e51b145b8061038557506001600160e01b03198316631dfe9a6f60e31b145b905080156103965750600192915050565b50600092915050565b6000544210156103c257604051636315bfbb60e01b815260040160405180910390fd5b60006103cc6105d0565b9050336001600160a01b038216146103f75760405163ea8e4eb560e01b815260040160405180910390fd5b838281146104185760405163b4fa3fb360e01b815260040160405180910390fd5b60005b8181101561055f5784848281811061043557610435610f2f565b905060200201602081019061044a9190610f45565b6001600160a01b03841660009081526001602052604081209089898581811061047557610475610f2f565b905060200201602081019061048a9190610f12565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f394777a58092892d136a90c4bb7e4350c72ac50fba6a0208128677f36527dcf5838888848181106104e6576104e6610f2f565b90506020020160208101906104fb9190610f12565b87878581811061050d5761050d610f2f565b90506020020160208101906105229190610f45565b604080516001600160a01b03948516815293909216602084015215159082015260600160405180910390a18061055781610f7d565b91505061041b565b50505050505050565b6000806000806105766108d0565b925092509250468314801561059357506001600160a01b03821633145b801561059e57508581145b156105bc5760405163b79e3f3f60e01b815260040160405180910390fd5b50630a85bd0160e11b979650505050505050565b6000806000806105de6108d0565b9250925092504683146105f5576000935050505090565b6040516331a9108f60e11b8152600481018290526001600160a01b03831690636352211e90602401602060405180830381865afa15801561063a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065e9190610f96565b935050505090565b6060610671336107e7565b61068e5760405163ea8e4eb560e01b815260040160405180910390fd5b6000544210156106b157604051636315bfbb60e01b815260040160405180910390fd5b83856001600160a01b03167f47d99ad340f52da66535aff7e10da1ceb85a32bcbd9fa1c42314d194545e14d285856040516106ed929190610fb3565b60405180910390a361070185858585610923565b95945050505050565b6107126105d0565b6001600160a01b0316336001600160a01b0316146107435760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561076657604051636315bfbb60e01b815260040160405180910390fd5b610774426301e13380610fe2565b811115610794576040516301814f7d60e31b815260040160405180910390fd5b60008190556040518181527fa7b24c66dd3269a292a60b3facdbb8f3e7557d1e19e64d99e0d6ee7250be63ad9060200160405180910390a150565b60008060006107dc6108d0565b925092509250909192565b60008060006107f46108d0565b6040516331a9108f60e11b8152600481018290529194509250600091506001600160a01b03841690636352211e90602401602060405180830381865afa158015610842573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108669190610f96565b9050806001600160a01b0316856001600160a01b03160361088c57506001949350505050565b6001600160a01b0380821660009081526001602090815260408083209389168352929052205460ff16156108c557506001949350505050565b506000949350505050565b604080516060808252608082019092526000918291829182919060208201818036833701905050905060ad604d60208301303c808060200190518101906109179190610ffb565b93509350935050909192565b60606000856001600160a01b0316858585604051610942929190611034565b60006040518083038185875af1925050503d806000811461097f576040519150601f19603f3d011682016040523d82523d6000602084013e610984565b606091505b50925090508061099657815160208301fd5b50949350505050565b6000602082840312156109b157600080fd5b81356001600160e01b0319811681146109c957600080fd5b9392505050565b60008083601f8401126109e257600080fd5b50813567ffffffffffffffff8111156109fa57600080fd5b6020830191508360208260051b8501011115610a1557600080fd5b9250929050565b60008060008060408587031215610a3257600080fd5b843567ffffffffffffffff80821115610a4a57600080fd5b610a56888389016109d0565b90965094506020870135915080821115610a6f57600080fd5b50610a7c878288016109d0565b95989497509550505050565b6001600160a01b0381168114610a9d57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610adf57610adf610aa0565b604052919050565b600082601f830112610af857600080fd5b813567ffffffffffffffff811115610b1257610b12610aa0565b610b25601f8201601f1916602001610ab6565b818152846020838601011115610b3a57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215610b6d57600080fd5b8435610b7881610a88565b93506020850135610b8881610a88565b925060408501359150606085013567ffffffffffffffff811115610bab57600080fd5b610bb787828801610ae7565b91505092959194509250565b60008060408385031215610bd657600080fd5b8235610be181610a88565b91506020830135610bf181610a88565b809150509250929050565b60008083601f840112610c0e57600080fd5b50813567ffffffffffffffff811115610c2657600080fd5b602083019150836020828501011115610a1557600080fd5b600080600080600080600060c0888a031215610c5957600080fd5b8735610c6481610a88565b965060208801359550604088013567ffffffffffffffff811115610c8757600080fd5b610c938a828b01610bfc565b9096509450506060880135610ca781610a88565b969995985093969295946080840135945060a09093013592915050565b60008060008060608587031215610cda57600080fd5b8435610ce581610a88565b935060208501359250604085013567ffffffffffffffff811115610d0857600080fd5b610a7c87828801610bfc565b600060208083528351808285015260005b81811015610d4157858101830151858201604001528201610d25565b506000604082860101526040601f19601f8301168501019250505092915050565b600082601f830112610d7357600080fd5b8135602067ffffffffffffffff821115610d8f57610d8f610aa0565b8160051b610d9e828201610ab6565b9283528481018201928281019087851115610db857600080fd5b83870192505b84831015610dd757823582529183019190830190610dbe565b979650505050505050565b600080600080600060a08688031215610dfa57600080fd5b8535610e0581610a88565b94506020860135610e1581610a88565b9350604086013567ffffffffffffffff80821115610e3257600080fd5b610e3e89838a01610d62565b94506060880135915080821115610e5457600080fd5b610e6089838a01610d62565b93506080880135915080821115610e7657600080fd5b50610e8388828901610ae7565b9150509295509295909350565b600060208284031215610ea257600080fd5b5035919050565b600080600080600060a08688031215610ec157600080fd5b8535610ecc81610a88565b94506020860135610edc81610a88565b93506040860135925060608601359150608086013567ffffffffffffffff811115610f0657600080fd5b610e8388828901610ae7565b600060208284031215610f2457600080fd5b81356109c981610a88565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610f5757600080fd5b813580151581146109c957600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610f8f57610f8f610f67565b5060010190565b600060208284031215610fa857600080fd5b81516109c981610a88565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b80820180821115610ff557610ff5610f67565b92915050565b60008060006060848603121561101057600080fd5b83519250602084015161102281610a88565b80925050604084015190509250925092565b818382376000910190815291905056fea264697066735822122072de4bddfaa6ccde56ae43975a9a19ad2f99076f5bc8ab728314c1075b86c27564736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x107A DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xE1 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0xA4E2D634 GT PUSH2 0x7F JUMPI DUP1 PUSH4 0xDD467064 GT PUSH2 0x59 JUMPI DUP1 PUSH4 0xDD467064 EQ PUSH2 0x294 JUMPI DUP1 PUSH4 0xF23A6E61 EQ PUSH2 0x2B4 JUMPI DUP1 PUSH4 0xFC0C546A EQ PUSH2 0x2E0 JUMPI DUP1 PUSH4 0xFE9FBB80 EQ PUSH2 0x318 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0xA4E2D634 EQ PUSH2 0x22D JUMPI DUP1 PUSH4 0xBC197C81 EQ PUSH2 0x244 JUMPI DUP1 PUSH4 0xCE0617EC EQ PUSH2 0x270 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1F9838B5 GT PUSH2 0xBB JUMPI DUP1 PUSH4 0x1F9838B5 EQ PUSH2 0x17D JUMPI DUP1 PUSH4 0x3FF956CC EQ PUSH2 0x1B8 JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x1E0 JUMPI DUP1 PUSH4 0x9E5D4C49 EQ PUSH2 0x20D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1FFC9A7 EQ PUSH2 0xED JUMPI DUP1 PUSH4 0x39721B1 EQ PUSH2 0x122 JUMPI DUP1 PUSH4 0x150B7A02 EQ PUSH2 0x144 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST CALLDATASIZE PUSH2 0xE8 JUMPI STOP JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xF9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x10D PUSH2 0x108 CALLDATASIZE PUSH1 0x4 PUSH2 0x99F JUMP JUMPDEST PUSH2 0x338 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x12E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x142 PUSH2 0x13D CALLDATASIZE PUSH1 0x4 PUSH2 0xA1C JUMP JUMPDEST PUSH2 0x39F JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x150 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x164 PUSH2 0x15F CALLDATASIZE PUSH1 0x4 PUSH2 0xB57 JUMP JUMPDEST PUSH2 0x568 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x119 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x189 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x10D PUSH2 0x198 CALLDATASIZE PUSH1 0x4 PUSH2 0xBC3 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1C4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x10D PUSH2 0x1D3 CALLDATASIZE PUSH1 0x4 PUSH2 0xC3E JUMP JUMPDEST PUSH1 0x0 SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1EC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1F5 PUSH2 0x5D0 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x119 JUMP JUMPDEST PUSH2 0x220 PUSH2 0x21B CALLDATASIZE PUSH1 0x4 PUSH2 0xCC4 JUMP JUMPDEST PUSH2 0x666 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x119 SWAP2 SWAP1 PUSH2 0xD14 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x239 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x0 SLOAD TIMESTAMP LT PUSH2 0x10D JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x250 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x164 PUSH2 0x25F CALLDATASIZE PUSH1 0x4 PUSH2 0xDE2 JUMP JUMPDEST PUSH4 0xBC197C81 PUSH1 0xE0 SHL SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x27C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x286 PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x119 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2A0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x142 PUSH2 0x2AF CALLDATASIZE PUSH1 0x4 PUSH2 0xE90 JUMP JUMPDEST PUSH2 0x70A JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2C0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x164 PUSH2 0x2CF CALLDATASIZE PUSH1 0x4 PUSH2 0xEA9 JUMP JUMPDEST PUSH4 0xF23A6E61 PUSH1 0xE0 SHL SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2EC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2F5 PUSH2 0x7CF JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP4 DUP5 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE SWAP1 DUP3 ADD MSTORE PUSH1 0x60 ADD PUSH2 0x119 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x324 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x10D PUSH2 0x333 CALLDATASIZE PUSH1 0x4 PUSH2 0xF12 JUMP JUMPDEST PUSH2 0x7E7 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x1FFC9A7 PUSH1 0xE0 SHL EQ DUP1 PUSH2 0x36A JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x2711897 PUSH1 0xE5 SHL EQ JUMPDEST DUP1 PUSH2 0x385 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x1DFE9A6F PUSH1 0xE3 SHL EQ JUMPDEST SWAP1 POP DUP1 ISZERO PUSH2 0x396 JUMPI POP PUSH1 0x1 SWAP3 SWAP2 POP POP JUMP JUMPDEST POP PUSH1 0x0 SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x3C2 JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x3CC PUSH2 0x5D0 JUMP JUMPDEST SWAP1 POP CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND EQ PUSH2 0x3F7 JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 DUP3 DUP2 EQ PUSH2 0x418 JUMPI PUSH1 0x40 MLOAD PUSH4 0xB4FA3FB3 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x55F JUMPI DUP5 DUP5 DUP3 DUP2 DUP2 LT PUSH2 0x435 JUMPI PUSH2 0x435 PUSH2 0xF2F JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x44A SWAP2 SWAP1 PUSH2 0xF45 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 SWAP1 DUP10 DUP10 DUP6 DUP2 DUP2 LT PUSH2 0x475 JUMPI PUSH2 0x475 PUSH2 0xF2F JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x48A SWAP2 SWAP1 PUSH2 0xF12 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP2 MSTORE PUSH1 0x20 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 ADD PUSH1 0x0 KECCAK256 DUP1 SLOAD PUSH1 0xFF NOT AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH32 0x394777A58092892D136A90C4BB7E4350C72AC50FBA6A0208128677F36527DCF5 DUP4 DUP9 DUP9 DUP5 DUP2 DUP2 LT PUSH2 0x4E6 JUMPI PUSH2 0x4E6 PUSH2 0xF2F JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x4FB SWAP2 SWAP1 PUSH2 0xF12 JUMP JUMPDEST DUP8 DUP8 DUP6 DUP2 DUP2 LT PUSH2 0x50D JUMPI PUSH2 0x50D PUSH2 0xF2F JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x522 SWAP2 SWAP1 PUSH2 0xF45 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP5 DUP6 AND DUP2 MSTORE SWAP4 SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE ISZERO ISZERO SWAP1 DUP3 ADD MSTORE PUSH1 0x60 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 DUP1 PUSH2 0x557 DUP2 PUSH2 0xF7D JUMP JUMPDEST SWAP2 POP POP PUSH2 0x41B JUMP JUMPDEST POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x576 PUSH2 0x8D0 JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP CHAINID DUP4 EQ DUP1 ISZERO PUSH2 0x593 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND CALLER EQ JUMPDEST DUP1 ISZERO PUSH2 0x59E JUMPI POP DUP6 DUP2 EQ JUMPDEST ISZERO PUSH2 0x5BC JUMPI PUSH1 0x40 MLOAD PUSH4 0xB79E3F3F PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP PUSH4 0xA85BD01 PUSH1 0xE1 SHL SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x5DE PUSH2 0x8D0 JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP CHAINID DUP4 EQ PUSH2 0x5F5 JUMPI PUSH1 0x0 SWAP4 POP POP POP POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x31A9108F PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND SWAP1 PUSH4 0x6352211E SWAP1 PUSH1 0x24 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x63A JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x65E SWAP2 SWAP1 PUSH2 0xF96 JUMP JUMPDEST SWAP4 POP POP POP POP SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH2 0x671 CALLER PUSH2 0x7E7 JUMP JUMPDEST PUSH2 0x68E JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x6B1 JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH32 0x47D99AD340F52DA66535AFF7E10DA1CEB85A32BCBD9FA1C42314D194545E14D2 DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0x6ED SWAP3 SWAP2 SWAP1 PUSH2 0xFB3 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 PUSH2 0x701 DUP6 DUP6 DUP6 DUP6 PUSH2 0x923 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0x712 PUSH2 0x5D0 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ PUSH2 0x743 JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x766 JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH2 0x774 TIMESTAMP PUSH4 0x1E13380 PUSH2 0xFE2 JUMP JUMPDEST DUP2 GT ISZERO PUSH2 0x794 JUMPI PUSH1 0x40 MLOAD PUSH4 0x1814F7D PUSH1 0xE3 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 DUP2 SWAP1 SSTORE PUSH1 0x40 MLOAD DUP2 DUP2 MSTORE PUSH32 0xA7B24C66DD3269A292A60B3FACDBB8F3E7557D1E19E64D99E0D6EE7250BE63AD SWAP1 PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x7DC PUSH2 0x8D0 JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP SWAP1 SWAP2 SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x7F4 PUSH2 0x8D0 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x31A9108F PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE SWAP2 SWAP5 POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND SWAP1 PUSH4 0x6352211E SWAP1 PUSH1 0x24 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x842 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x866 SWAP2 SWAP1 PUSH2 0xF96 JUMP JUMPDEST SWAP1 POP DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SUB PUSH2 0x88C JUMPI POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP1 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP10 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x8C5 JUMPI POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST POP PUSH1 0x0 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 DUP1 DUP3 MSTORE PUSH1 0x80 DUP3 ADD SWAP1 SWAP3 MSTORE PUSH1 0x0 SWAP2 DUP3 SWAP2 DUP3 SWAP2 DUP3 SWAP2 SWAP1 PUSH1 0x20 DUP3 ADD DUP2 DUP1 CALLDATASIZE DUP4 CALLDATACOPY ADD SWAP1 POP POP SWAP1 POP PUSH1 0xAD PUSH1 0x4D PUSH1 0x20 DUP4 ADD ADDRESS EXTCODECOPY DUP1 DUP1 PUSH1 0x20 ADD SWAP1 MLOAD DUP2 ADD SWAP1 PUSH2 0x917 SWAP2 SWAP1 PUSH2 0xFFB JUMP JUMPDEST SWAP4 POP SWAP4 POP SWAP4 POP POP SWAP1 SWAP2 SWAP3 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP6 DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0x942 SWAP3 SWAP2 SWAP1 PUSH2 0x1034 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 GAS CALL SWAP3 POP POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0x97F JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0x984 JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP3 POP SWAP1 POP DUP1 PUSH2 0x996 JUMPI DUP2 MLOAD PUSH1 0x20 DUP4 ADD REVERT JUMPDEST POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x9B1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP2 AND DUP2 EQ PUSH2 0x9C9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x9E2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x9FA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 PUSH1 0x5 SHL DUP6 ADD ADD GT ISZERO PUSH2 0xA15 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x40 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xA32 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xA4A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xA56 DUP9 DUP4 DUP10 ADD PUSH2 0x9D0 JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP PUSH1 0x20 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xA6F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xA7C DUP8 DUP3 DUP9 ADD PUSH2 0x9D0 JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0xA9D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT AND DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0xADF JUMPI PUSH2 0xADF PUSH2 0xAA0 JUMP JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xAF8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xB12 JUMPI PUSH2 0xB12 PUSH2 0xAA0 JUMP JUMPDEST PUSH2 0xB25 PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT AND PUSH1 0x20 ADD PUSH2 0xAB6 JUMP JUMPDEST DUP2 DUP2 MSTORE DUP5 PUSH1 0x20 DUP4 DUP7 ADD ADD GT ISZERO PUSH2 0xB3A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 PUSH1 0x20 DUP6 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 SWAP2 DUP2 ADD PUSH1 0x20 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xB6D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xB78 DUP2 PUSH2 0xA88 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH2 0xB88 DUP2 PUSH2 0xA88 JUMP JUMPDEST SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD SWAP2 POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xBAB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xBB7 DUP8 DUP3 DUP9 ADD PUSH2 0xAE7 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xBD6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH2 0xBE1 DUP2 PUSH2 0xA88 JUMP JUMPDEST SWAP2 POP PUSH1 0x20 DUP4 ADD CALLDATALOAD PUSH2 0xBF1 DUP2 PUSH2 0xA88 JUMP JUMPDEST DUP1 SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0xC0E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xC26 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0xA15 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xC0 DUP9 DUP11 SUB SLT ISZERO PUSH2 0xC59 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 CALLDATALOAD PUSH2 0xC64 DUP2 PUSH2 0xA88 JUMP JUMPDEST SWAP7 POP PUSH1 0x20 DUP9 ADD CALLDATALOAD SWAP6 POP PUSH1 0x40 DUP9 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xC87 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xC93 DUP11 DUP3 DUP12 ADD PUSH2 0xBFC JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP POP PUSH1 0x60 DUP9 ADD CALLDATALOAD PUSH2 0xCA7 DUP2 PUSH2 0xA88 JUMP JUMPDEST SWAP7 SWAP10 SWAP6 SWAP9 POP SWAP4 SWAP7 SWAP3 SWAP6 SWAP5 PUSH1 0x80 DUP5 ADD CALLDATALOAD SWAP5 POP PUSH1 0xA0 SWAP1 SWAP4 ADD CALLDATALOAD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x60 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xCDA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xCE5 DUP2 PUSH2 0xA88 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xD08 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xA7C DUP8 DUP3 DUP9 ADD PUSH2 0xBFC JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 MSTORE DUP4 MLOAD DUP1 DUP3 DUP6 ADD MSTORE PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xD41 JUMPI DUP6 DUP2 ADD DUP4 ADD MLOAD DUP6 DUP3 ADD PUSH1 0x40 ADD MSTORE DUP3 ADD PUSH2 0xD25 JUMP JUMPDEST POP PUSH1 0x0 PUSH1 0x40 DUP3 DUP7 ADD ADD MSTORE PUSH1 0x40 PUSH1 0x1F NOT PUSH1 0x1F DUP4 ADD AND DUP6 ADD ADD SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xD73 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH1 0x20 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0xD8F JUMPI PUSH2 0xD8F PUSH2 0xAA0 JUMP JUMPDEST DUP2 PUSH1 0x5 SHL PUSH2 0xD9E DUP3 DUP3 ADD PUSH2 0xAB6 JUMP JUMPDEST SWAP3 DUP4 MSTORE DUP5 DUP2 ADD DUP3 ADD SWAP3 DUP3 DUP2 ADD SWAP1 DUP8 DUP6 GT ISZERO PUSH2 0xDB8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 DUP8 ADD SWAP3 POP JUMPDEST DUP5 DUP4 LT ISZERO PUSH2 0xDD7 JUMPI DUP3 CALLDATALOAD DUP3 MSTORE SWAP2 DUP4 ADD SWAP2 SWAP1 DUP4 ADD SWAP1 PUSH2 0xDBE JUMP JUMPDEST SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xDFA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xE05 DUP2 PUSH2 0xA88 JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH2 0xE15 DUP2 PUSH2 0xA88 JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xE32 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xE3E DUP10 DUP4 DUP11 ADD PUSH2 0xD62 JUMP JUMPDEST SWAP5 POP PUSH1 0x60 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xE54 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xE60 DUP10 DUP4 DUP11 ADD PUSH2 0xD62 JUMP JUMPDEST SWAP4 POP PUSH1 0x80 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xE76 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xE83 DUP9 DUP3 DUP10 ADD PUSH2 0xAE7 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 SWAP1 SWAP4 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xEA2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xEC1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xECC DUP2 PUSH2 0xA88 JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH2 0xEDC DUP2 PUSH2 0xA88 JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD SWAP3 POP PUSH1 0x60 DUP7 ADD CALLDATALOAD SWAP2 POP PUSH1 0x80 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xF06 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xE83 DUP9 DUP3 DUP10 ADD PUSH2 0xAE7 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xF24 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x9C9 DUP2 PUSH2 0xA88 JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x32 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xF57 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP1 ISZERO ISZERO DUP2 EQ PUSH2 0x9C9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x11 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x1 DUP3 ADD PUSH2 0xF8F JUMPI PUSH2 0xF8F PUSH2 0xF67 JUMP JUMPDEST POP PUSH1 0x1 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xFA8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x9C9 DUP2 PUSH2 0xA88 JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE DUP2 PUSH1 0x20 DUP3 ADD MSTORE DUP2 DUP4 PUSH1 0x40 DUP4 ADD CALLDATACOPY PUSH1 0x0 DUP2 DUP4 ADD PUSH1 0x40 SWAP1 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x1F SWAP1 SWAP3 ADD PUSH1 0x1F NOT AND ADD ADD SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 DUP3 ADD DUP1 DUP3 GT ISZERO PUSH2 0xFF5 JUMPI PUSH2 0xFF5 PUSH2 0xF67 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x1010 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 MLOAD SWAP3 POP PUSH1 0x20 DUP5 ADD MLOAD PUSH2 0x1022 DUP2 PUSH2 0xA88 JUMP JUMPDEST DUP1 SWAP3 POP POP PUSH1 0x40 DUP5 ADD MLOAD SWAP1 POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST DUP2 DUP4 DUP3 CALLDATACOPY PUSH1 0x0 SWAP2 ADD SWAP1 DUP2 MSTORE SWAP2 SWAP1 POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 PUSH19 0xDE4BDDFAA6CCDE56AE43975A9A19AD2F99076F JUMPDEST 0xC8 0xAB PUSH19 0x8314C1075B86C27564736F6C63430008110033 ","sourceMap":"161:344:6:-:0;;;;;;;;;;;;;;;;;;;"},"deployedBytecode":{"functionDebugData":{"@_389":{"entryPoint":null,"id":389,"parameterSlots":0,"returnSlots":0},"@_call_787":{"entryPoint":2339,"id":787,"parameterSlots":4,"returnSlots":1},"@covalentBond_280":{"entryPoint":null,"id":280,"parameterSlots":7,"returnSlots":1},"@executeCall_418":{"entryPoint":1638,"id":418,"parameterSlots":4,"returnSlots":1},"@isAuthorized_623":{"entryPoint":2023,"id":623,"parameterSlots":1,"returnSlots":1},"@isLocked_532":{"entryPoint":null,"id":532,"parameterSlots":0,"returnSlots":1},"@lock_520":{"entryPoint":1802,"id":520,"parameterSlots":1,"returnSlots":0},"@lockedUntil_314":{"entryPoint":null,"id":314,"parameterSlots":0,"returnSlots":0},"@onERC1155BatchReceived_755":{"entryPoint":null,"id":755,"parameterSlots":5,"returnSlots":1},"@onERC1155Received_731":{"entryPoint":null,"id":731,"parameterSlots":5,"returnSlots":1},"@onERC721Received_709":{"entryPoint":1384,"id":709,"parameterSlots":4,"returnSlots":1},"@owner_581":{"entryPoint":1488,"id":581,"parameterSlots":0,"returnSlots":1},"@permissions_321":{"entryPoint":null,"id":321,"parameterSlots":0,"returnSlots":0},"@setPermissions_491":{"entryPoint":927,"id":491,"parameterSlots":4,"returnSlots":0},"@supportsInterface_662":{"entryPoint":824,"id":662,"parameterSlots":1,"returnSlots":1},"@token_547":{"entryPoint":1999,"id":547,"parameterSlots":0,"returnSlots":3},"@token_929":{"entryPoint":2256,"id":929,"parameterSlots":0,"returnSlots":3},"abi_decode_array_address_dyn_calldata":{"entryPoint":2512,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_array_uint256_dyn":{"entryPoint":3426,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_bytes":{"entryPoint":2791,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_string_calldata":{"entryPoint":3068,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_tuple_t_address":{"entryPoint":3858,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_address_fromMemory":{"entryPoint":3990,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_addresst_address":{"entryPoint":3011,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_tuple_t_addresst_addresst_array$_t_uint256_$dyn_memory_ptrt_array$_t_uint256_$dyn_memory_ptrt_bytes_memory_ptr":{"entryPoint":3554,"id":null,"parameterSlots":2,"returnSlots":5},"abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr":{"entryPoint":2903,"id":null,"parameterSlots":2,"returnSlots":4},"abi_decode_tuple_t_addresst_addresst_uint256t_uint256t_bytes_memory_ptr":{"entryPoint":3753,"id":null,"parameterSlots":2,"returnSlots":5},"abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptr":{"entryPoint":3268,"id":null,"parameterSlots":2,"returnSlots":4},"abi_decode_tuple_t_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_uint256":{"entryPoint":3134,"id":null,"parameterSlots":2,"returnSlots":7},"abi_decode_tuple_t_array$_t_address_$dyn_calldata_ptrt_array$_t_bool_$dyn_calldata_ptr":{"entryPoint":2588,"id":null,"parameterSlots":2,"returnSlots":4},"abi_decode_tuple_t_bool":{"entryPoint":3909,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_bytes4":{"entryPoint":2463,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_uint256":{"entryPoint":3728,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_uint256t_address_payablet_uint256_fromMemory":{"entryPoint":4091,"id":null,"parameterSlots":2,"returnSlots":3},"abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed":{"entryPoint":4148,"id":null,"parameterSlots":3,"returnSlots":1},"abi_encode_tuple_t_address__to_t_address__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_address_t_address_t_bool__to_t_address_t_address_t_bool__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":4,"returnSlots":1},"abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed":{"entryPoint":4019,"id":null,"parameterSlots":3,"returnSlots":1},"abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed":{"entryPoint":3348,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_uint256_t_address_t_uint256__to_t_uint256_t_address_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":4,"returnSlots":1},"allocate_memory":{"entryPoint":2742,"id":null,"parameterSlots":1,"returnSlots":1},"checked_add_t_uint256":{"entryPoint":4066,"id":null,"parameterSlots":2,"returnSlots":1},"increment_t_uint256":{"entryPoint":3965,"id":null,"parameterSlots":1,"returnSlots":1},"panic_error_0x11":{"entryPoint":3943,"id":null,"parameterSlots":0,"returnSlots":0},"panic_error_0x32":{"entryPoint":3887,"id":null,"parameterSlots":0,"returnSlots":0},"panic_error_0x41":{"entryPoint":2720,"id":null,"parameterSlots":0,"returnSlots":0},"validator_revert_address":{"entryPoint":2696,"id":null,"parameterSlots":1,"returnSlots":0}},"generatedSources":[{"ast":{"nodeType":"YulBlock","src":"0:12637:11","statements":[{"nodeType":"YulBlock","src":"6:3:11","statements":[]},{"body":{"nodeType":"YulBlock","src":"83:217:11","statements":[{"body":{"nodeType":"YulBlock","src":"129:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"138:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"141:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"131:6:11"},"nodeType":"YulFunctionCall","src":"131:12:11"},"nodeType":"YulExpressionStatement","src":"131:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"104:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"113:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"100:3:11"},"nodeType":"YulFunctionCall","src":"100:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"125:2:11","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"96:3:11"},"nodeType":"YulFunctionCall","src":"96:32:11"},"nodeType":"YulIf","src":"93:52:11"},{"nodeType":"YulVariableDeclaration","src":"154:36:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"180:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"167:12:11"},"nodeType":"YulFunctionCall","src":"167:23:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"158:5:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"254:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"263:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"266:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"256:6:11"},"nodeType":"YulFunctionCall","src":"256:12:11"},"nodeType":"YulExpressionStatement","src":"256:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"212:5:11"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"223:5:11"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"234:3:11","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"239:10:11","type":"","value":"0xffffffff"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"230:3:11"},"nodeType":"YulFunctionCall","src":"230:20:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"219:3:11"},"nodeType":"YulFunctionCall","src":"219:32:11"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"209:2:11"},"nodeType":"YulFunctionCall","src":"209:43:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"202:6:11"},"nodeType":"YulFunctionCall","src":"202:51:11"},"nodeType":"YulIf","src":"199:71:11"},{"nodeType":"YulAssignment","src":"279:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"289:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"279:6:11"}]}]},"name":"abi_decode_tuple_t_bytes4","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"49:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"60:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"72:6:11","type":""}],"src":"14:286:11"},{"body":{"nodeType":"YulBlock","src":"400:92:11","statements":[{"nodeType":"YulAssignment","src":"410:26:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"422:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"433:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"418:3:11"},"nodeType":"YulFunctionCall","src":"418:18:11"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"410:4:11"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"452:9:11"},{"arguments":[{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"477:6:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"470:6:11"},"nodeType":"YulFunctionCall","src":"470:14:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"463:6:11"},"nodeType":"YulFunctionCall","src":"463:22:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"445:6:11"},"nodeType":"YulFunctionCall","src":"445:41:11"},"nodeType":"YulExpressionStatement","src":"445:41:11"}]},"name":"abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"369:9:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"380:6:11","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"391:4:11","type":""}],"src":"305:187:11"},{"body":{"nodeType":"YulBlock","src":"581:283:11","statements":[{"body":{"nodeType":"YulBlock","src":"630:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"639:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"642:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"632:6:11"},"nodeType":"YulFunctionCall","src":"632:12:11"},"nodeType":"YulExpressionStatement","src":"632:12:11"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"609:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"617:4:11","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"605:3:11"},"nodeType":"YulFunctionCall","src":"605:17:11"},{"name":"end","nodeType":"YulIdentifier","src":"624:3:11"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"601:3:11"},"nodeType":"YulFunctionCall","src":"601:27:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"594:6:11"},"nodeType":"YulFunctionCall","src":"594:35:11"},"nodeType":"YulIf","src":"591:55:11"},{"nodeType":"YulAssignment","src":"655:30:11","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"678:6:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"665:12:11"},"nodeType":"YulFunctionCall","src":"665:20:11"},"variableNames":[{"name":"length","nodeType":"YulIdentifier","src":"655:6:11"}]},{"body":{"nodeType":"YulBlock","src":"728:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"737:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"740:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"730:6:11"},"nodeType":"YulFunctionCall","src":"730:12:11"},"nodeType":"YulExpressionStatement","src":"730:12:11"}]},"condition":{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"700:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"708:18:11","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"697:2:11"},"nodeType":"YulFunctionCall","src":"697:30:11"},"nodeType":"YulIf","src":"694:50:11"},{"nodeType":"YulAssignment","src":"753:29:11","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"769:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"777:4:11","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"765:3:11"},"nodeType":"YulFunctionCall","src":"765:17:11"},"variableNames":[{"name":"arrayPos","nodeType":"YulIdentifier","src":"753:8:11"}]},{"body":{"nodeType":"YulBlock","src":"842:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"851:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"854:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"844:6:11"},"nodeType":"YulFunctionCall","src":"844:12:11"},"nodeType":"YulExpressionStatement","src":"844:12:11"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"805:6:11"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"817:1:11","type":"","value":"5"},{"name":"length","nodeType":"YulIdentifier","src":"820:6:11"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"813:3:11"},"nodeType":"YulFunctionCall","src":"813:14:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"801:3:11"},"nodeType":"YulFunctionCall","src":"801:27:11"},{"kind":"number","nodeType":"YulLiteral","src":"830:4:11","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"797:3:11"},"nodeType":"YulFunctionCall","src":"797:38:11"},{"name":"end","nodeType":"YulIdentifier","src":"837:3:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"794:2:11"},"nodeType":"YulFunctionCall","src":"794:47:11"},"nodeType":"YulIf","src":"791:67:11"}]},"name":"abi_decode_array_address_dyn_calldata","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"544:6:11","type":""},{"name":"end","nodeType":"YulTypedName","src":"552:3:11","type":""}],"returnVariables":[{"name":"arrayPos","nodeType":"YulTypedName","src":"560:8:11","type":""},{"name":"length","nodeType":"YulTypedName","src":"570:6:11","type":""}],"src":"497:367:11"},{"body":{"nodeType":"YulBlock","src":"1023:616:11","statements":[{"body":{"nodeType":"YulBlock","src":"1069:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1078:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1081:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1071:6:11"},"nodeType":"YulFunctionCall","src":"1071:12:11"},"nodeType":"YulExpressionStatement","src":"1071:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"1044:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"1053:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1040:3:11"},"nodeType":"YulFunctionCall","src":"1040:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"1065:2:11","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"1036:3:11"},"nodeType":"YulFunctionCall","src":"1036:32:11"},"nodeType":"YulIf","src":"1033:52:11"},{"nodeType":"YulVariableDeclaration","src":"1094:37:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1121:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1108:12:11"},"nodeType":"YulFunctionCall","src":"1108:23:11"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"1098:6:11","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1140:28:11","value":{"kind":"number","nodeType":"YulLiteral","src":"1150:18:11","type":"","value":"0xffffffffffffffff"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"1144:2:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"1195:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1204:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1207:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1197:6:11"},"nodeType":"YulFunctionCall","src":"1197:12:11"},"nodeType":"YulExpressionStatement","src":"1197:12:11"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"1183:6:11"},{"name":"_1","nodeType":"YulIdentifier","src":"1191:2:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"1180:2:11"},"nodeType":"YulFunctionCall","src":"1180:14:11"},"nodeType":"YulIf","src":"1177:34:11"},{"nodeType":"YulVariableDeclaration","src":"1220:96:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1288:9:11"},{"name":"offset","nodeType":"YulIdentifier","src":"1299:6:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1284:3:11"},"nodeType":"YulFunctionCall","src":"1284:22:11"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"1308:7:11"}],"functionName":{"name":"abi_decode_array_address_dyn_calldata","nodeType":"YulIdentifier","src":"1246:37:11"},"nodeType":"YulFunctionCall","src":"1246:70:11"},"variables":[{"name":"value0_1","nodeType":"YulTypedName","src":"1224:8:11","type":""},{"name":"value1_1","nodeType":"YulTypedName","src":"1234:8:11","type":""}]},{"nodeType":"YulAssignment","src":"1325:18:11","value":{"name":"value0_1","nodeType":"YulIdentifier","src":"1335:8:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"1325:6:11"}]},{"nodeType":"YulAssignment","src":"1352:18:11","value":{"name":"value1_1","nodeType":"YulIdentifier","src":"1362:8:11"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"1352:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"1379:48:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1412:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"1423:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1408:3:11"},"nodeType":"YulFunctionCall","src":"1408:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1395:12:11"},"nodeType":"YulFunctionCall","src":"1395:32:11"},"variables":[{"name":"offset_1","nodeType":"YulTypedName","src":"1383:8:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"1456:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1465:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1468:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1458:6:11"},"nodeType":"YulFunctionCall","src":"1458:12:11"},"nodeType":"YulExpressionStatement","src":"1458:12:11"}]},"condition":{"arguments":[{"name":"offset_1","nodeType":"YulIdentifier","src":"1442:8:11"},{"name":"_1","nodeType":"YulIdentifier","src":"1452:2:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"1439:2:11"},"nodeType":"YulFunctionCall","src":"1439:16:11"},"nodeType":"YulIf","src":"1436:36:11"},{"nodeType":"YulVariableDeclaration","src":"1481:98:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1549:9:11"},{"name":"offset_1","nodeType":"YulIdentifier","src":"1560:8:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1545:3:11"},"nodeType":"YulFunctionCall","src":"1545:24:11"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"1571:7:11"}],"functionName":{"name":"abi_decode_array_address_dyn_calldata","nodeType":"YulIdentifier","src":"1507:37:11"},"nodeType":"YulFunctionCall","src":"1507:72:11"},"variables":[{"name":"value2_1","nodeType":"YulTypedName","src":"1485:8:11","type":""},{"name":"value3_1","nodeType":"YulTypedName","src":"1495:8:11","type":""}]},{"nodeType":"YulAssignment","src":"1588:18:11","value":{"name":"value2_1","nodeType":"YulIdentifier","src":"1598:8:11"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"1588:6:11"}]},{"nodeType":"YulAssignment","src":"1615:18:11","value":{"name":"value3_1","nodeType":"YulIdentifier","src":"1625:8:11"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"1615:6:11"}]}]},"name":"abi_decode_tuple_t_array$_t_address_$dyn_calldata_ptrt_array$_t_bool_$dyn_calldata_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"965:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"976:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"988:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"996:6:11","type":""},{"name":"value2","nodeType":"YulTypedName","src":"1004:6:11","type":""},{"name":"value3","nodeType":"YulTypedName","src":"1012:6:11","type":""}],"src":"869:770:11"},{"body":{"nodeType":"YulBlock","src":"1689:86:11","statements":[{"body":{"nodeType":"YulBlock","src":"1753:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1762:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1765:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1755:6:11"},"nodeType":"YulFunctionCall","src":"1755:12:11"},"nodeType":"YulExpressionStatement","src":"1755:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1712:5:11"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1723:5:11"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1738:3:11","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"1743:1:11","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1734:3:11"},"nodeType":"YulFunctionCall","src":"1734:11:11"},{"kind":"number","nodeType":"YulLiteral","src":"1747:1:11","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1730:3:11"},"nodeType":"YulFunctionCall","src":"1730:19:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1719:3:11"},"nodeType":"YulFunctionCall","src":"1719:31:11"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"1709:2:11"},"nodeType":"YulFunctionCall","src":"1709:42:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"1702:6:11"},"nodeType":"YulFunctionCall","src":"1702:50:11"},"nodeType":"YulIf","src":"1699:70:11"}]},"name":"validator_revert_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"value","nodeType":"YulTypedName","src":"1678:5:11","type":""}],"src":"1644:131:11"},{"body":{"nodeType":"YulBlock","src":"1812:95:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1829:1:11","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1836:3:11","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"1841:10:11","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1832:3:11"},"nodeType":"YulFunctionCall","src":"1832:20:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1822:6:11"},"nodeType":"YulFunctionCall","src":"1822:31:11"},"nodeType":"YulExpressionStatement","src":"1822:31:11"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1869:1:11","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"1872:4:11","type":"","value":"0x41"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1862:6:11"},"nodeType":"YulFunctionCall","src":"1862:15:11"},"nodeType":"YulExpressionStatement","src":"1862:15:11"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1893:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1896:4:11","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1886:6:11"},"nodeType":"YulFunctionCall","src":"1886:15:11"},"nodeType":"YulExpressionStatement","src":"1886:15:11"}]},"name":"panic_error_0x41","nodeType":"YulFunctionDefinition","src":"1780:127:11"},{"body":{"nodeType":"YulBlock","src":"1957:230:11","statements":[{"nodeType":"YulAssignment","src":"1967:19:11","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1983:2:11","type":"","value":"64"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"1977:5:11"},"nodeType":"YulFunctionCall","src":"1977:9:11"},"variableNames":[{"name":"memPtr","nodeType":"YulIdentifier","src":"1967:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"1995:58:11","value":{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"2017:6:11"},{"arguments":[{"arguments":[{"name":"size","nodeType":"YulIdentifier","src":"2033:4:11"},{"kind":"number","nodeType":"YulLiteral","src":"2039:2:11","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2029:3:11"},"nodeType":"YulFunctionCall","src":"2029:13:11"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2048:2:11","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"2044:3:11"},"nodeType":"YulFunctionCall","src":"2044:7:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"2025:3:11"},"nodeType":"YulFunctionCall","src":"2025:27:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2013:3:11"},"nodeType":"YulFunctionCall","src":"2013:40:11"},"variables":[{"name":"newFreePtr","nodeType":"YulTypedName","src":"1999:10:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"2128:22:11","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"2130:16:11"},"nodeType":"YulFunctionCall","src":"2130:18:11"},"nodeType":"YulExpressionStatement","src":"2130:18:11"}]},"condition":{"arguments":[{"arguments":[{"name":"newFreePtr","nodeType":"YulIdentifier","src":"2071:10:11"},{"kind":"number","nodeType":"YulLiteral","src":"2083:18:11","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2068:2:11"},"nodeType":"YulFunctionCall","src":"2068:34:11"},{"arguments":[{"name":"newFreePtr","nodeType":"YulIdentifier","src":"2107:10:11"},{"name":"memPtr","nodeType":"YulIdentifier","src":"2119:6:11"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"2104:2:11"},"nodeType":"YulFunctionCall","src":"2104:22:11"}],"functionName":{"name":"or","nodeType":"YulIdentifier","src":"2065:2:11"},"nodeType":"YulFunctionCall","src":"2065:62:11"},"nodeType":"YulIf","src":"2062:88:11"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2166:2:11","type":"","value":"64"},{"name":"newFreePtr","nodeType":"YulIdentifier","src":"2170:10:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2159:6:11"},"nodeType":"YulFunctionCall","src":"2159:22:11"},"nodeType":"YulExpressionStatement","src":"2159:22:11"}]},"name":"allocate_memory","nodeType":"YulFunctionDefinition","parameters":[{"name":"size","nodeType":"YulTypedName","src":"1937:4:11","type":""}],"returnVariables":[{"name":"memPtr","nodeType":"YulTypedName","src":"1946:6:11","type":""}],"src":"1912:275:11"},{"body":{"nodeType":"YulBlock","src":"2244:478:11","statements":[{"body":{"nodeType":"YulBlock","src":"2293:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2302:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2305:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2295:6:11"},"nodeType":"YulFunctionCall","src":"2295:12:11"},"nodeType":"YulExpressionStatement","src":"2295:12:11"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2272:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"2280:4:11","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2268:3:11"},"nodeType":"YulFunctionCall","src":"2268:17:11"},{"name":"end","nodeType":"YulIdentifier","src":"2287:3:11"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"2264:3:11"},"nodeType":"YulFunctionCall","src":"2264:27:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"2257:6:11"},"nodeType":"YulFunctionCall","src":"2257:35:11"},"nodeType":"YulIf","src":"2254:55:11"},{"nodeType":"YulVariableDeclaration","src":"2318:30:11","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2341:6:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2328:12:11"},"nodeType":"YulFunctionCall","src":"2328:20:11"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"2322:2:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"2387:22:11","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"2389:16:11"},"nodeType":"YulFunctionCall","src":"2389:18:11"},"nodeType":"YulExpressionStatement","src":"2389:18:11"}]},"condition":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"2363:2:11"},{"kind":"number","nodeType":"YulLiteral","src":"2367:18:11","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2360:2:11"},"nodeType":"YulFunctionCall","src":"2360:26:11"},"nodeType":"YulIf","src":"2357:52:11"},{"nodeType":"YulVariableDeclaration","src":"2418:70:11","value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"2461:2:11"},{"kind":"number","nodeType":"YulLiteral","src":"2465:4:11","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2457:3:11"},"nodeType":"YulFunctionCall","src":"2457:13:11"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2476:2:11","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"2472:3:11"},"nodeType":"YulFunctionCall","src":"2472:7:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"2453:3:11"},"nodeType":"YulFunctionCall","src":"2453:27:11"},{"kind":"number","nodeType":"YulLiteral","src":"2482:4:11","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2449:3:11"},"nodeType":"YulFunctionCall","src":"2449:38:11"}],"functionName":{"name":"allocate_memory","nodeType":"YulIdentifier","src":"2433:15:11"},"nodeType":"YulFunctionCall","src":"2433:55:11"},"variables":[{"name":"array_1","nodeType":"YulTypedName","src":"2422:7:11","type":""}]},{"expression":{"arguments":[{"name":"array_1","nodeType":"YulIdentifier","src":"2504:7:11"},{"name":"_1","nodeType":"YulIdentifier","src":"2513:2:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2497:6:11"},"nodeType":"YulFunctionCall","src":"2497:19:11"},"nodeType":"YulExpressionStatement","src":"2497:19:11"},{"body":{"nodeType":"YulBlock","src":"2564:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2573:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2576:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2566:6:11"},"nodeType":"YulFunctionCall","src":"2566:12:11"},"nodeType":"YulExpressionStatement","src":"2566:12:11"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2539:6:11"},{"name":"_1","nodeType":"YulIdentifier","src":"2547:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2535:3:11"},"nodeType":"YulFunctionCall","src":"2535:15:11"},{"kind":"number","nodeType":"YulLiteral","src":"2552:4:11","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2531:3:11"},"nodeType":"YulFunctionCall","src":"2531:26:11"},{"name":"end","nodeType":"YulIdentifier","src":"2559:3:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2528:2:11"},"nodeType":"YulFunctionCall","src":"2528:35:11"},"nodeType":"YulIf","src":"2525:55:11"},{"expression":{"arguments":[{"arguments":[{"name":"array_1","nodeType":"YulIdentifier","src":"2606:7:11"},{"kind":"number","nodeType":"YulLiteral","src":"2615:4:11","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2602:3:11"},"nodeType":"YulFunctionCall","src":"2602:18:11"},{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2626:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"2634:4:11","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2622:3:11"},"nodeType":"YulFunctionCall","src":"2622:17:11"},{"name":"_1","nodeType":"YulIdentifier","src":"2641:2:11"}],"functionName":{"name":"calldatacopy","nodeType":"YulIdentifier","src":"2589:12:11"},"nodeType":"YulFunctionCall","src":"2589:55:11"},"nodeType":"YulExpressionStatement","src":"2589:55:11"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"array_1","nodeType":"YulIdentifier","src":"2668:7:11"},{"name":"_1","nodeType":"YulIdentifier","src":"2677:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2664:3:11"},"nodeType":"YulFunctionCall","src":"2664:16:11"},{"kind":"number","nodeType":"YulLiteral","src":"2682:4:11","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2660:3:11"},"nodeType":"YulFunctionCall","src":"2660:27:11"},{"kind":"number","nodeType":"YulLiteral","src":"2689:1:11","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2653:6:11"},"nodeType":"YulFunctionCall","src":"2653:38:11"},"nodeType":"YulExpressionStatement","src":"2653:38:11"},{"nodeType":"YulAssignment","src":"2700:16:11","value":{"name":"array_1","nodeType":"YulIdentifier","src":"2709:7:11"},"variableNames":[{"name":"array","nodeType":"YulIdentifier","src":"2700:5:11"}]}]},"name":"abi_decode_bytes","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"2218:6:11","type":""},{"name":"end","nodeType":"YulTypedName","src":"2226:3:11","type":""}],"returnVariables":[{"name":"array","nodeType":"YulTypedName","src":"2234:5:11","type":""}],"src":"2192:530:11"},{"body":{"nodeType":"YulBlock","src":"2857:535:11","statements":[{"body":{"nodeType":"YulBlock","src":"2904:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2913:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2916:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2906:6:11"},"nodeType":"YulFunctionCall","src":"2906:12:11"},"nodeType":"YulExpressionStatement","src":"2906:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"2878:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"2887:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"2874:3:11"},"nodeType":"YulFunctionCall","src":"2874:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"2899:3:11","type":"","value":"128"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"2870:3:11"},"nodeType":"YulFunctionCall","src":"2870:33:11"},"nodeType":"YulIf","src":"2867:53:11"},{"nodeType":"YulVariableDeclaration","src":"2929:36:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2955:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2942:12:11"},"nodeType":"YulFunctionCall","src":"2942:23:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"2933:5:11","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"2999:5:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"2974:24:11"},"nodeType":"YulFunctionCall","src":"2974:31:11"},"nodeType":"YulExpressionStatement","src":"2974:31:11"},{"nodeType":"YulAssignment","src":"3014:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"3024:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"3014:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"3038:47:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3070:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"3081:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3066:3:11"},"nodeType":"YulFunctionCall","src":"3066:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3053:12:11"},"nodeType":"YulFunctionCall","src":"3053:32:11"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"3042:7:11","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"3119:7:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"3094:24:11"},"nodeType":"YulFunctionCall","src":"3094:33:11"},"nodeType":"YulExpressionStatement","src":"3094:33:11"},{"nodeType":"YulAssignment","src":"3136:17:11","value":{"name":"value_1","nodeType":"YulIdentifier","src":"3146:7:11"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"3136:6:11"}]},{"nodeType":"YulAssignment","src":"3162:42:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3189:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"3200:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3185:3:11"},"nodeType":"YulFunctionCall","src":"3185:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3172:12:11"},"nodeType":"YulFunctionCall","src":"3172:32:11"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"3162:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"3213:46:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3244:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"3255:2:11","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3240:3:11"},"nodeType":"YulFunctionCall","src":"3240:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3227:12:11"},"nodeType":"YulFunctionCall","src":"3227:32:11"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"3217:6:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"3302:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3311:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3314:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3304:6:11"},"nodeType":"YulFunctionCall","src":"3304:12:11"},"nodeType":"YulExpressionStatement","src":"3304:12:11"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"3274:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"3282:18:11","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"3271:2:11"},"nodeType":"YulFunctionCall","src":"3271:30:11"},"nodeType":"YulIf","src":"3268:50:11"},{"nodeType":"YulAssignment","src":"3327:59:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3358:9:11"},{"name":"offset","nodeType":"YulIdentifier","src":"3369:6:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3354:3:11"},"nodeType":"YulFunctionCall","src":"3354:22:11"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"3378:7:11"}],"functionName":{"name":"abi_decode_bytes","nodeType":"YulIdentifier","src":"3337:16:11"},"nodeType":"YulFunctionCall","src":"3337:49:11"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"3327:6:11"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"2799:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"2810:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"2822:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"2830:6:11","type":""},{"name":"value2","nodeType":"YulTypedName","src":"2838:6:11","type":""},{"name":"value3","nodeType":"YulTypedName","src":"2846:6:11","type":""}],"src":"2727:665:11"},{"body":{"nodeType":"YulBlock","src":"3496:103:11","statements":[{"nodeType":"YulAssignment","src":"3506:26:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3518:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"3529:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3514:3:11"},"nodeType":"YulFunctionCall","src":"3514:18:11"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"3506:4:11"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3548:9:11"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"3563:6:11"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3575:3:11","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"3580:10:11","type":"","value":"0xffffffff"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"3571:3:11"},"nodeType":"YulFunctionCall","src":"3571:20:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"3559:3:11"},"nodeType":"YulFunctionCall","src":"3559:33:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"3541:6:11"},"nodeType":"YulFunctionCall","src":"3541:52:11"},"nodeType":"YulExpressionStatement","src":"3541:52:11"}]},"name":"abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"3465:9:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"3476:6:11","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"3487:4:11","type":""}],"src":"3397:202:11"},{"body":{"nodeType":"YulBlock","src":"3691:301:11","statements":[{"body":{"nodeType":"YulBlock","src":"3737:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3746:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3749:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3739:6:11"},"nodeType":"YulFunctionCall","src":"3739:12:11"},"nodeType":"YulExpressionStatement","src":"3739:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"3712:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"3721:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"3708:3:11"},"nodeType":"YulFunctionCall","src":"3708:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"3733:2:11","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"3704:3:11"},"nodeType":"YulFunctionCall","src":"3704:32:11"},"nodeType":"YulIf","src":"3701:52:11"},{"nodeType":"YulVariableDeclaration","src":"3762:36:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3788:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3775:12:11"},"nodeType":"YulFunctionCall","src":"3775:23:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"3766:5:11","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"3832:5:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"3807:24:11"},"nodeType":"YulFunctionCall","src":"3807:31:11"},"nodeType":"YulExpressionStatement","src":"3807:31:11"},{"nodeType":"YulAssignment","src":"3847:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"3857:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"3847:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"3871:47:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3903:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"3914:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3899:3:11"},"nodeType":"YulFunctionCall","src":"3899:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3886:12:11"},"nodeType":"YulFunctionCall","src":"3886:32:11"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"3875:7:11","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"3952:7:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"3927:24:11"},"nodeType":"YulFunctionCall","src":"3927:33:11"},"nodeType":"YulExpressionStatement","src":"3927:33:11"},{"nodeType":"YulAssignment","src":"3969:17:11","value":{"name":"value_1","nodeType":"YulIdentifier","src":"3979:7:11"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"3969:6:11"}]}]},"name":"abi_decode_tuple_t_addresst_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"3649:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"3660:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"3672:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"3680:6:11","type":""}],"src":"3604:388:11"},{"body":{"nodeType":"YulBlock","src":"4070:275:11","statements":[{"body":{"nodeType":"YulBlock","src":"4119:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4128:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4131:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4121:6:11"},"nodeType":"YulFunctionCall","src":"4121:12:11"},"nodeType":"YulExpressionStatement","src":"4121:12:11"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"4098:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"4106:4:11","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4094:3:11"},"nodeType":"YulFunctionCall","src":"4094:17:11"},{"name":"end","nodeType":"YulIdentifier","src":"4113:3:11"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"4090:3:11"},"nodeType":"YulFunctionCall","src":"4090:27:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"4083:6:11"},"nodeType":"YulFunctionCall","src":"4083:35:11"},"nodeType":"YulIf","src":"4080:55:11"},{"nodeType":"YulAssignment","src":"4144:30:11","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"4167:6:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4154:12:11"},"nodeType":"YulFunctionCall","src":"4154:20:11"},"variableNames":[{"name":"length","nodeType":"YulIdentifier","src":"4144:6:11"}]},{"body":{"nodeType":"YulBlock","src":"4217:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4226:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4229:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4219:6:11"},"nodeType":"YulFunctionCall","src":"4219:12:11"},"nodeType":"YulExpressionStatement","src":"4219:12:11"}]},"condition":{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"4189:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"4197:18:11","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"4186:2:11"},"nodeType":"YulFunctionCall","src":"4186:30:11"},"nodeType":"YulIf","src":"4183:50:11"},{"nodeType":"YulAssignment","src":"4242:29:11","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"4258:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"4266:4:11","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4254:3:11"},"nodeType":"YulFunctionCall","src":"4254:17:11"},"variableNames":[{"name":"arrayPos","nodeType":"YulIdentifier","src":"4242:8:11"}]},{"body":{"nodeType":"YulBlock","src":"4323:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4332:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4335:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4325:6:11"},"nodeType":"YulFunctionCall","src":"4325:12:11"},"nodeType":"YulExpressionStatement","src":"4325:12:11"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"4294:6:11"},{"name":"length","nodeType":"YulIdentifier","src":"4302:6:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4290:3:11"},"nodeType":"YulFunctionCall","src":"4290:19:11"},{"kind":"number","nodeType":"YulLiteral","src":"4311:4:11","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4286:3:11"},"nodeType":"YulFunctionCall","src":"4286:30:11"},{"name":"end","nodeType":"YulIdentifier","src":"4318:3:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"4283:2:11"},"nodeType":"YulFunctionCall","src":"4283:39:11"},"nodeType":"YulIf","src":"4280:59:11"}]},"name":"abi_decode_string_calldata","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"4033:6:11","type":""},{"name":"end","nodeType":"YulTypedName","src":"4041:3:11","type":""}],"returnVariables":[{"name":"arrayPos","nodeType":"YulTypedName","src":"4049:8:11","type":""},{"name":"length","nodeType":"YulTypedName","src":"4059:6:11","type":""}],"src":"3997:348:11"},{"body":{"nodeType":"YulBlock","src":"4525:719:11","statements":[{"body":{"nodeType":"YulBlock","src":"4572:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4581:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4584:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4574:6:11"},"nodeType":"YulFunctionCall","src":"4574:12:11"},"nodeType":"YulExpressionStatement","src":"4574:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"4546:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"4555:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"4542:3:11"},"nodeType":"YulFunctionCall","src":"4542:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"4567:3:11","type":"","value":"192"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"4538:3:11"},"nodeType":"YulFunctionCall","src":"4538:33:11"},"nodeType":"YulIf","src":"4535:53:11"},{"nodeType":"YulVariableDeclaration","src":"4597:36:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4623:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4610:12:11"},"nodeType":"YulFunctionCall","src":"4610:23:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"4601:5:11","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"4667:5:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"4642:24:11"},"nodeType":"YulFunctionCall","src":"4642:31:11"},"nodeType":"YulExpressionStatement","src":"4642:31:11"},{"nodeType":"YulAssignment","src":"4682:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"4692:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"4682:6:11"}]},{"nodeType":"YulAssignment","src":"4706:42:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4733:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"4744:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4729:3:11"},"nodeType":"YulFunctionCall","src":"4729:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4716:12:11"},"nodeType":"YulFunctionCall","src":"4716:32:11"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"4706:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"4757:46:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4788:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"4799:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4784:3:11"},"nodeType":"YulFunctionCall","src":"4784:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4771:12:11"},"nodeType":"YulFunctionCall","src":"4771:32:11"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"4761:6:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"4846:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4855:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4858:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4848:6:11"},"nodeType":"YulFunctionCall","src":"4848:12:11"},"nodeType":"YulExpressionStatement","src":"4848:12:11"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"4818:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"4826:18:11","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"4815:2:11"},"nodeType":"YulFunctionCall","src":"4815:30:11"},"nodeType":"YulIf","src":"4812:50:11"},{"nodeType":"YulVariableDeclaration","src":"4871:85:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4928:9:11"},{"name":"offset","nodeType":"YulIdentifier","src":"4939:6:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4924:3:11"},"nodeType":"YulFunctionCall","src":"4924:22:11"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"4948:7:11"}],"functionName":{"name":"abi_decode_string_calldata","nodeType":"YulIdentifier","src":"4897:26:11"},"nodeType":"YulFunctionCall","src":"4897:59:11"},"variables":[{"name":"value2_1","nodeType":"YulTypedName","src":"4875:8:11","type":""},{"name":"value3_1","nodeType":"YulTypedName","src":"4885:8:11","type":""}]},{"nodeType":"YulAssignment","src":"4965:18:11","value":{"name":"value2_1","nodeType":"YulIdentifier","src":"4975:8:11"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"4965:6:11"}]},{"nodeType":"YulAssignment","src":"4992:18:11","value":{"name":"value3_1","nodeType":"YulIdentifier","src":"5002:8:11"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"4992:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"5019:47:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5051:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"5062:2:11","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5047:3:11"},"nodeType":"YulFunctionCall","src":"5047:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5034:12:11"},"nodeType":"YulFunctionCall","src":"5034:32:11"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"5023:7:11","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"5100:7:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"5075:24:11"},"nodeType":"YulFunctionCall","src":"5075:33:11"},"nodeType":"YulExpressionStatement","src":"5075:33:11"},{"nodeType":"YulAssignment","src":"5117:17:11","value":{"name":"value_1","nodeType":"YulIdentifier","src":"5127:7:11"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"5117:6:11"}]},{"nodeType":"YulAssignment","src":"5143:43:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5170:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"5181:3:11","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5166:3:11"},"nodeType":"YulFunctionCall","src":"5166:19:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5153:12:11"},"nodeType":"YulFunctionCall","src":"5153:33:11"},"variableNames":[{"name":"value5","nodeType":"YulIdentifier","src":"5143:6:11"}]},{"nodeType":"YulAssignment","src":"5195:43:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5222:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"5233:3:11","type":"","value":"160"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5218:3:11"},"nodeType":"YulFunctionCall","src":"5218:19:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5205:12:11"},"nodeType":"YulFunctionCall","src":"5205:33:11"},"variableNames":[{"name":"value6","nodeType":"YulIdentifier","src":"5195:6:11"}]}]},"name":"abi_decode_tuple_t_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"4443:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"4454:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"4466:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"4474:6:11","type":""},{"name":"value2","nodeType":"YulTypedName","src":"4482:6:11","type":""},{"name":"value3","nodeType":"YulTypedName","src":"4490:6:11","type":""},{"name":"value4","nodeType":"YulTypedName","src":"4498:6:11","type":""},{"name":"value5","nodeType":"YulTypedName","src":"4506:6:11","type":""},{"name":"value6","nodeType":"YulTypedName","src":"4514:6:11","type":""}],"src":"4350:894:11"},{"body":{"nodeType":"YulBlock","src":"5350:102:11","statements":[{"nodeType":"YulAssignment","src":"5360:26:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5372:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"5383:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5368:3:11"},"nodeType":"YulFunctionCall","src":"5368:18:11"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"5360:4:11"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5402:9:11"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"5417:6:11"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5433:3:11","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"5438:1:11","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"5429:3:11"},"nodeType":"YulFunctionCall","src":"5429:11:11"},{"kind":"number","nodeType":"YulLiteral","src":"5442:1:11","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"5425:3:11"},"nodeType":"YulFunctionCall","src":"5425:19:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"5413:3:11"},"nodeType":"YulFunctionCall","src":"5413:32:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5395:6:11"},"nodeType":"YulFunctionCall","src":"5395:51:11"},"nodeType":"YulExpressionStatement","src":"5395:51:11"}]},"name":"abi_encode_tuple_t_address__to_t_address__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"5319:9:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"5330:6:11","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"5341:4:11","type":""}],"src":"5249:203:11"},{"body":{"nodeType":"YulBlock","src":"5580:490:11","statements":[{"body":{"nodeType":"YulBlock","src":"5626:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5635:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"5638:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"5628:6:11"},"nodeType":"YulFunctionCall","src":"5628:12:11"},"nodeType":"YulExpressionStatement","src":"5628:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"5601:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"5610:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"5597:3:11"},"nodeType":"YulFunctionCall","src":"5597:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"5622:2:11","type":"","value":"96"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"5593:3:11"},"nodeType":"YulFunctionCall","src":"5593:32:11"},"nodeType":"YulIf","src":"5590:52:11"},{"nodeType":"YulVariableDeclaration","src":"5651:36:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5677:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5664:12:11"},"nodeType":"YulFunctionCall","src":"5664:23:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"5655:5:11","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"5721:5:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"5696:24:11"},"nodeType":"YulFunctionCall","src":"5696:31:11"},"nodeType":"YulExpressionStatement","src":"5696:31:11"},{"nodeType":"YulAssignment","src":"5736:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"5746:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"5736:6:11"}]},{"nodeType":"YulAssignment","src":"5760:42:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5787:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"5798:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5783:3:11"},"nodeType":"YulFunctionCall","src":"5783:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5770:12:11"},"nodeType":"YulFunctionCall","src":"5770:32:11"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"5760:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"5811:46:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5842:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"5853:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5838:3:11"},"nodeType":"YulFunctionCall","src":"5838:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5825:12:11"},"nodeType":"YulFunctionCall","src":"5825:32:11"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"5815:6:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"5900:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5909:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"5912:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"5902:6:11"},"nodeType":"YulFunctionCall","src":"5902:12:11"},"nodeType":"YulExpressionStatement","src":"5902:12:11"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"5872:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"5880:18:11","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"5869:2:11"},"nodeType":"YulFunctionCall","src":"5869:30:11"},"nodeType":"YulIf","src":"5866:50:11"},{"nodeType":"YulVariableDeclaration","src":"5925:85:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5982:9:11"},{"name":"offset","nodeType":"YulIdentifier","src":"5993:6:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5978:3:11"},"nodeType":"YulFunctionCall","src":"5978:22:11"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"6002:7:11"}],"functionName":{"name":"abi_decode_string_calldata","nodeType":"YulIdentifier","src":"5951:26:11"},"nodeType":"YulFunctionCall","src":"5951:59:11"},"variables":[{"name":"value2_1","nodeType":"YulTypedName","src":"5929:8:11","type":""},{"name":"value3_1","nodeType":"YulTypedName","src":"5939:8:11","type":""}]},{"nodeType":"YulAssignment","src":"6019:18:11","value":{"name":"value2_1","nodeType":"YulIdentifier","src":"6029:8:11"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"6019:6:11"}]},{"nodeType":"YulAssignment","src":"6046:18:11","value":{"name":"value3_1","nodeType":"YulIdentifier","src":"6056:8:11"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"6046:6:11"}]}]},"name":"abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"5522:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"5533:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"5545:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"5553:6:11","type":""},{"name":"value2","nodeType":"YulTypedName","src":"5561:6:11","type":""},{"name":"value3","nodeType":"YulTypedName","src":"5569:6:11","type":""}],"src":"5457:613:11"},{"body":{"nodeType":"YulBlock","src":"6194:427:11","statements":[{"nodeType":"YulVariableDeclaration","src":"6204:12:11","value":{"kind":"number","nodeType":"YulLiteral","src":"6214:2:11","type":"","value":"32"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"6208:2:11","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6232:9:11"},{"name":"_1","nodeType":"YulIdentifier","src":"6243:2:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6225:6:11"},"nodeType":"YulFunctionCall","src":"6225:21:11"},"nodeType":"YulExpressionStatement","src":"6225:21:11"},{"nodeType":"YulVariableDeclaration","src":"6255:27:11","value":{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"6275:6:11"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"6269:5:11"},"nodeType":"YulFunctionCall","src":"6269:13:11"},"variables":[{"name":"length","nodeType":"YulTypedName","src":"6259:6:11","type":""}]},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6302:9:11"},{"name":"_1","nodeType":"YulIdentifier","src":"6313:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6298:3:11"},"nodeType":"YulFunctionCall","src":"6298:18:11"},{"name":"length","nodeType":"YulIdentifier","src":"6318:6:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6291:6:11"},"nodeType":"YulFunctionCall","src":"6291:34:11"},"nodeType":"YulExpressionStatement","src":"6291:34:11"},{"nodeType":"YulVariableDeclaration","src":"6334:10:11","value":{"kind":"number","nodeType":"YulLiteral","src":"6343:1:11","type":"","value":"0"},"variables":[{"name":"i","nodeType":"YulTypedName","src":"6338:1:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"6403:90:11","statements":[{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6432:9:11"},{"name":"i","nodeType":"YulIdentifier","src":"6443:1:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6428:3:11"},"nodeType":"YulFunctionCall","src":"6428:17:11"},{"kind":"number","nodeType":"YulLiteral","src":"6447:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6424:3:11"},"nodeType":"YulFunctionCall","src":"6424:26:11"},{"arguments":[{"arguments":[{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"6466:6:11"},{"name":"i","nodeType":"YulIdentifier","src":"6474:1:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6462:3:11"},"nodeType":"YulFunctionCall","src":"6462:14:11"},{"name":"_1","nodeType":"YulIdentifier","src":"6478:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6458:3:11"},"nodeType":"YulFunctionCall","src":"6458:23:11"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"6452:5:11"},"nodeType":"YulFunctionCall","src":"6452:30:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6417:6:11"},"nodeType":"YulFunctionCall","src":"6417:66:11"},"nodeType":"YulExpressionStatement","src":"6417:66:11"}]},"condition":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"6364:1:11"},{"name":"length","nodeType":"YulIdentifier","src":"6367:6:11"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"6361:2:11"},"nodeType":"YulFunctionCall","src":"6361:13:11"},"nodeType":"YulForLoop","post":{"nodeType":"YulBlock","src":"6375:19:11","statements":[{"nodeType":"YulAssignment","src":"6377:15:11","value":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"6386:1:11"},{"name":"_1","nodeType":"YulIdentifier","src":"6389:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6382:3:11"},"nodeType":"YulFunctionCall","src":"6382:10:11"},"variableNames":[{"name":"i","nodeType":"YulIdentifier","src":"6377:1:11"}]}]},"pre":{"nodeType":"YulBlock","src":"6357:3:11","statements":[]},"src":"6353:140:11"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6517:9:11"},{"name":"length","nodeType":"YulIdentifier","src":"6528:6:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6513:3:11"},"nodeType":"YulFunctionCall","src":"6513:22:11"},{"kind":"number","nodeType":"YulLiteral","src":"6537:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6509:3:11"},"nodeType":"YulFunctionCall","src":"6509:31:11"},{"kind":"number","nodeType":"YulLiteral","src":"6542:1:11","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6502:6:11"},"nodeType":"YulFunctionCall","src":"6502:42:11"},"nodeType":"YulExpressionStatement","src":"6502:42:11"},{"nodeType":"YulAssignment","src":"6553:62:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6569:9:11"},{"arguments":[{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"6588:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"6596:2:11","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6584:3:11"},"nodeType":"YulFunctionCall","src":"6584:15:11"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6605:2:11","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"6601:3:11"},"nodeType":"YulFunctionCall","src":"6601:7:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"6580:3:11"},"nodeType":"YulFunctionCall","src":"6580:29:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6565:3:11"},"nodeType":"YulFunctionCall","src":"6565:45:11"},{"kind":"number","nodeType":"YulLiteral","src":"6612:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6561:3:11"},"nodeType":"YulFunctionCall","src":"6561:54:11"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"6553:4:11"}]}]},"name":"abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"6163:9:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"6174:6:11","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"6185:4:11","type":""}],"src":"6075:546:11"},{"body":{"nodeType":"YulBlock","src":"6690:648:11","statements":[{"body":{"nodeType":"YulBlock","src":"6739:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6748:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"6751:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"6741:6:11"},"nodeType":"YulFunctionCall","src":"6741:12:11"},"nodeType":"YulExpressionStatement","src":"6741:12:11"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"6718:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"6726:4:11","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6714:3:11"},"nodeType":"YulFunctionCall","src":"6714:17:11"},{"name":"end","nodeType":"YulIdentifier","src":"6733:3:11"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"6710:3:11"},"nodeType":"YulFunctionCall","src":"6710:27:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"6703:6:11"},"nodeType":"YulFunctionCall","src":"6703:35:11"},"nodeType":"YulIf","src":"6700:55:11"},{"nodeType":"YulVariableDeclaration","src":"6764:30:11","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"6787:6:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6774:12:11"},"nodeType":"YulFunctionCall","src":"6774:20:11"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"6768:2:11","type":""}]},{"nodeType":"YulVariableDeclaration","src":"6803:14:11","value":{"kind":"number","nodeType":"YulLiteral","src":"6813:4:11","type":"","value":"0x20"},"variables":[{"name":"_2","nodeType":"YulTypedName","src":"6807:2:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"6856:22:11","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"6858:16:11"},"nodeType":"YulFunctionCall","src":"6858:18:11"},"nodeType":"YulExpressionStatement","src":"6858:18:11"}]},"condition":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"6832:2:11"},{"kind":"number","nodeType":"YulLiteral","src":"6836:18:11","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"6829:2:11"},"nodeType":"YulFunctionCall","src":"6829:26:11"},"nodeType":"YulIf","src":"6826:52:11"},{"nodeType":"YulVariableDeclaration","src":"6887:20:11","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6901:1:11","type":"","value":"5"},{"name":"_1","nodeType":"YulIdentifier","src":"6904:2:11"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"6897:3:11"},"nodeType":"YulFunctionCall","src":"6897:10:11"},"variables":[{"name":"_3","nodeType":"YulTypedName","src":"6891:2:11","type":""}]},{"nodeType":"YulVariableDeclaration","src":"6916:39:11","value":{"arguments":[{"arguments":[{"name":"_3","nodeType":"YulIdentifier","src":"6947:2:11"},{"name":"_2","nodeType":"YulIdentifier","src":"6951:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6943:3:11"},"nodeType":"YulFunctionCall","src":"6943:11:11"}],"functionName":{"name":"allocate_memory","nodeType":"YulIdentifier","src":"6927:15:11"},"nodeType":"YulFunctionCall","src":"6927:28:11"},"variables":[{"name":"dst","nodeType":"YulTypedName","src":"6920:3:11","type":""}]},{"nodeType":"YulVariableDeclaration","src":"6964:16:11","value":{"name":"dst","nodeType":"YulIdentifier","src":"6977:3:11"},"variables":[{"name":"dst_1","nodeType":"YulTypedName","src":"6968:5:11","type":""}]},{"expression":{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"6996:3:11"},{"name":"_1","nodeType":"YulIdentifier","src":"7001:2:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6989:6:11"},"nodeType":"YulFunctionCall","src":"6989:15:11"},"nodeType":"YulExpressionStatement","src":"6989:15:11"},{"nodeType":"YulAssignment","src":"7013:19:11","value":{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"7024:3:11"},{"name":"_2","nodeType":"YulIdentifier","src":"7029:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7020:3:11"},"nodeType":"YulFunctionCall","src":"7020:12:11"},"variableNames":[{"name":"dst","nodeType":"YulIdentifier","src":"7013:3:11"}]},{"nodeType":"YulVariableDeclaration","src":"7041:38:11","value":{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"7063:6:11"},{"name":"_3","nodeType":"YulIdentifier","src":"7071:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7059:3:11"},"nodeType":"YulFunctionCall","src":"7059:15:11"},{"name":"_2","nodeType":"YulIdentifier","src":"7076:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7055:3:11"},"nodeType":"YulFunctionCall","src":"7055:24:11"},"variables":[{"name":"srcEnd","nodeType":"YulTypedName","src":"7045:6:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"7107:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7116:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"7119:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7109:6:11"},"nodeType":"YulFunctionCall","src":"7109:12:11"},"nodeType":"YulExpressionStatement","src":"7109:12:11"}]},"condition":{"arguments":[{"name":"srcEnd","nodeType":"YulIdentifier","src":"7094:6:11"},{"name":"end","nodeType":"YulIdentifier","src":"7102:3:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"7091:2:11"},"nodeType":"YulFunctionCall","src":"7091:15:11"},"nodeType":"YulIf","src":"7088:35:11"},{"nodeType":"YulVariableDeclaration","src":"7132:26:11","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"7147:6:11"},{"name":"_2","nodeType":"YulIdentifier","src":"7155:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7143:3:11"},"nodeType":"YulFunctionCall","src":"7143:15:11"},"variables":[{"name":"src","nodeType":"YulTypedName","src":"7136:3:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"7223:86:11","statements":[{"expression":{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"7244:3:11"},{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"7262:3:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7249:12:11"},"nodeType":"YulFunctionCall","src":"7249:17:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7237:6:11"},"nodeType":"YulFunctionCall","src":"7237:30:11"},"nodeType":"YulExpressionStatement","src":"7237:30:11"},{"nodeType":"YulAssignment","src":"7280:19:11","value":{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"7291:3:11"},{"name":"_2","nodeType":"YulIdentifier","src":"7296:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7287:3:11"},"nodeType":"YulFunctionCall","src":"7287:12:11"},"variableNames":[{"name":"dst","nodeType":"YulIdentifier","src":"7280:3:11"}]}]},"condition":{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"7178:3:11"},{"name":"srcEnd","nodeType":"YulIdentifier","src":"7183:6:11"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"7175:2:11"},"nodeType":"YulFunctionCall","src":"7175:15:11"},"nodeType":"YulForLoop","post":{"nodeType":"YulBlock","src":"7191:23:11","statements":[{"nodeType":"YulAssignment","src":"7193:19:11","value":{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"7204:3:11"},{"name":"_2","nodeType":"YulIdentifier","src":"7209:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7200:3:11"},"nodeType":"YulFunctionCall","src":"7200:12:11"},"variableNames":[{"name":"src","nodeType":"YulIdentifier","src":"7193:3:11"}]}]},"pre":{"nodeType":"YulBlock","src":"7171:3:11","statements":[]},"src":"7167:142:11"},{"nodeType":"YulAssignment","src":"7318:14:11","value":{"name":"dst_1","nodeType":"YulIdentifier","src":"7327:5:11"},"variableNames":[{"name":"array","nodeType":"YulIdentifier","src":"7318:5:11"}]}]},"name":"abi_decode_array_uint256_dyn","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"6664:6:11","type":""},{"name":"end","nodeType":"YulTypedName","src":"6672:3:11","type":""}],"returnVariables":[{"name":"array","nodeType":"YulTypedName","src":"6680:5:11","type":""}],"src":"6626:712:11"},{"body":{"nodeType":"YulBlock","src":"7540:874:11","statements":[{"body":{"nodeType":"YulBlock","src":"7587:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7596:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"7599:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7589:6:11"},"nodeType":"YulFunctionCall","src":"7589:12:11"},"nodeType":"YulExpressionStatement","src":"7589:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"7561:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"7570:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"7557:3:11"},"nodeType":"YulFunctionCall","src":"7557:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"7582:3:11","type":"","value":"160"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"7553:3:11"},"nodeType":"YulFunctionCall","src":"7553:33:11"},"nodeType":"YulIf","src":"7550:53:11"},{"nodeType":"YulVariableDeclaration","src":"7612:36:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7638:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7625:12:11"},"nodeType":"YulFunctionCall","src":"7625:23:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"7616:5:11","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"7682:5:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"7657:24:11"},"nodeType":"YulFunctionCall","src":"7657:31:11"},"nodeType":"YulExpressionStatement","src":"7657:31:11"},{"nodeType":"YulAssignment","src":"7697:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"7707:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"7697:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"7721:47:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7753:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"7764:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7749:3:11"},"nodeType":"YulFunctionCall","src":"7749:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7736:12:11"},"nodeType":"YulFunctionCall","src":"7736:32:11"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"7725:7:11","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"7802:7:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"7777:24:11"},"nodeType":"YulFunctionCall","src":"7777:33:11"},"nodeType":"YulExpressionStatement","src":"7777:33:11"},{"nodeType":"YulAssignment","src":"7819:17:11","value":{"name":"value_1","nodeType":"YulIdentifier","src":"7829:7:11"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"7819:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"7845:46:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7876:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"7887:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7872:3:11"},"nodeType":"YulFunctionCall","src":"7872:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7859:12:11"},"nodeType":"YulFunctionCall","src":"7859:32:11"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"7849:6:11","type":""}]},{"nodeType":"YulVariableDeclaration","src":"7900:28:11","value":{"kind":"number","nodeType":"YulLiteral","src":"7910:18:11","type":"","value":"0xffffffffffffffff"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"7904:2:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"7955:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7964:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"7967:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7957:6:11"},"nodeType":"YulFunctionCall","src":"7957:12:11"},"nodeType":"YulExpressionStatement","src":"7957:12:11"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"7943:6:11"},{"name":"_1","nodeType":"YulIdentifier","src":"7951:2:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"7940:2:11"},"nodeType":"YulFunctionCall","src":"7940:14:11"},"nodeType":"YulIf","src":"7937:34:11"},{"nodeType":"YulAssignment","src":"7980:71:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8023:9:11"},{"name":"offset","nodeType":"YulIdentifier","src":"8034:6:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8019:3:11"},"nodeType":"YulFunctionCall","src":"8019:22:11"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"8043:7:11"}],"functionName":{"name":"abi_decode_array_uint256_dyn","nodeType":"YulIdentifier","src":"7990:28:11"},"nodeType":"YulFunctionCall","src":"7990:61:11"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"7980:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"8060:48:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8093:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"8104:2:11","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8089:3:11"},"nodeType":"YulFunctionCall","src":"8089:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8076:12:11"},"nodeType":"YulFunctionCall","src":"8076:32:11"},"variables":[{"name":"offset_1","nodeType":"YulTypedName","src":"8064:8:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"8137:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"8146:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"8149:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"8139:6:11"},"nodeType":"YulFunctionCall","src":"8139:12:11"},"nodeType":"YulExpressionStatement","src":"8139:12:11"}]},"condition":{"arguments":[{"name":"offset_1","nodeType":"YulIdentifier","src":"8123:8:11"},{"name":"_1","nodeType":"YulIdentifier","src":"8133:2:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"8120:2:11"},"nodeType":"YulFunctionCall","src":"8120:16:11"},"nodeType":"YulIf","src":"8117:36:11"},{"nodeType":"YulAssignment","src":"8162:73:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8205:9:11"},{"name":"offset_1","nodeType":"YulIdentifier","src":"8216:8:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8201:3:11"},"nodeType":"YulFunctionCall","src":"8201:24:11"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"8227:7:11"}],"functionName":{"name":"abi_decode_array_uint256_dyn","nodeType":"YulIdentifier","src":"8172:28:11"},"nodeType":"YulFunctionCall","src":"8172:63:11"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"8162:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"8244:49:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8277:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"8288:3:11","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8273:3:11"},"nodeType":"YulFunctionCall","src":"8273:19:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8260:12:11"},"nodeType":"YulFunctionCall","src":"8260:33:11"},"variables":[{"name":"offset_2","nodeType":"YulTypedName","src":"8248:8:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"8322:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"8331:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"8334:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"8324:6:11"},"nodeType":"YulFunctionCall","src":"8324:12:11"},"nodeType":"YulExpressionStatement","src":"8324:12:11"}]},"condition":{"arguments":[{"name":"offset_2","nodeType":"YulIdentifier","src":"8308:8:11"},{"name":"_1","nodeType":"YulIdentifier","src":"8318:2:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"8305:2:11"},"nodeType":"YulFunctionCall","src":"8305:16:11"},"nodeType":"YulIf","src":"8302:36:11"},{"nodeType":"YulAssignment","src":"8347:61:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8378:9:11"},{"name":"offset_2","nodeType":"YulIdentifier","src":"8389:8:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8374:3:11"},"nodeType":"YulFunctionCall","src":"8374:24:11"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"8400:7:11"}],"functionName":{"name":"abi_decode_bytes","nodeType":"YulIdentifier","src":"8357:16:11"},"nodeType":"YulFunctionCall","src":"8357:51:11"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"8347:6:11"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_array$_t_uint256_$dyn_memory_ptrt_array$_t_uint256_$dyn_memory_ptrt_bytes_memory_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"7474:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"7485:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"7497:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"7505:6:11","type":""},{"name":"value2","nodeType":"YulTypedName","src":"7513:6:11","type":""},{"name":"value3","nodeType":"YulTypedName","src":"7521:6:11","type":""},{"name":"value4","nodeType":"YulTypedName","src":"7529:6:11","type":""}],"src":"7343:1071:11"},{"body":{"nodeType":"YulBlock","src":"8520:76:11","statements":[{"nodeType":"YulAssignment","src":"8530:26:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8542:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"8553:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8538:3:11"},"nodeType":"YulFunctionCall","src":"8538:18:11"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"8530:4:11"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8572:9:11"},{"name":"value0","nodeType":"YulIdentifier","src":"8583:6:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8565:6:11"},"nodeType":"YulFunctionCall","src":"8565:25:11"},"nodeType":"YulExpressionStatement","src":"8565:25:11"}]},"name":"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"8489:9:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"8500:6:11","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"8511:4:11","type":""}],"src":"8419:177:11"},{"body":{"nodeType":"YulBlock","src":"8671:110:11","statements":[{"body":{"nodeType":"YulBlock","src":"8717:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"8726:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"8729:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"8719:6:11"},"nodeType":"YulFunctionCall","src":"8719:12:11"},"nodeType":"YulExpressionStatement","src":"8719:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"8692:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"8701:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"8688:3:11"},"nodeType":"YulFunctionCall","src":"8688:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"8713:2:11","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"8684:3:11"},"nodeType":"YulFunctionCall","src":"8684:32:11"},"nodeType":"YulIf","src":"8681:52:11"},{"nodeType":"YulAssignment","src":"8742:33:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8765:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8752:12:11"},"nodeType":"YulFunctionCall","src":"8752:23:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"8742:6:11"}]}]},"name":"abi_decode_tuple_t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"8637:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"8648:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"8660:6:11","type":""}],"src":"8601:180:11"},{"body":{"nodeType":"YulBlock","src":"8933:587:11","statements":[{"body":{"nodeType":"YulBlock","src":"8980:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"8989:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"8992:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"8982:6:11"},"nodeType":"YulFunctionCall","src":"8982:12:11"},"nodeType":"YulExpressionStatement","src":"8982:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"8954:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"8963:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"8950:3:11"},"nodeType":"YulFunctionCall","src":"8950:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"8975:3:11","type":"","value":"160"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"8946:3:11"},"nodeType":"YulFunctionCall","src":"8946:33:11"},"nodeType":"YulIf","src":"8943:53:11"},{"nodeType":"YulVariableDeclaration","src":"9005:36:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9031:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"9018:12:11"},"nodeType":"YulFunctionCall","src":"9018:23:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"9009:5:11","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"9075:5:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"9050:24:11"},"nodeType":"YulFunctionCall","src":"9050:31:11"},"nodeType":"YulExpressionStatement","src":"9050:31:11"},{"nodeType":"YulAssignment","src":"9090:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"9100:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"9090:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"9114:47:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9146:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"9157:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9142:3:11"},"nodeType":"YulFunctionCall","src":"9142:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"9129:12:11"},"nodeType":"YulFunctionCall","src":"9129:32:11"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"9118:7:11","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"9195:7:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"9170:24:11"},"nodeType":"YulFunctionCall","src":"9170:33:11"},"nodeType":"YulExpressionStatement","src":"9170:33:11"},{"nodeType":"YulAssignment","src":"9212:17:11","value":{"name":"value_1","nodeType":"YulIdentifier","src":"9222:7:11"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"9212:6:11"}]},{"nodeType":"YulAssignment","src":"9238:42:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9265:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"9276:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9261:3:11"},"nodeType":"YulFunctionCall","src":"9261:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"9248:12:11"},"nodeType":"YulFunctionCall","src":"9248:32:11"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"9238:6:11"}]},{"nodeType":"YulAssignment","src":"9289:42:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9316:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"9327:2:11","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9312:3:11"},"nodeType":"YulFunctionCall","src":"9312:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"9299:12:11"},"nodeType":"YulFunctionCall","src":"9299:32:11"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"9289:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"9340:47:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9371:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"9382:3:11","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9367:3:11"},"nodeType":"YulFunctionCall","src":"9367:19:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"9354:12:11"},"nodeType":"YulFunctionCall","src":"9354:33:11"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"9344:6:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"9430:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9439:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"9442:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"9432:6:11"},"nodeType":"YulFunctionCall","src":"9432:12:11"},"nodeType":"YulExpressionStatement","src":"9432:12:11"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"9402:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"9410:18:11","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"9399:2:11"},"nodeType":"YulFunctionCall","src":"9399:30:11"},"nodeType":"YulIf","src":"9396:50:11"},{"nodeType":"YulAssignment","src":"9455:59:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9486:9:11"},{"name":"offset","nodeType":"YulIdentifier","src":"9497:6:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9482:3:11"},"nodeType":"YulFunctionCall","src":"9482:22:11"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"9506:7:11"}],"functionName":{"name":"abi_decode_bytes","nodeType":"YulIdentifier","src":"9465:16:11"},"nodeType":"YulFunctionCall","src":"9465:49:11"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"9455:6:11"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256t_uint256t_bytes_memory_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"8867:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"8878:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"8890:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"8898:6:11","type":""},{"name":"value2","nodeType":"YulTypedName","src":"8906:6:11","type":""},{"name":"value3","nodeType":"YulTypedName","src":"8914:6:11","type":""},{"name":"value4","nodeType":"YulTypedName","src":"8922:6:11","type":""}],"src":"8786:734:11"},{"body":{"nodeType":"YulBlock","src":"9682:188:11","statements":[{"nodeType":"YulAssignment","src":"9692:26:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9704:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"9715:2:11","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9700:3:11"},"nodeType":"YulFunctionCall","src":"9700:18:11"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"9692:4:11"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9734:9:11"},{"name":"value0","nodeType":"YulIdentifier","src":"9745:6:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9727:6:11"},"nodeType":"YulFunctionCall","src":"9727:25:11"},"nodeType":"YulExpressionStatement","src":"9727:25:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9772:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"9783:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9768:3:11"},"nodeType":"YulFunctionCall","src":"9768:18:11"},{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"9792:6:11"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9808:3:11","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"9813:1:11","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"9804:3:11"},"nodeType":"YulFunctionCall","src":"9804:11:11"},{"kind":"number","nodeType":"YulLiteral","src":"9817:1:11","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"9800:3:11"},"nodeType":"YulFunctionCall","src":"9800:19:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"9788:3:11"},"nodeType":"YulFunctionCall","src":"9788:32:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9761:6:11"},"nodeType":"YulFunctionCall","src":"9761:60:11"},"nodeType":"YulExpressionStatement","src":"9761:60:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9841:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"9852:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9837:3:11"},"nodeType":"YulFunctionCall","src":"9837:18:11"},{"name":"value2","nodeType":"YulIdentifier","src":"9857:6:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9830:6:11"},"nodeType":"YulFunctionCall","src":"9830:34:11"},"nodeType":"YulExpressionStatement","src":"9830:34:11"}]},"name":"abi_encode_tuple_t_uint256_t_address_t_uint256__to_t_uint256_t_address_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"9635:9:11","type":""},{"name":"value2","nodeType":"YulTypedName","src":"9646:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"9654:6:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"9662:6:11","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"9673:4:11","type":""}],"src":"9525:345:11"},{"body":{"nodeType":"YulBlock","src":"9945:177:11","statements":[{"body":{"nodeType":"YulBlock","src":"9991:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10000:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"10003:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"9993:6:11"},"nodeType":"YulFunctionCall","src":"9993:12:11"},"nodeType":"YulExpressionStatement","src":"9993:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"9966:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"9975:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"9962:3:11"},"nodeType":"YulFunctionCall","src":"9962:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"9987:2:11","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"9958:3:11"},"nodeType":"YulFunctionCall","src":"9958:32:11"},"nodeType":"YulIf","src":"9955:52:11"},{"nodeType":"YulVariableDeclaration","src":"10016:36:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10042:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"10029:12:11"},"nodeType":"YulFunctionCall","src":"10029:23:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"10020:5:11","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"10086:5:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"10061:24:11"},"nodeType":"YulFunctionCall","src":"10061:31:11"},"nodeType":"YulExpressionStatement","src":"10061:31:11"},{"nodeType":"YulAssignment","src":"10101:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"10111:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"10101:6:11"}]}]},"name":"abi_decode_tuple_t_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"9911:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"9922:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"9934:6:11","type":""}],"src":"9875:247:11"},{"body":{"nodeType":"YulBlock","src":"10159:95:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10176:1:11","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10183:3:11","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"10188:10:11","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"10179:3:11"},"nodeType":"YulFunctionCall","src":"10179:20:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10169:6:11"},"nodeType":"YulFunctionCall","src":"10169:31:11"},"nodeType":"YulExpressionStatement","src":"10169:31:11"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10216:1:11","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"10219:4:11","type":"","value":"0x32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10209:6:11"},"nodeType":"YulFunctionCall","src":"10209:15:11"},"nodeType":"YulExpressionStatement","src":"10209:15:11"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10240:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"10243:4:11","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"10233:6:11"},"nodeType":"YulFunctionCall","src":"10233:15:11"},"nodeType":"YulExpressionStatement","src":"10233:15:11"}]},"name":"panic_error_0x32","nodeType":"YulFunctionDefinition","src":"10127:127:11"},{"body":{"nodeType":"YulBlock","src":"10326:206:11","statements":[{"body":{"nodeType":"YulBlock","src":"10372:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10381:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"10384:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"10374:6:11"},"nodeType":"YulFunctionCall","src":"10374:12:11"},"nodeType":"YulExpressionStatement","src":"10374:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"10347:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"10356:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"10343:3:11"},"nodeType":"YulFunctionCall","src":"10343:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"10368:2:11","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"10339:3:11"},"nodeType":"YulFunctionCall","src":"10339:32:11"},"nodeType":"YulIf","src":"10336:52:11"},{"nodeType":"YulVariableDeclaration","src":"10397:36:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10423:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"10410:12:11"},"nodeType":"YulFunctionCall","src":"10410:23:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"10401:5:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"10486:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10495:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"10498:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"10488:6:11"},"nodeType":"YulFunctionCall","src":"10488:12:11"},"nodeType":"YulExpressionStatement","src":"10488:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"10455:5:11"},{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"10476:5:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"10469:6:11"},"nodeType":"YulFunctionCall","src":"10469:13:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"10462:6:11"},"nodeType":"YulFunctionCall","src":"10462:21:11"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"10452:2:11"},"nodeType":"YulFunctionCall","src":"10452:32:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"10445:6:11"},"nodeType":"YulFunctionCall","src":"10445:40:11"},"nodeType":"YulIf","src":"10442:60:11"},{"nodeType":"YulAssignment","src":"10511:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"10521:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"10511:6:11"}]}]},"name":"abi_decode_tuple_t_bool","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"10292:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"10303:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"10315:6:11","type":""}],"src":"10259:273:11"},{"body":{"nodeType":"YulBlock","src":"10688:234:11","statements":[{"nodeType":"YulAssignment","src":"10698:26:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10710:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"10721:2:11","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10706:3:11"},"nodeType":"YulFunctionCall","src":"10706:18:11"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"10698:4:11"}]},{"nodeType":"YulVariableDeclaration","src":"10733:29:11","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10751:3:11","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"10756:1:11","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"10747:3:11"},"nodeType":"YulFunctionCall","src":"10747:11:11"},{"kind":"number","nodeType":"YulLiteral","src":"10760:1:11","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"10743:3:11"},"nodeType":"YulFunctionCall","src":"10743:19:11"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"10737:2:11","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10778:9:11"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"10793:6:11"},{"name":"_1","nodeType":"YulIdentifier","src":"10801:2:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"10789:3:11"},"nodeType":"YulFunctionCall","src":"10789:15:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10771:6:11"},"nodeType":"YulFunctionCall","src":"10771:34:11"},"nodeType":"YulExpressionStatement","src":"10771:34:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10825:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"10836:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10821:3:11"},"nodeType":"YulFunctionCall","src":"10821:18:11"},{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"10845:6:11"},{"name":"_1","nodeType":"YulIdentifier","src":"10853:2:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"10841:3:11"},"nodeType":"YulFunctionCall","src":"10841:15:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10814:6:11"},"nodeType":"YulFunctionCall","src":"10814:43:11"},"nodeType":"YulExpressionStatement","src":"10814:43:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10877:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"10888:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10873:3:11"},"nodeType":"YulFunctionCall","src":"10873:18:11"},{"arguments":[{"arguments":[{"name":"value2","nodeType":"YulIdentifier","src":"10907:6:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"10900:6:11"},"nodeType":"YulFunctionCall","src":"10900:14:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"10893:6:11"},"nodeType":"YulFunctionCall","src":"10893:22:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10866:6:11"},"nodeType":"YulFunctionCall","src":"10866:50:11"},"nodeType":"YulExpressionStatement","src":"10866:50:11"}]},"name":"abi_encode_tuple_t_address_t_address_t_bool__to_t_address_t_address_t_bool__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"10641:9:11","type":""},{"name":"value2","nodeType":"YulTypedName","src":"10652:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"10660:6:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"10668:6:11","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"10679:4:11","type":""}],"src":"10537:385:11"},{"body":{"nodeType":"YulBlock","src":"10959:95:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10976:1:11","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10983:3:11","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"10988:10:11","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"10979:3:11"},"nodeType":"YulFunctionCall","src":"10979:20:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10969:6:11"},"nodeType":"YulFunctionCall","src":"10969:31:11"},"nodeType":"YulExpressionStatement","src":"10969:31:11"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"11016:1:11","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"11019:4:11","type":"","value":"0x11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"11009:6:11"},"nodeType":"YulFunctionCall","src":"11009:15:11"},"nodeType":"YulExpressionStatement","src":"11009:15:11"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"11040:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"11043:4:11","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"11033:6:11"},"nodeType":"YulFunctionCall","src":"11033:15:11"},"nodeType":"YulExpressionStatement","src":"11033:15:11"}]},"name":"panic_error_0x11","nodeType":"YulFunctionDefinition","src":"10927:127:11"},{"body":{"nodeType":"YulBlock","src":"11106:88:11","statements":[{"body":{"nodeType":"YulBlock","src":"11137:22:11","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x11","nodeType":"YulIdentifier","src":"11139:16:11"},"nodeType":"YulFunctionCall","src":"11139:18:11"},"nodeType":"YulExpressionStatement","src":"11139:18:11"}]},"condition":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"11122:5:11"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"11133:1:11","type":"","value":"0"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"11129:3:11"},"nodeType":"YulFunctionCall","src":"11129:6:11"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"11119:2:11"},"nodeType":"YulFunctionCall","src":"11119:17:11"},"nodeType":"YulIf","src":"11116:43:11"},{"nodeType":"YulAssignment","src":"11168:20:11","value":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"11179:5:11"},{"kind":"number","nodeType":"YulLiteral","src":"11186:1:11","type":"","value":"1"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11175:3:11"},"nodeType":"YulFunctionCall","src":"11175:13:11"},"variableNames":[{"name":"ret","nodeType":"YulIdentifier","src":"11168:3:11"}]}]},"name":"increment_t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"value","nodeType":"YulTypedName","src":"11088:5:11","type":""}],"returnVariables":[{"name":"ret","nodeType":"YulTypedName","src":"11098:3:11","type":""}],"src":"11059:135:11"},{"body":{"nodeType":"YulBlock","src":"11280:170:11","statements":[{"body":{"nodeType":"YulBlock","src":"11326:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"11335:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"11338:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"11328:6:11"},"nodeType":"YulFunctionCall","src":"11328:12:11"},"nodeType":"YulExpressionStatement","src":"11328:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"11301:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"11310:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"11297:3:11"},"nodeType":"YulFunctionCall","src":"11297:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"11322:2:11","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"11293:3:11"},"nodeType":"YulFunctionCall","src":"11293:32:11"},"nodeType":"YulIf","src":"11290:52:11"},{"nodeType":"YulVariableDeclaration","src":"11351:29:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11370:9:11"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"11364:5:11"},"nodeType":"YulFunctionCall","src":"11364:16:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"11355:5:11","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"11414:5:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"11389:24:11"},"nodeType":"YulFunctionCall","src":"11389:31:11"},"nodeType":"YulExpressionStatement","src":"11389:31:11"},{"nodeType":"YulAssignment","src":"11429:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"11439:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"11429:6:11"}]}]},"name":"abi_decode_tuple_t_address_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"11246:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"11257:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"11269:6:11","type":""}],"src":"11199:251:11"},{"body":{"nodeType":"YulBlock","src":"11584:259:11","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11601:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"11612:2:11","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"11594:6:11"},"nodeType":"YulFunctionCall","src":"11594:21:11"},"nodeType":"YulExpressionStatement","src":"11594:21:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11635:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"11646:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11631:3:11"},"nodeType":"YulFunctionCall","src":"11631:18:11"},{"name":"value1","nodeType":"YulIdentifier","src":"11651:6:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"11624:6:11"},"nodeType":"YulFunctionCall","src":"11624:34:11"},"nodeType":"YulExpressionStatement","src":"11624:34:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11684:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"11695:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11680:3:11"},"nodeType":"YulFunctionCall","src":"11680:18:11"},{"name":"value0","nodeType":"YulIdentifier","src":"11700:6:11"},{"name":"value1","nodeType":"YulIdentifier","src":"11708:6:11"}],"functionName":{"name":"calldatacopy","nodeType":"YulIdentifier","src":"11667:12:11"},"nodeType":"YulFunctionCall","src":"11667:48:11"},"nodeType":"YulExpressionStatement","src":"11667:48:11"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11739:9:11"},{"name":"value1","nodeType":"YulIdentifier","src":"11750:6:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11735:3:11"},"nodeType":"YulFunctionCall","src":"11735:22:11"},{"kind":"number","nodeType":"YulLiteral","src":"11759:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11731:3:11"},"nodeType":"YulFunctionCall","src":"11731:31:11"},{"kind":"number","nodeType":"YulLiteral","src":"11764:1:11","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"11724:6:11"},"nodeType":"YulFunctionCall","src":"11724:42:11"},"nodeType":"YulExpressionStatement","src":"11724:42:11"},{"nodeType":"YulAssignment","src":"11775:62:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11791:9:11"},{"arguments":[{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"11810:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"11818:2:11","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11806:3:11"},"nodeType":"YulFunctionCall","src":"11806:15:11"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"11827:2:11","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"11823:3:11"},"nodeType":"YulFunctionCall","src":"11823:7:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"11802:3:11"},"nodeType":"YulFunctionCall","src":"11802:29:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11787:3:11"},"nodeType":"YulFunctionCall","src":"11787:45:11"},{"kind":"number","nodeType":"YulLiteral","src":"11834:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11783:3:11"},"nodeType":"YulFunctionCall","src":"11783:54:11"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"11775:4:11"}]}]},"name":"abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"11545:9:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"11556:6:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"11564:6:11","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"11575:4:11","type":""}],"src":"11455:388:11"},{"body":{"nodeType":"YulBlock","src":"11896:77:11","statements":[{"nodeType":"YulAssignment","src":"11906:16:11","value":{"arguments":[{"name":"x","nodeType":"YulIdentifier","src":"11917:1:11"},{"name":"y","nodeType":"YulIdentifier","src":"11920:1:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11913:3:11"},"nodeType":"YulFunctionCall","src":"11913:9:11"},"variableNames":[{"name":"sum","nodeType":"YulIdentifier","src":"11906:3:11"}]},{"body":{"nodeType":"YulBlock","src":"11945:22:11","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x11","nodeType":"YulIdentifier","src":"11947:16:11"},"nodeType":"YulFunctionCall","src":"11947:18:11"},"nodeType":"YulExpressionStatement","src":"11947:18:11"}]},"condition":{"arguments":[{"name":"x","nodeType":"YulIdentifier","src":"11937:1:11"},{"name":"sum","nodeType":"YulIdentifier","src":"11940:3:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"11934:2:11"},"nodeType":"YulFunctionCall","src":"11934:10:11"},"nodeType":"YulIf","src":"11931:36:11"}]},"name":"checked_add_t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"x","nodeType":"YulTypedName","src":"11879:1:11","type":""},{"name":"y","nodeType":"YulTypedName","src":"11882:1:11","type":""}],"returnVariables":[{"name":"sum","nodeType":"YulTypedName","src":"11888:3:11","type":""}],"src":"11848:125:11"},{"body":{"nodeType":"YulBlock","src":"12101:258:11","statements":[{"body":{"nodeType":"YulBlock","src":"12147:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"12156:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"12159:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"12149:6:11"},"nodeType":"YulFunctionCall","src":"12149:12:11"},"nodeType":"YulExpressionStatement","src":"12149:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"12122:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"12131:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"12118:3:11"},"nodeType":"YulFunctionCall","src":"12118:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"12143:2:11","type":"","value":"96"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"12114:3:11"},"nodeType":"YulFunctionCall","src":"12114:32:11"},"nodeType":"YulIf","src":"12111:52:11"},{"nodeType":"YulAssignment","src":"12172:26:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"12188:9:11"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"12182:5:11"},"nodeType":"YulFunctionCall","src":"12182:16:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"12172:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"12207:38:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"12230:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"12241:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"12226:3:11"},"nodeType":"YulFunctionCall","src":"12226:18:11"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"12220:5:11"},"nodeType":"YulFunctionCall","src":"12220:25:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"12211:5:11","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"12279:5:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"12254:24:11"},"nodeType":"YulFunctionCall","src":"12254:31:11"},"nodeType":"YulExpressionStatement","src":"12254:31:11"},{"nodeType":"YulAssignment","src":"12294:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"12304:5:11"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"12294:6:11"}]},{"nodeType":"YulAssignment","src":"12318:35:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"12338:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"12349:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"12334:3:11"},"nodeType":"YulFunctionCall","src":"12334:18:11"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"12328:5:11"},"nodeType":"YulFunctionCall","src":"12328:25:11"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"12318:6:11"}]}]},"name":"abi_decode_tuple_t_uint256t_address_payablet_uint256_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"12051:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"12062:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"12074:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"12082:6:11","type":""},{"name":"value2","nodeType":"YulTypedName","src":"12090:6:11","type":""}],"src":"11978:381:11"},{"body":{"nodeType":"YulBlock","src":"12511:124:11","statements":[{"expression":{"arguments":[{"name":"pos","nodeType":"YulIdentifier","src":"12534:3:11"},{"name":"value0","nodeType":"YulIdentifier","src":"12539:6:11"},{"name":"value1","nodeType":"YulIdentifier","src":"12547:6:11"}],"functionName":{"name":"calldatacopy","nodeType":"YulIdentifier","src":"12521:12:11"},"nodeType":"YulFunctionCall","src":"12521:33:11"},"nodeType":"YulExpressionStatement","src":"12521:33:11"},{"nodeType":"YulVariableDeclaration","src":"12563:26:11","value":{"arguments":[{"name":"pos","nodeType":"YulIdentifier","src":"12577:3:11"},{"name":"value1","nodeType":"YulIdentifier","src":"12582:6:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"12573:3:11"},"nodeType":"YulFunctionCall","src":"12573:16:11"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"12567:2:11","type":""}]},{"expression":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"12605:2:11"},{"kind":"number","nodeType":"YulLiteral","src":"12609:1:11","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"12598:6:11"},"nodeType":"YulFunctionCall","src":"12598:13:11"},"nodeType":"YulExpressionStatement","src":"12598:13:11"},{"nodeType":"YulAssignment","src":"12620:9:11","value":{"name":"_1","nodeType":"YulIdentifier","src":"12627:2:11"},"variableNames":[{"name":"end","nodeType":"YulIdentifier","src":"12620:3:11"}]}]},"name":"abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"pos","nodeType":"YulTypedName","src":"12479:3:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"12484:6:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"12492:6:11","type":""}],"returnVariables":[{"name":"end","nodeType":"YulTypedName","src":"12503:3:11","type":""}],"src":"12364:271:11"}]},"contents":"{\n { }\n function abi_decode_tuple_t_bytes4(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := calldataload(headStart)\n if iszero(eq(value, and(value, shl(224, 0xffffffff)))) { revert(0, 0) }\n value0 := value\n }\n function abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, iszero(iszero(value0)))\n }\n function abi_decode_array_address_dyn_calldata(offset, end) -> arrayPos, length\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n length := calldataload(offset)\n if gt(length, 0xffffffffffffffff) { revert(0, 0) }\n arrayPos := add(offset, 0x20)\n if gt(add(add(offset, shl(5, length)), 0x20), end) { revert(0, 0) }\n }\n function abi_decode_tuple_t_array$_t_address_$dyn_calldata_ptrt_array$_t_bool_$dyn_calldata_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n let offset := calldataload(headStart)\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n let value0_1, value1_1 := abi_decode_array_address_dyn_calldata(add(headStart, offset), dataEnd)\n value0 := value0_1\n value1 := value1_1\n let offset_1 := calldataload(add(headStart, 32))\n if gt(offset_1, _1) { revert(0, 0) }\n let value2_1, value3_1 := abi_decode_array_address_dyn_calldata(add(headStart, offset_1), dataEnd)\n value2 := value2_1\n value3 := value3_1\n }\n function validator_revert_address(value)\n {\n if iszero(eq(value, and(value, sub(shl(160, 1), 1)))) { revert(0, 0) }\n }\n function panic_error_0x41()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x41)\n revert(0, 0x24)\n }\n function allocate_memory(size) -> memPtr\n {\n memPtr := mload(64)\n let newFreePtr := add(memPtr, and(add(size, 31), not(31)))\n if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n mstore(64, newFreePtr)\n }\n function abi_decode_bytes(offset, end) -> array\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n let _1 := calldataload(offset)\n if gt(_1, 0xffffffffffffffff) { panic_error_0x41() }\n let array_1 := allocate_memory(add(and(add(_1, 0x1f), not(31)), 0x20))\n mstore(array_1, _1)\n if gt(add(add(offset, _1), 0x20), end) { revert(0, 0) }\n calldatacopy(add(array_1, 0x20), add(offset, 0x20), _1)\n mstore(add(add(array_1, _1), 0x20), 0)\n array := array_1\n }\n function abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 128) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n value2 := calldataload(add(headStart, 64))\n let offset := calldataload(add(headStart, 96))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n value3 := abi_decode_bytes(add(headStart, offset), dataEnd)\n }\n function abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, shl(224, 0xffffffff)))\n }\n function abi_decode_tuple_t_addresst_address(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n }\n function abi_decode_string_calldata(offset, end) -> arrayPos, length\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n length := calldataload(offset)\n if gt(length, 0xffffffffffffffff) { revert(0, 0) }\n arrayPos := add(offset, 0x20)\n if gt(add(add(offset, length), 0x20), end) { revert(0, 0) }\n }\n function abi_decode_tuple_t_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_uint256(headStart, dataEnd) -> value0, value1, value2, value3, value4, value5, value6\n {\n if slt(sub(dataEnd, headStart), 192) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n value1 := calldataload(add(headStart, 32))\n let offset := calldataload(add(headStart, 64))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n let value2_1, value3_1 := abi_decode_string_calldata(add(headStart, offset), dataEnd)\n value2 := value2_1\n value3 := value3_1\n let value_1 := calldataload(add(headStart, 96))\n validator_revert_address(value_1)\n value4 := value_1\n value5 := calldataload(add(headStart, 128))\n value6 := calldataload(add(headStart, 160))\n }\n function abi_encode_tuple_t_address__to_t_address__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, sub(shl(160, 1), 1)))\n }\n function abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 96) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n value1 := calldataload(add(headStart, 32))\n let offset := calldataload(add(headStart, 64))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n let value2_1, value3_1 := abi_decode_string_calldata(add(headStart, offset), dataEnd)\n value2 := value2_1\n value3 := value3_1\n }\n function abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value0) -> tail\n {\n let _1 := 32\n mstore(headStart, _1)\n let length := mload(value0)\n mstore(add(headStart, _1), length)\n let i := 0\n for { } lt(i, length) { i := add(i, _1) }\n {\n mstore(add(add(headStart, i), 64), mload(add(add(value0, i), _1)))\n }\n mstore(add(add(headStart, length), 64), 0)\n tail := add(add(headStart, and(add(length, 31), not(31))), 64)\n }\n function abi_decode_array_uint256_dyn(offset, end) -> array\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n let _1 := calldataload(offset)\n let _2 := 0x20\n if gt(_1, 0xffffffffffffffff) { panic_error_0x41() }\n let _3 := shl(5, _1)\n let dst := allocate_memory(add(_3, _2))\n let dst_1 := dst\n mstore(dst, _1)\n dst := add(dst, _2)\n let srcEnd := add(add(offset, _3), _2)\n if gt(srcEnd, end) { revert(0, 0) }\n let src := add(offset, _2)\n for { } lt(src, srcEnd) { src := add(src, _2) }\n {\n mstore(dst, calldataload(src))\n dst := add(dst, _2)\n }\n array := dst_1\n }\n function abi_decode_tuple_t_addresst_addresst_array$_t_uint256_$dyn_memory_ptrt_array$_t_uint256_$dyn_memory_ptrt_bytes_memory_ptr(headStart, dataEnd) -> value0, value1, value2, value3, value4\n {\n if slt(sub(dataEnd, headStart), 160) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n let offset := calldataload(add(headStart, 64))\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n value2 := abi_decode_array_uint256_dyn(add(headStart, offset), dataEnd)\n let offset_1 := calldataload(add(headStart, 96))\n if gt(offset_1, _1) { revert(0, 0) }\n value3 := abi_decode_array_uint256_dyn(add(headStart, offset_1), dataEnd)\n let offset_2 := calldataload(add(headStart, 128))\n if gt(offset_2, _1) { revert(0, 0) }\n value4 := abi_decode_bytes(add(headStart, offset_2), dataEnd)\n }\n function abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, value0)\n }\n function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n value0 := calldataload(headStart)\n }\n function abi_decode_tuple_t_addresst_addresst_uint256t_uint256t_bytes_memory_ptr(headStart, dataEnd) -> value0, value1, value2, value3, value4\n {\n if slt(sub(dataEnd, headStart), 160) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n value2 := calldataload(add(headStart, 64))\n value3 := calldataload(add(headStart, 96))\n let offset := calldataload(add(headStart, 128))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n value4 := abi_decode_bytes(add(headStart, offset), dataEnd)\n }\n function abi_encode_tuple_t_uint256_t_address_t_uint256__to_t_uint256_t_address_t_uint256__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n tail := add(headStart, 96)\n mstore(headStart, value0)\n mstore(add(headStart, 32), and(value1, sub(shl(160, 1), 1)))\n mstore(add(headStart, 64), value2)\n }\n function abi_decode_tuple_t_address(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n }\n function panic_error_0x32()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x32)\n revert(0, 0x24)\n }\n function abi_decode_tuple_t_bool(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := calldataload(headStart)\n if iszero(eq(value, iszero(iszero(value)))) { revert(0, 0) }\n value0 := value\n }\n function abi_encode_tuple_t_address_t_address_t_bool__to_t_address_t_address_t_bool__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n tail := add(headStart, 96)\n let _1 := sub(shl(160, 1), 1)\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), and(value1, _1))\n mstore(add(headStart, 64), iszero(iszero(value2)))\n }\n function panic_error_0x11()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x11)\n revert(0, 0x24)\n }\n function increment_t_uint256(value) -> ret\n {\n if eq(value, not(0)) { panic_error_0x11() }\n ret := add(value, 1)\n }\n function abi_decode_tuple_t_address_fromMemory(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := mload(headStart)\n validator_revert_address(value)\n value0 := value\n }\n function abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value1, value0) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), value1)\n calldatacopy(add(headStart, 64), value0, value1)\n mstore(add(add(headStart, value1), 64), 0)\n tail := add(add(headStart, and(add(value1, 31), not(31))), 64)\n }\n function checked_add_t_uint256(x, y) -> sum\n {\n sum := add(x, y)\n if gt(x, sum) { panic_error_0x11() }\n }\n function abi_decode_tuple_t_uint256t_address_payablet_uint256_fromMemory(headStart, dataEnd) -> value0, value1, value2\n {\n if slt(sub(dataEnd, headStart), 96) { revert(0, 0) }\n value0 := mload(headStart)\n let value := mload(add(headStart, 32))\n validator_revert_address(value)\n value1 := value\n value2 := mload(add(headStart, 64))\n }\n function abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed(pos, value1, value0) -> end\n {\n calldatacopy(pos, value0, value1)\n let _1 := add(pos, value1)\n mstore(_1, 0)\n end := _1\n }\n}","id":11,"language":"Yul","name":"#utility.yul"}],"immutableReferences":{},"linkReferences":{},"object":"6080604052600436106100e15760003560e01c8063a4e2d6341161007f578063dd46706411610059578063dd46706414610294578063f23a6e61146102b4578063fc0c546a146102e0578063fe9fbb801461031857600080fd5b8063a4e2d6341461022d578063bc197c8114610244578063ce0617ec1461027057600080fd5b80631f9838b5116100bb5780631f9838b51461017d5780633ff956cc146101b85780638da5cb5b146101e05780639e5d4c491461020d57600080fd5b806301ffc9a7146100ed578063039721b114610122578063150b7a021461014457600080fd5b366100e857005b600080fd5b3480156100f957600080fd5b5061010d61010836600461099f565b610338565b60405190151581526020015b60405180910390f35b34801561012e57600080fd5b5061014261013d366004610a1c565b61039f565b005b34801561015057600080fd5b5061016461015f366004610b57565b610568565b6040516001600160e01b03199091168152602001610119565b34801561018957600080fd5b5061010d610198366004610bc3565b600160209081526000928352604080842090915290825290205460ff1681565b3480156101c457600080fd5b5061010d6101d3366004610c3e565b6000979650505050505050565b3480156101ec57600080fd5b506101f56105d0565b6040516001600160a01b039091168152602001610119565b61022061021b366004610cc4565b610666565b6040516101199190610d14565b34801561023957600080fd5b50600054421061010d565b34801561025057600080fd5b5061016461025f366004610de2565b63bc197c8160e01b95945050505050565b34801561027c57600080fd5b5061028660005481565b604051908152602001610119565b3480156102a057600080fd5b506101426102af366004610e90565b61070a565b3480156102c057600080fd5b506101646102cf366004610ea9565b63f23a6e6160e01b95945050505050565b3480156102ec57600080fd5b506102f56107cf565b604080519384526001600160a01b03909216602084015290820152606001610119565b34801561032457600080fd5b5061010d610333366004610f12565b6107e7565b6000806001600160e01b031983166301ffc9a760e01b148061036a57506001600160e01b03198316630271189760e51b145b8061038557506001600160e01b03198316631dfe9a6f60e31b145b905080156103965750600192915050565b50600092915050565b6000544210156103c257604051636315bfbb60e01b815260040160405180910390fd5b60006103cc6105d0565b9050336001600160a01b038216146103f75760405163ea8e4eb560e01b815260040160405180910390fd5b838281146104185760405163b4fa3fb360e01b815260040160405180910390fd5b60005b8181101561055f5784848281811061043557610435610f2f565b905060200201602081019061044a9190610f45565b6001600160a01b03841660009081526001602052604081209089898581811061047557610475610f2f565b905060200201602081019061048a9190610f12565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f394777a58092892d136a90c4bb7e4350c72ac50fba6a0208128677f36527dcf5838888848181106104e6576104e6610f2f565b90506020020160208101906104fb9190610f12565b87878581811061050d5761050d610f2f565b90506020020160208101906105229190610f45565b604080516001600160a01b03948516815293909216602084015215159082015260600160405180910390a18061055781610f7d565b91505061041b565b50505050505050565b6000806000806105766108d0565b925092509250468314801561059357506001600160a01b03821633145b801561059e57508581145b156105bc5760405163b79e3f3f60e01b815260040160405180910390fd5b50630a85bd0160e11b979650505050505050565b6000806000806105de6108d0565b9250925092504683146105f5576000935050505090565b6040516331a9108f60e11b8152600481018290526001600160a01b03831690636352211e90602401602060405180830381865afa15801561063a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065e9190610f96565b935050505090565b6060610671336107e7565b61068e5760405163ea8e4eb560e01b815260040160405180910390fd5b6000544210156106b157604051636315bfbb60e01b815260040160405180910390fd5b83856001600160a01b03167f47d99ad340f52da66535aff7e10da1ceb85a32bcbd9fa1c42314d194545e14d285856040516106ed929190610fb3565b60405180910390a361070185858585610923565b95945050505050565b6107126105d0565b6001600160a01b0316336001600160a01b0316146107435760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561076657604051636315bfbb60e01b815260040160405180910390fd5b610774426301e13380610fe2565b811115610794576040516301814f7d60e31b815260040160405180910390fd5b60008190556040518181527fa7b24c66dd3269a292a60b3facdbb8f3e7557d1e19e64d99e0d6ee7250be63ad9060200160405180910390a150565b60008060006107dc6108d0565b925092509250909192565b60008060006107f46108d0565b6040516331a9108f60e11b8152600481018290529194509250600091506001600160a01b03841690636352211e90602401602060405180830381865afa158015610842573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108669190610f96565b9050806001600160a01b0316856001600160a01b03160361088c57506001949350505050565b6001600160a01b0380821660009081526001602090815260408083209389168352929052205460ff16156108c557506001949350505050565b506000949350505050565b604080516060808252608082019092526000918291829182919060208201818036833701905050905060ad604d60208301303c808060200190518101906109179190610ffb565b93509350935050909192565b60606000856001600160a01b0316858585604051610942929190611034565b60006040518083038185875af1925050503d806000811461097f576040519150601f19603f3d011682016040523d82523d6000602084013e610984565b606091505b50925090508061099657815160208301fd5b50949350505050565b6000602082840312156109b157600080fd5b81356001600160e01b0319811681146109c957600080fd5b9392505050565b60008083601f8401126109e257600080fd5b50813567ffffffffffffffff8111156109fa57600080fd5b6020830191508360208260051b8501011115610a1557600080fd5b9250929050565b60008060008060408587031215610a3257600080fd5b843567ffffffffffffffff80821115610a4a57600080fd5b610a56888389016109d0565b90965094506020870135915080821115610a6f57600080fd5b50610a7c878288016109d0565b95989497509550505050565b6001600160a01b0381168114610a9d57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610adf57610adf610aa0565b604052919050565b600082601f830112610af857600080fd5b813567ffffffffffffffff811115610b1257610b12610aa0565b610b25601f8201601f1916602001610ab6565b818152846020838601011115610b3a57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215610b6d57600080fd5b8435610b7881610a88565b93506020850135610b8881610a88565b925060408501359150606085013567ffffffffffffffff811115610bab57600080fd5b610bb787828801610ae7565b91505092959194509250565b60008060408385031215610bd657600080fd5b8235610be181610a88565b91506020830135610bf181610a88565b809150509250929050565b60008083601f840112610c0e57600080fd5b50813567ffffffffffffffff811115610c2657600080fd5b602083019150836020828501011115610a1557600080fd5b600080600080600080600060c0888a031215610c5957600080fd5b8735610c6481610a88565b965060208801359550604088013567ffffffffffffffff811115610c8757600080fd5b610c938a828b01610bfc565b9096509450506060880135610ca781610a88565b969995985093969295946080840135945060a09093013592915050565b60008060008060608587031215610cda57600080fd5b8435610ce581610a88565b935060208501359250604085013567ffffffffffffffff811115610d0857600080fd5b610a7c87828801610bfc565b600060208083528351808285015260005b81811015610d4157858101830151858201604001528201610d25565b506000604082860101526040601f19601f8301168501019250505092915050565b600082601f830112610d7357600080fd5b8135602067ffffffffffffffff821115610d8f57610d8f610aa0565b8160051b610d9e828201610ab6565b9283528481018201928281019087851115610db857600080fd5b83870192505b84831015610dd757823582529183019190830190610dbe565b979650505050505050565b600080600080600060a08688031215610dfa57600080fd5b8535610e0581610a88565b94506020860135610e1581610a88565b9350604086013567ffffffffffffffff80821115610e3257600080fd5b610e3e89838a01610d62565b94506060880135915080821115610e5457600080fd5b610e6089838a01610d62565b93506080880135915080821115610e7657600080fd5b50610e8388828901610ae7565b9150509295509295909350565b600060208284031215610ea257600080fd5b5035919050565b600080600080600060a08688031215610ec157600080fd5b8535610ecc81610a88565b94506020860135610edc81610a88565b93506040860135925060608601359150608086013567ffffffffffffffff811115610f0657600080fd5b610e8388828901610ae7565b600060208284031215610f2457600080fd5b81356109c981610a88565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610f5757600080fd5b813580151581146109c957600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610f8f57610f8f610f67565b5060010190565b600060208284031215610fa857600080fd5b81516109c981610a88565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b80820180821115610ff557610ff5610f67565b92915050565b60008060006060848603121561101057600080fd5b83519250602084015161102281610a88565b80925050604084015190509250925092565b818382376000910190815291905056fea264697066735822122072de4bddfaa6ccde56ae43975a9a19ad2f99076f5bc8ab728314c1075b86c27564736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xE1 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0xA4E2D634 GT PUSH2 0x7F JUMPI DUP1 PUSH4 0xDD467064 GT PUSH2 0x59 JUMPI DUP1 PUSH4 0xDD467064 EQ PUSH2 0x294 JUMPI DUP1 PUSH4 0xF23A6E61 EQ PUSH2 0x2B4 JUMPI DUP1 PUSH4 0xFC0C546A EQ PUSH2 0x2E0 JUMPI DUP1 PUSH4 0xFE9FBB80 EQ PUSH2 0x318 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0xA4E2D634 EQ PUSH2 0x22D JUMPI DUP1 PUSH4 0xBC197C81 EQ PUSH2 0x244 JUMPI DUP1 PUSH4 0xCE0617EC EQ PUSH2 0x270 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1F9838B5 GT PUSH2 0xBB JUMPI DUP1 PUSH4 0x1F9838B5 EQ PUSH2 0x17D JUMPI DUP1 PUSH4 0x3FF956CC EQ PUSH2 0x1B8 JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x1E0 JUMPI DUP1 PUSH4 0x9E5D4C49 EQ PUSH2 0x20D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1FFC9A7 EQ PUSH2 0xED JUMPI DUP1 PUSH4 0x39721B1 EQ PUSH2 0x122 JUMPI DUP1 PUSH4 0x150B7A02 EQ PUSH2 0x144 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST CALLDATASIZE PUSH2 0xE8 JUMPI STOP JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xF9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x10D PUSH2 0x108 CALLDATASIZE PUSH1 0x4 PUSH2 0x99F JUMP JUMPDEST PUSH2 0x338 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x12E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x142 PUSH2 0x13D CALLDATASIZE PUSH1 0x4 PUSH2 0xA1C JUMP JUMPDEST PUSH2 0x39F JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x150 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x164 PUSH2 0x15F CALLDATASIZE PUSH1 0x4 PUSH2 0xB57 JUMP JUMPDEST PUSH2 0x568 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x119 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x189 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x10D PUSH2 0x198 CALLDATASIZE PUSH1 0x4 PUSH2 0xBC3 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1C4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x10D PUSH2 0x1D3 CALLDATASIZE PUSH1 0x4 PUSH2 0xC3E JUMP JUMPDEST PUSH1 0x0 SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1EC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1F5 PUSH2 0x5D0 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x119 JUMP JUMPDEST PUSH2 0x220 PUSH2 0x21B CALLDATASIZE PUSH1 0x4 PUSH2 0xCC4 JUMP JUMPDEST PUSH2 0x666 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x119 SWAP2 SWAP1 PUSH2 0xD14 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x239 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x0 SLOAD TIMESTAMP LT PUSH2 0x10D JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x250 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x164 PUSH2 0x25F CALLDATASIZE PUSH1 0x4 PUSH2 0xDE2 JUMP JUMPDEST PUSH4 0xBC197C81 PUSH1 0xE0 SHL SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x27C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x286 PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x119 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2A0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x142 PUSH2 0x2AF CALLDATASIZE PUSH1 0x4 PUSH2 0xE90 JUMP JUMPDEST PUSH2 0x70A JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2C0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x164 PUSH2 0x2CF CALLDATASIZE PUSH1 0x4 PUSH2 0xEA9 JUMP JUMPDEST PUSH4 0xF23A6E61 PUSH1 0xE0 SHL SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2EC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2F5 PUSH2 0x7CF JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP4 DUP5 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE SWAP1 DUP3 ADD MSTORE PUSH1 0x60 ADD PUSH2 0x119 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x324 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x10D PUSH2 0x333 CALLDATASIZE PUSH1 0x4 PUSH2 0xF12 JUMP JUMPDEST PUSH2 0x7E7 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x1FFC9A7 PUSH1 0xE0 SHL EQ DUP1 PUSH2 0x36A JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x2711897 PUSH1 0xE5 SHL EQ JUMPDEST DUP1 PUSH2 0x385 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x1DFE9A6F PUSH1 0xE3 SHL EQ JUMPDEST SWAP1 POP DUP1 ISZERO PUSH2 0x396 JUMPI POP PUSH1 0x1 SWAP3 SWAP2 POP POP JUMP JUMPDEST POP PUSH1 0x0 SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x3C2 JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x3CC PUSH2 0x5D0 JUMP JUMPDEST SWAP1 POP CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND EQ PUSH2 0x3F7 JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 DUP3 DUP2 EQ PUSH2 0x418 JUMPI PUSH1 0x40 MLOAD PUSH4 0xB4FA3FB3 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x55F JUMPI DUP5 DUP5 DUP3 DUP2 DUP2 LT PUSH2 0x435 JUMPI PUSH2 0x435 PUSH2 0xF2F JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x44A SWAP2 SWAP1 PUSH2 0xF45 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 SWAP1 DUP10 DUP10 DUP6 DUP2 DUP2 LT PUSH2 0x475 JUMPI PUSH2 0x475 PUSH2 0xF2F JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x48A SWAP2 SWAP1 PUSH2 0xF12 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP2 MSTORE PUSH1 0x20 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 ADD PUSH1 0x0 KECCAK256 DUP1 SLOAD PUSH1 0xFF NOT AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH32 0x394777A58092892D136A90C4BB7E4350C72AC50FBA6A0208128677F36527DCF5 DUP4 DUP9 DUP9 DUP5 DUP2 DUP2 LT PUSH2 0x4E6 JUMPI PUSH2 0x4E6 PUSH2 0xF2F JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x4FB SWAP2 SWAP1 PUSH2 0xF12 JUMP JUMPDEST DUP8 DUP8 DUP6 DUP2 DUP2 LT PUSH2 0x50D JUMPI PUSH2 0x50D PUSH2 0xF2F JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x522 SWAP2 SWAP1 PUSH2 0xF45 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP5 DUP6 AND DUP2 MSTORE SWAP4 SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE ISZERO ISZERO SWAP1 DUP3 ADD MSTORE PUSH1 0x60 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 DUP1 PUSH2 0x557 DUP2 PUSH2 0xF7D JUMP JUMPDEST SWAP2 POP POP PUSH2 0x41B JUMP JUMPDEST POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x576 PUSH2 0x8D0 JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP CHAINID DUP4 EQ DUP1 ISZERO PUSH2 0x593 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND CALLER EQ JUMPDEST DUP1 ISZERO PUSH2 0x59E JUMPI POP DUP6 DUP2 EQ JUMPDEST ISZERO PUSH2 0x5BC JUMPI PUSH1 0x40 MLOAD PUSH4 0xB79E3F3F PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP PUSH4 0xA85BD01 PUSH1 0xE1 SHL SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x5DE PUSH2 0x8D0 JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP CHAINID DUP4 EQ PUSH2 0x5F5 JUMPI PUSH1 0x0 SWAP4 POP POP POP POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x31A9108F PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND SWAP1 PUSH4 0x6352211E SWAP1 PUSH1 0x24 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x63A JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x65E SWAP2 SWAP1 PUSH2 0xF96 JUMP JUMPDEST SWAP4 POP POP POP POP SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH2 0x671 CALLER PUSH2 0x7E7 JUMP JUMPDEST PUSH2 0x68E JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x6B1 JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH32 0x47D99AD340F52DA66535AFF7E10DA1CEB85A32BCBD9FA1C42314D194545E14D2 DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0x6ED SWAP3 SWAP2 SWAP1 PUSH2 0xFB3 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 PUSH2 0x701 DUP6 DUP6 DUP6 DUP6 PUSH2 0x923 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0x712 PUSH2 0x5D0 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ PUSH2 0x743 JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x766 JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH2 0x774 TIMESTAMP PUSH4 0x1E13380 PUSH2 0xFE2 JUMP JUMPDEST DUP2 GT ISZERO PUSH2 0x794 JUMPI PUSH1 0x40 MLOAD PUSH4 0x1814F7D PUSH1 0xE3 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 DUP2 SWAP1 SSTORE PUSH1 0x40 MLOAD DUP2 DUP2 MSTORE PUSH32 0xA7B24C66DD3269A292A60B3FACDBB8F3E7557D1E19E64D99E0D6EE7250BE63AD SWAP1 PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x7DC PUSH2 0x8D0 JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP SWAP1 SWAP2 SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x7F4 PUSH2 0x8D0 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x31A9108F PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE SWAP2 SWAP5 POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND SWAP1 PUSH4 0x6352211E SWAP1 PUSH1 0x24 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x842 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x866 SWAP2 SWAP1 PUSH2 0xF96 JUMP JUMPDEST SWAP1 POP DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SUB PUSH2 0x88C JUMPI POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP1 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP10 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x8C5 JUMPI POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST POP PUSH1 0x0 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 DUP1 DUP3 MSTORE PUSH1 0x80 DUP3 ADD SWAP1 SWAP3 MSTORE PUSH1 0x0 SWAP2 DUP3 SWAP2 DUP3 SWAP2 DUP3 SWAP2 SWAP1 PUSH1 0x20 DUP3 ADD DUP2 DUP1 CALLDATASIZE DUP4 CALLDATACOPY ADD SWAP1 POP POP SWAP1 POP PUSH1 0xAD PUSH1 0x4D PUSH1 0x20 DUP4 ADD ADDRESS EXTCODECOPY DUP1 DUP1 PUSH1 0x20 ADD SWAP1 MLOAD DUP2 ADD SWAP1 PUSH2 0x917 SWAP2 SWAP1 PUSH2 0xFFB JUMP JUMPDEST SWAP4 POP SWAP4 POP SWAP4 POP POP SWAP1 SWAP2 SWAP3 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP6 DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0x942 SWAP3 SWAP2 SWAP1 PUSH2 0x1034 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 GAS CALL SWAP3 POP POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0x97F JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0x984 JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP3 POP SWAP1 POP DUP1 PUSH2 0x996 JUMPI DUP2 MLOAD PUSH1 0x20 DUP4 ADD REVERT JUMPDEST POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x9B1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP2 AND DUP2 EQ PUSH2 0x9C9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x9E2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x9FA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 PUSH1 0x5 SHL DUP6 ADD ADD GT ISZERO PUSH2 0xA15 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x40 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xA32 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xA4A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xA56 DUP9 DUP4 DUP10 ADD PUSH2 0x9D0 JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP PUSH1 0x20 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xA6F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xA7C DUP8 DUP3 DUP9 ADD PUSH2 0x9D0 JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0xA9D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT AND DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0xADF JUMPI PUSH2 0xADF PUSH2 0xAA0 JUMP JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xAF8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xB12 JUMPI PUSH2 0xB12 PUSH2 0xAA0 JUMP JUMPDEST PUSH2 0xB25 PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT AND PUSH1 0x20 ADD PUSH2 0xAB6 JUMP JUMPDEST DUP2 DUP2 MSTORE DUP5 PUSH1 0x20 DUP4 DUP7 ADD ADD GT ISZERO PUSH2 0xB3A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 PUSH1 0x20 DUP6 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 SWAP2 DUP2 ADD PUSH1 0x20 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xB6D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xB78 DUP2 PUSH2 0xA88 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH2 0xB88 DUP2 PUSH2 0xA88 JUMP JUMPDEST SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD SWAP2 POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xBAB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xBB7 DUP8 DUP3 DUP9 ADD PUSH2 0xAE7 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xBD6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH2 0xBE1 DUP2 PUSH2 0xA88 JUMP JUMPDEST SWAP2 POP PUSH1 0x20 DUP4 ADD CALLDATALOAD PUSH2 0xBF1 DUP2 PUSH2 0xA88 JUMP JUMPDEST DUP1 SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0xC0E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xC26 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0xA15 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xC0 DUP9 DUP11 SUB SLT ISZERO PUSH2 0xC59 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 CALLDATALOAD PUSH2 0xC64 DUP2 PUSH2 0xA88 JUMP JUMPDEST SWAP7 POP PUSH1 0x20 DUP9 ADD CALLDATALOAD SWAP6 POP PUSH1 0x40 DUP9 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xC87 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xC93 DUP11 DUP3 DUP12 ADD PUSH2 0xBFC JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP POP PUSH1 0x60 DUP9 ADD CALLDATALOAD PUSH2 0xCA7 DUP2 PUSH2 0xA88 JUMP JUMPDEST SWAP7 SWAP10 SWAP6 SWAP9 POP SWAP4 SWAP7 SWAP3 SWAP6 SWAP5 PUSH1 0x80 DUP5 ADD CALLDATALOAD SWAP5 POP PUSH1 0xA0 SWAP1 SWAP4 ADD CALLDATALOAD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x60 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xCDA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xCE5 DUP2 PUSH2 0xA88 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xD08 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xA7C DUP8 DUP3 DUP9 ADD PUSH2 0xBFC JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 MSTORE DUP4 MLOAD DUP1 DUP3 DUP6 ADD MSTORE PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xD41 JUMPI DUP6 DUP2 ADD DUP4 ADD MLOAD DUP6 DUP3 ADD PUSH1 0x40 ADD MSTORE DUP3 ADD PUSH2 0xD25 JUMP JUMPDEST POP PUSH1 0x0 PUSH1 0x40 DUP3 DUP7 ADD ADD MSTORE PUSH1 0x40 PUSH1 0x1F NOT PUSH1 0x1F DUP4 ADD AND DUP6 ADD ADD SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xD73 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH1 0x20 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0xD8F JUMPI PUSH2 0xD8F PUSH2 0xAA0 JUMP JUMPDEST DUP2 PUSH1 0x5 SHL PUSH2 0xD9E DUP3 DUP3 ADD PUSH2 0xAB6 JUMP JUMPDEST SWAP3 DUP4 MSTORE DUP5 DUP2 ADD DUP3 ADD SWAP3 DUP3 DUP2 ADD SWAP1 DUP8 DUP6 GT ISZERO PUSH2 0xDB8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 DUP8 ADD SWAP3 POP JUMPDEST DUP5 DUP4 LT ISZERO PUSH2 0xDD7 JUMPI DUP3 CALLDATALOAD DUP3 MSTORE SWAP2 DUP4 ADD SWAP2 SWAP1 DUP4 ADD SWAP1 PUSH2 0xDBE JUMP JUMPDEST SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xDFA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xE05 DUP2 PUSH2 0xA88 JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH2 0xE15 DUP2 PUSH2 0xA88 JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xE32 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xE3E DUP10 DUP4 DUP11 ADD PUSH2 0xD62 JUMP JUMPDEST SWAP5 POP PUSH1 0x60 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xE54 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xE60 DUP10 DUP4 DUP11 ADD PUSH2 0xD62 JUMP JUMPDEST SWAP4 POP PUSH1 0x80 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xE76 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xE83 DUP9 DUP3 DUP10 ADD PUSH2 0xAE7 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 SWAP1 SWAP4 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xEA2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xEC1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xECC DUP2 PUSH2 0xA88 JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH2 0xEDC DUP2 PUSH2 0xA88 JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD SWAP3 POP PUSH1 0x60 DUP7 ADD CALLDATALOAD SWAP2 POP PUSH1 0x80 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xF06 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xE83 DUP9 DUP3 DUP10 ADD PUSH2 0xAE7 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xF24 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x9C9 DUP2 PUSH2 0xA88 JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x32 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xF57 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP1 ISZERO ISZERO DUP2 EQ PUSH2 0x9C9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x11 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x1 DUP3 ADD PUSH2 0xF8F JUMPI PUSH2 0xF8F PUSH2 0xF67 JUMP JUMPDEST POP PUSH1 0x1 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xFA8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x9C9 DUP2 PUSH2 0xA88 JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE DUP2 PUSH1 0x20 DUP3 ADD MSTORE DUP2 DUP4 PUSH1 0x40 DUP4 ADD CALLDATACOPY PUSH1 0x0 DUP2 DUP4 ADD PUSH1 0x40 SWAP1 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x1F SWAP1 SWAP3 ADD PUSH1 0x1F NOT AND ADD ADD SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 DUP3 ADD DUP1 DUP3 GT ISZERO PUSH2 0xFF5 JUMPI PUSH2 0xFF5 PUSH2 0xF67 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x1010 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 MLOAD SWAP3 POP PUSH1 0x20 DUP5 ADD MLOAD PUSH2 0x1022 DUP2 PUSH2 0xA88 JUMP JUMPDEST DUP1 SWAP3 POP POP PUSH1 0x40 DUP5 ADD MLOAD SWAP1 POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST DUP2 DUP4 DUP3 CALLDATACOPY PUSH1 0x0 SWAP2 ADD SWAP1 DUP2 MSTORE SWAP2 SWAP1 POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 PUSH19 0xDE4BDDFAA6CCDE56AE43975A9A19AD2F99076F JUMPDEST 0xC8 0xAB PUSH19 0x8314C1075B86C27564736F6C63430008110033 ","sourceMap":"161:344:6:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4889:393:7;;;;;;;;;;-1:-1:-1;4889:393:7;;;;;:::i;:::-;;:::i;:::-;;;470:14:11;;463:22;445:41;;433:2;418:18;4889:393:7;;;;;;;;2357:528;;;;;;;;;;-1:-1:-1;2357:528:7;;;;;:::i;:::-;;:::i;:::-;;5427:526;;;;;;;;;;-1:-1:-1;5427:526:7;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;;3559:33:11;;;3541:52;;3529:2;3514:18;5427:526:7;3397:202:11;965:63:7;;;;;;;;;;-1:-1:-1;965:63:7;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;221:282:6;;;;;;;;;;-1:-1:-1;221:282:6;;;;;:::i;:::-;433:12;221:282;;;;;;;;;;3891:310:7;;;;;;;;;;;;;:::i;:::-;;;-1:-1:-1;;;;;5413:32:11;;;5395:51;;5383:2;5368:18;3891:310:7;5249:203:11;2029:265:7;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;3276:100::-;;;;;;;;;;-1:-1:-1;3317:4:7;3340:11;3354:15;-1:-1:-1;3276:100:7;;6356:244;;;;;;;;;;-1:-1:-1;6356:244:7;;;;;:::i;:::-;-1:-1:-1;;;6356:244:7;;;;;;;;871:26;;;;;;;;;;;;;;;;;;;8565:25:11;;;8553:2;8538:18;871:26:7;8419:177:11;2948:249:7;;;;;;;;;;-1:-1:-1;2948:249:7;;;;;:::i;:::-;;:::i;6043:216::-;;;;;;;;;;-1:-1:-1;6043:216:7;;;;;:::i;:::-;-1:-1:-1;;;6043:216:7;;;;;;;;3508:220;;;;;;;;;;;;;:::i;:::-;;;;9727:25:11;;;-1:-1:-1;;;;;9788:32:11;;;9783:2;9768:18;;9761:60;9837:18;;;9830:34;9715:2;9700:18;3508:220:7;9525:345:11;4272:480:7;;;;;;;;;;-1:-1:-1;4272:480:7;;;;;:::i;:::-;;:::i;4889:393::-;4999:4;;-1:-1:-1;;;;;;5041:40:7;;-1:-1:-1;;;5041:40:7;;:105;;-1:-1:-1;;;;;;;5097:49:7;;-1:-1:-1;;;5097:49:7;5041:105;:169;;;-1:-1:-1;;;;;;;5162:48:7;;-1:-1:-1;;;5162:48:7;5041:169;5019:191;;5225:14;5221:31;;;-1:-1:-1;5248:4:7;;4889:393;-1:-1:-1;;4889:393:7:o;5221:31::-;-1:-1:-1;5270:5:7;;4889:393;-1:-1:-1;;4889:393:7:o;2357:528::-;3317:4;3340:11;3354:15;-1:-1:-1;1722:38:7;;;1745:15;;-1:-1:-1;;;1745:15:7;;;;;;;;;;;1722:38;2493:14:::1;2510:7;:5;:7::i;:::-;2493:24:::0;-1:-1:-1;2531:10:7::1;-1:-1:-1::0;;;;;2531:20:7;::::1;;2527:48;;2560:15;;-1:-1:-1::0;;;2560:15:7::1;;;;;;;;;;;2527:48;2603:7:::0;2632:29;;::::1;2628:56;;2670:14;;-1:-1:-1::0;;;2670:14:7::1;;;;;;;;;;;2628:56;2700:9;2695:184;2719:6;2715:1;:10;2695:184;;;2780:12;;2793:1;2780:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;2746:19:7;::::1;;::::0;;;:11:::1;:19;::::0;;;;;2766:7;;2774:1;2766:10;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;2746:31:7::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;2746:31:7;:49;;-1:-1:-1;;2746:49:7::1;::::0;::::1;;::::0;;;::::1;::::0;;2814:54:::1;2832:6:::0;2840:7;;2848:1;2840:10;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;2852:12;;2865:1;2852:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;2814:54;::::0;;-1:-1:-1;;;;;10789:15:11;;;10771:34;;10841:15;;;;10836:2;10821:18;;10814:43;10900:14;10893:22;10873:18;;;10866:50;10721:2;10706:18;2814:54:7::1;;;;;;;2727:3:::0;::::1;::::0;::::1;:::i;:::-;;;;2695:184;;;;2483:402;;2357:528:::0;;;;:::o;5427:526::-;5578:6;5610:15;5639:21;5674:15;5702:25;:23;:25::i;:::-;5596:131;;;;;;5766:13;5755:7;:24;:67;;;;-1:-1:-1;;;;;;5795:27:7;;5812:10;5795:27;5755:67;:109;;;;;5849:15;5838:7;:26;5755:109;5738:160;;;5882:16;;-1:-1:-1;;;5882:16:7;;;;;;;;;;;5738:160;-1:-1:-1;;;;5916:30:7;5427:526;-1:-1:-1;;;;;;;5427:526:7:o;3891:310::-;3929:7;3962:15;3991:21;4026:15;4054:25;:23;:25::i;:::-;3948:131;;;;;;4105:13;4094:7;:24;4090:47;;4135:1;4120:17;;;;;3891:310;:::o;4090:47::-;4155:39;;-1:-1:-1;;;4155:39:7;;;;;8565:25:11;;;-1:-1:-1;;;;;4155:30:7;;;;;8538:18:11;;4155:39:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4148:46;;;;;3891:310;:::o;2029:265::-;2182:12;1559:24;1572:10;1559:12;:24::i;:::-;1554:53;;1592:15;;-1:-1:-1;;;1592:15:7;;;;;;;;;;;1554:53;3317:4;3340:11;3354:15;-1:-1:-1;1722:38:7::1;;;1745:15;;-1:-1:-1::0;;;1745:15:7::1;;;;;;;;;;;1722:38;2235:5:::2;2231:2;-1:-1:-1::0;;;;;2211:36:7::2;;2242:4;;2211:36;;;;;;;:::i;:::-;;;;;;;;2265:22;2271:2;2275:5;2282:4;;2265:5;:22::i;:::-;2258:29:::0;2029:265;-1:-1:-1;;;;;2029:265:7:o;2948:249::-;1387:7;:5;:7::i;:::-;-1:-1:-1;;;;;1373:21:7;:10;-1:-1:-1;;;;;1373:21:7;;1369:49;;1403:15;;-1:-1:-1;;;1403:15:7;;;;;;;;;;;1369:49;3317:4;3340:11;3354:15;-1:-1:-1;1722:38:7::1;;;1745:15;;-1:-1:-1::0;;;1745:15:7::1;;;;;;;;;;;1722:38;3045:26:::2;:15;3063:8;3045:26;:::i;:::-;3030:12;:41;3026:86;;;3092:20;;-1:-1:-1::0;;;3092:20:7::2;;;;;;;;;;;3026:86;3123:11;:26:::0;;;3165:25:::2;::::0;8565::11;;;3165::7::2;::::0;8553:2:11;8538:18;3165:25:7::2;;;;;;;2948:249:::0;:::o;3508:220::-;3585:15;3614:21;3649:15;3696:25;:23;:25::i;:::-;3689:32;;;;;;3508:220;;;:::o;4272:480::-;4331:4;4375:21;4410:15;4438:25;:23;:25::i;:::-;4490:39;;-1:-1:-1;;;4490:39:7;;;;;8565:25:11;;;4347:116:7;;-1:-1:-1;4347:116:7;-1:-1:-1;4473:14:7;;-1:-1:-1;;;;;;4490:30:7;;;;;8538:18:11;;4490:39:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4473:56;;4587:6;-1:-1:-1;;;;;4577:16:7;:6;-1:-1:-1;;;;;4577:16:7;;4573:33;;-1:-1:-1;4602:4:7;;4272:480;-1:-1:-1;;;;4272:480:7:o;4573:33::-;-1:-1:-1;;;;;4682:19:7;;;;;;;:11;:19;;;;;;;;:27;;;;;;;;;;;;4678:44;;;-1:-1:-1;4718:4:7;;4272:480;-1:-1:-1;;;;4272:480:7:o;4678:44::-;-1:-1:-1;4740:5:7;;4272:480;-1:-1:-1;;;;4272:480:7:o;90:406:10:-;263:15;;;273:4;263:15;;;;;;;;;167:7;;;;;;;;263:15;;;;;;;;;;;-1:-1:-1;263:15:10;241:37;;410:4;404;397;389:6;385:17;374:9;362:53;453:6;442:47;;;;;;;;;;;;:::i;:::-;435:54;;;;;;;90:406;;;:::o;6645:345:7:-;6756:19;6787:12;6829:2;-1:-1:-1;;;;;6829:7:7;6844:5;6851:4;;6829:27;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6809:47:7;-1:-1:-1;6809:47:7;-1:-1:-1;6809:47:7;6867:117;;6952:6;6946:13;6941:2;6933:6;6929:15;6922:38;6867:117;6777:213;6645:345;;;;;;:::o;14:286:11:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:11;;209:43;;199:71;;266:1;263;256:12;199:71;289:5;14:286;-1:-1:-1;;;14:286:11:o;497:367::-;560:8;570:6;624:3;617:4;609:6;605:17;601:27;591:55;;642:1;639;632:12;591:55;-1:-1:-1;665:20:11;;708:18;697:30;;694:50;;;740:1;737;730:12;694:50;777:4;769:6;765:17;753:29;;837:3;830:4;820:6;817:1;813:14;805:6;801:27;797:38;794:47;791:67;;;854:1;851;844:12;791:67;497:367;;;;;:::o;869:770::-;988:6;996;1004;1012;1065:2;1053:9;1044:7;1040:23;1036:32;1033:52;;;1081:1;1078;1071:12;1033:52;1121:9;1108:23;1150:18;1191:2;1183:6;1180:14;1177:34;;;1207:1;1204;1197:12;1177:34;1246:70;1308:7;1299:6;1288:9;1284:22;1246:70;:::i;:::-;1335:8;;-1:-1:-1;1220:96:11;-1:-1:-1;1423:2:11;1408:18;;1395:32;;-1:-1:-1;1439:16:11;;;1436:36;;;1468:1;1465;1458:12;1436:36;;1507:72;1571:7;1560:8;1549:9;1545:24;1507:72;:::i;:::-;869:770;;;;-1:-1:-1;1598:8:11;-1:-1:-1;;;;869:770:11:o;1644:131::-;-1:-1:-1;;;;;1719:31:11;;1709:42;;1699:70;;1765:1;1762;1755:12;1699:70;1644:131;:::o;1780:127::-;1841:10;1836:3;1832:20;1829:1;1822:31;1872:4;1869:1;1862:15;1896:4;1893:1;1886:15;1912:275;1983:2;1977:9;2048:2;2029:13;;-1:-1:-1;;2025:27:11;2013:40;;2083:18;2068:34;;2104:22;;;2065:62;2062:88;;;2130:18;;:::i;:::-;2166:2;2159:22;1912:275;;-1:-1:-1;1912:275:11:o;2192:530::-;2234:5;2287:3;2280:4;2272:6;2268:17;2264:27;2254:55;;2305:1;2302;2295:12;2254:55;2341:6;2328:20;2367:18;2363:2;2360:26;2357:52;;;2389:18;;:::i;:::-;2433:55;2476:2;2457:13;;-1:-1:-1;;2453:27:11;2482:4;2449:38;2433:55;:::i;:::-;2513:2;2504:7;2497:19;2559:3;2552:4;2547:2;2539:6;2535:15;2531:26;2528:35;2525:55;;;2576:1;2573;2566:12;2525:55;2641:2;2634:4;2626:6;2622:17;2615:4;2606:7;2602:18;2589:55;2689:1;2664:16;;;2682:4;2660:27;2653:38;;;;2668:7;2192:530;-1:-1:-1;;;2192:530:11:o;2727:665::-;2822:6;2830;2838;2846;2899:3;2887:9;2878:7;2874:23;2870:33;2867:53;;;2916:1;2913;2906:12;2867:53;2955:9;2942:23;2974:31;2999:5;2974:31;:::i;:::-;3024:5;-1:-1:-1;3081:2:11;3066:18;;3053:32;3094:33;3053:32;3094:33;:::i;:::-;3146:7;-1:-1:-1;3200:2:11;3185:18;;3172:32;;-1:-1:-1;3255:2:11;3240:18;;3227:32;3282:18;3271:30;;3268:50;;;3314:1;3311;3304:12;3268:50;3337:49;3378:7;3369:6;3358:9;3354:22;3337:49;:::i;:::-;3327:59;;;2727:665;;;;;;;:::o;3604:388::-;3672:6;3680;3733:2;3721:9;3712:7;3708:23;3704:32;3701:52;;;3749:1;3746;3739:12;3701:52;3788:9;3775:23;3807:31;3832:5;3807:31;:::i;:::-;3857:5;-1:-1:-1;3914:2:11;3899:18;;3886:32;3927:33;3886:32;3927:33;:::i;:::-;3979:7;3969:17;;;3604:388;;;;;:::o;3997:348::-;4049:8;4059:6;4113:3;4106:4;4098:6;4094:17;4090:27;4080:55;;4131:1;4128;4121:12;4080:55;-1:-1:-1;4154:20:11;;4197:18;4186:30;;4183:50;;;4229:1;4226;4219:12;4183:50;4266:4;4258:6;4254:17;4242:29;;4318:3;4311:4;4302:6;4294;4290:19;4286:30;4283:39;4280:59;;;4335:1;4332;4325:12;4350:894;4466:6;4474;4482;4490;4498;4506;4514;4567:3;4555:9;4546:7;4542:23;4538:33;4535:53;;;4584:1;4581;4574:12;4535:53;4623:9;4610:23;4642:31;4667:5;4642:31;:::i;:::-;4692:5;-1:-1:-1;4744:2:11;4729:18;;4716:32;;-1:-1:-1;4799:2:11;4784:18;;4771:32;4826:18;4815:30;;4812:50;;;4858:1;4855;4848:12;4812:50;4897:59;4948:7;4939:6;4928:9;4924:22;4897:59;:::i;:::-;4975:8;;-1:-1:-1;4871:85:11;-1:-1:-1;;5062:2:11;5047:18;;5034:32;5075:33;5034:32;5075:33;:::i;:::-;4350:894;;;;-1:-1:-1;4350:894:11;;;;5127:7;5181:3;5166:19;;5153:33;;-1:-1:-1;5233:3:11;5218:19;;;5205:33;;4350:894;-1:-1:-1;;4350:894:11:o;5457:613::-;5545:6;5553;5561;5569;5622:2;5610:9;5601:7;5597:23;5593:32;5590:52;;;5638:1;5635;5628:12;5590:52;5677:9;5664:23;5696:31;5721:5;5696:31;:::i;:::-;5746:5;-1:-1:-1;5798:2:11;5783:18;;5770:32;;-1:-1:-1;5853:2:11;5838:18;;5825:32;5880:18;5869:30;;5866:50;;;5912:1;5909;5902:12;5866:50;5951:59;6002:7;5993:6;5982:9;5978:22;5951:59;:::i;6075:546::-;6185:4;6214:2;6243;6232:9;6225:21;6275:6;6269:13;6318:6;6313:2;6302:9;6298:18;6291:34;6343:1;6353:140;6367:6;6364:1;6361:13;6353:140;;;6462:14;;;6458:23;;6452:30;6428:17;;;6447:2;6424:26;6417:66;6382:10;;6353:140;;;6357:3;6542:1;6537:2;6528:6;6517:9;6513:22;6509:31;6502:42;6612:2;6605;6601:7;6596:2;6588:6;6584:15;6580:29;6569:9;6565:45;6561:54;6553:62;;;;6075:546;;;;:::o;6626:712::-;6680:5;6733:3;6726:4;6718:6;6714:17;6710:27;6700:55;;6751:1;6748;6741:12;6700:55;6787:6;6774:20;6813:4;6836:18;6832:2;6829:26;6826:52;;;6858:18;;:::i;:::-;6904:2;6901:1;6897:10;6927:28;6951:2;6947;6943:11;6927:28;:::i;:::-;6989:15;;;7059;;;7055:24;;;7020:12;;;;7091:15;;;7088:35;;;7119:1;7116;7109:12;7088:35;7155:2;7147:6;7143:15;7132:26;;7167:142;7183:6;7178:3;7175:15;7167:142;;;7249:17;;7237:30;;7200:12;;;;7287;;;;7167:142;;;7327:5;6626:712;-1:-1:-1;;;;;;;6626:712:11:o;7343:1071::-;7497:6;7505;7513;7521;7529;7582:3;7570:9;7561:7;7557:23;7553:33;7550:53;;;7599:1;7596;7589:12;7550:53;7638:9;7625:23;7657:31;7682:5;7657:31;:::i;:::-;7707:5;-1:-1:-1;7764:2:11;7749:18;;7736:32;7777:33;7736:32;7777:33;:::i;:::-;7829:7;-1:-1:-1;7887:2:11;7872:18;;7859:32;7910:18;7940:14;;;7937:34;;;7967:1;7964;7957:12;7937:34;7990:61;8043:7;8034:6;8023:9;8019:22;7990:61;:::i;:::-;7980:71;;8104:2;8093:9;8089:18;8076:32;8060:48;;8133:2;8123:8;8120:16;8117:36;;;8149:1;8146;8139:12;8117:36;8172:63;8227:7;8216:8;8205:9;8201:24;8172:63;:::i;:::-;8162:73;;8288:3;8277:9;8273:19;8260:33;8244:49;;8318:2;8308:8;8305:16;8302:36;;;8334:1;8331;8324:12;8302:36;;8357:51;8400:7;8389:8;8378:9;8374:24;8357:51;:::i;:::-;8347:61;;;7343:1071;;;;;;;;:::o;8601:180::-;8660:6;8713:2;8701:9;8692:7;8688:23;8684:32;8681:52;;;8729:1;8726;8719:12;8681:52;-1:-1:-1;8752:23:11;;8601:180;-1:-1:-1;8601:180:11:o;8786:734::-;8890:6;8898;8906;8914;8922;8975:3;8963:9;8954:7;8950:23;8946:33;8943:53;;;8992:1;8989;8982:12;8943:53;9031:9;9018:23;9050:31;9075:5;9050:31;:::i;:::-;9100:5;-1:-1:-1;9157:2:11;9142:18;;9129:32;9170:33;9129:32;9170:33;:::i;:::-;9222:7;-1:-1:-1;9276:2:11;9261:18;;9248:32;;-1:-1:-1;9327:2:11;9312:18;;9299:32;;-1:-1:-1;9382:3:11;9367:19;;9354:33;9410:18;9399:30;;9396:50;;;9442:1;9439;9432:12;9396:50;9465:49;9506:7;9497:6;9486:9;9482:22;9465:49;:::i;9875:247::-;9934:6;9987:2;9975:9;9966:7;9962:23;9958:32;9955:52;;;10003:1;10000;9993:12;9955:52;10042:9;10029:23;10061:31;10086:5;10061:31;:::i;10127:127::-;10188:10;10183:3;10179:20;10176:1;10169:31;10219:4;10216:1;10209:15;10243:4;10240:1;10233:15;10259:273;10315:6;10368:2;10356:9;10347:7;10343:23;10339:32;10336:52;;;10384:1;10381;10374:12;10336:52;10423:9;10410:23;10476:5;10469:13;10462:21;10455:5;10452:32;10442:60;;10498:1;10495;10488:12;10927:127;10988:10;10983:3;10979:20;10976:1;10969:31;11019:4;11016:1;11009:15;11043:4;11040:1;11033:15;11059:135;11098:3;11119:17;;;11116:43;;11139:18;;:::i;:::-;-1:-1:-1;11186:1:11;11175:13;;11059:135::o;11199:251::-;11269:6;11322:2;11310:9;11301:7;11297:23;11293:32;11290:52;;;11338:1;11335;11328:12;11290:52;11370:9;11364:16;11389:31;11414:5;11389:31;:::i;11455:388::-;11612:2;11601:9;11594:21;11651:6;11646:2;11635:9;11631:18;11624:34;11708:6;11700;11695:2;11684:9;11680:18;11667:48;11764:1;11735:22;;;11759:2;11731:31;;;11724:42;;;;11827:2;11806:15;;;-1:-1:-1;;11802:29:11;11787:45;11783:54;;11455:388;-1:-1:-1;11455:388:11:o;11848:125::-;11913:9;;;11934:10;;;11931:36;;;11947:18;;:::i;:::-;11848:125;;;;:::o;11978:381::-;12074:6;12082;12090;12143:2;12131:9;12122:7;12118:23;12114:32;12111:52;;;12159:1;12156;12149:12;12111:52;12188:9;12182:16;12172:26;;12241:2;12230:9;12226:18;12220:25;12254:31;12279:5;12254:31;:::i;:::-;12304:5;12294:15;;;12349:2;12338:9;12334:18;12328:25;12318:35;;11978:381;;;;;:::o;12364:271::-;12547:6;12539;12534:3;12521:33;12503:3;12573:16;;12598:13;;;12573:16;12364:271;-1:-1:-1;12364:271:11:o"},"gasEstimates":{"creation":{"codeDepositCost":"843600","executionCost":"877","totalCost":"844477"},"external":{"covalentBond(address,uint256,string,address,uint256,uint256)":"infinite","executeCall(address,uint256,bytes)":"infinite","isAuthorized(address)":"infinite","isLocked()":"2315","lock(uint256)":"infinite","lockedUntil()":"2362","onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":"infinite","onERC1155Received(address,address,uint256,uint256,bytes)":"infinite","onERC721Received(address,address,uint256,bytes)":"infinite","owner()":"infinite","permissions(address,address)":"infinite","setPermissions(address[],bool[])":"infinite","supportsInterface(bytes4)":"538","token()":"infinite"}},"methodIdentifiers":{"covalentBond(address,uint256,string,address,uint256,uint256)":"3ff956cc","executeCall(address,uint256,bytes)":"9e5d4c49","isAuthorized(address)":"fe9fbb80","isLocked()":"a4e2d634","lock(uint256)":"dd467064","lockedUntil()":"ce0617ec","onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":"bc197c81","onERC1155Received(address,address,uint256,uint256,bytes)":"f23a6e61","onERC721Received(address,address,uint256,bytes)":"150b7a02","owner()":"8da5cb5b","permissions(address,address)":"1f9838b5","setPermissions(address[],bool[])":"039721b1","supportsInterface(bytes4)":"01ffc9a7","token()":"fc0c546a"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"AccountLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExceedsMaxLockTime\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInput\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAuthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnershipCycle\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lockedUntil\",\"type\":\"uint256\"}],\"name\":\"LockUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"OverrideUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"hasPermission\",\"type\":\"bool\"}],\"name\":\"PermissionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"TransactionExecuted\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"basketManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"covalentBond\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"executeCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"isAuthorized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isLocked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_lockedUntil\",\"type\":\"uint256\"}],\"name\":\"lock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lockedUntil\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"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\":\"receivedTokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"permissions\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"callers\",\"type\":\"address[]\"},{\"internalType\":\"bool[]\",\"name\":\"_permissions\",\"type\":\"bool[]\"}],\"name\":\"setPermissions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"executeCall(address,uint256,bytes)\":{\"details\":\"executes a low-level call against an account if the caller is authorized to make calls\"},\"isAuthorized(address)\":{\"details\":\"Returns the authorization status for a given caller\"},\"isLocked()\":{\"details\":\"returns the current lock status of the account as a boolean\"},\"lock(uint256)\":{\"details\":\"locks the account until a certain timestamp\"},\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"details\":\"Allows ERC-1155 token batches to be received. This function can be overriden.\"},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"details\":\"Allows ERC-1155 tokens to be received. This function can be overriden.\"},\"onERC721Received(address,address,uint256,bytes)\":{\"details\":\"Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle. This function can be overriden.\"},\"owner()\":{\"details\":\"Returns the owner of the ERC-721 token which owns this account. By default, the owner of the token has full permissions on the account.\"},\"setPermissions(address[],bool[])\":{\"details\":\"grants a given caller execution permissions\"},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if a given interfaceId is supported by this account. This method can be extended by an override.\"},\"token()\":{\"details\":\"Returns the EIP-155 chain ID, token contract address, and token ID for the token that owns this account.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ChargedParticlesAccount.sol\":\"ChargedParticlesAccount\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (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 *\\n * NOTE: 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 *\\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.\\n *\\n * NOTE: 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 *\\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\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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`.\\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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\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(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface 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 `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/ChargedParticlesAccount.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\nimport \\\"./MinimalisticAccount.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\ncontract ChargedParticlesAccount is MinimalisticAccount {\\n function covalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success) {\\n // Check permission\\n\\n // Transfer to self\\n }\\n}\",\"keccak256\":\"0xcd4b902b6094df42436d8ab6e3ed4775a44ba9ea76eab445e312bff65864024d\",\"license\":\"UNLICENSED\"},\"contracts/MinimalisticAccount.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\nimport \\\"./interfaces/IERC6551Account.sol\\\";\\nimport \\\"./lib/ERC6551AccountLib.sol\\\";\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/interfaces/IERC1271.sol\\\";\\n\\nerror NotAuthorized();\\nerror InvalidInput();\\nerror AccountLocked();\\nerror ExceedsMaxLockTime();\\nerror UntrustedImplementation();\\nerror OwnershipCycle();\\n\\n/**\\n * @title A smart contract account owned by a single ERC721 token\\n */\\ncontract MinimalisticAccount is\\n IERC165,\\n IERC6551Account,\\n IERC721Receiver,\\n IERC1155Receiver\\n{\\n /// @dev timestamp at which this account will be unlocked\\n uint256 public lockedUntil;\\n\\n /// @dev mapping from owner => caller => has permissions\\n mapping(address => mapping(address => bool)) public permissions;\\n\\n event OverrideUpdated(\\n address owner,\\n bytes4 selector,\\n address implementation\\n );\\n\\n event PermissionUpdated(address owner, address caller, bool hasPermission);\\n\\n event LockUpdated(uint256 lockedUntil);\\n\\n /// @dev reverts if caller is not the owner of the account\\n modifier onlyOwner() {\\n if (msg.sender != owner()) revert NotAuthorized();\\n _;\\n }\\n\\n /// @dev reverts if caller is not authorized to execute on this account\\n modifier onlyAuthorized() {\\n if (!isAuthorized(msg.sender)) revert NotAuthorized();\\n _;\\n }\\n\\n /// @dev reverts if this account is currently locked\\n modifier onlyUnlocked() {\\n if (isLocked()) revert AccountLocked();\\n _;\\n }\\n\\n constructor() {}\\n\\n /// @dev allows eth transfers by default, but allows account owner to override\\n receive() external payable {\\n }\\n\\n /// @dev executes a low-level call against an account if the caller is authorized to make calls\\n function executeCall(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) external payable onlyAuthorized onlyUnlocked returns (bytes memory) {\\n emit TransactionExecuted(to, value, data);\\n\\n return _call(to, value, data);\\n }\\n\\n /// @dev grants a given caller execution permissions\\n function setPermissions(\\n address[] calldata callers,\\n bool[] calldata _permissions\\n ) external onlyUnlocked {\\n address _owner = owner();\\n if (msg.sender != _owner) revert NotAuthorized();\\n\\n uint256 length = callers.length;\\n\\n if (_permissions.length != length) revert InvalidInput();\\n\\n for (uint256 i = 0; i < length; i++) {\\n permissions[_owner][callers[i]] = _permissions[i];\\n emit PermissionUpdated(_owner, callers[i], _permissions[i]);\\n }\\n }\\n\\n /// @dev locks the account until a certain timestamp\\n function lock(uint256 _lockedUntil) external onlyOwner onlyUnlocked {\\n if (_lockedUntil > block.timestamp + 365 days)\\n revert ExceedsMaxLockTime();\\n\\n lockedUntil = _lockedUntil;\\n\\n emit LockUpdated(_lockedUntil);\\n }\\n\\n /// @dev returns the current lock status of the account as a boolean\\n function isLocked() public view returns (bool) {\\n return lockedUntil > block.timestamp;\\n }\\n\\n /// @dev Returns the EIP-155 chain ID, token contract address, and token ID for the token that\\n /// owns this account.\\n function token()\\n external\\n view\\n returns (\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n )\\n {\\n return ERC6551AccountLib.token();\\n }\\n\\n /// @dev Returns the owner of the ERC-721 token which owns this account. By default, the owner\\n /// of the token has full permissions on the account.\\n function owner() public view returns (address) {\\n (\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) = ERC6551AccountLib.token();\\n\\n if (chainId != block.chainid) return address(0);\\n\\n return IERC721(tokenContract).ownerOf(tokenId);\\n }\\n\\n /// @dev Returns the authorization status for a given caller\\n function isAuthorized(address caller) public view returns (bool) {\\n (\\n ,\\n address tokenContract,\\n uint256 tokenId\\n ) = ERC6551AccountLib.token();\\n address _owner = IERC721(tokenContract).ownerOf(tokenId);\\n\\n // authorize token owner\\n if (caller == _owner) return true;\\n\\n // authorize caller if owner has granted permissions\\n if (permissions[_owner][caller]) return true;\\n\\n return false;\\n }\\n\\n /// @dev Returns true if a given interfaceId is supported by this account. This method can be\\n /// extended by an override.\\n function supportsInterface(bytes4 interfaceId)\\n public\\n pure \\n override\\n returns (bool)\\n {\\n bool defaultSupport = interfaceId == type(IERC165).interfaceId ||\\n interfaceId == type(IERC1155Receiver).interfaceId ||\\n interfaceId == type(IERC6551Account).interfaceId;\\n\\n if (defaultSupport) return true;\\n\\n return false;\\n }\\n\\n /// @dev Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle.\\n /// This function can be overriden.\\n function onERC721Received(\\n address,\\n address,\\n uint256 receivedTokenId,\\n bytes memory\\n ) public view override returns (bytes4) {\\n (\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) = ERC6551AccountLib.token();\\n\\n if (\\n chainId == block.chainid &&\\n tokenContract == msg.sender &&\\n tokenId == receivedTokenId\\n ) revert OwnershipCycle();\\n\\n return this.onERC721Received.selector;\\n }\\n\\n /// @dev Allows ERC-1155 tokens to be received. This function can be overriden.\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes memory\\n ) public pure override returns (bytes4) {\\n return this.onERC1155Received.selector;\\n }\\n\\n /// @dev Allows ERC-1155 token batches to be received. This function can be overriden.\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] memory,\\n uint256[] memory,\\n bytes memory\\n ) public pure override returns (bytes4) {\\n return this.onERC1155BatchReceived.selector;\\n }\\n\\n /// @dev Executes a low-level call\\n function _call(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) internal returns (bytes memory result) {\\n bool success;\\n (success, result) = to.call{value: value}(data);\\n\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /// @dev Executes a low-level static call\\n function _callStatic(address to, bytes calldata data)\\n internal\\n view\\n returns (bytes memory result)\\n {\\n bool success;\\n (success, result) = to.staticcall(data);\\n\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xed537db66c8c88618b283b038ec6e1b55b56c1ad4006658a1fef0fe8e60fb528\",\"license\":\"UNLICENSED\"},\"contracts/interfaces/IERC6551Account.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\ninterface IERC6551AccountProxy {\\n function implementation() external view returns (address);\\n}\\n\\n/// @dev the ERC-165 identifier for this interface is `0xeff4d378`\\ninterface IERC6551Account {\\n event TransactionExecuted(address indexed target, uint256 indexed value, bytes data);\\n\\n receive() external payable;\\n\\n function executeCall(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) external payable returns (bytes memory);\\n\\n function token()\\n external\\n view\\n returns (uint256 chainId, address tokenContract, uint256 tokenId);\\n\\n function owner() external view returns (address);\\n}\\n\",\"keccak256\":\"0x5fe2dca745f8e753d414778980a0846c1bbcbb26a09d7cd7fb712c7db7939582\",\"license\":\"UNLICENSED\"},\"contracts/lib/ERC6551AccountLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.13;\\n\\nlibrary ERC6551AccountLib {\\n function token()\\n internal\\n view\\n returns (\\n uint256,\\n address,\\n uint256\\n )\\n {\\n bytes memory footer = new bytes(0x60);\\n\\n assembly {\\n // copy 0x60 bytes from end of footer\\n extcodecopy(address(), add(footer, 0x20), 0x4d, 0xad)\\n }\\n\\n return abi.decode(footer, (uint256, address, uint256));\\n }\\n\\n function salt() internal view returns (uint256) {\\n bytes memory footer = new bytes(0x20);\\n\\n assembly {\\n // copy 0x20 bytes from beginning of footer\\n extcodecopy(address(), add(footer, 0x20), 0x2d, 0x4d)\\n }\\n\\n return abi.decode(footer, (uint256));\\n }\\n}\\n\",\"keccak256\":\"0xf7a8eb3b4fb63068eb8ed2a1a129e4676af842541f43c1a1dc96a9f295060c45\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[{"astId":314,"contract":"contracts/ChargedParticlesAccount.sol:ChargedParticlesAccount","label":"lockedUntil","offset":0,"slot":"0","type":"t_uint256"},{"astId":321,"contract":"contracts/ChargedParticlesAccount.sol:ChargedParticlesAccount","label":"permissions","offset":0,"slot":"1","type":"t_mapping(t_address,t_mapping(t_address,t_bool))"}],"types":{"t_address":{"encoding":"inplace","label":"address","numberOfBytes":"20"},"t_bool":{"encoding":"inplace","label":"bool","numberOfBytes":"1"},"t_mapping(t_address,t_bool)":{"encoding":"mapping","key":"t_address","label":"mapping(address => bool)","numberOfBytes":"32","value":"t_bool"},"t_mapping(t_address,t_mapping(t_address,t_bool))":{"encoding":"mapping","key":"t_address","label":"mapping(address => mapping(address => bool))","numberOfBytes":"32","value":"t_mapping(t_address,t_bool)"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/MinimalisticAccount.sol":{"MinimalisticAccount":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccountLocked","type":"error"},{"inputs":[],"name":"ExceedsMaxLockTime","type":"error"},{"inputs":[],"name":"InvalidInput","type":"error"},{"inputs":[],"name":"NotAuthorized","type":"error"},{"inputs":[],"name":"OwnershipCycle","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"lockedUntil","type":"uint256"}],"name":"LockUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"bytes4","name":"selector","type":"bytes4"},{"indexed":false,"internalType":"address","name":"implementation","type":"address"}],"name":"OverrideUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"bool","name":"hasPermission","type":"bool"}],"name":"PermissionUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":true,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"TransactionExecuted","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"executeCall","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"isAuthorized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lockedUntil","type":"uint256"}],"name":"lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockedUntil","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"receivedTokenId","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"permissions","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"callers","type":"address[]"},{"internalType":"bool[]","name":"_permissions","type":"bool[]"}],"name":"setPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}],"devdoc":{"kind":"dev","methods":{"executeCall(address,uint256,bytes)":{"details":"executes a low-level call against an account if the caller is authorized to make calls"},"isAuthorized(address)":{"details":"Returns the authorization status for a given caller"},"isLocked()":{"details":"returns the current lock status of the account as a boolean"},"lock(uint256)":{"details":"locks the account until a certain timestamp"},"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":{"details":"Allows ERC-1155 token batches to be received. This function can be overriden."},"onERC1155Received(address,address,uint256,uint256,bytes)":{"details":"Allows ERC-1155 tokens to be received. This function can be overriden."},"onERC721Received(address,address,uint256,bytes)":{"details":"Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle. This function can be overriden."},"owner()":{"details":"Returns the owner of the ERC-721 token which owns this account. By default, the owner of the token has full permissions on the account."},"setPermissions(address[],bool[])":{"details":"grants a given caller execution permissions"},"supportsInterface(bytes4)":{"details":"Returns true if a given interfaceId is supported by this account. This method can be extended by an override."},"token()":{"details":"Returns the EIP-155 chain ID, token contract address, and token ID for the token that owns this account."}},"stateVariables":{"lockedUntil":{"details":"timestamp at which this account will be unlocked"},"permissions":{"details":"mapping from owner => caller => has permissions"}},"title":"A smart contract account owned by a single ERC721 token","version":1},"evm":{"bytecode":{"functionDebugData":{"@_384":{"entryPoint":null,"id":384,"parameterSlots":0,"returnSlots":0}},"generatedSources":[],"linkReferences":{},"object":"608060405234801561001057600080fd5b50610fa8806100206000396000f3fe6080604052600436106100c65760003560e01c8063a4e2d6341161007f578063dd46706411610059578063dd46706414610251578063f23a6e6114610271578063fc0c546a1461029d578063fe9fbb80146102d557600080fd5b8063a4e2d634146101ea578063bc197c8114610201578063ce0617ec1461022d57600080fd5b806301ffc9a7146100d2578063039721b114610107578063150b7a02146101295780631f9838b5146101625780638da5cb5b1461019d5780639e5d4c49146101ca57600080fd5b366100cd57005b600080fd5b3480156100de57600080fd5b506100f26100ed36600461095c565b6102f5565b60405190151581526020015b60405180910390f35b34801561011357600080fd5b506101276101223660046109d9565b61035c565b005b34801561013557600080fd5b50610149610144366004610b14565b610525565b6040516001600160e01b031990911681526020016100fe565b34801561016e57600080fd5b506100f261017d366004610b80565b600160209081526000928352604080842090915290825290205460ff1681565b3480156101a957600080fd5b506101b261058d565b6040516001600160a01b0390911681526020016100fe565b6101dd6101d8366004610bb9565b610623565b6040516100fe9190610c42565b3480156101f657600080fd5b5060005442106100f2565b34801561020d57600080fd5b5061014961021c366004610d10565b63bc197c8160e01b95945050505050565b34801561023957600080fd5b5061024360005481565b6040519081526020016100fe565b34801561025d57600080fd5b5061012761026c366004610dbe565b6106c7565b34801561027d57600080fd5b5061014961028c366004610dd7565b63f23a6e6160e01b95945050505050565b3480156102a957600080fd5b506102b261078c565b604080519384526001600160a01b039092166020840152908201526060016100fe565b3480156102e157600080fd5b506100f26102f0366004610e40565b6107a4565b6000806001600160e01b031983166301ffc9a760e01b148061032757506001600160e01b03198316630271189760e51b145b8061034257506001600160e01b03198316631dfe9a6f60e31b145b905080156103535750600192915050565b50600092915050565b60005442101561037f57604051636315bfbb60e01b815260040160405180910390fd5b600061038961058d565b9050336001600160a01b038216146103b45760405163ea8e4eb560e01b815260040160405180910390fd5b838281146103d55760405163b4fa3fb360e01b815260040160405180910390fd5b60005b8181101561051c578484828181106103f2576103f2610e5d565b90506020020160208101906104079190610e73565b6001600160a01b03841660009081526001602052604081209089898581811061043257610432610e5d565b90506020020160208101906104479190610e40565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f394777a58092892d136a90c4bb7e4350c72ac50fba6a0208128677f36527dcf5838888848181106104a3576104a3610e5d565b90506020020160208101906104b89190610e40565b8787858181106104ca576104ca610e5d565b90506020020160208101906104df9190610e73565b604080516001600160a01b03948516815293909216602084015215159082015260600160405180910390a18061051481610eab565b9150506103d8565b50505050505050565b60008060008061053361088d565b925092509250468314801561055057506001600160a01b03821633145b801561055b57508581145b156105795760405163b79e3f3f60e01b815260040160405180910390fd5b50630a85bd0160e11b979650505050505050565b60008060008061059b61088d565b9250925092504683146105b2576000935050505090565b6040516331a9108f60e11b8152600481018290526001600160a01b03831690636352211e90602401602060405180830381865afa1580156105f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061b9190610ec4565b935050505090565b606061062e336107a4565b61064b5760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561066e57604051636315bfbb60e01b815260040160405180910390fd5b83856001600160a01b03167f47d99ad340f52da66535aff7e10da1ceb85a32bcbd9fa1c42314d194545e14d285856040516106aa929190610ee1565b60405180910390a36106be858585856108e0565b95945050505050565b6106cf61058d565b6001600160a01b0316336001600160a01b0316146107005760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561072357604051636315bfbb60e01b815260040160405180910390fd5b610731426301e13380610f10565b811115610751576040516301814f7d60e31b815260040160405180910390fd5b60008190556040518181527fa7b24c66dd3269a292a60b3facdbb8f3e7557d1e19e64d99e0d6ee7250be63ad9060200160405180910390a150565b600080600061079961088d565b925092509250909192565b60008060006107b161088d565b6040516331a9108f60e11b8152600481018290529194509250600091506001600160a01b03841690636352211e90602401602060405180830381865afa1580156107ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108239190610ec4565b9050806001600160a01b0316856001600160a01b03160361084957506001949350505050565b6001600160a01b0380821660009081526001602090815260408083209389168352929052205460ff161561088257506001949350505050565b506000949350505050565b604080516060808252608082019092526000918291829182919060208201818036833701905050905060ad604d60208301303c808060200190518101906108d49190610f29565b93509350935050909192565b60606000856001600160a01b03168585856040516108ff929190610f62565b60006040518083038185875af1925050503d806000811461093c576040519150601f19603f3d011682016040523d82523d6000602084013e610941565b606091505b50925090508061095357815160208301fd5b50949350505050565b60006020828403121561096e57600080fd5b81356001600160e01b03198116811461098657600080fd5b9392505050565b60008083601f84011261099f57600080fd5b50813567ffffffffffffffff8111156109b757600080fd5b6020830191508360208260051b85010111156109d257600080fd5b9250929050565b600080600080604085870312156109ef57600080fd5b843567ffffffffffffffff80821115610a0757600080fd5b610a138883890161098d565b90965094506020870135915080821115610a2c57600080fd5b50610a398782880161098d565b95989497509550505050565b6001600160a01b0381168114610a5a57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610a9c57610a9c610a5d565b604052919050565b600082601f830112610ab557600080fd5b813567ffffffffffffffff811115610acf57610acf610a5d565b610ae2601f8201601f1916602001610a73565b818152846020838601011115610af757600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215610b2a57600080fd5b8435610b3581610a45565b93506020850135610b4581610a45565b925060408501359150606085013567ffffffffffffffff811115610b6857600080fd5b610b7487828801610aa4565b91505092959194509250565b60008060408385031215610b9357600080fd5b8235610b9e81610a45565b91506020830135610bae81610a45565b809150509250929050565b60008060008060608587031215610bcf57600080fd5b8435610bda81610a45565b935060208501359250604085013567ffffffffffffffff80821115610bfe57600080fd5b818701915087601f830112610c1257600080fd5b813581811115610c2157600080fd5b886020828501011115610c3357600080fd5b95989497505060200194505050565b600060208083528351808285015260005b81811015610c6f57858101830151858201604001528201610c53565b506000604082860101526040601f19601f8301168501019250505092915050565b600082601f830112610ca157600080fd5b8135602067ffffffffffffffff821115610cbd57610cbd610a5d565b8160051b610ccc828201610a73565b9283528481018201928281019087851115610ce657600080fd5b83870192505b84831015610d0557823582529183019190830190610cec565b979650505050505050565b600080600080600060a08688031215610d2857600080fd5b8535610d3381610a45565b94506020860135610d4381610a45565b9350604086013567ffffffffffffffff80821115610d6057600080fd5b610d6c89838a01610c90565b94506060880135915080821115610d8257600080fd5b610d8e89838a01610c90565b93506080880135915080821115610da457600080fd5b50610db188828901610aa4565b9150509295509295909350565b600060208284031215610dd057600080fd5b5035919050565b600080600080600060a08688031215610def57600080fd5b8535610dfa81610a45565b94506020860135610e0a81610a45565b93506040860135925060608601359150608086013567ffffffffffffffff811115610e3457600080fd5b610db188828901610aa4565b600060208284031215610e5257600080fd5b813561098681610a45565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610e8557600080fd5b8135801515811461098657600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610ebd57610ebd610e95565b5060010190565b600060208284031215610ed657600080fd5b815161098681610a45565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b80820180821115610f2357610f23610e95565b92915050565b600080600060608486031215610f3e57600080fd5b835192506020840151610f5081610a45565b80925050604084015190509250925092565b818382376000910190815291905056fea26469706673582212208586a5aa87cff87a1d8e1dc4952c1d3b167ebfafab4c2b56ed97ed8a5ec5921664736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xFA8 DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xC6 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0xA4E2D634 GT PUSH2 0x7F JUMPI DUP1 PUSH4 0xDD467064 GT PUSH2 0x59 JUMPI DUP1 PUSH4 0xDD467064 EQ PUSH2 0x251 JUMPI DUP1 PUSH4 0xF23A6E61 EQ PUSH2 0x271 JUMPI DUP1 PUSH4 0xFC0C546A EQ PUSH2 0x29D JUMPI DUP1 PUSH4 0xFE9FBB80 EQ PUSH2 0x2D5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0xA4E2D634 EQ PUSH2 0x1EA JUMPI DUP1 PUSH4 0xBC197C81 EQ PUSH2 0x201 JUMPI DUP1 PUSH4 0xCE0617EC EQ PUSH2 0x22D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1FFC9A7 EQ PUSH2 0xD2 JUMPI DUP1 PUSH4 0x39721B1 EQ PUSH2 0x107 JUMPI DUP1 PUSH4 0x150B7A02 EQ PUSH2 0x129 JUMPI DUP1 PUSH4 0x1F9838B5 EQ PUSH2 0x162 JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x19D JUMPI DUP1 PUSH4 0x9E5D4C49 EQ PUSH2 0x1CA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST CALLDATASIZE PUSH2 0xCD JUMPI STOP JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xDE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xF2 PUSH2 0xED CALLDATASIZE PUSH1 0x4 PUSH2 0x95C JUMP JUMPDEST PUSH2 0x2F5 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x113 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x127 PUSH2 0x122 CALLDATASIZE PUSH1 0x4 PUSH2 0x9D9 JUMP JUMPDEST PUSH2 0x35C JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x135 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x149 PUSH2 0x144 CALLDATASIZE PUSH1 0x4 PUSH2 0xB14 JUMP JUMPDEST PUSH2 0x525 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xFE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x16E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xF2 PUSH2 0x17D CALLDATASIZE PUSH1 0x4 PUSH2 0xB80 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1A9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B2 PUSH2 0x58D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xFE JUMP JUMPDEST PUSH2 0x1DD PUSH2 0x1D8 CALLDATASIZE PUSH1 0x4 PUSH2 0xBB9 JUMP JUMPDEST PUSH2 0x623 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xFE SWAP2 SWAP1 PUSH2 0xC42 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1F6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x0 SLOAD TIMESTAMP LT PUSH2 0xF2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x20D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x149 PUSH2 0x21C CALLDATASIZE PUSH1 0x4 PUSH2 0xD10 JUMP JUMPDEST PUSH4 0xBC197C81 PUSH1 0xE0 SHL SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x239 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x243 PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xFE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x25D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x127 PUSH2 0x26C CALLDATASIZE PUSH1 0x4 PUSH2 0xDBE JUMP JUMPDEST PUSH2 0x6C7 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x27D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x149 PUSH2 0x28C CALLDATASIZE PUSH1 0x4 PUSH2 0xDD7 JUMP JUMPDEST PUSH4 0xF23A6E61 PUSH1 0xE0 SHL SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2A9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2B2 PUSH2 0x78C JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP4 DUP5 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE SWAP1 DUP3 ADD MSTORE PUSH1 0x60 ADD PUSH2 0xFE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2E1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xF2 PUSH2 0x2F0 CALLDATASIZE PUSH1 0x4 PUSH2 0xE40 JUMP JUMPDEST PUSH2 0x7A4 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x1FFC9A7 PUSH1 0xE0 SHL EQ DUP1 PUSH2 0x327 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x2711897 PUSH1 0xE5 SHL EQ JUMPDEST DUP1 PUSH2 0x342 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x1DFE9A6F PUSH1 0xE3 SHL EQ JUMPDEST SWAP1 POP DUP1 ISZERO PUSH2 0x353 JUMPI POP PUSH1 0x1 SWAP3 SWAP2 POP POP JUMP JUMPDEST POP PUSH1 0x0 SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x37F JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x389 PUSH2 0x58D JUMP JUMPDEST SWAP1 POP CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND EQ PUSH2 0x3B4 JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 DUP3 DUP2 EQ PUSH2 0x3D5 JUMPI PUSH1 0x40 MLOAD PUSH4 0xB4FA3FB3 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x51C JUMPI DUP5 DUP5 DUP3 DUP2 DUP2 LT PUSH2 0x3F2 JUMPI PUSH2 0x3F2 PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x407 SWAP2 SWAP1 PUSH2 0xE73 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 SWAP1 DUP10 DUP10 DUP6 DUP2 DUP2 LT PUSH2 0x432 JUMPI PUSH2 0x432 PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x447 SWAP2 SWAP1 PUSH2 0xE40 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP2 MSTORE PUSH1 0x20 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 ADD PUSH1 0x0 KECCAK256 DUP1 SLOAD PUSH1 0xFF NOT AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH32 0x394777A58092892D136A90C4BB7E4350C72AC50FBA6A0208128677F36527DCF5 DUP4 DUP9 DUP9 DUP5 DUP2 DUP2 LT PUSH2 0x4A3 JUMPI PUSH2 0x4A3 PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x4B8 SWAP2 SWAP1 PUSH2 0xE40 JUMP JUMPDEST DUP8 DUP8 DUP6 DUP2 DUP2 LT PUSH2 0x4CA JUMPI PUSH2 0x4CA PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x4DF SWAP2 SWAP1 PUSH2 0xE73 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP5 DUP6 AND DUP2 MSTORE SWAP4 SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE ISZERO ISZERO SWAP1 DUP3 ADD MSTORE PUSH1 0x60 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 DUP1 PUSH2 0x514 DUP2 PUSH2 0xEAB JUMP JUMPDEST SWAP2 POP POP PUSH2 0x3D8 JUMP JUMPDEST POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x533 PUSH2 0x88D JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP CHAINID DUP4 EQ DUP1 ISZERO PUSH2 0x550 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND CALLER EQ JUMPDEST DUP1 ISZERO PUSH2 0x55B JUMPI POP DUP6 DUP2 EQ JUMPDEST ISZERO PUSH2 0x579 JUMPI PUSH1 0x40 MLOAD PUSH4 0xB79E3F3F PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP PUSH4 0xA85BD01 PUSH1 0xE1 SHL SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x59B PUSH2 0x88D JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP CHAINID DUP4 EQ PUSH2 0x5B2 JUMPI PUSH1 0x0 SWAP4 POP POP POP POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x31A9108F PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND SWAP1 PUSH4 0x6352211E SWAP1 PUSH1 0x24 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x5F7 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x61B SWAP2 SWAP1 PUSH2 0xEC4 JUMP JUMPDEST SWAP4 POP POP POP POP SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH2 0x62E CALLER PUSH2 0x7A4 JUMP JUMPDEST PUSH2 0x64B JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x66E JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH32 0x47D99AD340F52DA66535AFF7E10DA1CEB85A32BCBD9FA1C42314D194545E14D2 DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0x6AA SWAP3 SWAP2 SWAP1 PUSH2 0xEE1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 PUSH2 0x6BE DUP6 DUP6 DUP6 DUP6 PUSH2 0x8E0 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0x6CF PUSH2 0x58D JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ PUSH2 0x700 JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x723 JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH2 0x731 TIMESTAMP PUSH4 0x1E13380 PUSH2 0xF10 JUMP JUMPDEST DUP2 GT ISZERO PUSH2 0x751 JUMPI PUSH1 0x40 MLOAD PUSH4 0x1814F7D PUSH1 0xE3 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 DUP2 SWAP1 SSTORE PUSH1 0x40 MLOAD DUP2 DUP2 MSTORE PUSH32 0xA7B24C66DD3269A292A60B3FACDBB8F3E7557D1E19E64D99E0D6EE7250BE63AD SWAP1 PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x799 PUSH2 0x88D JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP SWAP1 SWAP2 SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x7B1 PUSH2 0x88D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x31A9108F PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE SWAP2 SWAP5 POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND SWAP1 PUSH4 0x6352211E SWAP1 PUSH1 0x24 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x7FF JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x823 SWAP2 SWAP1 PUSH2 0xEC4 JUMP JUMPDEST SWAP1 POP DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SUB PUSH2 0x849 JUMPI POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP1 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP10 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x882 JUMPI POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST POP PUSH1 0x0 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 DUP1 DUP3 MSTORE PUSH1 0x80 DUP3 ADD SWAP1 SWAP3 MSTORE PUSH1 0x0 SWAP2 DUP3 SWAP2 DUP3 SWAP2 DUP3 SWAP2 SWAP1 PUSH1 0x20 DUP3 ADD DUP2 DUP1 CALLDATASIZE DUP4 CALLDATACOPY ADD SWAP1 POP POP SWAP1 POP PUSH1 0xAD PUSH1 0x4D PUSH1 0x20 DUP4 ADD ADDRESS EXTCODECOPY DUP1 DUP1 PUSH1 0x20 ADD SWAP1 MLOAD DUP2 ADD SWAP1 PUSH2 0x8D4 SWAP2 SWAP1 PUSH2 0xF29 JUMP JUMPDEST SWAP4 POP SWAP4 POP SWAP4 POP POP SWAP1 SWAP2 SWAP3 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP6 DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0x8FF SWAP3 SWAP2 SWAP1 PUSH2 0xF62 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 GAS CALL SWAP3 POP POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0x93C JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0x941 JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP3 POP SWAP1 POP DUP1 PUSH2 0x953 JUMPI DUP2 MLOAD PUSH1 0x20 DUP4 ADD REVERT JUMPDEST POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x96E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP2 AND DUP2 EQ PUSH2 0x986 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x99F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x9B7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 PUSH1 0x5 SHL DUP6 ADD ADD GT ISZERO PUSH2 0x9D2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x40 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x9EF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xA07 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xA13 DUP9 DUP4 DUP10 ADD PUSH2 0x98D JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP PUSH1 0x20 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xA2C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xA39 DUP8 DUP3 DUP9 ADD PUSH2 0x98D JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0xA5A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT AND DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0xA9C JUMPI PUSH2 0xA9C PUSH2 0xA5D JUMP JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xAB5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xACF JUMPI PUSH2 0xACF PUSH2 0xA5D JUMP JUMPDEST PUSH2 0xAE2 PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT AND PUSH1 0x20 ADD PUSH2 0xA73 JUMP JUMPDEST DUP2 DUP2 MSTORE DUP5 PUSH1 0x20 DUP4 DUP7 ADD ADD GT ISZERO PUSH2 0xAF7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 PUSH1 0x20 DUP6 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 SWAP2 DUP2 ADD PUSH1 0x20 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xB2A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xB35 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH2 0xB45 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD SWAP2 POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xB68 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xB74 DUP8 DUP3 DUP9 ADD PUSH2 0xAA4 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xB93 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH2 0xB9E DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP2 POP PUSH1 0x20 DUP4 ADD CALLDATALOAD PUSH2 0xBAE DUP2 PUSH2 0xA45 JUMP JUMPDEST DUP1 SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x60 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xBCF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xBDA DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xBFE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP8 ADD SWAP2 POP DUP8 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xC12 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP2 DUP2 GT ISZERO PUSH2 0xC21 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP9 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0xC33 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP POP PUSH1 0x20 ADD SWAP5 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 MSTORE DUP4 MLOAD DUP1 DUP3 DUP6 ADD MSTORE PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xC6F JUMPI DUP6 DUP2 ADD DUP4 ADD MLOAD DUP6 DUP3 ADD PUSH1 0x40 ADD MSTORE DUP3 ADD PUSH2 0xC53 JUMP JUMPDEST POP PUSH1 0x0 PUSH1 0x40 DUP3 DUP7 ADD ADD MSTORE PUSH1 0x40 PUSH1 0x1F NOT PUSH1 0x1F DUP4 ADD AND DUP6 ADD ADD SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xCA1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH1 0x20 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0xCBD JUMPI PUSH2 0xCBD PUSH2 0xA5D JUMP JUMPDEST DUP2 PUSH1 0x5 SHL PUSH2 0xCCC DUP3 DUP3 ADD PUSH2 0xA73 JUMP JUMPDEST SWAP3 DUP4 MSTORE DUP5 DUP2 ADD DUP3 ADD SWAP3 DUP3 DUP2 ADD SWAP1 DUP8 DUP6 GT ISZERO PUSH2 0xCE6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 DUP8 ADD SWAP3 POP JUMPDEST DUP5 DUP4 LT ISZERO PUSH2 0xD05 JUMPI DUP3 CALLDATALOAD DUP3 MSTORE SWAP2 DUP4 ADD SWAP2 SWAP1 DUP4 ADD SWAP1 PUSH2 0xCEC JUMP JUMPDEST SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xD28 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xD33 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH2 0xD43 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xD60 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD6C DUP10 DUP4 DUP11 ADD PUSH2 0xC90 JUMP JUMPDEST SWAP5 POP PUSH1 0x60 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xD82 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD8E DUP10 DUP4 DUP11 ADD PUSH2 0xC90 JUMP JUMPDEST SWAP4 POP PUSH1 0x80 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xDA4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xDB1 DUP9 DUP3 DUP10 ADD PUSH2 0xAA4 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 SWAP1 SWAP4 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xDD0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xDEF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xDFA DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH2 0xE0A DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD SWAP3 POP PUSH1 0x60 DUP7 ADD CALLDATALOAD SWAP2 POP PUSH1 0x80 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xE34 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xDB1 DUP9 DUP3 DUP10 ADD PUSH2 0xAA4 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xE52 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x986 DUP2 PUSH2 0xA45 JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x32 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xE85 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP1 ISZERO ISZERO DUP2 EQ PUSH2 0x986 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x11 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x1 DUP3 ADD PUSH2 0xEBD JUMPI PUSH2 0xEBD PUSH2 0xE95 JUMP JUMPDEST POP PUSH1 0x1 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xED6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x986 DUP2 PUSH2 0xA45 JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE DUP2 PUSH1 0x20 DUP3 ADD MSTORE DUP2 DUP4 PUSH1 0x40 DUP4 ADD CALLDATACOPY PUSH1 0x0 DUP2 DUP4 ADD PUSH1 0x40 SWAP1 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x1F SWAP1 SWAP3 ADD PUSH1 0x1F NOT AND ADD ADD SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 DUP3 ADD DUP1 DUP3 GT ISZERO PUSH2 0xF23 JUMPI PUSH2 0xF23 PUSH2 0xE95 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xF3E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 MLOAD SWAP3 POP PUSH1 0x20 DUP5 ADD MLOAD PUSH2 0xF50 DUP2 PUSH2 0xA45 JUMP JUMPDEST DUP1 SWAP3 POP POP PUSH1 0x40 DUP5 ADD MLOAD SWAP1 POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST DUP2 DUP4 DUP3 CALLDATACOPY PUSH1 0x0 SWAP2 ADD SWAP1 DUP2 MSTORE SWAP2 SWAP1 POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 DUP6 DUP7 0xA5 0xAA DUP8 0xCF 0xF8 PUSH27 0x1D8E1DC4952C1D3B167EBFAFAB4C2B56ED97ED8A5EC5921664736F PUSH13 0x63430008110033000000000000 ","sourceMap":"695:6680:7:-:0;;;1784:16;;;;;;;;;;695:6680;;;;;;"},"deployedBytecode":{"functionDebugData":{"@_389":{"entryPoint":null,"id":389,"parameterSlots":0,"returnSlots":0},"@_call_787":{"entryPoint":2272,"id":787,"parameterSlots":4,"returnSlots":1},"@executeCall_418":{"entryPoint":1571,"id":418,"parameterSlots":4,"returnSlots":1},"@isAuthorized_623":{"entryPoint":1956,"id":623,"parameterSlots":1,"returnSlots":1},"@isLocked_532":{"entryPoint":null,"id":532,"parameterSlots":0,"returnSlots":1},"@lock_520":{"entryPoint":1735,"id":520,"parameterSlots":1,"returnSlots":0},"@lockedUntil_314":{"entryPoint":null,"id":314,"parameterSlots":0,"returnSlots":0},"@onERC1155BatchReceived_755":{"entryPoint":null,"id":755,"parameterSlots":5,"returnSlots":1},"@onERC1155Received_731":{"entryPoint":null,"id":731,"parameterSlots":5,"returnSlots":1},"@onERC721Received_709":{"entryPoint":1317,"id":709,"parameterSlots":4,"returnSlots":1},"@owner_581":{"entryPoint":1421,"id":581,"parameterSlots":0,"returnSlots":1},"@permissions_321":{"entryPoint":null,"id":321,"parameterSlots":0,"returnSlots":0},"@setPermissions_491":{"entryPoint":860,"id":491,"parameterSlots":4,"returnSlots":0},"@supportsInterface_662":{"entryPoint":757,"id":662,"parameterSlots":1,"returnSlots":1},"@token_547":{"entryPoint":1932,"id":547,"parameterSlots":0,"returnSlots":3},"@token_929":{"entryPoint":2189,"id":929,"parameterSlots":0,"returnSlots":3},"abi_decode_array_address_dyn_calldata":{"entryPoint":2445,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_array_uint256_dyn":{"entryPoint":3216,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_bytes":{"entryPoint":2724,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_address":{"entryPoint":3648,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_address_fromMemory":{"entryPoint":3780,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_addresst_address":{"entryPoint":2944,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_tuple_t_addresst_addresst_array$_t_uint256_$dyn_memory_ptrt_array$_t_uint256_$dyn_memory_ptrt_bytes_memory_ptr":{"entryPoint":3344,"id":null,"parameterSlots":2,"returnSlots":5},"abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr":{"entryPoint":2836,"id":null,"parameterSlots":2,"returnSlots":4},"abi_decode_tuple_t_addresst_addresst_uint256t_uint256t_bytes_memory_ptr":{"entryPoint":3543,"id":null,"parameterSlots":2,"returnSlots":5},"abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptr":{"entryPoint":3001,"id":null,"parameterSlots":2,"returnSlots":4},"abi_decode_tuple_t_array$_t_address_$dyn_calldata_ptrt_array$_t_bool_$dyn_calldata_ptr":{"entryPoint":2521,"id":null,"parameterSlots":2,"returnSlots":4},"abi_decode_tuple_t_bool":{"entryPoint":3699,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_bytes4":{"entryPoint":2396,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_uint256":{"entryPoint":3518,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_uint256t_address_payablet_uint256_fromMemory":{"entryPoint":3881,"id":null,"parameterSlots":2,"returnSlots":3},"abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed":{"entryPoint":3938,"id":null,"parameterSlots":3,"returnSlots":1},"abi_encode_tuple_t_address__to_t_address__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_address_t_address_t_bool__to_t_address_t_address_t_bool__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":4,"returnSlots":1},"abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed":{"entryPoint":3809,"id":null,"parameterSlots":3,"returnSlots":1},"abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed":{"entryPoint":3138,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_uint256_t_address_t_uint256__to_t_uint256_t_address_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":4,"returnSlots":1},"allocate_memory":{"entryPoint":2675,"id":null,"parameterSlots":1,"returnSlots":1},"checked_add_t_uint256":{"entryPoint":3856,"id":null,"parameterSlots":2,"returnSlots":1},"increment_t_uint256":{"entryPoint":3755,"id":null,"parameterSlots":1,"returnSlots":1},"panic_error_0x11":{"entryPoint":3733,"id":null,"parameterSlots":0,"returnSlots":0},"panic_error_0x32":{"entryPoint":3677,"id":null,"parameterSlots":0,"returnSlots":0},"panic_error_0x41":{"entryPoint":2653,"id":null,"parameterSlots":0,"returnSlots":0},"validator_revert_address":{"entryPoint":2629,"id":null,"parameterSlots":1,"returnSlots":0}},"generatedSources":[{"ast":{"nodeType":"YulBlock","src":"0:11566:11","statements":[{"nodeType":"YulBlock","src":"6:3:11","statements":[]},{"body":{"nodeType":"YulBlock","src":"83:217:11","statements":[{"body":{"nodeType":"YulBlock","src":"129:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"138:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"141:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"131:6:11"},"nodeType":"YulFunctionCall","src":"131:12:11"},"nodeType":"YulExpressionStatement","src":"131:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"104:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"113:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"100:3:11"},"nodeType":"YulFunctionCall","src":"100:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"125:2:11","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"96:3:11"},"nodeType":"YulFunctionCall","src":"96:32:11"},"nodeType":"YulIf","src":"93:52:11"},{"nodeType":"YulVariableDeclaration","src":"154:36:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"180:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"167:12:11"},"nodeType":"YulFunctionCall","src":"167:23:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"158:5:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"254:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"263:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"266:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"256:6:11"},"nodeType":"YulFunctionCall","src":"256:12:11"},"nodeType":"YulExpressionStatement","src":"256:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"212:5:11"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"223:5:11"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"234:3:11","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"239:10:11","type":"","value":"0xffffffff"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"230:3:11"},"nodeType":"YulFunctionCall","src":"230:20:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"219:3:11"},"nodeType":"YulFunctionCall","src":"219:32:11"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"209:2:11"},"nodeType":"YulFunctionCall","src":"209:43:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"202:6:11"},"nodeType":"YulFunctionCall","src":"202:51:11"},"nodeType":"YulIf","src":"199:71:11"},{"nodeType":"YulAssignment","src":"279:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"289:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"279:6:11"}]}]},"name":"abi_decode_tuple_t_bytes4","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"49:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"60:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"72:6:11","type":""}],"src":"14:286:11"},{"body":{"nodeType":"YulBlock","src":"400:92:11","statements":[{"nodeType":"YulAssignment","src":"410:26:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"422:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"433:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"418:3:11"},"nodeType":"YulFunctionCall","src":"418:18:11"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"410:4:11"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"452:9:11"},{"arguments":[{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"477:6:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"470:6:11"},"nodeType":"YulFunctionCall","src":"470:14:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"463:6:11"},"nodeType":"YulFunctionCall","src":"463:22:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"445:6:11"},"nodeType":"YulFunctionCall","src":"445:41:11"},"nodeType":"YulExpressionStatement","src":"445:41:11"}]},"name":"abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"369:9:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"380:6:11","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"391:4:11","type":""}],"src":"305:187:11"},{"body":{"nodeType":"YulBlock","src":"581:283:11","statements":[{"body":{"nodeType":"YulBlock","src":"630:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"639:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"642:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"632:6:11"},"nodeType":"YulFunctionCall","src":"632:12:11"},"nodeType":"YulExpressionStatement","src":"632:12:11"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"609:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"617:4:11","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"605:3:11"},"nodeType":"YulFunctionCall","src":"605:17:11"},{"name":"end","nodeType":"YulIdentifier","src":"624:3:11"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"601:3:11"},"nodeType":"YulFunctionCall","src":"601:27:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"594:6:11"},"nodeType":"YulFunctionCall","src":"594:35:11"},"nodeType":"YulIf","src":"591:55:11"},{"nodeType":"YulAssignment","src":"655:30:11","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"678:6:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"665:12:11"},"nodeType":"YulFunctionCall","src":"665:20:11"},"variableNames":[{"name":"length","nodeType":"YulIdentifier","src":"655:6:11"}]},{"body":{"nodeType":"YulBlock","src":"728:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"737:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"740:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"730:6:11"},"nodeType":"YulFunctionCall","src":"730:12:11"},"nodeType":"YulExpressionStatement","src":"730:12:11"}]},"condition":{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"700:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"708:18:11","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"697:2:11"},"nodeType":"YulFunctionCall","src":"697:30:11"},"nodeType":"YulIf","src":"694:50:11"},{"nodeType":"YulAssignment","src":"753:29:11","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"769:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"777:4:11","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"765:3:11"},"nodeType":"YulFunctionCall","src":"765:17:11"},"variableNames":[{"name":"arrayPos","nodeType":"YulIdentifier","src":"753:8:11"}]},{"body":{"nodeType":"YulBlock","src":"842:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"851:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"854:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"844:6:11"},"nodeType":"YulFunctionCall","src":"844:12:11"},"nodeType":"YulExpressionStatement","src":"844:12:11"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"805:6:11"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"817:1:11","type":"","value":"5"},{"name":"length","nodeType":"YulIdentifier","src":"820:6:11"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"813:3:11"},"nodeType":"YulFunctionCall","src":"813:14:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"801:3:11"},"nodeType":"YulFunctionCall","src":"801:27:11"},{"kind":"number","nodeType":"YulLiteral","src":"830:4:11","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"797:3:11"},"nodeType":"YulFunctionCall","src":"797:38:11"},{"name":"end","nodeType":"YulIdentifier","src":"837:3:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"794:2:11"},"nodeType":"YulFunctionCall","src":"794:47:11"},"nodeType":"YulIf","src":"791:67:11"}]},"name":"abi_decode_array_address_dyn_calldata","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"544:6:11","type":""},{"name":"end","nodeType":"YulTypedName","src":"552:3:11","type":""}],"returnVariables":[{"name":"arrayPos","nodeType":"YulTypedName","src":"560:8:11","type":""},{"name":"length","nodeType":"YulTypedName","src":"570:6:11","type":""}],"src":"497:367:11"},{"body":{"nodeType":"YulBlock","src":"1023:616:11","statements":[{"body":{"nodeType":"YulBlock","src":"1069:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1078:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1081:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1071:6:11"},"nodeType":"YulFunctionCall","src":"1071:12:11"},"nodeType":"YulExpressionStatement","src":"1071:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"1044:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"1053:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1040:3:11"},"nodeType":"YulFunctionCall","src":"1040:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"1065:2:11","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"1036:3:11"},"nodeType":"YulFunctionCall","src":"1036:32:11"},"nodeType":"YulIf","src":"1033:52:11"},{"nodeType":"YulVariableDeclaration","src":"1094:37:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1121:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1108:12:11"},"nodeType":"YulFunctionCall","src":"1108:23:11"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"1098:6:11","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1140:28:11","value":{"kind":"number","nodeType":"YulLiteral","src":"1150:18:11","type":"","value":"0xffffffffffffffff"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"1144:2:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"1195:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1204:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1207:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1197:6:11"},"nodeType":"YulFunctionCall","src":"1197:12:11"},"nodeType":"YulExpressionStatement","src":"1197:12:11"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"1183:6:11"},{"name":"_1","nodeType":"YulIdentifier","src":"1191:2:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"1180:2:11"},"nodeType":"YulFunctionCall","src":"1180:14:11"},"nodeType":"YulIf","src":"1177:34:11"},{"nodeType":"YulVariableDeclaration","src":"1220:96:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1288:9:11"},{"name":"offset","nodeType":"YulIdentifier","src":"1299:6:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1284:3:11"},"nodeType":"YulFunctionCall","src":"1284:22:11"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"1308:7:11"}],"functionName":{"name":"abi_decode_array_address_dyn_calldata","nodeType":"YulIdentifier","src":"1246:37:11"},"nodeType":"YulFunctionCall","src":"1246:70:11"},"variables":[{"name":"value0_1","nodeType":"YulTypedName","src":"1224:8:11","type":""},{"name":"value1_1","nodeType":"YulTypedName","src":"1234:8:11","type":""}]},{"nodeType":"YulAssignment","src":"1325:18:11","value":{"name":"value0_1","nodeType":"YulIdentifier","src":"1335:8:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"1325:6:11"}]},{"nodeType":"YulAssignment","src":"1352:18:11","value":{"name":"value1_1","nodeType":"YulIdentifier","src":"1362:8:11"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"1352:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"1379:48:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1412:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"1423:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1408:3:11"},"nodeType":"YulFunctionCall","src":"1408:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1395:12:11"},"nodeType":"YulFunctionCall","src":"1395:32:11"},"variables":[{"name":"offset_1","nodeType":"YulTypedName","src":"1383:8:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"1456:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1465:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1468:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1458:6:11"},"nodeType":"YulFunctionCall","src":"1458:12:11"},"nodeType":"YulExpressionStatement","src":"1458:12:11"}]},"condition":{"arguments":[{"name":"offset_1","nodeType":"YulIdentifier","src":"1442:8:11"},{"name":"_1","nodeType":"YulIdentifier","src":"1452:2:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"1439:2:11"},"nodeType":"YulFunctionCall","src":"1439:16:11"},"nodeType":"YulIf","src":"1436:36:11"},{"nodeType":"YulVariableDeclaration","src":"1481:98:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1549:9:11"},{"name":"offset_1","nodeType":"YulIdentifier","src":"1560:8:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1545:3:11"},"nodeType":"YulFunctionCall","src":"1545:24:11"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"1571:7:11"}],"functionName":{"name":"abi_decode_array_address_dyn_calldata","nodeType":"YulIdentifier","src":"1507:37:11"},"nodeType":"YulFunctionCall","src":"1507:72:11"},"variables":[{"name":"value2_1","nodeType":"YulTypedName","src":"1485:8:11","type":""},{"name":"value3_1","nodeType":"YulTypedName","src":"1495:8:11","type":""}]},{"nodeType":"YulAssignment","src":"1588:18:11","value":{"name":"value2_1","nodeType":"YulIdentifier","src":"1598:8:11"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"1588:6:11"}]},{"nodeType":"YulAssignment","src":"1615:18:11","value":{"name":"value3_1","nodeType":"YulIdentifier","src":"1625:8:11"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"1615:6:11"}]}]},"name":"abi_decode_tuple_t_array$_t_address_$dyn_calldata_ptrt_array$_t_bool_$dyn_calldata_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"965:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"976:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"988:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"996:6:11","type":""},{"name":"value2","nodeType":"YulTypedName","src":"1004:6:11","type":""},{"name":"value3","nodeType":"YulTypedName","src":"1012:6:11","type":""}],"src":"869:770:11"},{"body":{"nodeType":"YulBlock","src":"1689:86:11","statements":[{"body":{"nodeType":"YulBlock","src":"1753:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1762:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1765:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1755:6:11"},"nodeType":"YulFunctionCall","src":"1755:12:11"},"nodeType":"YulExpressionStatement","src":"1755:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1712:5:11"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1723:5:11"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1738:3:11","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"1743:1:11","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1734:3:11"},"nodeType":"YulFunctionCall","src":"1734:11:11"},{"kind":"number","nodeType":"YulLiteral","src":"1747:1:11","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1730:3:11"},"nodeType":"YulFunctionCall","src":"1730:19:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1719:3:11"},"nodeType":"YulFunctionCall","src":"1719:31:11"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"1709:2:11"},"nodeType":"YulFunctionCall","src":"1709:42:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"1702:6:11"},"nodeType":"YulFunctionCall","src":"1702:50:11"},"nodeType":"YulIf","src":"1699:70:11"}]},"name":"validator_revert_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"value","nodeType":"YulTypedName","src":"1678:5:11","type":""}],"src":"1644:131:11"},{"body":{"nodeType":"YulBlock","src":"1812:95:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1829:1:11","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1836:3:11","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"1841:10:11","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1832:3:11"},"nodeType":"YulFunctionCall","src":"1832:20:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1822:6:11"},"nodeType":"YulFunctionCall","src":"1822:31:11"},"nodeType":"YulExpressionStatement","src":"1822:31:11"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1869:1:11","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"1872:4:11","type":"","value":"0x41"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1862:6:11"},"nodeType":"YulFunctionCall","src":"1862:15:11"},"nodeType":"YulExpressionStatement","src":"1862:15:11"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1893:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1896:4:11","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1886:6:11"},"nodeType":"YulFunctionCall","src":"1886:15:11"},"nodeType":"YulExpressionStatement","src":"1886:15:11"}]},"name":"panic_error_0x41","nodeType":"YulFunctionDefinition","src":"1780:127:11"},{"body":{"nodeType":"YulBlock","src":"1957:230:11","statements":[{"nodeType":"YulAssignment","src":"1967:19:11","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1983:2:11","type":"","value":"64"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"1977:5:11"},"nodeType":"YulFunctionCall","src":"1977:9:11"},"variableNames":[{"name":"memPtr","nodeType":"YulIdentifier","src":"1967:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"1995:58:11","value":{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"2017:6:11"},{"arguments":[{"arguments":[{"name":"size","nodeType":"YulIdentifier","src":"2033:4:11"},{"kind":"number","nodeType":"YulLiteral","src":"2039:2:11","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2029:3:11"},"nodeType":"YulFunctionCall","src":"2029:13:11"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2048:2:11","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"2044:3:11"},"nodeType":"YulFunctionCall","src":"2044:7:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"2025:3:11"},"nodeType":"YulFunctionCall","src":"2025:27:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2013:3:11"},"nodeType":"YulFunctionCall","src":"2013:40:11"},"variables":[{"name":"newFreePtr","nodeType":"YulTypedName","src":"1999:10:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"2128:22:11","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"2130:16:11"},"nodeType":"YulFunctionCall","src":"2130:18:11"},"nodeType":"YulExpressionStatement","src":"2130:18:11"}]},"condition":{"arguments":[{"arguments":[{"name":"newFreePtr","nodeType":"YulIdentifier","src":"2071:10:11"},{"kind":"number","nodeType":"YulLiteral","src":"2083:18:11","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2068:2:11"},"nodeType":"YulFunctionCall","src":"2068:34:11"},{"arguments":[{"name":"newFreePtr","nodeType":"YulIdentifier","src":"2107:10:11"},{"name":"memPtr","nodeType":"YulIdentifier","src":"2119:6:11"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"2104:2:11"},"nodeType":"YulFunctionCall","src":"2104:22:11"}],"functionName":{"name":"or","nodeType":"YulIdentifier","src":"2065:2:11"},"nodeType":"YulFunctionCall","src":"2065:62:11"},"nodeType":"YulIf","src":"2062:88:11"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2166:2:11","type":"","value":"64"},{"name":"newFreePtr","nodeType":"YulIdentifier","src":"2170:10:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2159:6:11"},"nodeType":"YulFunctionCall","src":"2159:22:11"},"nodeType":"YulExpressionStatement","src":"2159:22:11"}]},"name":"allocate_memory","nodeType":"YulFunctionDefinition","parameters":[{"name":"size","nodeType":"YulTypedName","src":"1937:4:11","type":""}],"returnVariables":[{"name":"memPtr","nodeType":"YulTypedName","src":"1946:6:11","type":""}],"src":"1912:275:11"},{"body":{"nodeType":"YulBlock","src":"2244:478:11","statements":[{"body":{"nodeType":"YulBlock","src":"2293:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2302:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2305:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2295:6:11"},"nodeType":"YulFunctionCall","src":"2295:12:11"},"nodeType":"YulExpressionStatement","src":"2295:12:11"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2272:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"2280:4:11","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2268:3:11"},"nodeType":"YulFunctionCall","src":"2268:17:11"},{"name":"end","nodeType":"YulIdentifier","src":"2287:3:11"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"2264:3:11"},"nodeType":"YulFunctionCall","src":"2264:27:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"2257:6:11"},"nodeType":"YulFunctionCall","src":"2257:35:11"},"nodeType":"YulIf","src":"2254:55:11"},{"nodeType":"YulVariableDeclaration","src":"2318:30:11","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2341:6:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2328:12:11"},"nodeType":"YulFunctionCall","src":"2328:20:11"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"2322:2:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"2387:22:11","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"2389:16:11"},"nodeType":"YulFunctionCall","src":"2389:18:11"},"nodeType":"YulExpressionStatement","src":"2389:18:11"}]},"condition":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"2363:2:11"},{"kind":"number","nodeType":"YulLiteral","src":"2367:18:11","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2360:2:11"},"nodeType":"YulFunctionCall","src":"2360:26:11"},"nodeType":"YulIf","src":"2357:52:11"},{"nodeType":"YulVariableDeclaration","src":"2418:70:11","value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"2461:2:11"},{"kind":"number","nodeType":"YulLiteral","src":"2465:4:11","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2457:3:11"},"nodeType":"YulFunctionCall","src":"2457:13:11"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2476:2:11","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"2472:3:11"},"nodeType":"YulFunctionCall","src":"2472:7:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"2453:3:11"},"nodeType":"YulFunctionCall","src":"2453:27:11"},{"kind":"number","nodeType":"YulLiteral","src":"2482:4:11","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2449:3:11"},"nodeType":"YulFunctionCall","src":"2449:38:11"}],"functionName":{"name":"allocate_memory","nodeType":"YulIdentifier","src":"2433:15:11"},"nodeType":"YulFunctionCall","src":"2433:55:11"},"variables":[{"name":"array_1","nodeType":"YulTypedName","src":"2422:7:11","type":""}]},{"expression":{"arguments":[{"name":"array_1","nodeType":"YulIdentifier","src":"2504:7:11"},{"name":"_1","nodeType":"YulIdentifier","src":"2513:2:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2497:6:11"},"nodeType":"YulFunctionCall","src":"2497:19:11"},"nodeType":"YulExpressionStatement","src":"2497:19:11"},{"body":{"nodeType":"YulBlock","src":"2564:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2573:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2576:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2566:6:11"},"nodeType":"YulFunctionCall","src":"2566:12:11"},"nodeType":"YulExpressionStatement","src":"2566:12:11"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2539:6:11"},{"name":"_1","nodeType":"YulIdentifier","src":"2547:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2535:3:11"},"nodeType":"YulFunctionCall","src":"2535:15:11"},{"kind":"number","nodeType":"YulLiteral","src":"2552:4:11","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2531:3:11"},"nodeType":"YulFunctionCall","src":"2531:26:11"},{"name":"end","nodeType":"YulIdentifier","src":"2559:3:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2528:2:11"},"nodeType":"YulFunctionCall","src":"2528:35:11"},"nodeType":"YulIf","src":"2525:55:11"},{"expression":{"arguments":[{"arguments":[{"name":"array_1","nodeType":"YulIdentifier","src":"2606:7:11"},{"kind":"number","nodeType":"YulLiteral","src":"2615:4:11","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2602:3:11"},"nodeType":"YulFunctionCall","src":"2602:18:11"},{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2626:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"2634:4:11","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2622:3:11"},"nodeType":"YulFunctionCall","src":"2622:17:11"},{"name":"_1","nodeType":"YulIdentifier","src":"2641:2:11"}],"functionName":{"name":"calldatacopy","nodeType":"YulIdentifier","src":"2589:12:11"},"nodeType":"YulFunctionCall","src":"2589:55:11"},"nodeType":"YulExpressionStatement","src":"2589:55:11"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"array_1","nodeType":"YulIdentifier","src":"2668:7:11"},{"name":"_1","nodeType":"YulIdentifier","src":"2677:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2664:3:11"},"nodeType":"YulFunctionCall","src":"2664:16:11"},{"kind":"number","nodeType":"YulLiteral","src":"2682:4:11","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2660:3:11"},"nodeType":"YulFunctionCall","src":"2660:27:11"},{"kind":"number","nodeType":"YulLiteral","src":"2689:1:11","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2653:6:11"},"nodeType":"YulFunctionCall","src":"2653:38:11"},"nodeType":"YulExpressionStatement","src":"2653:38:11"},{"nodeType":"YulAssignment","src":"2700:16:11","value":{"name":"array_1","nodeType":"YulIdentifier","src":"2709:7:11"},"variableNames":[{"name":"array","nodeType":"YulIdentifier","src":"2700:5:11"}]}]},"name":"abi_decode_bytes","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"2218:6:11","type":""},{"name":"end","nodeType":"YulTypedName","src":"2226:3:11","type":""}],"returnVariables":[{"name":"array","nodeType":"YulTypedName","src":"2234:5:11","type":""}],"src":"2192:530:11"},{"body":{"nodeType":"YulBlock","src":"2857:535:11","statements":[{"body":{"nodeType":"YulBlock","src":"2904:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2913:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2916:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2906:6:11"},"nodeType":"YulFunctionCall","src":"2906:12:11"},"nodeType":"YulExpressionStatement","src":"2906:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"2878:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"2887:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"2874:3:11"},"nodeType":"YulFunctionCall","src":"2874:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"2899:3:11","type":"","value":"128"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"2870:3:11"},"nodeType":"YulFunctionCall","src":"2870:33:11"},"nodeType":"YulIf","src":"2867:53:11"},{"nodeType":"YulVariableDeclaration","src":"2929:36:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2955:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2942:12:11"},"nodeType":"YulFunctionCall","src":"2942:23:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"2933:5:11","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"2999:5:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"2974:24:11"},"nodeType":"YulFunctionCall","src":"2974:31:11"},"nodeType":"YulExpressionStatement","src":"2974:31:11"},{"nodeType":"YulAssignment","src":"3014:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"3024:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"3014:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"3038:47:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3070:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"3081:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3066:3:11"},"nodeType":"YulFunctionCall","src":"3066:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3053:12:11"},"nodeType":"YulFunctionCall","src":"3053:32:11"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"3042:7:11","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"3119:7:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"3094:24:11"},"nodeType":"YulFunctionCall","src":"3094:33:11"},"nodeType":"YulExpressionStatement","src":"3094:33:11"},{"nodeType":"YulAssignment","src":"3136:17:11","value":{"name":"value_1","nodeType":"YulIdentifier","src":"3146:7:11"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"3136:6:11"}]},{"nodeType":"YulAssignment","src":"3162:42:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3189:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"3200:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3185:3:11"},"nodeType":"YulFunctionCall","src":"3185:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3172:12:11"},"nodeType":"YulFunctionCall","src":"3172:32:11"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"3162:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"3213:46:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3244:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"3255:2:11","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3240:3:11"},"nodeType":"YulFunctionCall","src":"3240:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3227:12:11"},"nodeType":"YulFunctionCall","src":"3227:32:11"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"3217:6:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"3302:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3311:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3314:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3304:6:11"},"nodeType":"YulFunctionCall","src":"3304:12:11"},"nodeType":"YulExpressionStatement","src":"3304:12:11"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"3274:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"3282:18:11","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"3271:2:11"},"nodeType":"YulFunctionCall","src":"3271:30:11"},"nodeType":"YulIf","src":"3268:50:11"},{"nodeType":"YulAssignment","src":"3327:59:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3358:9:11"},{"name":"offset","nodeType":"YulIdentifier","src":"3369:6:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3354:3:11"},"nodeType":"YulFunctionCall","src":"3354:22:11"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"3378:7:11"}],"functionName":{"name":"abi_decode_bytes","nodeType":"YulIdentifier","src":"3337:16:11"},"nodeType":"YulFunctionCall","src":"3337:49:11"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"3327:6:11"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"2799:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"2810:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"2822:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"2830:6:11","type":""},{"name":"value2","nodeType":"YulTypedName","src":"2838:6:11","type":""},{"name":"value3","nodeType":"YulTypedName","src":"2846:6:11","type":""}],"src":"2727:665:11"},{"body":{"nodeType":"YulBlock","src":"3496:103:11","statements":[{"nodeType":"YulAssignment","src":"3506:26:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3518:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"3529:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3514:3:11"},"nodeType":"YulFunctionCall","src":"3514:18:11"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"3506:4:11"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3548:9:11"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"3563:6:11"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3575:3:11","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"3580:10:11","type":"","value":"0xffffffff"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"3571:3:11"},"nodeType":"YulFunctionCall","src":"3571:20:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"3559:3:11"},"nodeType":"YulFunctionCall","src":"3559:33:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"3541:6:11"},"nodeType":"YulFunctionCall","src":"3541:52:11"},"nodeType":"YulExpressionStatement","src":"3541:52:11"}]},"name":"abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"3465:9:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"3476:6:11","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"3487:4:11","type":""}],"src":"3397:202:11"},{"body":{"nodeType":"YulBlock","src":"3691:301:11","statements":[{"body":{"nodeType":"YulBlock","src":"3737:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3746:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3749:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3739:6:11"},"nodeType":"YulFunctionCall","src":"3739:12:11"},"nodeType":"YulExpressionStatement","src":"3739:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"3712:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"3721:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"3708:3:11"},"nodeType":"YulFunctionCall","src":"3708:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"3733:2:11","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"3704:3:11"},"nodeType":"YulFunctionCall","src":"3704:32:11"},"nodeType":"YulIf","src":"3701:52:11"},{"nodeType":"YulVariableDeclaration","src":"3762:36:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3788:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3775:12:11"},"nodeType":"YulFunctionCall","src":"3775:23:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"3766:5:11","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"3832:5:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"3807:24:11"},"nodeType":"YulFunctionCall","src":"3807:31:11"},"nodeType":"YulExpressionStatement","src":"3807:31:11"},{"nodeType":"YulAssignment","src":"3847:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"3857:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"3847:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"3871:47:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3903:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"3914:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3899:3:11"},"nodeType":"YulFunctionCall","src":"3899:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3886:12:11"},"nodeType":"YulFunctionCall","src":"3886:32:11"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"3875:7:11","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"3952:7:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"3927:24:11"},"nodeType":"YulFunctionCall","src":"3927:33:11"},"nodeType":"YulExpressionStatement","src":"3927:33:11"},{"nodeType":"YulAssignment","src":"3969:17:11","value":{"name":"value_1","nodeType":"YulIdentifier","src":"3979:7:11"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"3969:6:11"}]}]},"name":"abi_decode_tuple_t_addresst_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"3649:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"3660:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"3672:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"3680:6:11","type":""}],"src":"3604:388:11"},{"body":{"nodeType":"YulBlock","src":"4098:102:11","statements":[{"nodeType":"YulAssignment","src":"4108:26:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4120:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"4131:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4116:3:11"},"nodeType":"YulFunctionCall","src":"4116:18:11"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"4108:4:11"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4150:9:11"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"4165:6:11"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4181:3:11","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"4186:1:11","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"4177:3:11"},"nodeType":"YulFunctionCall","src":"4177:11:11"},{"kind":"number","nodeType":"YulLiteral","src":"4190:1:11","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"4173:3:11"},"nodeType":"YulFunctionCall","src":"4173:19:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"4161:3:11"},"nodeType":"YulFunctionCall","src":"4161:32:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"4143:6:11"},"nodeType":"YulFunctionCall","src":"4143:51:11"},"nodeType":"YulExpressionStatement","src":"4143:51:11"}]},"name":"abi_encode_tuple_t_address__to_t_address__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"4067:9:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"4078:6:11","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"4089:4:11","type":""}],"src":"3997:203:11"},{"body":{"nodeType":"YulBlock","src":"4328:671:11","statements":[{"body":{"nodeType":"YulBlock","src":"4374:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4383:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4386:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4376:6:11"},"nodeType":"YulFunctionCall","src":"4376:12:11"},"nodeType":"YulExpressionStatement","src":"4376:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"4349:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"4358:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"4345:3:11"},"nodeType":"YulFunctionCall","src":"4345:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"4370:2:11","type":"","value":"96"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"4341:3:11"},"nodeType":"YulFunctionCall","src":"4341:32:11"},"nodeType":"YulIf","src":"4338:52:11"},{"nodeType":"YulVariableDeclaration","src":"4399:36:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4425:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4412:12:11"},"nodeType":"YulFunctionCall","src":"4412:23:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"4403:5:11","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"4469:5:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"4444:24:11"},"nodeType":"YulFunctionCall","src":"4444:31:11"},"nodeType":"YulExpressionStatement","src":"4444:31:11"},{"nodeType":"YulAssignment","src":"4484:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"4494:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"4484:6:11"}]},{"nodeType":"YulAssignment","src":"4508:42:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4535:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"4546:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4531:3:11"},"nodeType":"YulFunctionCall","src":"4531:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4518:12:11"},"nodeType":"YulFunctionCall","src":"4518:32:11"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"4508:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"4559:46:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4590:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"4601:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4586:3:11"},"nodeType":"YulFunctionCall","src":"4586:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4573:12:11"},"nodeType":"YulFunctionCall","src":"4573:32:11"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"4563:6:11","type":""}]},{"nodeType":"YulVariableDeclaration","src":"4614:28:11","value":{"kind":"number","nodeType":"YulLiteral","src":"4624:18:11","type":"","value":"0xffffffffffffffff"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"4618:2:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"4669:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4678:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4681:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4671:6:11"},"nodeType":"YulFunctionCall","src":"4671:12:11"},"nodeType":"YulExpressionStatement","src":"4671:12:11"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"4657:6:11"},{"name":"_1","nodeType":"YulIdentifier","src":"4665:2:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"4654:2:11"},"nodeType":"YulFunctionCall","src":"4654:14:11"},"nodeType":"YulIf","src":"4651:34:11"},{"nodeType":"YulVariableDeclaration","src":"4694:32:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4708:9:11"},{"name":"offset","nodeType":"YulIdentifier","src":"4719:6:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4704:3:11"},"nodeType":"YulFunctionCall","src":"4704:22:11"},"variables":[{"name":"_2","nodeType":"YulTypedName","src":"4698:2:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"4774:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4783:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4786:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4776:6:11"},"nodeType":"YulFunctionCall","src":"4776:12:11"},"nodeType":"YulExpressionStatement","src":"4776:12:11"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"4753:2:11"},{"kind":"number","nodeType":"YulLiteral","src":"4757:4:11","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4749:3:11"},"nodeType":"YulFunctionCall","src":"4749:13:11"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"4764:7:11"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"4745:3:11"},"nodeType":"YulFunctionCall","src":"4745:27:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"4738:6:11"},"nodeType":"YulFunctionCall","src":"4738:35:11"},"nodeType":"YulIf","src":"4735:55:11"},{"nodeType":"YulVariableDeclaration","src":"4799:30:11","value":{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"4826:2:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4813:12:11"},"nodeType":"YulFunctionCall","src":"4813:16:11"},"variables":[{"name":"length","nodeType":"YulTypedName","src":"4803:6:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"4856:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4865:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4868:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4858:6:11"},"nodeType":"YulFunctionCall","src":"4858:12:11"},"nodeType":"YulExpressionStatement","src":"4858:12:11"}]},"condition":{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"4844:6:11"},{"name":"_1","nodeType":"YulIdentifier","src":"4852:2:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"4841:2:11"},"nodeType":"YulFunctionCall","src":"4841:14:11"},"nodeType":"YulIf","src":"4838:34:11"},{"body":{"nodeType":"YulBlock","src":"4922:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4931:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4934:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4924:6:11"},"nodeType":"YulFunctionCall","src":"4924:12:11"},"nodeType":"YulExpressionStatement","src":"4924:12:11"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"4895:2:11"},{"name":"length","nodeType":"YulIdentifier","src":"4899:6:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4891:3:11"},"nodeType":"YulFunctionCall","src":"4891:15:11"},{"kind":"number","nodeType":"YulLiteral","src":"4908:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4887:3:11"},"nodeType":"YulFunctionCall","src":"4887:24:11"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"4913:7:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"4884:2:11"},"nodeType":"YulFunctionCall","src":"4884:37:11"},"nodeType":"YulIf","src":"4881:57:11"},{"nodeType":"YulAssignment","src":"4947:21:11","value":{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"4961:2:11"},{"kind":"number","nodeType":"YulLiteral","src":"4965:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4957:3:11"},"nodeType":"YulFunctionCall","src":"4957:11:11"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"4947:6:11"}]},{"nodeType":"YulAssignment","src":"4977:16:11","value":{"name":"length","nodeType":"YulIdentifier","src":"4987:6:11"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"4977:6:11"}]}]},"name":"abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"4270:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"4281:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"4293:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"4301:6:11","type":""},{"name":"value2","nodeType":"YulTypedName","src":"4309:6:11","type":""},{"name":"value3","nodeType":"YulTypedName","src":"4317:6:11","type":""}],"src":"4205:794:11"},{"body":{"nodeType":"YulBlock","src":"5123:427:11","statements":[{"nodeType":"YulVariableDeclaration","src":"5133:12:11","value":{"kind":"number","nodeType":"YulLiteral","src":"5143:2:11","type":"","value":"32"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"5137:2:11","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5161:9:11"},{"name":"_1","nodeType":"YulIdentifier","src":"5172:2:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5154:6:11"},"nodeType":"YulFunctionCall","src":"5154:21:11"},"nodeType":"YulExpressionStatement","src":"5154:21:11"},{"nodeType":"YulVariableDeclaration","src":"5184:27:11","value":{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"5204:6:11"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"5198:5:11"},"nodeType":"YulFunctionCall","src":"5198:13:11"},"variables":[{"name":"length","nodeType":"YulTypedName","src":"5188:6:11","type":""}]},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5231:9:11"},{"name":"_1","nodeType":"YulIdentifier","src":"5242:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5227:3:11"},"nodeType":"YulFunctionCall","src":"5227:18:11"},{"name":"length","nodeType":"YulIdentifier","src":"5247:6:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5220:6:11"},"nodeType":"YulFunctionCall","src":"5220:34:11"},"nodeType":"YulExpressionStatement","src":"5220:34:11"},{"nodeType":"YulVariableDeclaration","src":"5263:10:11","value":{"kind":"number","nodeType":"YulLiteral","src":"5272:1:11","type":"","value":"0"},"variables":[{"name":"i","nodeType":"YulTypedName","src":"5267:1:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"5332:90:11","statements":[{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5361:9:11"},{"name":"i","nodeType":"YulIdentifier","src":"5372:1:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5357:3:11"},"nodeType":"YulFunctionCall","src":"5357:17:11"},{"kind":"number","nodeType":"YulLiteral","src":"5376:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5353:3:11"},"nodeType":"YulFunctionCall","src":"5353:26:11"},{"arguments":[{"arguments":[{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"5395:6:11"},{"name":"i","nodeType":"YulIdentifier","src":"5403:1:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5391:3:11"},"nodeType":"YulFunctionCall","src":"5391:14:11"},{"name":"_1","nodeType":"YulIdentifier","src":"5407:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5387:3:11"},"nodeType":"YulFunctionCall","src":"5387:23:11"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"5381:5:11"},"nodeType":"YulFunctionCall","src":"5381:30:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5346:6:11"},"nodeType":"YulFunctionCall","src":"5346:66:11"},"nodeType":"YulExpressionStatement","src":"5346:66:11"}]},"condition":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"5293:1:11"},{"name":"length","nodeType":"YulIdentifier","src":"5296:6:11"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"5290:2:11"},"nodeType":"YulFunctionCall","src":"5290:13:11"},"nodeType":"YulForLoop","post":{"nodeType":"YulBlock","src":"5304:19:11","statements":[{"nodeType":"YulAssignment","src":"5306:15:11","value":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"5315:1:11"},{"name":"_1","nodeType":"YulIdentifier","src":"5318:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5311:3:11"},"nodeType":"YulFunctionCall","src":"5311:10:11"},"variableNames":[{"name":"i","nodeType":"YulIdentifier","src":"5306:1:11"}]}]},"pre":{"nodeType":"YulBlock","src":"5286:3:11","statements":[]},"src":"5282:140:11"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5446:9:11"},{"name":"length","nodeType":"YulIdentifier","src":"5457:6:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5442:3:11"},"nodeType":"YulFunctionCall","src":"5442:22:11"},{"kind":"number","nodeType":"YulLiteral","src":"5466:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5438:3:11"},"nodeType":"YulFunctionCall","src":"5438:31:11"},{"kind":"number","nodeType":"YulLiteral","src":"5471:1:11","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5431:6:11"},"nodeType":"YulFunctionCall","src":"5431:42:11"},"nodeType":"YulExpressionStatement","src":"5431:42:11"},{"nodeType":"YulAssignment","src":"5482:62:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5498:9:11"},{"arguments":[{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"5517:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"5525:2:11","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5513:3:11"},"nodeType":"YulFunctionCall","src":"5513:15:11"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5534:2:11","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"5530:3:11"},"nodeType":"YulFunctionCall","src":"5530:7:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"5509:3:11"},"nodeType":"YulFunctionCall","src":"5509:29:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5494:3:11"},"nodeType":"YulFunctionCall","src":"5494:45:11"},{"kind":"number","nodeType":"YulLiteral","src":"5541:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5490:3:11"},"nodeType":"YulFunctionCall","src":"5490:54:11"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"5482:4:11"}]}]},"name":"abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"5092:9:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"5103:6:11","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"5114:4:11","type":""}],"src":"5004:546:11"},{"body":{"nodeType":"YulBlock","src":"5619:648:11","statements":[{"body":{"nodeType":"YulBlock","src":"5668:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5677:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"5680:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"5670:6:11"},"nodeType":"YulFunctionCall","src":"5670:12:11"},"nodeType":"YulExpressionStatement","src":"5670:12:11"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"5647:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"5655:4:11","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5643:3:11"},"nodeType":"YulFunctionCall","src":"5643:17:11"},{"name":"end","nodeType":"YulIdentifier","src":"5662:3:11"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"5639:3:11"},"nodeType":"YulFunctionCall","src":"5639:27:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"5632:6:11"},"nodeType":"YulFunctionCall","src":"5632:35:11"},"nodeType":"YulIf","src":"5629:55:11"},{"nodeType":"YulVariableDeclaration","src":"5693:30:11","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"5716:6:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5703:12:11"},"nodeType":"YulFunctionCall","src":"5703:20:11"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"5697:2:11","type":""}]},{"nodeType":"YulVariableDeclaration","src":"5732:14:11","value":{"kind":"number","nodeType":"YulLiteral","src":"5742:4:11","type":"","value":"0x20"},"variables":[{"name":"_2","nodeType":"YulTypedName","src":"5736:2:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"5785:22:11","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"5787:16:11"},"nodeType":"YulFunctionCall","src":"5787:18:11"},"nodeType":"YulExpressionStatement","src":"5787:18:11"}]},"condition":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"5761:2:11"},{"kind":"number","nodeType":"YulLiteral","src":"5765:18:11","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"5758:2:11"},"nodeType":"YulFunctionCall","src":"5758:26:11"},"nodeType":"YulIf","src":"5755:52:11"},{"nodeType":"YulVariableDeclaration","src":"5816:20:11","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5830:1:11","type":"","value":"5"},{"name":"_1","nodeType":"YulIdentifier","src":"5833:2:11"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"5826:3:11"},"nodeType":"YulFunctionCall","src":"5826:10:11"},"variables":[{"name":"_3","nodeType":"YulTypedName","src":"5820:2:11","type":""}]},{"nodeType":"YulVariableDeclaration","src":"5845:39:11","value":{"arguments":[{"arguments":[{"name":"_3","nodeType":"YulIdentifier","src":"5876:2:11"},{"name":"_2","nodeType":"YulIdentifier","src":"5880:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5872:3:11"},"nodeType":"YulFunctionCall","src":"5872:11:11"}],"functionName":{"name":"allocate_memory","nodeType":"YulIdentifier","src":"5856:15:11"},"nodeType":"YulFunctionCall","src":"5856:28:11"},"variables":[{"name":"dst","nodeType":"YulTypedName","src":"5849:3:11","type":""}]},{"nodeType":"YulVariableDeclaration","src":"5893:16:11","value":{"name":"dst","nodeType":"YulIdentifier","src":"5906:3:11"},"variables":[{"name":"dst_1","nodeType":"YulTypedName","src":"5897:5:11","type":""}]},{"expression":{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"5925:3:11"},{"name":"_1","nodeType":"YulIdentifier","src":"5930:2:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5918:6:11"},"nodeType":"YulFunctionCall","src":"5918:15:11"},"nodeType":"YulExpressionStatement","src":"5918:15:11"},{"nodeType":"YulAssignment","src":"5942:19:11","value":{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"5953:3:11"},{"name":"_2","nodeType":"YulIdentifier","src":"5958:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5949:3:11"},"nodeType":"YulFunctionCall","src":"5949:12:11"},"variableNames":[{"name":"dst","nodeType":"YulIdentifier","src":"5942:3:11"}]},{"nodeType":"YulVariableDeclaration","src":"5970:38:11","value":{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"5992:6:11"},{"name":"_3","nodeType":"YulIdentifier","src":"6000:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5988:3:11"},"nodeType":"YulFunctionCall","src":"5988:15:11"},{"name":"_2","nodeType":"YulIdentifier","src":"6005:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5984:3:11"},"nodeType":"YulFunctionCall","src":"5984:24:11"},"variables":[{"name":"srcEnd","nodeType":"YulTypedName","src":"5974:6:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"6036:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6045:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"6048:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"6038:6:11"},"nodeType":"YulFunctionCall","src":"6038:12:11"},"nodeType":"YulExpressionStatement","src":"6038:12:11"}]},"condition":{"arguments":[{"name":"srcEnd","nodeType":"YulIdentifier","src":"6023:6:11"},{"name":"end","nodeType":"YulIdentifier","src":"6031:3:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"6020:2:11"},"nodeType":"YulFunctionCall","src":"6020:15:11"},"nodeType":"YulIf","src":"6017:35:11"},{"nodeType":"YulVariableDeclaration","src":"6061:26:11","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"6076:6:11"},{"name":"_2","nodeType":"YulIdentifier","src":"6084:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6072:3:11"},"nodeType":"YulFunctionCall","src":"6072:15:11"},"variables":[{"name":"src","nodeType":"YulTypedName","src":"6065:3:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"6152:86:11","statements":[{"expression":{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"6173:3:11"},{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"6191:3:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6178:12:11"},"nodeType":"YulFunctionCall","src":"6178:17:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6166:6:11"},"nodeType":"YulFunctionCall","src":"6166:30:11"},"nodeType":"YulExpressionStatement","src":"6166:30:11"},{"nodeType":"YulAssignment","src":"6209:19:11","value":{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"6220:3:11"},{"name":"_2","nodeType":"YulIdentifier","src":"6225:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6216:3:11"},"nodeType":"YulFunctionCall","src":"6216:12:11"},"variableNames":[{"name":"dst","nodeType":"YulIdentifier","src":"6209:3:11"}]}]},"condition":{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"6107:3:11"},{"name":"srcEnd","nodeType":"YulIdentifier","src":"6112:6:11"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"6104:2:11"},"nodeType":"YulFunctionCall","src":"6104:15:11"},"nodeType":"YulForLoop","post":{"nodeType":"YulBlock","src":"6120:23:11","statements":[{"nodeType":"YulAssignment","src":"6122:19:11","value":{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"6133:3:11"},{"name":"_2","nodeType":"YulIdentifier","src":"6138:2:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6129:3:11"},"nodeType":"YulFunctionCall","src":"6129:12:11"},"variableNames":[{"name":"src","nodeType":"YulIdentifier","src":"6122:3:11"}]}]},"pre":{"nodeType":"YulBlock","src":"6100:3:11","statements":[]},"src":"6096:142:11"},{"nodeType":"YulAssignment","src":"6247:14:11","value":{"name":"dst_1","nodeType":"YulIdentifier","src":"6256:5:11"},"variableNames":[{"name":"array","nodeType":"YulIdentifier","src":"6247:5:11"}]}]},"name":"abi_decode_array_uint256_dyn","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"5593:6:11","type":""},{"name":"end","nodeType":"YulTypedName","src":"5601:3:11","type":""}],"returnVariables":[{"name":"array","nodeType":"YulTypedName","src":"5609:5:11","type":""}],"src":"5555:712:11"},{"body":{"nodeType":"YulBlock","src":"6469:874:11","statements":[{"body":{"nodeType":"YulBlock","src":"6516:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6525:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"6528:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"6518:6:11"},"nodeType":"YulFunctionCall","src":"6518:12:11"},"nodeType":"YulExpressionStatement","src":"6518:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"6490:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"6499:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"6486:3:11"},"nodeType":"YulFunctionCall","src":"6486:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"6511:3:11","type":"","value":"160"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"6482:3:11"},"nodeType":"YulFunctionCall","src":"6482:33:11"},"nodeType":"YulIf","src":"6479:53:11"},{"nodeType":"YulVariableDeclaration","src":"6541:36:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6567:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6554:12:11"},"nodeType":"YulFunctionCall","src":"6554:23:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"6545:5:11","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"6611:5:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"6586:24:11"},"nodeType":"YulFunctionCall","src":"6586:31:11"},"nodeType":"YulExpressionStatement","src":"6586:31:11"},{"nodeType":"YulAssignment","src":"6626:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"6636:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"6626:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"6650:47:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6682:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"6693:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6678:3:11"},"nodeType":"YulFunctionCall","src":"6678:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6665:12:11"},"nodeType":"YulFunctionCall","src":"6665:32:11"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"6654:7:11","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"6731:7:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"6706:24:11"},"nodeType":"YulFunctionCall","src":"6706:33:11"},"nodeType":"YulExpressionStatement","src":"6706:33:11"},{"nodeType":"YulAssignment","src":"6748:17:11","value":{"name":"value_1","nodeType":"YulIdentifier","src":"6758:7:11"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"6748:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"6774:46:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6805:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"6816:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6801:3:11"},"nodeType":"YulFunctionCall","src":"6801:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6788:12:11"},"nodeType":"YulFunctionCall","src":"6788:32:11"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"6778:6:11","type":""}]},{"nodeType":"YulVariableDeclaration","src":"6829:28:11","value":{"kind":"number","nodeType":"YulLiteral","src":"6839:18:11","type":"","value":"0xffffffffffffffff"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"6833:2:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"6884:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6893:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"6896:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"6886:6:11"},"nodeType":"YulFunctionCall","src":"6886:12:11"},"nodeType":"YulExpressionStatement","src":"6886:12:11"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"6872:6:11"},{"name":"_1","nodeType":"YulIdentifier","src":"6880:2:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"6869:2:11"},"nodeType":"YulFunctionCall","src":"6869:14:11"},"nodeType":"YulIf","src":"6866:34:11"},{"nodeType":"YulAssignment","src":"6909:71:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6952:9:11"},{"name":"offset","nodeType":"YulIdentifier","src":"6963:6:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6948:3:11"},"nodeType":"YulFunctionCall","src":"6948:22:11"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"6972:7:11"}],"functionName":{"name":"abi_decode_array_uint256_dyn","nodeType":"YulIdentifier","src":"6919:28:11"},"nodeType":"YulFunctionCall","src":"6919:61:11"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"6909:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"6989:48:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7022:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"7033:2:11","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7018:3:11"},"nodeType":"YulFunctionCall","src":"7018:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7005:12:11"},"nodeType":"YulFunctionCall","src":"7005:32:11"},"variables":[{"name":"offset_1","nodeType":"YulTypedName","src":"6993:8:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"7066:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7075:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"7078:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7068:6:11"},"nodeType":"YulFunctionCall","src":"7068:12:11"},"nodeType":"YulExpressionStatement","src":"7068:12:11"}]},"condition":{"arguments":[{"name":"offset_1","nodeType":"YulIdentifier","src":"7052:8:11"},{"name":"_1","nodeType":"YulIdentifier","src":"7062:2:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"7049:2:11"},"nodeType":"YulFunctionCall","src":"7049:16:11"},"nodeType":"YulIf","src":"7046:36:11"},{"nodeType":"YulAssignment","src":"7091:73:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7134:9:11"},{"name":"offset_1","nodeType":"YulIdentifier","src":"7145:8:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7130:3:11"},"nodeType":"YulFunctionCall","src":"7130:24:11"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"7156:7:11"}],"functionName":{"name":"abi_decode_array_uint256_dyn","nodeType":"YulIdentifier","src":"7101:28:11"},"nodeType":"YulFunctionCall","src":"7101:63:11"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"7091:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"7173:49:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7206:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"7217:3:11","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7202:3:11"},"nodeType":"YulFunctionCall","src":"7202:19:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7189:12:11"},"nodeType":"YulFunctionCall","src":"7189:33:11"},"variables":[{"name":"offset_2","nodeType":"YulTypedName","src":"7177:8:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"7251:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7260:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"7263:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7253:6:11"},"nodeType":"YulFunctionCall","src":"7253:12:11"},"nodeType":"YulExpressionStatement","src":"7253:12:11"}]},"condition":{"arguments":[{"name":"offset_2","nodeType":"YulIdentifier","src":"7237:8:11"},{"name":"_1","nodeType":"YulIdentifier","src":"7247:2:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"7234:2:11"},"nodeType":"YulFunctionCall","src":"7234:16:11"},"nodeType":"YulIf","src":"7231:36:11"},{"nodeType":"YulAssignment","src":"7276:61:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7307:9:11"},{"name":"offset_2","nodeType":"YulIdentifier","src":"7318:8:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7303:3:11"},"nodeType":"YulFunctionCall","src":"7303:24:11"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"7329:7:11"}],"functionName":{"name":"abi_decode_bytes","nodeType":"YulIdentifier","src":"7286:16:11"},"nodeType":"YulFunctionCall","src":"7286:51:11"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"7276:6:11"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_array$_t_uint256_$dyn_memory_ptrt_array$_t_uint256_$dyn_memory_ptrt_bytes_memory_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"6403:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"6414:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"6426:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"6434:6:11","type":""},{"name":"value2","nodeType":"YulTypedName","src":"6442:6:11","type":""},{"name":"value3","nodeType":"YulTypedName","src":"6450:6:11","type":""},{"name":"value4","nodeType":"YulTypedName","src":"6458:6:11","type":""}],"src":"6272:1071:11"},{"body":{"nodeType":"YulBlock","src":"7449:76:11","statements":[{"nodeType":"YulAssignment","src":"7459:26:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7471:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"7482:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7467:3:11"},"nodeType":"YulFunctionCall","src":"7467:18:11"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"7459:4:11"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7501:9:11"},{"name":"value0","nodeType":"YulIdentifier","src":"7512:6:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7494:6:11"},"nodeType":"YulFunctionCall","src":"7494:25:11"},"nodeType":"YulExpressionStatement","src":"7494:25:11"}]},"name":"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"7418:9:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"7429:6:11","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"7440:4:11","type":""}],"src":"7348:177:11"},{"body":{"nodeType":"YulBlock","src":"7600:110:11","statements":[{"body":{"nodeType":"YulBlock","src":"7646:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7655:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"7658:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7648:6:11"},"nodeType":"YulFunctionCall","src":"7648:12:11"},"nodeType":"YulExpressionStatement","src":"7648:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"7621:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"7630:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"7617:3:11"},"nodeType":"YulFunctionCall","src":"7617:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"7642:2:11","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"7613:3:11"},"nodeType":"YulFunctionCall","src":"7613:32:11"},"nodeType":"YulIf","src":"7610:52:11"},{"nodeType":"YulAssignment","src":"7671:33:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7694:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7681:12:11"},"nodeType":"YulFunctionCall","src":"7681:23:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"7671:6:11"}]}]},"name":"abi_decode_tuple_t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"7566:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"7577:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"7589:6:11","type":""}],"src":"7530:180:11"},{"body":{"nodeType":"YulBlock","src":"7862:587:11","statements":[{"body":{"nodeType":"YulBlock","src":"7909:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7918:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"7921:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7911:6:11"},"nodeType":"YulFunctionCall","src":"7911:12:11"},"nodeType":"YulExpressionStatement","src":"7911:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"7883:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"7892:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"7879:3:11"},"nodeType":"YulFunctionCall","src":"7879:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"7904:3:11","type":"","value":"160"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"7875:3:11"},"nodeType":"YulFunctionCall","src":"7875:33:11"},"nodeType":"YulIf","src":"7872:53:11"},{"nodeType":"YulVariableDeclaration","src":"7934:36:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7960:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7947:12:11"},"nodeType":"YulFunctionCall","src":"7947:23:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"7938:5:11","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"8004:5:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"7979:24:11"},"nodeType":"YulFunctionCall","src":"7979:31:11"},"nodeType":"YulExpressionStatement","src":"7979:31:11"},{"nodeType":"YulAssignment","src":"8019:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"8029:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"8019:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"8043:47:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8075:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"8086:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8071:3:11"},"nodeType":"YulFunctionCall","src":"8071:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8058:12:11"},"nodeType":"YulFunctionCall","src":"8058:32:11"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"8047:7:11","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"8124:7:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"8099:24:11"},"nodeType":"YulFunctionCall","src":"8099:33:11"},"nodeType":"YulExpressionStatement","src":"8099:33:11"},{"nodeType":"YulAssignment","src":"8141:17:11","value":{"name":"value_1","nodeType":"YulIdentifier","src":"8151:7:11"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"8141:6:11"}]},{"nodeType":"YulAssignment","src":"8167:42:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8194:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"8205:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8190:3:11"},"nodeType":"YulFunctionCall","src":"8190:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8177:12:11"},"nodeType":"YulFunctionCall","src":"8177:32:11"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"8167:6:11"}]},{"nodeType":"YulAssignment","src":"8218:42:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8245:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"8256:2:11","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8241:3:11"},"nodeType":"YulFunctionCall","src":"8241:18:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8228:12:11"},"nodeType":"YulFunctionCall","src":"8228:32:11"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"8218:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"8269:47:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8300:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"8311:3:11","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8296:3:11"},"nodeType":"YulFunctionCall","src":"8296:19:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8283:12:11"},"nodeType":"YulFunctionCall","src":"8283:33:11"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"8273:6:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"8359:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"8368:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"8371:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"8361:6:11"},"nodeType":"YulFunctionCall","src":"8361:12:11"},"nodeType":"YulExpressionStatement","src":"8361:12:11"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"8331:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"8339:18:11","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"8328:2:11"},"nodeType":"YulFunctionCall","src":"8328:30:11"},"nodeType":"YulIf","src":"8325:50:11"},{"nodeType":"YulAssignment","src":"8384:59:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8415:9:11"},{"name":"offset","nodeType":"YulIdentifier","src":"8426:6:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8411:3:11"},"nodeType":"YulFunctionCall","src":"8411:22:11"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"8435:7:11"}],"functionName":{"name":"abi_decode_bytes","nodeType":"YulIdentifier","src":"8394:16:11"},"nodeType":"YulFunctionCall","src":"8394:49:11"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"8384:6:11"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256t_uint256t_bytes_memory_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"7796:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"7807:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"7819:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"7827:6:11","type":""},{"name":"value2","nodeType":"YulTypedName","src":"7835:6:11","type":""},{"name":"value3","nodeType":"YulTypedName","src":"7843:6:11","type":""},{"name":"value4","nodeType":"YulTypedName","src":"7851:6:11","type":""}],"src":"7715:734:11"},{"body":{"nodeType":"YulBlock","src":"8611:188:11","statements":[{"nodeType":"YulAssignment","src":"8621:26:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8633:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"8644:2:11","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8629:3:11"},"nodeType":"YulFunctionCall","src":"8629:18:11"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"8621:4:11"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8663:9:11"},{"name":"value0","nodeType":"YulIdentifier","src":"8674:6:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8656:6:11"},"nodeType":"YulFunctionCall","src":"8656:25:11"},"nodeType":"YulExpressionStatement","src":"8656:25:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8701:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"8712:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8697:3:11"},"nodeType":"YulFunctionCall","src":"8697:18:11"},{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"8721:6:11"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"8737:3:11","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"8742:1:11","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"8733:3:11"},"nodeType":"YulFunctionCall","src":"8733:11:11"},{"kind":"number","nodeType":"YulLiteral","src":"8746:1:11","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"8729:3:11"},"nodeType":"YulFunctionCall","src":"8729:19:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"8717:3:11"},"nodeType":"YulFunctionCall","src":"8717:32:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8690:6:11"},"nodeType":"YulFunctionCall","src":"8690:60:11"},"nodeType":"YulExpressionStatement","src":"8690:60:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8770:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"8781:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8766:3:11"},"nodeType":"YulFunctionCall","src":"8766:18:11"},{"name":"value2","nodeType":"YulIdentifier","src":"8786:6:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8759:6:11"},"nodeType":"YulFunctionCall","src":"8759:34:11"},"nodeType":"YulExpressionStatement","src":"8759:34:11"}]},"name":"abi_encode_tuple_t_uint256_t_address_t_uint256__to_t_uint256_t_address_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"8564:9:11","type":""},{"name":"value2","nodeType":"YulTypedName","src":"8575:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"8583:6:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"8591:6:11","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"8602:4:11","type":""}],"src":"8454:345:11"},{"body":{"nodeType":"YulBlock","src":"8874:177:11","statements":[{"body":{"nodeType":"YulBlock","src":"8920:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"8929:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"8932:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"8922:6:11"},"nodeType":"YulFunctionCall","src":"8922:12:11"},"nodeType":"YulExpressionStatement","src":"8922:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"8895:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"8904:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"8891:3:11"},"nodeType":"YulFunctionCall","src":"8891:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"8916:2:11","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"8887:3:11"},"nodeType":"YulFunctionCall","src":"8887:32:11"},"nodeType":"YulIf","src":"8884:52:11"},{"nodeType":"YulVariableDeclaration","src":"8945:36:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8971:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8958:12:11"},"nodeType":"YulFunctionCall","src":"8958:23:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"8949:5:11","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"9015:5:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"8990:24:11"},"nodeType":"YulFunctionCall","src":"8990:31:11"},"nodeType":"YulExpressionStatement","src":"8990:31:11"},{"nodeType":"YulAssignment","src":"9030:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"9040:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"9030:6:11"}]}]},"name":"abi_decode_tuple_t_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"8840:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"8851:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"8863:6:11","type":""}],"src":"8804:247:11"},{"body":{"nodeType":"YulBlock","src":"9088:95:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9105:1:11","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9112:3:11","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"9117:10:11","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"9108:3:11"},"nodeType":"YulFunctionCall","src":"9108:20:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9098:6:11"},"nodeType":"YulFunctionCall","src":"9098:31:11"},"nodeType":"YulExpressionStatement","src":"9098:31:11"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9145:1:11","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"9148:4:11","type":"","value":"0x32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9138:6:11"},"nodeType":"YulFunctionCall","src":"9138:15:11"},"nodeType":"YulExpressionStatement","src":"9138:15:11"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9169:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"9172:4:11","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"9162:6:11"},"nodeType":"YulFunctionCall","src":"9162:15:11"},"nodeType":"YulExpressionStatement","src":"9162:15:11"}]},"name":"panic_error_0x32","nodeType":"YulFunctionDefinition","src":"9056:127:11"},{"body":{"nodeType":"YulBlock","src":"9255:206:11","statements":[{"body":{"nodeType":"YulBlock","src":"9301:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9310:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"9313:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"9303:6:11"},"nodeType":"YulFunctionCall","src":"9303:12:11"},"nodeType":"YulExpressionStatement","src":"9303:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"9276:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"9285:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"9272:3:11"},"nodeType":"YulFunctionCall","src":"9272:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"9297:2:11","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"9268:3:11"},"nodeType":"YulFunctionCall","src":"9268:32:11"},"nodeType":"YulIf","src":"9265:52:11"},{"nodeType":"YulVariableDeclaration","src":"9326:36:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9352:9:11"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"9339:12:11"},"nodeType":"YulFunctionCall","src":"9339:23:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"9330:5:11","type":""}]},{"body":{"nodeType":"YulBlock","src":"9415:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9424:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"9427:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"9417:6:11"},"nodeType":"YulFunctionCall","src":"9417:12:11"},"nodeType":"YulExpressionStatement","src":"9417:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"9384:5:11"},{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"9405:5:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"9398:6:11"},"nodeType":"YulFunctionCall","src":"9398:13:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"9391:6:11"},"nodeType":"YulFunctionCall","src":"9391:21:11"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"9381:2:11"},"nodeType":"YulFunctionCall","src":"9381:32:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"9374:6:11"},"nodeType":"YulFunctionCall","src":"9374:40:11"},"nodeType":"YulIf","src":"9371:60:11"},{"nodeType":"YulAssignment","src":"9440:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"9450:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"9440:6:11"}]}]},"name":"abi_decode_tuple_t_bool","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"9221:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"9232:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"9244:6:11","type":""}],"src":"9188:273:11"},{"body":{"nodeType":"YulBlock","src":"9617:234:11","statements":[{"nodeType":"YulAssignment","src":"9627:26:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9639:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"9650:2:11","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9635:3:11"},"nodeType":"YulFunctionCall","src":"9635:18:11"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"9627:4:11"}]},{"nodeType":"YulVariableDeclaration","src":"9662:29:11","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9680:3:11","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"9685:1:11","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"9676:3:11"},"nodeType":"YulFunctionCall","src":"9676:11:11"},{"kind":"number","nodeType":"YulLiteral","src":"9689:1:11","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"9672:3:11"},"nodeType":"YulFunctionCall","src":"9672:19:11"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"9666:2:11","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9707:9:11"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"9722:6:11"},{"name":"_1","nodeType":"YulIdentifier","src":"9730:2:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"9718:3:11"},"nodeType":"YulFunctionCall","src":"9718:15:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9700:6:11"},"nodeType":"YulFunctionCall","src":"9700:34:11"},"nodeType":"YulExpressionStatement","src":"9700:34:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9754:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"9765:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9750:3:11"},"nodeType":"YulFunctionCall","src":"9750:18:11"},{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"9774:6:11"},{"name":"_1","nodeType":"YulIdentifier","src":"9782:2:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"9770:3:11"},"nodeType":"YulFunctionCall","src":"9770:15:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9743:6:11"},"nodeType":"YulFunctionCall","src":"9743:43:11"},"nodeType":"YulExpressionStatement","src":"9743:43:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9806:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"9817:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9802:3:11"},"nodeType":"YulFunctionCall","src":"9802:18:11"},{"arguments":[{"arguments":[{"name":"value2","nodeType":"YulIdentifier","src":"9836:6:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"9829:6:11"},"nodeType":"YulFunctionCall","src":"9829:14:11"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"9822:6:11"},"nodeType":"YulFunctionCall","src":"9822:22:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9795:6:11"},"nodeType":"YulFunctionCall","src":"9795:50:11"},"nodeType":"YulExpressionStatement","src":"9795:50:11"}]},"name":"abi_encode_tuple_t_address_t_address_t_bool__to_t_address_t_address_t_bool__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"9570:9:11","type":""},{"name":"value2","nodeType":"YulTypedName","src":"9581:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"9589:6:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"9597:6:11","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"9608:4:11","type":""}],"src":"9466:385:11"},{"body":{"nodeType":"YulBlock","src":"9888:95:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9905:1:11","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9912:3:11","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"9917:10:11","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"9908:3:11"},"nodeType":"YulFunctionCall","src":"9908:20:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9898:6:11"},"nodeType":"YulFunctionCall","src":"9898:31:11"},"nodeType":"YulExpressionStatement","src":"9898:31:11"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9945:1:11","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"9948:4:11","type":"","value":"0x11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9938:6:11"},"nodeType":"YulFunctionCall","src":"9938:15:11"},"nodeType":"YulExpressionStatement","src":"9938:15:11"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9969:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"9972:4:11","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"9962:6:11"},"nodeType":"YulFunctionCall","src":"9962:15:11"},"nodeType":"YulExpressionStatement","src":"9962:15:11"}]},"name":"panic_error_0x11","nodeType":"YulFunctionDefinition","src":"9856:127:11"},{"body":{"nodeType":"YulBlock","src":"10035:88:11","statements":[{"body":{"nodeType":"YulBlock","src":"10066:22:11","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x11","nodeType":"YulIdentifier","src":"10068:16:11"},"nodeType":"YulFunctionCall","src":"10068:18:11"},"nodeType":"YulExpressionStatement","src":"10068:18:11"}]},"condition":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"10051:5:11"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10062:1:11","type":"","value":"0"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"10058:3:11"},"nodeType":"YulFunctionCall","src":"10058:6:11"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"10048:2:11"},"nodeType":"YulFunctionCall","src":"10048:17:11"},"nodeType":"YulIf","src":"10045:43:11"},{"nodeType":"YulAssignment","src":"10097:20:11","value":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"10108:5:11"},{"kind":"number","nodeType":"YulLiteral","src":"10115:1:11","type":"","value":"1"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10104:3:11"},"nodeType":"YulFunctionCall","src":"10104:13:11"},"variableNames":[{"name":"ret","nodeType":"YulIdentifier","src":"10097:3:11"}]}]},"name":"increment_t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"value","nodeType":"YulTypedName","src":"10017:5:11","type":""}],"returnVariables":[{"name":"ret","nodeType":"YulTypedName","src":"10027:3:11","type":""}],"src":"9988:135:11"},{"body":{"nodeType":"YulBlock","src":"10209:170:11","statements":[{"body":{"nodeType":"YulBlock","src":"10255:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10264:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"10267:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"10257:6:11"},"nodeType":"YulFunctionCall","src":"10257:12:11"},"nodeType":"YulExpressionStatement","src":"10257:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"10230:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"10239:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"10226:3:11"},"nodeType":"YulFunctionCall","src":"10226:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"10251:2:11","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"10222:3:11"},"nodeType":"YulFunctionCall","src":"10222:32:11"},"nodeType":"YulIf","src":"10219:52:11"},{"nodeType":"YulVariableDeclaration","src":"10280:29:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10299:9:11"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"10293:5:11"},"nodeType":"YulFunctionCall","src":"10293:16:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"10284:5:11","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"10343:5:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"10318:24:11"},"nodeType":"YulFunctionCall","src":"10318:31:11"},"nodeType":"YulExpressionStatement","src":"10318:31:11"},{"nodeType":"YulAssignment","src":"10358:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"10368:5:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"10358:6:11"}]}]},"name":"abi_decode_tuple_t_address_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"10175:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"10186:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"10198:6:11","type":""}],"src":"10128:251:11"},{"body":{"nodeType":"YulBlock","src":"10513:259:11","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10530:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"10541:2:11","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10523:6:11"},"nodeType":"YulFunctionCall","src":"10523:21:11"},"nodeType":"YulExpressionStatement","src":"10523:21:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10564:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"10575:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10560:3:11"},"nodeType":"YulFunctionCall","src":"10560:18:11"},{"name":"value1","nodeType":"YulIdentifier","src":"10580:6:11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10553:6:11"},"nodeType":"YulFunctionCall","src":"10553:34:11"},"nodeType":"YulExpressionStatement","src":"10553:34:11"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10613:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"10624:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10609:3:11"},"nodeType":"YulFunctionCall","src":"10609:18:11"},{"name":"value0","nodeType":"YulIdentifier","src":"10629:6:11"},{"name":"value1","nodeType":"YulIdentifier","src":"10637:6:11"}],"functionName":{"name":"calldatacopy","nodeType":"YulIdentifier","src":"10596:12:11"},"nodeType":"YulFunctionCall","src":"10596:48:11"},"nodeType":"YulExpressionStatement","src":"10596:48:11"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10668:9:11"},{"name":"value1","nodeType":"YulIdentifier","src":"10679:6:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10664:3:11"},"nodeType":"YulFunctionCall","src":"10664:22:11"},{"kind":"number","nodeType":"YulLiteral","src":"10688:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10660:3:11"},"nodeType":"YulFunctionCall","src":"10660:31:11"},{"kind":"number","nodeType":"YulLiteral","src":"10693:1:11","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10653:6:11"},"nodeType":"YulFunctionCall","src":"10653:42:11"},"nodeType":"YulExpressionStatement","src":"10653:42:11"},{"nodeType":"YulAssignment","src":"10704:62:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10720:9:11"},{"arguments":[{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"10739:6:11"},{"kind":"number","nodeType":"YulLiteral","src":"10747:2:11","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10735:3:11"},"nodeType":"YulFunctionCall","src":"10735:15:11"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10756:2:11","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"10752:3:11"},"nodeType":"YulFunctionCall","src":"10752:7:11"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"10731:3:11"},"nodeType":"YulFunctionCall","src":"10731:29:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10716:3:11"},"nodeType":"YulFunctionCall","src":"10716:45:11"},{"kind":"number","nodeType":"YulLiteral","src":"10763:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10712:3:11"},"nodeType":"YulFunctionCall","src":"10712:54:11"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"10704:4:11"}]}]},"name":"abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"10474:9:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"10485:6:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"10493:6:11","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"10504:4:11","type":""}],"src":"10384:388:11"},{"body":{"nodeType":"YulBlock","src":"10825:77:11","statements":[{"nodeType":"YulAssignment","src":"10835:16:11","value":{"arguments":[{"name":"x","nodeType":"YulIdentifier","src":"10846:1:11"},{"name":"y","nodeType":"YulIdentifier","src":"10849:1:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10842:3:11"},"nodeType":"YulFunctionCall","src":"10842:9:11"},"variableNames":[{"name":"sum","nodeType":"YulIdentifier","src":"10835:3:11"}]},{"body":{"nodeType":"YulBlock","src":"10874:22:11","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x11","nodeType":"YulIdentifier","src":"10876:16:11"},"nodeType":"YulFunctionCall","src":"10876:18:11"},"nodeType":"YulExpressionStatement","src":"10876:18:11"}]},"condition":{"arguments":[{"name":"x","nodeType":"YulIdentifier","src":"10866:1:11"},{"name":"sum","nodeType":"YulIdentifier","src":"10869:3:11"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"10863:2:11"},"nodeType":"YulFunctionCall","src":"10863:10:11"},"nodeType":"YulIf","src":"10860:36:11"}]},"name":"checked_add_t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"x","nodeType":"YulTypedName","src":"10808:1:11","type":""},{"name":"y","nodeType":"YulTypedName","src":"10811:1:11","type":""}],"returnVariables":[{"name":"sum","nodeType":"YulTypedName","src":"10817:3:11","type":""}],"src":"10777:125:11"},{"body":{"nodeType":"YulBlock","src":"11030:258:11","statements":[{"body":{"nodeType":"YulBlock","src":"11076:16:11","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"11085:1:11","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"11088:1:11","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"11078:6:11"},"nodeType":"YulFunctionCall","src":"11078:12:11"},"nodeType":"YulExpressionStatement","src":"11078:12:11"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"11051:7:11"},{"name":"headStart","nodeType":"YulIdentifier","src":"11060:9:11"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"11047:3:11"},"nodeType":"YulFunctionCall","src":"11047:23:11"},{"kind":"number","nodeType":"YulLiteral","src":"11072:2:11","type":"","value":"96"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"11043:3:11"},"nodeType":"YulFunctionCall","src":"11043:32:11"},"nodeType":"YulIf","src":"11040:52:11"},{"nodeType":"YulAssignment","src":"11101:26:11","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11117:9:11"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"11111:5:11"},"nodeType":"YulFunctionCall","src":"11111:16:11"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"11101:6:11"}]},{"nodeType":"YulVariableDeclaration","src":"11136:38:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11159:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"11170:2:11","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11155:3:11"},"nodeType":"YulFunctionCall","src":"11155:18:11"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"11149:5:11"},"nodeType":"YulFunctionCall","src":"11149:25:11"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"11140:5:11","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"11208:5:11"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"11183:24:11"},"nodeType":"YulFunctionCall","src":"11183:31:11"},"nodeType":"YulExpressionStatement","src":"11183:31:11"},{"nodeType":"YulAssignment","src":"11223:15:11","value":{"name":"value","nodeType":"YulIdentifier","src":"11233:5:11"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"11223:6:11"}]},{"nodeType":"YulAssignment","src":"11247:35:11","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11267:9:11"},{"kind":"number","nodeType":"YulLiteral","src":"11278:2:11","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11263:3:11"},"nodeType":"YulFunctionCall","src":"11263:18:11"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"11257:5:11"},"nodeType":"YulFunctionCall","src":"11257:25:11"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"11247:6:11"}]}]},"name":"abi_decode_tuple_t_uint256t_address_payablet_uint256_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"10980:9:11","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"10991:7:11","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"11003:6:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"11011:6:11","type":""},{"name":"value2","nodeType":"YulTypedName","src":"11019:6:11","type":""}],"src":"10907:381:11"},{"body":{"nodeType":"YulBlock","src":"11440:124:11","statements":[{"expression":{"arguments":[{"name":"pos","nodeType":"YulIdentifier","src":"11463:3:11"},{"name":"value0","nodeType":"YulIdentifier","src":"11468:6:11"},{"name":"value1","nodeType":"YulIdentifier","src":"11476:6:11"}],"functionName":{"name":"calldatacopy","nodeType":"YulIdentifier","src":"11450:12:11"},"nodeType":"YulFunctionCall","src":"11450:33:11"},"nodeType":"YulExpressionStatement","src":"11450:33:11"},{"nodeType":"YulVariableDeclaration","src":"11492:26:11","value":{"arguments":[{"name":"pos","nodeType":"YulIdentifier","src":"11506:3:11"},{"name":"value1","nodeType":"YulIdentifier","src":"11511:6:11"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11502:3:11"},"nodeType":"YulFunctionCall","src":"11502:16:11"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"11496:2:11","type":""}]},{"expression":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"11534:2:11"},{"kind":"number","nodeType":"YulLiteral","src":"11538:1:11","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"11527:6:11"},"nodeType":"YulFunctionCall","src":"11527:13:11"},"nodeType":"YulExpressionStatement","src":"11527:13:11"},{"nodeType":"YulAssignment","src":"11549:9:11","value":{"name":"_1","nodeType":"YulIdentifier","src":"11556:2:11"},"variableNames":[{"name":"end","nodeType":"YulIdentifier","src":"11549:3:11"}]}]},"name":"abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"pos","nodeType":"YulTypedName","src":"11408:3:11","type":""},{"name":"value1","nodeType":"YulTypedName","src":"11413:6:11","type":""},{"name":"value0","nodeType":"YulTypedName","src":"11421:6:11","type":""}],"returnVariables":[{"name":"end","nodeType":"YulTypedName","src":"11432:3:11","type":""}],"src":"11293:271:11"}]},"contents":"{\n { }\n function abi_decode_tuple_t_bytes4(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := calldataload(headStart)\n if iszero(eq(value, and(value, shl(224, 0xffffffff)))) { revert(0, 0) }\n value0 := value\n }\n function abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, iszero(iszero(value0)))\n }\n function abi_decode_array_address_dyn_calldata(offset, end) -> arrayPos, length\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n length := calldataload(offset)\n if gt(length, 0xffffffffffffffff) { revert(0, 0) }\n arrayPos := add(offset, 0x20)\n if gt(add(add(offset, shl(5, length)), 0x20), end) { revert(0, 0) }\n }\n function abi_decode_tuple_t_array$_t_address_$dyn_calldata_ptrt_array$_t_bool_$dyn_calldata_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n let offset := calldataload(headStart)\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n let value0_1, value1_1 := abi_decode_array_address_dyn_calldata(add(headStart, offset), dataEnd)\n value0 := value0_1\n value1 := value1_1\n let offset_1 := calldataload(add(headStart, 32))\n if gt(offset_1, _1) { revert(0, 0) }\n let value2_1, value3_1 := abi_decode_array_address_dyn_calldata(add(headStart, offset_1), dataEnd)\n value2 := value2_1\n value3 := value3_1\n }\n function validator_revert_address(value)\n {\n if iszero(eq(value, and(value, sub(shl(160, 1), 1)))) { revert(0, 0) }\n }\n function panic_error_0x41()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x41)\n revert(0, 0x24)\n }\n function allocate_memory(size) -> memPtr\n {\n memPtr := mload(64)\n let newFreePtr := add(memPtr, and(add(size, 31), not(31)))\n if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n mstore(64, newFreePtr)\n }\n function abi_decode_bytes(offset, end) -> array\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n let _1 := calldataload(offset)\n if gt(_1, 0xffffffffffffffff) { panic_error_0x41() }\n let array_1 := allocate_memory(add(and(add(_1, 0x1f), not(31)), 0x20))\n mstore(array_1, _1)\n if gt(add(add(offset, _1), 0x20), end) { revert(0, 0) }\n calldatacopy(add(array_1, 0x20), add(offset, 0x20), _1)\n mstore(add(add(array_1, _1), 0x20), 0)\n array := array_1\n }\n function abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 128) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n value2 := calldataload(add(headStart, 64))\n let offset := calldataload(add(headStart, 96))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n value3 := abi_decode_bytes(add(headStart, offset), dataEnd)\n }\n function abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, shl(224, 0xffffffff)))\n }\n function abi_decode_tuple_t_addresst_address(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n }\n function abi_encode_tuple_t_address__to_t_address__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, sub(shl(160, 1), 1)))\n }\n function abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 96) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n value1 := calldataload(add(headStart, 32))\n let offset := calldataload(add(headStart, 64))\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n let _2 := add(headStart, offset)\n if iszero(slt(add(_2, 0x1f), dataEnd)) { revert(0, 0) }\n let length := calldataload(_2)\n if gt(length, _1) { revert(0, 0) }\n if gt(add(add(_2, length), 32), dataEnd) { revert(0, 0) }\n value2 := add(_2, 32)\n value3 := length\n }\n function abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value0) -> tail\n {\n let _1 := 32\n mstore(headStart, _1)\n let length := mload(value0)\n mstore(add(headStart, _1), length)\n let i := 0\n for { } lt(i, length) { i := add(i, _1) }\n {\n mstore(add(add(headStart, i), 64), mload(add(add(value0, i), _1)))\n }\n mstore(add(add(headStart, length), 64), 0)\n tail := add(add(headStart, and(add(length, 31), not(31))), 64)\n }\n function abi_decode_array_uint256_dyn(offset, end) -> array\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n let _1 := calldataload(offset)\n let _2 := 0x20\n if gt(_1, 0xffffffffffffffff) { panic_error_0x41() }\n let _3 := shl(5, _1)\n let dst := allocate_memory(add(_3, _2))\n let dst_1 := dst\n mstore(dst, _1)\n dst := add(dst, _2)\n let srcEnd := add(add(offset, _3), _2)\n if gt(srcEnd, end) { revert(0, 0) }\n let src := add(offset, _2)\n for { } lt(src, srcEnd) { src := add(src, _2) }\n {\n mstore(dst, calldataload(src))\n dst := add(dst, _2)\n }\n array := dst_1\n }\n function abi_decode_tuple_t_addresst_addresst_array$_t_uint256_$dyn_memory_ptrt_array$_t_uint256_$dyn_memory_ptrt_bytes_memory_ptr(headStart, dataEnd) -> value0, value1, value2, value3, value4\n {\n if slt(sub(dataEnd, headStart), 160) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n let offset := calldataload(add(headStart, 64))\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n value2 := abi_decode_array_uint256_dyn(add(headStart, offset), dataEnd)\n let offset_1 := calldataload(add(headStart, 96))\n if gt(offset_1, _1) { revert(0, 0) }\n value3 := abi_decode_array_uint256_dyn(add(headStart, offset_1), dataEnd)\n let offset_2 := calldataload(add(headStart, 128))\n if gt(offset_2, _1) { revert(0, 0) }\n value4 := abi_decode_bytes(add(headStart, offset_2), dataEnd)\n }\n function abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, value0)\n }\n function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n value0 := calldataload(headStart)\n }\n function abi_decode_tuple_t_addresst_addresst_uint256t_uint256t_bytes_memory_ptr(headStart, dataEnd) -> value0, value1, value2, value3, value4\n {\n if slt(sub(dataEnd, headStart), 160) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n value2 := calldataload(add(headStart, 64))\n value3 := calldataload(add(headStart, 96))\n let offset := calldataload(add(headStart, 128))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n value4 := abi_decode_bytes(add(headStart, offset), dataEnd)\n }\n function abi_encode_tuple_t_uint256_t_address_t_uint256__to_t_uint256_t_address_t_uint256__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n tail := add(headStart, 96)\n mstore(headStart, value0)\n mstore(add(headStart, 32), and(value1, sub(shl(160, 1), 1)))\n mstore(add(headStart, 64), value2)\n }\n function abi_decode_tuple_t_address(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n }\n function panic_error_0x32()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x32)\n revert(0, 0x24)\n }\n function abi_decode_tuple_t_bool(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := calldataload(headStart)\n if iszero(eq(value, iszero(iszero(value)))) { revert(0, 0) }\n value0 := value\n }\n function abi_encode_tuple_t_address_t_address_t_bool__to_t_address_t_address_t_bool__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n tail := add(headStart, 96)\n let _1 := sub(shl(160, 1), 1)\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), and(value1, _1))\n mstore(add(headStart, 64), iszero(iszero(value2)))\n }\n function panic_error_0x11()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x11)\n revert(0, 0x24)\n }\n function increment_t_uint256(value) -> ret\n {\n if eq(value, not(0)) { panic_error_0x11() }\n ret := add(value, 1)\n }\n function abi_decode_tuple_t_address_fromMemory(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := mload(headStart)\n validator_revert_address(value)\n value0 := value\n }\n function abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value1, value0) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), value1)\n calldatacopy(add(headStart, 64), value0, value1)\n mstore(add(add(headStart, value1), 64), 0)\n tail := add(add(headStart, and(add(value1, 31), not(31))), 64)\n }\n function checked_add_t_uint256(x, y) -> sum\n {\n sum := add(x, y)\n if gt(x, sum) { panic_error_0x11() }\n }\n function abi_decode_tuple_t_uint256t_address_payablet_uint256_fromMemory(headStart, dataEnd) -> value0, value1, value2\n {\n if slt(sub(dataEnd, headStart), 96) { revert(0, 0) }\n value0 := mload(headStart)\n let value := mload(add(headStart, 32))\n validator_revert_address(value)\n value1 := value\n value2 := mload(add(headStart, 64))\n }\n function abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed(pos, value1, value0) -> end\n {\n calldatacopy(pos, value0, value1)\n let _1 := add(pos, value1)\n mstore(_1, 0)\n end := _1\n }\n}","id":11,"language":"Yul","name":"#utility.yul"}],"immutableReferences":{},"linkReferences":{},"object":"6080604052600436106100c65760003560e01c8063a4e2d6341161007f578063dd46706411610059578063dd46706414610251578063f23a6e6114610271578063fc0c546a1461029d578063fe9fbb80146102d557600080fd5b8063a4e2d634146101ea578063bc197c8114610201578063ce0617ec1461022d57600080fd5b806301ffc9a7146100d2578063039721b114610107578063150b7a02146101295780631f9838b5146101625780638da5cb5b1461019d5780639e5d4c49146101ca57600080fd5b366100cd57005b600080fd5b3480156100de57600080fd5b506100f26100ed36600461095c565b6102f5565b60405190151581526020015b60405180910390f35b34801561011357600080fd5b506101276101223660046109d9565b61035c565b005b34801561013557600080fd5b50610149610144366004610b14565b610525565b6040516001600160e01b031990911681526020016100fe565b34801561016e57600080fd5b506100f261017d366004610b80565b600160209081526000928352604080842090915290825290205460ff1681565b3480156101a957600080fd5b506101b261058d565b6040516001600160a01b0390911681526020016100fe565b6101dd6101d8366004610bb9565b610623565b6040516100fe9190610c42565b3480156101f657600080fd5b5060005442106100f2565b34801561020d57600080fd5b5061014961021c366004610d10565b63bc197c8160e01b95945050505050565b34801561023957600080fd5b5061024360005481565b6040519081526020016100fe565b34801561025d57600080fd5b5061012761026c366004610dbe565b6106c7565b34801561027d57600080fd5b5061014961028c366004610dd7565b63f23a6e6160e01b95945050505050565b3480156102a957600080fd5b506102b261078c565b604080519384526001600160a01b039092166020840152908201526060016100fe565b3480156102e157600080fd5b506100f26102f0366004610e40565b6107a4565b6000806001600160e01b031983166301ffc9a760e01b148061032757506001600160e01b03198316630271189760e51b145b8061034257506001600160e01b03198316631dfe9a6f60e31b145b905080156103535750600192915050565b50600092915050565b60005442101561037f57604051636315bfbb60e01b815260040160405180910390fd5b600061038961058d565b9050336001600160a01b038216146103b45760405163ea8e4eb560e01b815260040160405180910390fd5b838281146103d55760405163b4fa3fb360e01b815260040160405180910390fd5b60005b8181101561051c578484828181106103f2576103f2610e5d565b90506020020160208101906104079190610e73565b6001600160a01b03841660009081526001602052604081209089898581811061043257610432610e5d565b90506020020160208101906104479190610e40565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f394777a58092892d136a90c4bb7e4350c72ac50fba6a0208128677f36527dcf5838888848181106104a3576104a3610e5d565b90506020020160208101906104b89190610e40565b8787858181106104ca576104ca610e5d565b90506020020160208101906104df9190610e73565b604080516001600160a01b03948516815293909216602084015215159082015260600160405180910390a18061051481610eab565b9150506103d8565b50505050505050565b60008060008061053361088d565b925092509250468314801561055057506001600160a01b03821633145b801561055b57508581145b156105795760405163b79e3f3f60e01b815260040160405180910390fd5b50630a85bd0160e11b979650505050505050565b60008060008061059b61088d565b9250925092504683146105b2576000935050505090565b6040516331a9108f60e11b8152600481018290526001600160a01b03831690636352211e90602401602060405180830381865afa1580156105f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061b9190610ec4565b935050505090565b606061062e336107a4565b61064b5760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561066e57604051636315bfbb60e01b815260040160405180910390fd5b83856001600160a01b03167f47d99ad340f52da66535aff7e10da1ceb85a32bcbd9fa1c42314d194545e14d285856040516106aa929190610ee1565b60405180910390a36106be858585856108e0565b95945050505050565b6106cf61058d565b6001600160a01b0316336001600160a01b0316146107005760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561072357604051636315bfbb60e01b815260040160405180910390fd5b610731426301e13380610f10565b811115610751576040516301814f7d60e31b815260040160405180910390fd5b60008190556040518181527fa7b24c66dd3269a292a60b3facdbb8f3e7557d1e19e64d99e0d6ee7250be63ad9060200160405180910390a150565b600080600061079961088d565b925092509250909192565b60008060006107b161088d565b6040516331a9108f60e11b8152600481018290529194509250600091506001600160a01b03841690636352211e90602401602060405180830381865afa1580156107ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108239190610ec4565b9050806001600160a01b0316856001600160a01b03160361084957506001949350505050565b6001600160a01b0380821660009081526001602090815260408083209389168352929052205460ff161561088257506001949350505050565b506000949350505050565b604080516060808252608082019092526000918291829182919060208201818036833701905050905060ad604d60208301303c808060200190518101906108d49190610f29565b93509350935050909192565b60606000856001600160a01b03168585856040516108ff929190610f62565b60006040518083038185875af1925050503d806000811461093c576040519150601f19603f3d011682016040523d82523d6000602084013e610941565b606091505b50925090508061095357815160208301fd5b50949350505050565b60006020828403121561096e57600080fd5b81356001600160e01b03198116811461098657600080fd5b9392505050565b60008083601f84011261099f57600080fd5b50813567ffffffffffffffff8111156109b757600080fd5b6020830191508360208260051b85010111156109d257600080fd5b9250929050565b600080600080604085870312156109ef57600080fd5b843567ffffffffffffffff80821115610a0757600080fd5b610a138883890161098d565b90965094506020870135915080821115610a2c57600080fd5b50610a398782880161098d565b95989497509550505050565b6001600160a01b0381168114610a5a57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610a9c57610a9c610a5d565b604052919050565b600082601f830112610ab557600080fd5b813567ffffffffffffffff811115610acf57610acf610a5d565b610ae2601f8201601f1916602001610a73565b818152846020838601011115610af757600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215610b2a57600080fd5b8435610b3581610a45565b93506020850135610b4581610a45565b925060408501359150606085013567ffffffffffffffff811115610b6857600080fd5b610b7487828801610aa4565b91505092959194509250565b60008060408385031215610b9357600080fd5b8235610b9e81610a45565b91506020830135610bae81610a45565b809150509250929050565b60008060008060608587031215610bcf57600080fd5b8435610bda81610a45565b935060208501359250604085013567ffffffffffffffff80821115610bfe57600080fd5b818701915087601f830112610c1257600080fd5b813581811115610c2157600080fd5b886020828501011115610c3357600080fd5b95989497505060200194505050565b600060208083528351808285015260005b81811015610c6f57858101830151858201604001528201610c53565b506000604082860101526040601f19601f8301168501019250505092915050565b600082601f830112610ca157600080fd5b8135602067ffffffffffffffff821115610cbd57610cbd610a5d565b8160051b610ccc828201610a73565b9283528481018201928281019087851115610ce657600080fd5b83870192505b84831015610d0557823582529183019190830190610cec565b979650505050505050565b600080600080600060a08688031215610d2857600080fd5b8535610d3381610a45565b94506020860135610d4381610a45565b9350604086013567ffffffffffffffff80821115610d6057600080fd5b610d6c89838a01610c90565b94506060880135915080821115610d8257600080fd5b610d8e89838a01610c90565b93506080880135915080821115610da457600080fd5b50610db188828901610aa4565b9150509295509295909350565b600060208284031215610dd057600080fd5b5035919050565b600080600080600060a08688031215610def57600080fd5b8535610dfa81610a45565b94506020860135610e0a81610a45565b93506040860135925060608601359150608086013567ffffffffffffffff811115610e3457600080fd5b610db188828901610aa4565b600060208284031215610e5257600080fd5b813561098681610a45565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610e8557600080fd5b8135801515811461098657600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610ebd57610ebd610e95565b5060010190565b600060208284031215610ed657600080fd5b815161098681610a45565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b80820180821115610f2357610f23610e95565b92915050565b600080600060608486031215610f3e57600080fd5b835192506020840151610f5081610a45565b80925050604084015190509250925092565b818382376000910190815291905056fea26469706673582212208586a5aa87cff87a1d8e1dc4952c1d3b167ebfafab4c2b56ed97ed8a5ec5921664736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xC6 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0xA4E2D634 GT PUSH2 0x7F JUMPI DUP1 PUSH4 0xDD467064 GT PUSH2 0x59 JUMPI DUP1 PUSH4 0xDD467064 EQ PUSH2 0x251 JUMPI DUP1 PUSH4 0xF23A6E61 EQ PUSH2 0x271 JUMPI DUP1 PUSH4 0xFC0C546A EQ PUSH2 0x29D JUMPI DUP1 PUSH4 0xFE9FBB80 EQ PUSH2 0x2D5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0xA4E2D634 EQ PUSH2 0x1EA JUMPI DUP1 PUSH4 0xBC197C81 EQ PUSH2 0x201 JUMPI DUP1 PUSH4 0xCE0617EC EQ PUSH2 0x22D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1FFC9A7 EQ PUSH2 0xD2 JUMPI DUP1 PUSH4 0x39721B1 EQ PUSH2 0x107 JUMPI DUP1 PUSH4 0x150B7A02 EQ PUSH2 0x129 JUMPI DUP1 PUSH4 0x1F9838B5 EQ PUSH2 0x162 JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x19D JUMPI DUP1 PUSH4 0x9E5D4C49 EQ PUSH2 0x1CA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST CALLDATASIZE PUSH2 0xCD JUMPI STOP JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xDE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xF2 PUSH2 0xED CALLDATASIZE PUSH1 0x4 PUSH2 0x95C JUMP JUMPDEST PUSH2 0x2F5 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x113 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x127 PUSH2 0x122 CALLDATASIZE PUSH1 0x4 PUSH2 0x9D9 JUMP JUMPDEST PUSH2 0x35C JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x135 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x149 PUSH2 0x144 CALLDATASIZE PUSH1 0x4 PUSH2 0xB14 JUMP JUMPDEST PUSH2 0x525 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xFE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x16E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xF2 PUSH2 0x17D CALLDATASIZE PUSH1 0x4 PUSH2 0xB80 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1A9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B2 PUSH2 0x58D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xFE JUMP JUMPDEST PUSH2 0x1DD PUSH2 0x1D8 CALLDATASIZE PUSH1 0x4 PUSH2 0xBB9 JUMP JUMPDEST PUSH2 0x623 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xFE SWAP2 SWAP1 PUSH2 0xC42 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1F6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x0 SLOAD TIMESTAMP LT PUSH2 0xF2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x20D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x149 PUSH2 0x21C CALLDATASIZE PUSH1 0x4 PUSH2 0xD10 JUMP JUMPDEST PUSH4 0xBC197C81 PUSH1 0xE0 SHL SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x239 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x243 PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xFE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x25D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x127 PUSH2 0x26C CALLDATASIZE PUSH1 0x4 PUSH2 0xDBE JUMP JUMPDEST PUSH2 0x6C7 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x27D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x149 PUSH2 0x28C CALLDATASIZE PUSH1 0x4 PUSH2 0xDD7 JUMP JUMPDEST PUSH4 0xF23A6E61 PUSH1 0xE0 SHL SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2A9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2B2 PUSH2 0x78C JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP4 DUP5 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE SWAP1 DUP3 ADD MSTORE PUSH1 0x60 ADD PUSH2 0xFE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2E1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xF2 PUSH2 0x2F0 CALLDATASIZE PUSH1 0x4 PUSH2 0xE40 JUMP JUMPDEST PUSH2 0x7A4 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x1FFC9A7 PUSH1 0xE0 SHL EQ DUP1 PUSH2 0x327 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x2711897 PUSH1 0xE5 SHL EQ JUMPDEST DUP1 PUSH2 0x342 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x1DFE9A6F PUSH1 0xE3 SHL EQ JUMPDEST SWAP1 POP DUP1 ISZERO PUSH2 0x353 JUMPI POP PUSH1 0x1 SWAP3 SWAP2 POP POP JUMP JUMPDEST POP PUSH1 0x0 SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x37F JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x389 PUSH2 0x58D JUMP JUMPDEST SWAP1 POP CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND EQ PUSH2 0x3B4 JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 DUP3 DUP2 EQ PUSH2 0x3D5 JUMPI PUSH1 0x40 MLOAD PUSH4 0xB4FA3FB3 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x51C JUMPI DUP5 DUP5 DUP3 DUP2 DUP2 LT PUSH2 0x3F2 JUMPI PUSH2 0x3F2 PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x407 SWAP2 SWAP1 PUSH2 0xE73 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 SWAP1 DUP10 DUP10 DUP6 DUP2 DUP2 LT PUSH2 0x432 JUMPI PUSH2 0x432 PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x447 SWAP2 SWAP1 PUSH2 0xE40 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP2 MSTORE PUSH1 0x20 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 ADD PUSH1 0x0 KECCAK256 DUP1 SLOAD PUSH1 0xFF NOT AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH32 0x394777A58092892D136A90C4BB7E4350C72AC50FBA6A0208128677F36527DCF5 DUP4 DUP9 DUP9 DUP5 DUP2 DUP2 LT PUSH2 0x4A3 JUMPI PUSH2 0x4A3 PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x4B8 SWAP2 SWAP1 PUSH2 0xE40 JUMP JUMPDEST DUP8 DUP8 DUP6 DUP2 DUP2 LT PUSH2 0x4CA JUMPI PUSH2 0x4CA PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x4DF SWAP2 SWAP1 PUSH2 0xE73 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP5 DUP6 AND DUP2 MSTORE SWAP4 SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE ISZERO ISZERO SWAP1 DUP3 ADD MSTORE PUSH1 0x60 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 DUP1 PUSH2 0x514 DUP2 PUSH2 0xEAB JUMP JUMPDEST SWAP2 POP POP PUSH2 0x3D8 JUMP JUMPDEST POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x533 PUSH2 0x88D JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP CHAINID DUP4 EQ DUP1 ISZERO PUSH2 0x550 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND CALLER EQ JUMPDEST DUP1 ISZERO PUSH2 0x55B JUMPI POP DUP6 DUP2 EQ JUMPDEST ISZERO PUSH2 0x579 JUMPI PUSH1 0x40 MLOAD PUSH4 0xB79E3F3F PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP PUSH4 0xA85BD01 PUSH1 0xE1 SHL SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x59B PUSH2 0x88D JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP CHAINID DUP4 EQ PUSH2 0x5B2 JUMPI PUSH1 0x0 SWAP4 POP POP POP POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x31A9108F PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND SWAP1 PUSH4 0x6352211E SWAP1 PUSH1 0x24 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x5F7 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x61B SWAP2 SWAP1 PUSH2 0xEC4 JUMP JUMPDEST SWAP4 POP POP POP POP SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH2 0x62E CALLER PUSH2 0x7A4 JUMP JUMPDEST PUSH2 0x64B JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x66E JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH32 0x47D99AD340F52DA66535AFF7E10DA1CEB85A32BCBD9FA1C42314D194545E14D2 DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0x6AA SWAP3 SWAP2 SWAP1 PUSH2 0xEE1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 PUSH2 0x6BE DUP6 DUP6 DUP6 DUP6 PUSH2 0x8E0 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0x6CF PUSH2 0x58D JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ PUSH2 0x700 JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x723 JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH2 0x731 TIMESTAMP PUSH4 0x1E13380 PUSH2 0xF10 JUMP JUMPDEST DUP2 GT ISZERO PUSH2 0x751 JUMPI PUSH1 0x40 MLOAD PUSH4 0x1814F7D PUSH1 0xE3 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 DUP2 SWAP1 SSTORE PUSH1 0x40 MLOAD DUP2 DUP2 MSTORE PUSH32 0xA7B24C66DD3269A292A60B3FACDBB8F3E7557D1E19E64D99E0D6EE7250BE63AD SWAP1 PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x799 PUSH2 0x88D JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP SWAP1 SWAP2 SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x7B1 PUSH2 0x88D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x31A9108F PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE SWAP2 SWAP5 POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND SWAP1 PUSH4 0x6352211E SWAP1 PUSH1 0x24 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x7FF JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x823 SWAP2 SWAP1 PUSH2 0xEC4 JUMP JUMPDEST SWAP1 POP DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SUB PUSH2 0x849 JUMPI POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP1 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP10 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x882 JUMPI POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST POP PUSH1 0x0 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 DUP1 DUP3 MSTORE PUSH1 0x80 DUP3 ADD SWAP1 SWAP3 MSTORE PUSH1 0x0 SWAP2 DUP3 SWAP2 DUP3 SWAP2 DUP3 SWAP2 SWAP1 PUSH1 0x20 DUP3 ADD DUP2 DUP1 CALLDATASIZE DUP4 CALLDATACOPY ADD SWAP1 POP POP SWAP1 POP PUSH1 0xAD PUSH1 0x4D PUSH1 0x20 DUP4 ADD ADDRESS EXTCODECOPY DUP1 DUP1 PUSH1 0x20 ADD SWAP1 MLOAD DUP2 ADD SWAP1 PUSH2 0x8D4 SWAP2 SWAP1 PUSH2 0xF29 JUMP JUMPDEST SWAP4 POP SWAP4 POP SWAP4 POP POP SWAP1 SWAP2 SWAP3 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP6 DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0x8FF SWAP3 SWAP2 SWAP1 PUSH2 0xF62 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 GAS CALL SWAP3 POP POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0x93C JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0x941 JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP3 POP SWAP1 POP DUP1 PUSH2 0x953 JUMPI DUP2 MLOAD PUSH1 0x20 DUP4 ADD REVERT JUMPDEST POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x96E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP2 AND DUP2 EQ PUSH2 0x986 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x99F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x9B7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 PUSH1 0x5 SHL DUP6 ADD ADD GT ISZERO PUSH2 0x9D2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x40 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x9EF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xA07 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xA13 DUP9 DUP4 DUP10 ADD PUSH2 0x98D JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP PUSH1 0x20 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xA2C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xA39 DUP8 DUP3 DUP9 ADD PUSH2 0x98D JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0xA5A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT AND DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0xA9C JUMPI PUSH2 0xA9C PUSH2 0xA5D JUMP JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xAB5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xACF JUMPI PUSH2 0xACF PUSH2 0xA5D JUMP JUMPDEST PUSH2 0xAE2 PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT AND PUSH1 0x20 ADD PUSH2 0xA73 JUMP JUMPDEST DUP2 DUP2 MSTORE DUP5 PUSH1 0x20 DUP4 DUP7 ADD ADD GT ISZERO PUSH2 0xAF7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 PUSH1 0x20 DUP6 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 SWAP2 DUP2 ADD PUSH1 0x20 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xB2A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xB35 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH2 0xB45 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD SWAP2 POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xB68 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xB74 DUP8 DUP3 DUP9 ADD PUSH2 0xAA4 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xB93 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH2 0xB9E DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP2 POP PUSH1 0x20 DUP4 ADD CALLDATALOAD PUSH2 0xBAE DUP2 PUSH2 0xA45 JUMP JUMPDEST DUP1 SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x60 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xBCF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xBDA DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xBFE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP8 ADD SWAP2 POP DUP8 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xC12 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP2 DUP2 GT ISZERO PUSH2 0xC21 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP9 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0xC33 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP POP PUSH1 0x20 ADD SWAP5 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 MSTORE DUP4 MLOAD DUP1 DUP3 DUP6 ADD MSTORE PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xC6F JUMPI DUP6 DUP2 ADD DUP4 ADD MLOAD DUP6 DUP3 ADD PUSH1 0x40 ADD MSTORE DUP3 ADD PUSH2 0xC53 JUMP JUMPDEST POP PUSH1 0x0 PUSH1 0x40 DUP3 DUP7 ADD ADD MSTORE PUSH1 0x40 PUSH1 0x1F NOT PUSH1 0x1F DUP4 ADD AND DUP6 ADD ADD SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xCA1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH1 0x20 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0xCBD JUMPI PUSH2 0xCBD PUSH2 0xA5D JUMP JUMPDEST DUP2 PUSH1 0x5 SHL PUSH2 0xCCC DUP3 DUP3 ADD PUSH2 0xA73 JUMP JUMPDEST SWAP3 DUP4 MSTORE DUP5 DUP2 ADD DUP3 ADD SWAP3 DUP3 DUP2 ADD SWAP1 DUP8 DUP6 GT ISZERO PUSH2 0xCE6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 DUP8 ADD SWAP3 POP JUMPDEST DUP5 DUP4 LT ISZERO PUSH2 0xD05 JUMPI DUP3 CALLDATALOAD DUP3 MSTORE SWAP2 DUP4 ADD SWAP2 SWAP1 DUP4 ADD SWAP1 PUSH2 0xCEC JUMP JUMPDEST SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xD28 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xD33 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH2 0xD43 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xD60 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD6C DUP10 DUP4 DUP11 ADD PUSH2 0xC90 JUMP JUMPDEST SWAP5 POP PUSH1 0x60 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xD82 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD8E DUP10 DUP4 DUP11 ADD PUSH2 0xC90 JUMP JUMPDEST SWAP4 POP PUSH1 0x80 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xDA4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xDB1 DUP9 DUP3 DUP10 ADD PUSH2 0xAA4 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 SWAP1 SWAP4 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xDD0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xDEF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xDFA DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH2 0xE0A DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD SWAP3 POP PUSH1 0x60 DUP7 ADD CALLDATALOAD SWAP2 POP PUSH1 0x80 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xE34 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xDB1 DUP9 DUP3 DUP10 ADD PUSH2 0xAA4 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xE52 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x986 DUP2 PUSH2 0xA45 JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x32 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xE85 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP1 ISZERO ISZERO DUP2 EQ PUSH2 0x986 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x11 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x1 DUP3 ADD PUSH2 0xEBD JUMPI PUSH2 0xEBD PUSH2 0xE95 JUMP JUMPDEST POP PUSH1 0x1 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xED6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x986 DUP2 PUSH2 0xA45 JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE DUP2 PUSH1 0x20 DUP3 ADD MSTORE DUP2 DUP4 PUSH1 0x40 DUP4 ADD CALLDATACOPY PUSH1 0x0 DUP2 DUP4 ADD PUSH1 0x40 SWAP1 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x1F SWAP1 SWAP3 ADD PUSH1 0x1F NOT AND ADD ADD SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 DUP3 ADD DUP1 DUP3 GT ISZERO PUSH2 0xF23 JUMPI PUSH2 0xF23 PUSH2 0xE95 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xF3E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 MLOAD SWAP3 POP PUSH1 0x20 DUP5 ADD MLOAD PUSH2 0xF50 DUP2 PUSH2 0xA45 JUMP JUMPDEST DUP1 SWAP3 POP POP PUSH1 0x40 DUP5 ADD MLOAD SWAP1 POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST DUP2 DUP4 DUP3 CALLDATACOPY PUSH1 0x0 SWAP2 ADD SWAP1 DUP2 MSTORE SWAP2 SWAP1 POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 DUP6 DUP7 0xA5 0xAA DUP8 0xCF 0xF8 PUSH27 0x1D8E1DC4952C1D3B167EBFAFAB4C2B56ED97ED8A5EC5921664736F PUSH13 0x63430008110033000000000000 ","sourceMap":"695:6680:7:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4889:393;;;;;;;;;;-1:-1:-1;4889:393:7;;;;;:::i;:::-;;:::i;:::-;;;470:14:11;;463:22;445:41;;433:2;418:18;4889:393:7;;;;;;;;2357:528;;;;;;;;;;-1:-1:-1;2357:528:7;;;;;:::i;:::-;;:::i;:::-;;5427:526;;;;;;;;;;-1:-1:-1;5427:526:7;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;;3559:33:11;;;3541:52;;3529:2;3514:18;5427:526:7;3397:202:11;965:63:7;;;;;;;;;;-1:-1:-1;965:63:7;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;3891:310;;;;;;;;;;;;;:::i;:::-;;;-1:-1:-1;;;;;4161:32:11;;;4143:51;;4131:2;4116:18;3891:310:7;3997:203:11;2029:265:7;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;3276:100::-;;;;;;;;;;-1:-1:-1;3317:4:7;3340:11;3354:15;-1:-1:-1;3276:100:7;;6356:244;;;;;;;;;;-1:-1:-1;6356:244:7;;;;;:::i;:::-;-1:-1:-1;;;6356:244:7;;;;;;;;871:26;;;;;;;;;;;;;;;;;;;7494:25:11;;;7482:2;7467:18;871:26:7;7348:177:11;2948:249:7;;;;;;;;;;-1:-1:-1;2948:249:7;;;;;:::i;:::-;;:::i;6043:216::-;;;;;;;;;;-1:-1:-1;6043:216:7;;;;;:::i;:::-;-1:-1:-1;;;6043:216:7;;;;;;;;3508:220;;;;;;;;;;;;;:::i;:::-;;;;8656:25:11;;;-1:-1:-1;;;;;8717:32:11;;;8712:2;8697:18;;8690:60;8766:18;;;8759:34;8644:2;8629:18;3508:220:7;8454:345:11;4272:480:7;;;;;;;;;;-1:-1:-1;4272:480:7;;;;;:::i;:::-;;:::i;4889:393::-;4999:4;;-1:-1:-1;;;;;;5041:40:7;;-1:-1:-1;;;5041:40:7;;:105;;-1:-1:-1;;;;;;;5097:49:7;;-1:-1:-1;;;5097:49:7;5041:105;:169;;;-1:-1:-1;;;;;;;5162:48:7;;-1:-1:-1;;;5162:48:7;5041:169;5019:191;;5225:14;5221:31;;;-1:-1:-1;5248:4:7;;4889:393;-1:-1:-1;;4889:393:7:o;5221:31::-;-1:-1:-1;5270:5:7;;4889:393;-1:-1:-1;;4889:393:7:o;2357:528::-;3317:4;3340:11;3354:15;-1:-1:-1;1722:38:7;;;1745:15;;-1:-1:-1;;;1745:15:7;;;;;;;;;;;1722:38;2493:14:::1;2510:7;:5;:7::i;:::-;2493:24:::0;-1:-1:-1;2531:10:7::1;-1:-1:-1::0;;;;;2531:20:7;::::1;;2527:48;;2560:15;;-1:-1:-1::0;;;2560:15:7::1;;;;;;;;;;;2527:48;2603:7:::0;2632:29;;::::1;2628:56;;2670:14;;-1:-1:-1::0;;;2670:14:7::1;;;;;;;;;;;2628:56;2700:9;2695:184;2719:6;2715:1;:10;2695:184;;;2780:12;;2793:1;2780:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;2746:19:7;::::1;;::::0;;;:11:::1;:19;::::0;;;;;2766:7;;2774:1;2766:10;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;2746:31:7::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;2746:31:7;:49;;-1:-1:-1;;2746:49:7::1;::::0;::::1;;::::0;;;::::1;::::0;;2814:54:::1;2832:6:::0;2840:7;;2848:1;2840:10;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;2852:12;;2865:1;2852:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;2814:54;::::0;;-1:-1:-1;;;;;9718:15:11;;;9700:34;;9770:15;;;;9765:2;9750:18;;9743:43;9829:14;9822:22;9802:18;;;9795:50;9650:2;9635:18;2814:54:7::1;;;;;;;2727:3:::0;::::1;::::0;::::1;:::i;:::-;;;;2695:184;;;;2483:402;;2357:528:::0;;;;:::o;5427:526::-;5578:6;5610:15;5639:21;5674:15;5702:25;:23;:25::i;:::-;5596:131;;;;;;5766:13;5755:7;:24;:67;;;;-1:-1:-1;;;;;;5795:27:7;;5812:10;5795:27;5755:67;:109;;;;;5849:15;5838:7;:26;5755:109;5738:160;;;5882:16;;-1:-1:-1;;;5882:16:7;;;;;;;;;;;5738:160;-1:-1:-1;;;;5916:30:7;5427:526;-1:-1:-1;;;;;;;5427:526:7:o;3891:310::-;3929:7;3962:15;3991:21;4026:15;4054:25;:23;:25::i;:::-;3948:131;;;;;;4105:13;4094:7;:24;4090:47;;4135:1;4120:17;;;;;3891:310;:::o;4090:47::-;4155:39;;-1:-1:-1;;;4155:39:7;;;;;7494:25:11;;;-1:-1:-1;;;;;4155:30:7;;;;;7467:18:11;;4155:39:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4148:46;;;;;3891:310;:::o;2029:265::-;2182:12;1559:24;1572:10;1559:12;:24::i;:::-;1554:53;;1592:15;;-1:-1:-1;;;1592:15:7;;;;;;;;;;;1554:53;3317:4;3340:11;3354:15;-1:-1:-1;1722:38:7::1;;;1745:15;;-1:-1:-1::0;;;1745:15:7::1;;;;;;;;;;;1722:38;2235:5:::2;2231:2;-1:-1:-1::0;;;;;2211:36:7::2;;2242:4;;2211:36;;;;;;;:::i;:::-;;;;;;;;2265:22;2271:2;2275:5;2282:4;;2265:5;:22::i;:::-;2258:29:::0;2029:265;-1:-1:-1;;;;;2029:265:7:o;2948:249::-;1387:7;:5;:7::i;:::-;-1:-1:-1;;;;;1373:21:7;:10;-1:-1:-1;;;;;1373:21:7;;1369:49;;1403:15;;-1:-1:-1;;;1403:15:7;;;;;;;;;;;1369:49;3317:4;3340:11;3354:15;-1:-1:-1;1722:38:7::1;;;1745:15;;-1:-1:-1::0;;;1745:15:7::1;;;;;;;;;;;1722:38;3045:26:::2;:15;3063:8;3045:26;:::i;:::-;3030:12;:41;3026:86;;;3092:20;;-1:-1:-1::0;;;3092:20:7::2;;;;;;;;;;;3026:86;3123:11;:26:::0;;;3165:25:::2;::::0;7494::11;;;3165::7::2;::::0;7482:2:11;7467:18;3165:25:7::2;;;;;;;2948:249:::0;:::o;3508:220::-;3585:15;3614:21;3649:15;3696:25;:23;:25::i;:::-;3689:32;;;;;;3508:220;;;:::o;4272:480::-;4331:4;4375:21;4410:15;4438:25;:23;:25::i;:::-;4490:39;;-1:-1:-1;;;4490:39:7;;;;;7494:25:11;;;4347:116:7;;-1:-1:-1;4347:116:7;-1:-1:-1;4473:14:7;;-1:-1:-1;;;;;;4490:30:7;;;;;7467:18:11;;4490:39:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4473:56;;4587:6;-1:-1:-1;;;;;4577:16:7;:6;-1:-1:-1;;;;;4577:16:7;;4573:33;;-1:-1:-1;4602:4:7;;4272:480;-1:-1:-1;;;;4272:480:7:o;4573:33::-;-1:-1:-1;;;;;4682:19:7;;;;;;;:11;:19;;;;;;;;:27;;;;;;;;;;;;4678:44;;;-1:-1:-1;4718:4:7;;4272:480;-1:-1:-1;;;;4272:480:7:o;4678:44::-;-1:-1:-1;4740:5:7;;4272:480;-1:-1:-1;;;;4272:480:7:o;90:406:10:-;263:15;;;273:4;263:15;;;;;;;;;167:7;;;;;;;;263:15;;;;;;;;;;;-1:-1:-1;263:15:10;241:37;;410:4;404;397;389:6;385:17;374:9;362:53;453:6;442:47;;;;;;;;;;;;:::i;:::-;435:54;;;;;;;90:406;;;:::o;6645:345:7:-;6756:19;6787:12;6829:2;-1:-1:-1;;;;;6829:7:7;6844:5;6851:4;;6829:27;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6809:47:7;-1:-1:-1;6809:47:7;-1:-1:-1;6809:47:7;6867:117;;6952:6;6946:13;6941:2;6933:6;6929:15;6922:38;6867:117;6777:213;6645:345;;;;;;:::o;14:286:11:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:11;;209:43;;199:71;;266:1;263;256:12;199:71;289:5;14:286;-1:-1:-1;;;14:286:11:o;497:367::-;560:8;570:6;624:3;617:4;609:6;605:17;601:27;591:55;;642:1;639;632:12;591:55;-1:-1:-1;665:20:11;;708:18;697:30;;694:50;;;740:1;737;730:12;694:50;777:4;769:6;765:17;753:29;;837:3;830:4;820:6;817:1;813:14;805:6;801:27;797:38;794:47;791:67;;;854:1;851;844:12;791:67;497:367;;;;;:::o;869:770::-;988:6;996;1004;1012;1065:2;1053:9;1044:7;1040:23;1036:32;1033:52;;;1081:1;1078;1071:12;1033:52;1121:9;1108:23;1150:18;1191:2;1183:6;1180:14;1177:34;;;1207:1;1204;1197:12;1177:34;1246:70;1308:7;1299:6;1288:9;1284:22;1246:70;:::i;:::-;1335:8;;-1:-1:-1;1220:96:11;-1:-1:-1;1423:2:11;1408:18;;1395:32;;-1:-1:-1;1439:16:11;;;1436:36;;;1468:1;1465;1458:12;1436:36;;1507:72;1571:7;1560:8;1549:9;1545:24;1507:72;:::i;:::-;869:770;;;;-1:-1:-1;1598:8:11;-1:-1:-1;;;;869:770:11:o;1644:131::-;-1:-1:-1;;;;;1719:31:11;;1709:42;;1699:70;;1765:1;1762;1755:12;1699:70;1644:131;:::o;1780:127::-;1841:10;1836:3;1832:20;1829:1;1822:31;1872:4;1869:1;1862:15;1896:4;1893:1;1886:15;1912:275;1983:2;1977:9;2048:2;2029:13;;-1:-1:-1;;2025:27:11;2013:40;;2083:18;2068:34;;2104:22;;;2065:62;2062:88;;;2130:18;;:::i;:::-;2166:2;2159:22;1912:275;;-1:-1:-1;1912:275:11:o;2192:530::-;2234:5;2287:3;2280:4;2272:6;2268:17;2264:27;2254:55;;2305:1;2302;2295:12;2254:55;2341:6;2328:20;2367:18;2363:2;2360:26;2357:52;;;2389:18;;:::i;:::-;2433:55;2476:2;2457:13;;-1:-1:-1;;2453:27:11;2482:4;2449:38;2433:55;:::i;:::-;2513:2;2504:7;2497:19;2559:3;2552:4;2547:2;2539:6;2535:15;2531:26;2528:35;2525:55;;;2576:1;2573;2566:12;2525:55;2641:2;2634:4;2626:6;2622:17;2615:4;2606:7;2602:18;2589:55;2689:1;2664:16;;;2682:4;2660:27;2653:38;;;;2668:7;2192:530;-1:-1:-1;;;2192:530:11:o;2727:665::-;2822:6;2830;2838;2846;2899:3;2887:9;2878:7;2874:23;2870:33;2867:53;;;2916:1;2913;2906:12;2867:53;2955:9;2942:23;2974:31;2999:5;2974:31;:::i;:::-;3024:5;-1:-1:-1;3081:2:11;3066:18;;3053:32;3094:33;3053:32;3094:33;:::i;:::-;3146:7;-1:-1:-1;3200:2:11;3185:18;;3172:32;;-1:-1:-1;3255:2:11;3240:18;;3227:32;3282:18;3271:30;;3268:50;;;3314:1;3311;3304:12;3268:50;3337:49;3378:7;3369:6;3358:9;3354:22;3337:49;:::i;:::-;3327:59;;;2727:665;;;;;;;:::o;3604:388::-;3672:6;3680;3733:2;3721:9;3712:7;3708:23;3704:32;3701:52;;;3749:1;3746;3739:12;3701:52;3788:9;3775:23;3807:31;3832:5;3807:31;:::i;:::-;3857:5;-1:-1:-1;3914:2:11;3899:18;;3886:32;3927:33;3886:32;3927:33;:::i;:::-;3979:7;3969:17;;;3604:388;;;;;:::o;4205:794::-;4293:6;4301;4309;4317;4370:2;4358:9;4349:7;4345:23;4341:32;4338:52;;;4386:1;4383;4376:12;4338:52;4425:9;4412:23;4444:31;4469:5;4444:31;:::i;:::-;4494:5;-1:-1:-1;4546:2:11;4531:18;;4518:32;;-1:-1:-1;4601:2:11;4586:18;;4573:32;4624:18;4654:14;;;4651:34;;;4681:1;4678;4671:12;4651:34;4719:6;4708:9;4704:22;4694:32;;4764:7;4757:4;4753:2;4749:13;4745:27;4735:55;;4786:1;4783;4776:12;4735:55;4826:2;4813:16;4852:2;4844:6;4841:14;4838:34;;;4868:1;4865;4858:12;4838:34;4913:7;4908:2;4899:6;4895:2;4891:15;4887:24;4884:37;4881:57;;;4934:1;4931;4924:12;4881:57;4205:794;;;;-1:-1:-1;;4965:2:11;4957:11;;-1:-1:-1;;;4205:794:11:o;5004:546::-;5114:4;5143:2;5172;5161:9;5154:21;5204:6;5198:13;5247:6;5242:2;5231:9;5227:18;5220:34;5272:1;5282:140;5296:6;5293:1;5290:13;5282:140;;;5391:14;;;5387:23;;5381:30;5357:17;;;5376:2;5353:26;5346:66;5311:10;;5282:140;;;5286:3;5471:1;5466:2;5457:6;5446:9;5442:22;5438:31;5431:42;5541:2;5534;5530:7;5525:2;5517:6;5513:15;5509:29;5498:9;5494:45;5490:54;5482:62;;;;5004:546;;;;:::o;5555:712::-;5609:5;5662:3;5655:4;5647:6;5643:17;5639:27;5629:55;;5680:1;5677;5670:12;5629:55;5716:6;5703:20;5742:4;5765:18;5761:2;5758:26;5755:52;;;5787:18;;:::i;:::-;5833:2;5830:1;5826:10;5856:28;5880:2;5876;5872:11;5856:28;:::i;:::-;5918:15;;;5988;;;5984:24;;;5949:12;;;;6020:15;;;6017:35;;;6048:1;6045;6038:12;6017:35;6084:2;6076:6;6072:15;6061:26;;6096:142;6112:6;6107:3;6104:15;6096:142;;;6178:17;;6166:30;;6129:12;;;;6216;;;;6096:142;;;6256:5;5555:712;-1:-1:-1;;;;;;;5555:712:11:o;6272:1071::-;6426:6;6434;6442;6450;6458;6511:3;6499:9;6490:7;6486:23;6482:33;6479:53;;;6528:1;6525;6518:12;6479:53;6567:9;6554:23;6586:31;6611:5;6586:31;:::i;:::-;6636:5;-1:-1:-1;6693:2:11;6678:18;;6665:32;6706:33;6665:32;6706:33;:::i;:::-;6758:7;-1:-1:-1;6816:2:11;6801:18;;6788:32;6839:18;6869:14;;;6866:34;;;6896:1;6893;6886:12;6866:34;6919:61;6972:7;6963:6;6952:9;6948:22;6919:61;:::i;:::-;6909:71;;7033:2;7022:9;7018:18;7005:32;6989:48;;7062:2;7052:8;7049:16;7046:36;;;7078:1;7075;7068:12;7046:36;7101:63;7156:7;7145:8;7134:9;7130:24;7101:63;:::i;:::-;7091:73;;7217:3;7206:9;7202:19;7189:33;7173:49;;7247:2;7237:8;7234:16;7231:36;;;7263:1;7260;7253:12;7231:36;;7286:51;7329:7;7318:8;7307:9;7303:24;7286:51;:::i;:::-;7276:61;;;6272:1071;;;;;;;;:::o;7530:180::-;7589:6;7642:2;7630:9;7621:7;7617:23;7613:32;7610:52;;;7658:1;7655;7648:12;7610:52;-1:-1:-1;7681:23:11;;7530:180;-1:-1:-1;7530:180:11:o;7715:734::-;7819:6;7827;7835;7843;7851;7904:3;7892:9;7883:7;7879:23;7875:33;7872:53;;;7921:1;7918;7911:12;7872:53;7960:9;7947:23;7979:31;8004:5;7979:31;:::i;:::-;8029:5;-1:-1:-1;8086:2:11;8071:18;;8058:32;8099:33;8058:32;8099:33;:::i;:::-;8151:7;-1:-1:-1;8205:2:11;8190:18;;8177:32;;-1:-1:-1;8256:2:11;8241:18;;8228:32;;-1:-1:-1;8311:3:11;8296:19;;8283:33;8339:18;8328:30;;8325:50;;;8371:1;8368;8361:12;8325:50;8394:49;8435:7;8426:6;8415:9;8411:22;8394:49;:::i;8804:247::-;8863:6;8916:2;8904:9;8895:7;8891:23;8887:32;8884:52;;;8932:1;8929;8922:12;8884:52;8971:9;8958:23;8990:31;9015:5;8990:31;:::i;9056:127::-;9117:10;9112:3;9108:20;9105:1;9098:31;9148:4;9145:1;9138:15;9172:4;9169:1;9162:15;9188:273;9244:6;9297:2;9285:9;9276:7;9272:23;9268:32;9265:52;;;9313:1;9310;9303:12;9265:52;9352:9;9339:23;9405:5;9398:13;9391:21;9384:5;9381:32;9371:60;;9427:1;9424;9417:12;9856:127;9917:10;9912:3;9908:20;9905:1;9898:31;9948:4;9945:1;9938:15;9972:4;9969:1;9962:15;9988:135;10027:3;10048:17;;;10045:43;;10068:18;;:::i;:::-;-1:-1:-1;10115:1:11;10104:13;;9988:135::o;10128:251::-;10198:6;10251:2;10239:9;10230:7;10226:23;10222:32;10219:52;;;10267:1;10264;10257:12;10219:52;10299:9;10293:16;10318:31;10343:5;10318:31;:::i;10384:388::-;10541:2;10530:9;10523:21;10580:6;10575:2;10564:9;10560:18;10553:34;10637:6;10629;10624:2;10613:9;10609:18;10596:48;10693:1;10664:22;;;10688:2;10660:31;;;10653:42;;;;10756:2;10735:15;;;-1:-1:-1;;10731:29:11;10716:45;10712:54;;10384:388;-1:-1:-1;10384:388:11:o;10777:125::-;10842:9;;;10863:10;;;10860:36;;;10876:18;;:::i;:::-;10777:125;;;;:::o;10907:381::-;11003:6;11011;11019;11072:2;11060:9;11051:7;11047:23;11043:32;11040:52;;;11088:1;11085;11078:12;11040:52;11117:9;11111:16;11101:26;;11170:2;11159:9;11155:18;11149:25;11183:31;11208:5;11183:31;:::i;:::-;11233:5;11223:15;;;11278:2;11267:9;11263:18;11257:25;11247:35;;10907:381;;;;;:::o;11293:271::-;11476:6;11468;11463:3;11450:33;11432:3;11502:16;;11527:13;;;11502:16;11293:271;-1:-1:-1;11293:271:11:o"},"gasEstimates":{"creation":{"codeDepositCost":"801600","executionCost":"838","totalCost":"802438"},"external":{"executeCall(address,uint256,bytes)":"infinite","isAuthorized(address)":"infinite","isLocked()":"2315","lock(uint256)":"infinite","lockedUntil()":"2362","onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":"infinite","onERC1155Received(address,address,uint256,uint256,bytes)":"infinite","onERC721Received(address,address,uint256,bytes)":"infinite","owner()":"infinite","permissions(address,address)":"infinite","setPermissions(address[],bool[])":"infinite","supportsInterface(bytes4)":"515","token()":"infinite"},"internal":{"_call(address,uint256,bytes calldata)":"infinite","_callStatic(address,bytes calldata)":"infinite"}},"methodIdentifiers":{"executeCall(address,uint256,bytes)":"9e5d4c49","isAuthorized(address)":"fe9fbb80","isLocked()":"a4e2d634","lock(uint256)":"dd467064","lockedUntil()":"ce0617ec","onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":"bc197c81","onERC1155Received(address,address,uint256,uint256,bytes)":"f23a6e61","onERC721Received(address,address,uint256,bytes)":"150b7a02","owner()":"8da5cb5b","permissions(address,address)":"1f9838b5","setPermissions(address[],bool[])":"039721b1","supportsInterface(bytes4)":"01ffc9a7","token()":"fc0c546a"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccountLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExceedsMaxLockTime\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInput\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAuthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnershipCycle\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lockedUntil\",\"type\":\"uint256\"}],\"name\":\"LockUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"OverrideUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"hasPermission\",\"type\":\"bool\"}],\"name\":\"PermissionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"TransactionExecuted\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"executeCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"isAuthorized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isLocked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_lockedUntil\",\"type\":\"uint256\"}],\"name\":\"lock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lockedUntil\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"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\":\"receivedTokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"permissions\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"callers\",\"type\":\"address[]\"},{\"internalType\":\"bool[]\",\"name\":\"_permissions\",\"type\":\"bool[]\"}],\"name\":\"setPermissions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"executeCall(address,uint256,bytes)\":{\"details\":\"executes a low-level call against an account if the caller is authorized to make calls\"},\"isAuthorized(address)\":{\"details\":\"Returns the authorization status for a given caller\"},\"isLocked()\":{\"details\":\"returns the current lock status of the account as a boolean\"},\"lock(uint256)\":{\"details\":\"locks the account until a certain timestamp\"},\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"details\":\"Allows ERC-1155 token batches to be received. This function can be overriden.\"},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"details\":\"Allows ERC-1155 tokens to be received. This function can be overriden.\"},\"onERC721Received(address,address,uint256,bytes)\":{\"details\":\"Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle. This function can be overriden.\"},\"owner()\":{\"details\":\"Returns the owner of the ERC-721 token which owns this account. By default, the owner of the token has full permissions on the account.\"},\"setPermissions(address[],bool[])\":{\"details\":\"grants a given caller execution permissions\"},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if a given interfaceId is supported by this account. This method can be extended by an override.\"},\"token()\":{\"details\":\"Returns the EIP-155 chain ID, token contract address, and token ID for the token that owns this account.\"}},\"stateVariables\":{\"lockedUntil\":{\"details\":\"timestamp at which this account will be unlocked\"},\"permissions\":{\"details\":\"mapping from owner => caller => has permissions\"}},\"title\":\"A smart contract account owned by a single ERC721 token\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/MinimalisticAccount.sol\":\"MinimalisticAccount\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (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 *\\n * NOTE: 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 *\\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.\\n *\\n * NOTE: 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 *\\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\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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`.\\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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\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(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface 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 `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/MinimalisticAccount.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\nimport \\\"./interfaces/IERC6551Account.sol\\\";\\nimport \\\"./lib/ERC6551AccountLib.sol\\\";\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/interfaces/IERC1271.sol\\\";\\n\\nerror NotAuthorized();\\nerror InvalidInput();\\nerror AccountLocked();\\nerror ExceedsMaxLockTime();\\nerror UntrustedImplementation();\\nerror OwnershipCycle();\\n\\n/**\\n * @title A smart contract account owned by a single ERC721 token\\n */\\ncontract MinimalisticAccount is\\n IERC165,\\n IERC6551Account,\\n IERC721Receiver,\\n IERC1155Receiver\\n{\\n /// @dev timestamp at which this account will be unlocked\\n uint256 public lockedUntil;\\n\\n /// @dev mapping from owner => caller => has permissions\\n mapping(address => mapping(address => bool)) public permissions;\\n\\n event OverrideUpdated(\\n address owner,\\n bytes4 selector,\\n address implementation\\n );\\n\\n event PermissionUpdated(address owner, address caller, bool hasPermission);\\n\\n event LockUpdated(uint256 lockedUntil);\\n\\n /// @dev reverts if caller is not the owner of the account\\n modifier onlyOwner() {\\n if (msg.sender != owner()) revert NotAuthorized();\\n _;\\n }\\n\\n /// @dev reverts if caller is not authorized to execute on this account\\n modifier onlyAuthorized() {\\n if (!isAuthorized(msg.sender)) revert NotAuthorized();\\n _;\\n }\\n\\n /// @dev reverts if this account is currently locked\\n modifier onlyUnlocked() {\\n if (isLocked()) revert AccountLocked();\\n _;\\n }\\n\\n constructor() {}\\n\\n /// @dev allows eth transfers by default, but allows account owner to override\\n receive() external payable {\\n }\\n\\n /// @dev executes a low-level call against an account if the caller is authorized to make calls\\n function executeCall(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) external payable onlyAuthorized onlyUnlocked returns (bytes memory) {\\n emit TransactionExecuted(to, value, data);\\n\\n return _call(to, value, data);\\n }\\n\\n /// @dev grants a given caller execution permissions\\n function setPermissions(\\n address[] calldata callers,\\n bool[] calldata _permissions\\n ) external onlyUnlocked {\\n address _owner = owner();\\n if (msg.sender != _owner) revert NotAuthorized();\\n\\n uint256 length = callers.length;\\n\\n if (_permissions.length != length) revert InvalidInput();\\n\\n for (uint256 i = 0; i < length; i++) {\\n permissions[_owner][callers[i]] = _permissions[i];\\n emit PermissionUpdated(_owner, callers[i], _permissions[i]);\\n }\\n }\\n\\n /// @dev locks the account until a certain timestamp\\n function lock(uint256 _lockedUntil) external onlyOwner onlyUnlocked {\\n if (_lockedUntil > block.timestamp + 365 days)\\n revert ExceedsMaxLockTime();\\n\\n lockedUntil = _lockedUntil;\\n\\n emit LockUpdated(_lockedUntil);\\n }\\n\\n /// @dev returns the current lock status of the account as a boolean\\n function isLocked() public view returns (bool) {\\n return lockedUntil > block.timestamp;\\n }\\n\\n /// @dev Returns the EIP-155 chain ID, token contract address, and token ID for the token that\\n /// owns this account.\\n function token()\\n external\\n view\\n returns (\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n )\\n {\\n return ERC6551AccountLib.token();\\n }\\n\\n /// @dev Returns the owner of the ERC-721 token which owns this account. By default, the owner\\n /// of the token has full permissions on the account.\\n function owner() public view returns (address) {\\n (\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) = ERC6551AccountLib.token();\\n\\n if (chainId != block.chainid) return address(0);\\n\\n return IERC721(tokenContract).ownerOf(tokenId);\\n }\\n\\n /// @dev Returns the authorization status for a given caller\\n function isAuthorized(address caller) public view returns (bool) {\\n (\\n ,\\n address tokenContract,\\n uint256 tokenId\\n ) = ERC6551AccountLib.token();\\n address _owner = IERC721(tokenContract).ownerOf(tokenId);\\n\\n // authorize token owner\\n if (caller == _owner) return true;\\n\\n // authorize caller if owner has granted permissions\\n if (permissions[_owner][caller]) return true;\\n\\n return false;\\n }\\n\\n /// @dev Returns true if a given interfaceId is supported by this account. This method can be\\n /// extended by an override.\\n function supportsInterface(bytes4 interfaceId)\\n public\\n pure \\n override\\n returns (bool)\\n {\\n bool defaultSupport = interfaceId == type(IERC165).interfaceId ||\\n interfaceId == type(IERC1155Receiver).interfaceId ||\\n interfaceId == type(IERC6551Account).interfaceId;\\n\\n if (defaultSupport) return true;\\n\\n return false;\\n }\\n\\n /// @dev Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle.\\n /// This function can be overriden.\\n function onERC721Received(\\n address,\\n address,\\n uint256 receivedTokenId,\\n bytes memory\\n ) public view override returns (bytes4) {\\n (\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) = ERC6551AccountLib.token();\\n\\n if (\\n chainId == block.chainid &&\\n tokenContract == msg.sender &&\\n tokenId == receivedTokenId\\n ) revert OwnershipCycle();\\n\\n return this.onERC721Received.selector;\\n }\\n\\n /// @dev Allows ERC-1155 tokens to be received. This function can be overriden.\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes memory\\n ) public pure override returns (bytes4) {\\n return this.onERC1155Received.selector;\\n }\\n\\n /// @dev Allows ERC-1155 token batches to be received. This function can be overriden.\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] memory,\\n uint256[] memory,\\n bytes memory\\n ) public pure override returns (bytes4) {\\n return this.onERC1155BatchReceived.selector;\\n }\\n\\n /// @dev Executes a low-level call\\n function _call(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) internal returns (bytes memory result) {\\n bool success;\\n (success, result) = to.call{value: value}(data);\\n\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /// @dev Executes a low-level static call\\n function _callStatic(address to, bytes calldata data)\\n internal\\n view\\n returns (bytes memory result)\\n {\\n bool success;\\n (success, result) = to.staticcall(data);\\n\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xed537db66c8c88618b283b038ec6e1b55b56c1ad4006658a1fef0fe8e60fb528\",\"license\":\"UNLICENSED\"},\"contracts/interfaces/IERC6551Account.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\ninterface IERC6551AccountProxy {\\n function implementation() external view returns (address);\\n}\\n\\n/// @dev the ERC-165 identifier for this interface is `0xeff4d378`\\ninterface IERC6551Account {\\n event TransactionExecuted(address indexed target, uint256 indexed value, bytes data);\\n\\n receive() external payable;\\n\\n function executeCall(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) external payable returns (bytes memory);\\n\\n function token()\\n external\\n view\\n returns (uint256 chainId, address tokenContract, uint256 tokenId);\\n\\n function owner() external view returns (address);\\n}\\n\",\"keccak256\":\"0x5fe2dca745f8e753d414778980a0846c1bbcbb26a09d7cd7fb712c7db7939582\",\"license\":\"UNLICENSED\"},\"contracts/lib/ERC6551AccountLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.13;\\n\\nlibrary ERC6551AccountLib {\\n function token()\\n internal\\n view\\n returns (\\n uint256,\\n address,\\n uint256\\n )\\n {\\n bytes memory footer = new bytes(0x60);\\n\\n assembly {\\n // copy 0x60 bytes from end of footer\\n extcodecopy(address(), add(footer, 0x20), 0x4d, 0xad)\\n }\\n\\n return abi.decode(footer, (uint256, address, uint256));\\n }\\n\\n function salt() internal view returns (uint256) {\\n bytes memory footer = new bytes(0x20);\\n\\n assembly {\\n // copy 0x20 bytes from beginning of footer\\n extcodecopy(address(), add(footer, 0x20), 0x2d, 0x4d)\\n }\\n\\n return abi.decode(footer, (uint256));\\n }\\n}\\n\",\"keccak256\":\"0xf7a8eb3b4fb63068eb8ed2a1a129e4676af842541f43c1a1dc96a9f295060c45\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[{"astId":314,"contract":"contracts/MinimalisticAccount.sol:MinimalisticAccount","label":"lockedUntil","offset":0,"slot":"0","type":"t_uint256"},{"astId":321,"contract":"contracts/MinimalisticAccount.sol:MinimalisticAccount","label":"permissions","offset":0,"slot":"1","type":"t_mapping(t_address,t_mapping(t_address,t_bool))"}],"types":{"t_address":{"encoding":"inplace","label":"address","numberOfBytes":"20"},"t_bool":{"encoding":"inplace","label":"bool","numberOfBytes":"1"},"t_mapping(t_address,t_bool)":{"encoding":"mapping","key":"t_address","label":"mapping(address => bool)","numberOfBytes":"32","value":"t_bool"},"t_mapping(t_address,t_mapping(t_address,t_bool))":{"encoding":"mapping","key":"t_address","label":"mapping(address => mapping(address => bool))","numberOfBytes":"32","value":"t_mapping(t_address,t_bool)"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/interfaces/IERC6551Account.sol":{"IERC6551Account":{"abi":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":true,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"TransactionExecuted","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"executeCall","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}],"devdoc":{"details":"the ERC-165 identifier for this interface is `0xeff4d378`","kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"executeCall(address,uint256,bytes)":"9e5d4c49","owner()":"8da5cb5b","token()":"fc0c546a"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"TransactionExecuted\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"executeCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"the ERC-165 identifier for this interface is `0xeff4d378`\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/interfaces/IERC6551Account.sol\":\"IERC6551Account\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interfaces/IERC6551Account.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\ninterface IERC6551AccountProxy {\\n function implementation() external view returns (address);\\n}\\n\\n/// @dev the ERC-165 identifier for this interface is `0xeff4d378`\\ninterface IERC6551Account {\\n event TransactionExecuted(address indexed target, uint256 indexed value, bytes data);\\n\\n receive() external payable;\\n\\n function executeCall(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) external payable returns (bytes memory);\\n\\n function token()\\n external\\n view\\n returns (uint256 chainId, address tokenContract, uint256 tokenId);\\n\\n function owner() external view returns (address);\\n}\\n\",\"keccak256\":\"0x5fe2dca745f8e753d414778980a0846c1bbcbb26a09d7cd7fb712c7db7939582\",\"license\":\"UNLICENSED\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}},"IERC6551AccountProxy":{"abi":[{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"implementation()":"5c60da1b"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/interfaces/IERC6551Account.sol\":\"IERC6551AccountProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interfaces/IERC6551Account.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\ninterface IERC6551AccountProxy {\\n function implementation() external view returns (address);\\n}\\n\\n/// @dev the ERC-165 identifier for this interface is `0xeff4d378`\\ninterface IERC6551Account {\\n event TransactionExecuted(address indexed target, uint256 indexed value, bytes data);\\n\\n receive() external payable;\\n\\n function executeCall(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) external payable returns (bytes memory);\\n\\n function token()\\n external\\n view\\n returns (uint256 chainId, address tokenContract, uint256 tokenId);\\n\\n function owner() external view returns (address);\\n}\\n\",\"keccak256\":\"0x5fe2dca745f8e753d414778980a0846c1bbcbb26a09d7cd7fb712c7db7939582\",\"license\":\"UNLICENSED\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/interfaces/IRegistry.sol":{"IRegistry":{"abi":[{"inputs":[{"internalType":"address","name":"implementation","type":"address"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"}],"name":"account","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"implementation","type":"address"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"initData","type":"bytes"}],"name":"createAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"account(address,uint256,address,uint256,uint256)":"5e9bc536","createAccount(address,uint256,address,uint256,uint256,bytes)":"da7323b3"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"salt\",\"type\":\"uint256\"}],\"name\":\"account\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"salt\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initData\",\"type\":\"bytes\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/interfaces/IRegistry.sol\":\"IRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interfaces/IRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\ninterface IRegistry {\\n function createAccount(\\n address implementation,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId,\\n uint256 salt,\\n bytes calldata initData\\n ) external returns (address);\\n\\n function account(\\n address implementation,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId,\\n uint256 salt\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xd24999d4d474bd349b1e2e5006eff215c5d9a64a481a9ebac3293f98603fbd27\",\"license\":\"UNLICENSED\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/lib/ERC6551AccountLib.sol":{"ERC6551AccountLib":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220507d1af45fff54535180cd2db9c0244503eb6a3f2538827633938e9a22f0be7564736f6c63430008110033","opcodes":"PUSH1 0x56 PUSH1 0x37 PUSH1 0xB DUP3 DUP3 DUP3 CODECOPY DUP1 MLOAD PUSH1 0x0 BYTE PUSH1 0x73 EQ PUSH1 0x2A JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x0 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST ADDRESS PUSH1 0x0 MSTORE PUSH1 0x73 DUP2 MSTORE8 DUP3 DUP2 RETURN INVALID PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 POP PUSH30 0x1AF45FFF54535180CD2DB9C0244503EB6A3F2538827633938E9A22F0BE75 PUSH5 0x736F6C6343 STOP ADDMOD GT STOP CALLER ","sourceMap":"58:747:10:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;58:747:10;;;;;;;;;;;;;;;;;"},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220507d1af45fff54535180cd2db9c0244503eb6a3f2538827633938e9a22f0be7564736f6c63430008110033","opcodes":"PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 POP PUSH30 0x1AF45FFF54535180CD2DB9C0244503EB6A3F2538827633938E9A22F0BE75 PUSH5 0x736F6C6343 STOP ADDMOD GT STOP CALLER ","sourceMap":"58:747:10:-:0;;;;;;;;"},"gasEstimates":{"creation":{"codeDepositCost":"17200","executionCost":"103","totalCost":"17303"},"internal":{"salt()":"infinite","token()":"infinite"}},"methodIdentifiers":{}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/lib/ERC6551AccountLib.sol\":\"ERC6551AccountLib\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/lib/ERC6551AccountLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.13;\\n\\nlibrary ERC6551AccountLib {\\n function token()\\n internal\\n view\\n returns (\\n uint256,\\n address,\\n uint256\\n )\\n {\\n bytes memory footer = new bytes(0x60);\\n\\n assembly {\\n // copy 0x60 bytes from end of footer\\n extcodecopy(address(), add(footer, 0x20), 0x4d, 0xad)\\n }\\n\\n return abi.decode(footer, (uint256, address, uint256));\\n }\\n\\n function salt() internal view returns (uint256) {\\n bytes memory footer = new bytes(0x20);\\n\\n assembly {\\n // copy 0x20 bytes from beginning of footer\\n extcodecopy(address(), add(footer, 0x20), 0x2d, 0x4d)\\n }\\n\\n return abi.decode(footer, (uint256));\\n }\\n}\\n\",\"keccak256\":\"0xf7a8eb3b4fb63068eb8ed2a1a129e4676af842541f43c1a1dc96a9f295060c45\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}}}}} \ No newline at end of file diff --git a/build/contracts/build-info/298a06569c51eccf42345b43561716ff.json b/build/contracts/build-info/298a06569c51eccf42345b43561716ff.json deleted file mode 100644 index b9ba6d3..0000000 --- a/build/contracts/build-info/298a06569c51eccf42345b43561716ff.json +++ /dev/null @@ -1 +0,0 @@ -{"id":"298a06569c51eccf42345b43561716ff","_format":"hh-sol-build-info-1","solcVersion":"0.8.17","solcLongVersion":"0.8.17+commit.8df45f5f","input":{"language":"Solidity","sources":{"@openzeppelin/contracts/interfaces/IERC1271.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n"},"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (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 *\n * NOTE: 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 *\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.\n *\n * NOTE: 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 *\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/token/ERC721/IERC721.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (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`.\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(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\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(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"},"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface 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 `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"},"@openzeppelin/contracts/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"},"contracts/ChargedParticlesAccount.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\nimport \"./MinimalisticAccount.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\n\ncontract ChargedParticlesAccount is MinimalisticAccount {\n function covalentBond(\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external {\n // Transfer to self\n IERC721(nftTokenAddress).safeTransferFrom(\n msg.sender,\n address(this),\n nftTokenId\n );\n }\n\n function breakCovalentBond(\n address receiver,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external {\n IERC721(nftTokenAddress).safeTransferFrom(address(this), receiver, nftTokenId);\n }\n}\n"},"contracts/interfaces/IERC6551Account.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\ninterface IERC6551AccountProxy {\n function implementation() external view returns (address);\n}\n\n/// @dev the ERC-165 identifier for this interface is `0xeff4d378`\ninterface IERC6551Account {\n event TransactionExecuted(address indexed target, uint256 indexed value, bytes data);\n\n receive() external payable;\n\n function executeCall(\n address to,\n uint256 value,\n bytes calldata data\n ) external payable returns (bytes memory);\n\n function token()\n external\n view\n returns (uint256 chainId, address tokenContract, uint256 tokenId);\n\n function owner() external view returns (address);\n}\n"},"contracts/lib/ERC6551AccountLib.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\nlibrary ERC6551AccountLib {\n function token()\n internal\n view\n returns (\n uint256,\n address,\n uint256\n )\n {\n bytes memory footer = new bytes(0x60);\n\n assembly {\n // copy 0x60 bytes from end of footer\n extcodecopy(address(), add(footer, 0x20), 0x4d, 0xad)\n }\n\n return abi.decode(footer, (uint256, address, uint256));\n }\n\n function salt() internal view returns (uint256) {\n bytes memory footer = new bytes(0x20);\n\n assembly {\n // copy 0x20 bytes from beginning of footer\n extcodecopy(address(), add(footer, 0x20), 0x2d, 0x4d)\n }\n\n return abi.decode(footer, (uint256));\n }\n}\n"},"contracts/MinimalisticAccount.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\nimport \"./interfaces/IERC6551Account.sol\";\nimport \"./lib/ERC6551AccountLib.sol\";\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC1271.sol\";\n\nerror NotAuthorized();\nerror InvalidInput();\nerror AccountLocked();\nerror ExceedsMaxLockTime();\nerror UntrustedImplementation();\nerror OwnershipCycle();\n\n/**\n * @title A smart contract account owned by a single ERC721 token\n */\ncontract MinimalisticAccount is\n IERC165,\n IERC6551Account,\n IERC721Receiver,\n IERC1155Receiver\n{\n /// @dev timestamp at which this account will be unlocked\n uint256 public lockedUntil;\n\n /// @dev mapping from owner => caller => has permissions\n mapping(address => mapping(address => bool)) public permissions;\n\n event OverrideUpdated(\n address owner,\n bytes4 selector,\n address implementation\n );\n\n event PermissionUpdated(address owner, address caller, bool hasPermission);\n\n event LockUpdated(uint256 lockedUntil);\n\n /// @dev reverts if caller is not the owner of the account\n modifier onlyOwner() {\n if (msg.sender != owner()) revert NotAuthorized();\n _;\n }\n\n /// @dev reverts if caller is not authorized to execute on this account\n modifier onlyAuthorized() {\n if (!isAuthorized(msg.sender)) revert NotAuthorized();\n _;\n }\n\n /// @dev reverts if this account is currently locked\n modifier onlyUnlocked() {\n if (isLocked()) revert AccountLocked();\n _;\n }\n\n constructor() {}\n\n /// @dev allows eth transfers by default, but allows account owner to override\n receive() external payable {\n }\n\n /// @dev executes a low-level call against an account if the caller is authorized to make calls\n function executeCall(\n address to,\n uint256 value,\n bytes calldata data\n ) external payable onlyAuthorized onlyUnlocked returns (bytes memory) {\n emit TransactionExecuted(to, value, data);\n\n return _call(to, value, data);\n }\n\n /// @dev grants a given caller execution permissions\n function setPermissions(\n address[] calldata callers,\n bool[] calldata _permissions\n ) external onlyUnlocked {\n address _owner = owner();\n if (msg.sender != _owner) revert NotAuthorized();\n\n uint256 length = callers.length;\n\n if (_permissions.length != length) revert InvalidInput();\n\n for (uint256 i = 0; i < length; i++) {\n permissions[_owner][callers[i]] = _permissions[i];\n emit PermissionUpdated(_owner, callers[i], _permissions[i]);\n }\n }\n\n /// @dev locks the account until a certain timestamp\n function lock(uint256 _lockedUntil) external onlyOwner onlyUnlocked {\n if (_lockedUntil > block.timestamp + 365 days)\n revert ExceedsMaxLockTime();\n\n lockedUntil = _lockedUntil;\n\n emit LockUpdated(_lockedUntil);\n }\n\n /// @dev returns the current lock status of the account as a boolean\n function isLocked() public view returns (bool) {\n return lockedUntil > block.timestamp;\n }\n\n /// @dev Returns the EIP-155 chain ID, token contract address, and token ID for the token that\n /// owns this account.\n function token()\n external\n view\n returns (\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n )\n {\n return ERC6551AccountLib.token();\n }\n\n /// @dev Returns the owner of the ERC-721 token which owns this account. By default, the owner\n /// of the token has full permissions on the account.\n function owner() public view returns (address) {\n (\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) = ERC6551AccountLib.token();\n\n if (chainId != block.chainid) return address(0);\n\n return IERC721(tokenContract).ownerOf(tokenId);\n }\n\n /// @dev Returns the authorization status for a given caller\n function isAuthorized(address caller) public view returns (bool) {\n (\n ,\n address tokenContract,\n uint256 tokenId\n ) = ERC6551AccountLib.token();\n address _owner = IERC721(tokenContract).ownerOf(tokenId);\n\n // authorize token owner\n if (caller == _owner) return true;\n\n // authorize caller if owner has granted permissions\n if (permissions[_owner][caller]) return true;\n\n return false;\n }\n\n /// @dev Returns true if a given interfaceId is supported by this account. This method can be\n /// extended by an override.\n function supportsInterface(bytes4 interfaceId)\n public\n pure \n override\n returns (bool)\n {\n bool defaultSupport = interfaceId == type(IERC165).interfaceId ||\n interfaceId == type(IERC1155Receiver).interfaceId ||\n interfaceId == type(IERC6551Account).interfaceId;\n\n if (defaultSupport) return true;\n\n return false;\n }\n\n /// @dev Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle.\n /// This function can be overriden.\n function onERC721Received(\n address,\n address,\n uint256 receivedTokenId,\n bytes memory\n ) public view override returns (bytes4) {\n (\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) = ERC6551AccountLib.token();\n\n if (\n chainId == block.chainid &&\n tokenContract == msg.sender &&\n tokenId == receivedTokenId\n ) revert OwnershipCycle();\n\n return this.onERC721Received.selector;\n }\n\n /// @dev Allows ERC-1155 tokens to be received. This function can be overriden.\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes memory\n ) public pure override returns (bytes4) {\n return this.onERC1155Received.selector;\n }\n\n /// @dev Allows ERC-1155 token batches to be received. This function can be overriden.\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] memory,\n uint256[] memory,\n bytes memory\n ) public pure override returns (bytes4) {\n return this.onERC1155BatchReceived.selector;\n }\n\n /// @dev Executes a low-level call\n function _call(\n address to,\n uint256 value,\n bytes calldata data\n ) internal returns (bytes memory result) {\n bool success;\n (success, result) = to.call{value: value}(data);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /// @dev Executes a low-level static call\n function _callStatic(address to, bytes calldata data)\n internal\n view\n returns (bytes memory result)\n {\n bool success;\n (success, result) = to.staticcall(data);\n\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n}\n"}},"settings":{"optimizer":{"enabled":true,"runs":200},"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata","devdoc","userdoc","storageLayout","evm.gasEstimates"],"":["ast"]}},"metadata":{"useLiteralContent":true}}},"output":{"errors":[{"component":"general","errorCode":"5667","formattedMessage":"Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.\n --> contracts/ChargedParticlesAccount.sol:11:9:\n |\n11 | uint256 nftTokenAmount\n | ^^^^^^^^^^^^^^^^^^^^^^\n\n","message":"Unused function parameter. Remove or comment out the variable name to silence this warning.","severity":"warning","sourceLocation":{"end":337,"file":"contracts/ChargedParticlesAccount.sol","start":315},"type":"Warning"},{"component":"general","errorCode":"5667","formattedMessage":"Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.\n --> contracts/ChargedParticlesAccount.sol:25:9:\n |\n25 | uint256 nftTokenAmount\n | ^^^^^^^^^^^^^^^^^^^^^^\n\n","message":"Unused function parameter. Remove or comment out the variable name to silence this warning.","severity":"warning","sourceLocation":{"end":675,"file":"contracts/ChargedParticlesAccount.sol","start":653},"type":"Warning"}],"sources":{"@openzeppelin/contracts/interfaces/IERC1271.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/interfaces/IERC1271.sol","exportedSymbols":{"IERC1271":[13]},"id":14,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":1,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"92:23:0"},{"abstract":false,"baseContracts":[],"canonicalName":"IERC1271","contractDependencies":[],"contractKind":"interface","documentation":{"id":2,"nodeType":"StructuredDocumentation","src":"117:189:0","text":" @dev Interface of the ERC1271 standard signature validation method for\n contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n _Available since v4.1._"},"fullyImplemented":false,"id":13,"linearizedBaseContracts":[13],"name":"IERC1271","nameLocation":"317:8:0","nodeType":"ContractDefinition","nodes":[{"documentation":{"id":3,"nodeType":"StructuredDocumentation","src":"332:220:0","text":" @dev Should return whether the signature provided is valid for the provided data\n @param hash Hash of the data to be signed\n @param signature Signature byte array associated with _data"},"functionSelector":"1626ba7e","id":12,"implemented":false,"kind":"function","modifiers":[],"name":"isValidSignature","nameLocation":"566:16:0","nodeType":"FunctionDefinition","parameters":{"id":8,"nodeType":"ParameterList","parameters":[{"constant":false,"id":5,"mutability":"mutable","name":"hash","nameLocation":"591:4:0","nodeType":"VariableDeclaration","scope":12,"src":"583:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"},"typeName":{"id":4,"name":"bytes32","nodeType":"ElementaryTypeName","src":"583:7:0","typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}},"visibility":"internal"},{"constant":false,"id":7,"mutability":"mutable","name":"signature","nameLocation":"610:9:0","nodeType":"VariableDeclaration","scope":12,"src":"597:22:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":6,"name":"bytes","nodeType":"ElementaryTypeName","src":"597:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"582:38:0"},"returnParameters":{"id":11,"nodeType":"ParameterList","parameters":[{"constant":false,"id":10,"mutability":"mutable","name":"magicValue","nameLocation":"651:10:0","nodeType":"VariableDeclaration","scope":12,"src":"644:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":9,"name":"bytes4","nodeType":"ElementaryTypeName","src":"644:6:0","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"643:19:0"},"scope":13,"src":"557:106:0","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":14,"src":"307:358:0","usedErrors":[]}],"src":"92:574:0"},"id":0},"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol","exportedSymbols":{"IERC1155Receiver":[54],"IERC165":[200]},"id":55,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":15,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"118:23:1"},{"absolutePath":"@openzeppelin/contracts/utils/introspection/IERC165.sol","file":"../../utils/introspection/IERC165.sol","id":16,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":55,"sourceUnit":201,"src":"143:47:1","symbolAliases":[],"unitAlias":""},{"abstract":false,"baseContracts":[{"baseName":{"id":18,"name":"IERC165","nameLocations":["262:7:1"],"nodeType":"IdentifierPath","referencedDeclaration":200,"src":"262:7:1"},"id":19,"nodeType":"InheritanceSpecifier","src":"262:7:1"}],"canonicalName":"IERC1155Receiver","contractDependencies":[],"contractKind":"interface","documentation":{"id":17,"nodeType":"StructuredDocumentation","src":"192:39:1","text":" @dev _Available since v3.1._"},"fullyImplemented":false,"id":54,"linearizedBaseContracts":[54,200],"name":"IERC1155Receiver","nameLocation":"242:16:1","nodeType":"ContractDefinition","nodes":[{"documentation":{"id":20,"nodeType":"StructuredDocumentation","src":"276:826:1","text":" @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 NOTE: 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"},"functionSelector":"f23a6e61","id":35,"implemented":false,"kind":"function","modifiers":[],"name":"onERC1155Received","nameLocation":"1116:17:1","nodeType":"FunctionDefinition","parameters":{"id":31,"nodeType":"ParameterList","parameters":[{"constant":false,"id":22,"mutability":"mutable","name":"operator","nameLocation":"1151:8:1","nodeType":"VariableDeclaration","scope":35,"src":"1143:16:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":21,"name":"address","nodeType":"ElementaryTypeName","src":"1143:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":24,"mutability":"mutable","name":"from","nameLocation":"1177:4:1","nodeType":"VariableDeclaration","scope":35,"src":"1169:12:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":23,"name":"address","nodeType":"ElementaryTypeName","src":"1169:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":26,"mutability":"mutable","name":"id","nameLocation":"1199:2:1","nodeType":"VariableDeclaration","scope":35,"src":"1191:10:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":25,"name":"uint256","nodeType":"ElementaryTypeName","src":"1191:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":28,"mutability":"mutable","name":"value","nameLocation":"1219:5:1","nodeType":"VariableDeclaration","scope":35,"src":"1211:13:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":27,"name":"uint256","nodeType":"ElementaryTypeName","src":"1211:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":30,"mutability":"mutable","name":"data","nameLocation":"1249:4:1","nodeType":"VariableDeclaration","scope":35,"src":"1234:19:1","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":29,"name":"bytes","nodeType":"ElementaryTypeName","src":"1234:5:1","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1133:126:1"},"returnParameters":{"id":34,"nodeType":"ParameterList","parameters":[{"constant":false,"id":33,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":35,"src":"1278:6:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":32,"name":"bytes4","nodeType":"ElementaryTypeName","src":"1278:6:1","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"1277:8:1"},"scope":54,"src":"1107:179:1","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":36,"nodeType":"StructuredDocumentation","src":"1292:994:1","text":" @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.\n NOTE: 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"},"functionSelector":"bc197c81","id":53,"implemented":false,"kind":"function","modifiers":[],"name":"onERC1155BatchReceived","nameLocation":"2300:22:1","nodeType":"FunctionDefinition","parameters":{"id":49,"nodeType":"ParameterList","parameters":[{"constant":false,"id":38,"mutability":"mutable","name":"operator","nameLocation":"2340:8:1","nodeType":"VariableDeclaration","scope":53,"src":"2332:16:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":37,"name":"address","nodeType":"ElementaryTypeName","src":"2332:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":40,"mutability":"mutable","name":"from","nameLocation":"2366:4:1","nodeType":"VariableDeclaration","scope":53,"src":"2358:12:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":39,"name":"address","nodeType":"ElementaryTypeName","src":"2358:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":43,"mutability":"mutable","name":"ids","nameLocation":"2399:3:1","nodeType":"VariableDeclaration","scope":53,"src":"2380:22:1","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_calldata_ptr","typeString":"uint256[]"},"typeName":{"baseType":{"id":41,"name":"uint256","nodeType":"ElementaryTypeName","src":"2380:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":42,"nodeType":"ArrayTypeName","src":"2380:9:1","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_storage_ptr","typeString":"uint256[]"}},"visibility":"internal"},{"constant":false,"id":46,"mutability":"mutable","name":"values","nameLocation":"2431:6:1","nodeType":"VariableDeclaration","scope":53,"src":"2412:25:1","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_calldata_ptr","typeString":"uint256[]"},"typeName":{"baseType":{"id":44,"name":"uint256","nodeType":"ElementaryTypeName","src":"2412:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":45,"nodeType":"ArrayTypeName","src":"2412:9:1","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_storage_ptr","typeString":"uint256[]"}},"visibility":"internal"},{"constant":false,"id":48,"mutability":"mutable","name":"data","nameLocation":"2462:4:1","nodeType":"VariableDeclaration","scope":53,"src":"2447:19:1","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":47,"name":"bytes","nodeType":"ElementaryTypeName","src":"2447:5:1","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"2322:150:1"},"returnParameters":{"id":52,"nodeType":"ParameterList","parameters":[{"constant":false,"id":51,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":53,"src":"2491:6:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":50,"name":"bytes4","nodeType":"ElementaryTypeName","src":"2491:6:1","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"2490:8:1"},"scope":54,"src":"2291:208:1","stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"scope":55,"src":"232:2269:1","usedErrors":[]}],"src":"118:2384:1"},"id":1},"@openzeppelin/contracts/token/ERC721/IERC721.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721.sol","exportedSymbols":{"IERC165":[200],"IERC721":[170]},"id":171,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":56,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"108:23:2"},{"absolutePath":"@openzeppelin/contracts/utils/introspection/IERC165.sol","file":"../../utils/introspection/IERC165.sol","id":57,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":171,"sourceUnit":201,"src":"133:47:2","symbolAliases":[],"unitAlias":""},{"abstract":false,"baseContracts":[{"baseName":{"id":59,"name":"IERC165","nameLocations":["271:7:2"],"nodeType":"IdentifierPath","referencedDeclaration":200,"src":"271:7:2"},"id":60,"nodeType":"InheritanceSpecifier","src":"271:7:2"}],"canonicalName":"IERC721","contractDependencies":[],"contractKind":"interface","documentation":{"id":58,"nodeType":"StructuredDocumentation","src":"182:67:2","text":" @dev Required interface of an ERC721 compliant contract."},"fullyImplemented":false,"id":170,"linearizedBaseContracts":[170,200],"name":"IERC721","nameLocation":"260:7:2","nodeType":"ContractDefinition","nodes":[{"anonymous":false,"documentation":{"id":61,"nodeType":"StructuredDocumentation","src":"285:88:2","text":" @dev Emitted when `tokenId` token is transferred from `from` to `to`."},"eventSelector":"ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","id":69,"name":"Transfer","nameLocation":"384:8:2","nodeType":"EventDefinition","parameters":{"id":68,"nodeType":"ParameterList","parameters":[{"constant":false,"id":63,"indexed":true,"mutability":"mutable","name":"from","nameLocation":"409:4:2","nodeType":"VariableDeclaration","scope":69,"src":"393:20:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":62,"name":"address","nodeType":"ElementaryTypeName","src":"393:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":65,"indexed":true,"mutability":"mutable","name":"to","nameLocation":"431:2:2","nodeType":"VariableDeclaration","scope":69,"src":"415:18:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":64,"name":"address","nodeType":"ElementaryTypeName","src":"415:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":67,"indexed":true,"mutability":"mutable","name":"tokenId","nameLocation":"451:7:2","nodeType":"VariableDeclaration","scope":69,"src":"435:23:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":66,"name":"uint256","nodeType":"ElementaryTypeName","src":"435:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"392:67:2"},"src":"378:82:2"},{"anonymous":false,"documentation":{"id":70,"nodeType":"StructuredDocumentation","src":"466:94:2","text":" @dev Emitted when `owner` enables `approved` to manage the `tokenId` token."},"eventSelector":"8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925","id":78,"name":"Approval","nameLocation":"571:8:2","nodeType":"EventDefinition","parameters":{"id":77,"nodeType":"ParameterList","parameters":[{"constant":false,"id":72,"indexed":true,"mutability":"mutable","name":"owner","nameLocation":"596:5:2","nodeType":"VariableDeclaration","scope":78,"src":"580:21:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":71,"name":"address","nodeType":"ElementaryTypeName","src":"580:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":74,"indexed":true,"mutability":"mutable","name":"approved","nameLocation":"619:8:2","nodeType":"VariableDeclaration","scope":78,"src":"603:24:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":73,"name":"address","nodeType":"ElementaryTypeName","src":"603:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":76,"indexed":true,"mutability":"mutable","name":"tokenId","nameLocation":"645:7:2","nodeType":"VariableDeclaration","scope":78,"src":"629:23:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":75,"name":"uint256","nodeType":"ElementaryTypeName","src":"629:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"579:74:2"},"src":"565:89:2"},{"anonymous":false,"documentation":{"id":79,"nodeType":"StructuredDocumentation","src":"660:117:2","text":" @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets."},"eventSelector":"17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31","id":87,"name":"ApprovalForAll","nameLocation":"788:14:2","nodeType":"EventDefinition","parameters":{"id":86,"nodeType":"ParameterList","parameters":[{"constant":false,"id":81,"indexed":true,"mutability":"mutable","name":"owner","nameLocation":"819:5:2","nodeType":"VariableDeclaration","scope":87,"src":"803:21:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":80,"name":"address","nodeType":"ElementaryTypeName","src":"803:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":83,"indexed":true,"mutability":"mutable","name":"operator","nameLocation":"842:8:2","nodeType":"VariableDeclaration","scope":87,"src":"826:24:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":82,"name":"address","nodeType":"ElementaryTypeName","src":"826:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":85,"indexed":false,"mutability":"mutable","name":"approved","nameLocation":"857:8:2","nodeType":"VariableDeclaration","scope":87,"src":"852:13:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":84,"name":"bool","nodeType":"ElementaryTypeName","src":"852:4:2","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"802:64:2"},"src":"782:85:2"},{"documentation":{"id":88,"nodeType":"StructuredDocumentation","src":"873:76:2","text":" @dev Returns the number of tokens in ``owner``'s account."},"functionSelector":"70a08231","id":95,"implemented":false,"kind":"function","modifiers":[],"name":"balanceOf","nameLocation":"963:9:2","nodeType":"FunctionDefinition","parameters":{"id":91,"nodeType":"ParameterList","parameters":[{"constant":false,"id":90,"mutability":"mutable","name":"owner","nameLocation":"981:5:2","nodeType":"VariableDeclaration","scope":95,"src":"973:13:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":89,"name":"address","nodeType":"ElementaryTypeName","src":"973:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"972:15:2"},"returnParameters":{"id":94,"nodeType":"ParameterList","parameters":[{"constant":false,"id":93,"mutability":"mutable","name":"balance","nameLocation":"1019:7:2","nodeType":"VariableDeclaration","scope":95,"src":"1011:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":92,"name":"uint256","nodeType":"ElementaryTypeName","src":"1011:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1010:17:2"},"scope":170,"src":"954:74:2","stateMutability":"view","virtual":false,"visibility":"external"},{"documentation":{"id":96,"nodeType":"StructuredDocumentation","src":"1034:131:2","text":" @dev Returns the owner of the `tokenId` token.\n Requirements:\n - `tokenId` must exist."},"functionSelector":"6352211e","id":103,"implemented":false,"kind":"function","modifiers":[],"name":"ownerOf","nameLocation":"1179:7:2","nodeType":"FunctionDefinition","parameters":{"id":99,"nodeType":"ParameterList","parameters":[{"constant":false,"id":98,"mutability":"mutable","name":"tokenId","nameLocation":"1195:7:2","nodeType":"VariableDeclaration","scope":103,"src":"1187:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":97,"name":"uint256","nodeType":"ElementaryTypeName","src":"1187:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1186:17:2"},"returnParameters":{"id":102,"nodeType":"ParameterList","parameters":[{"constant":false,"id":101,"mutability":"mutable","name":"owner","nameLocation":"1235:5:2","nodeType":"VariableDeclaration","scope":103,"src":"1227:13:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":100,"name":"address","nodeType":"ElementaryTypeName","src":"1227:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1226:15:2"},"scope":170,"src":"1170:72:2","stateMutability":"view","virtual":false,"visibility":"external"},{"documentation":{"id":104,"nodeType":"StructuredDocumentation","src":"1248:556:2","text":" @dev Safely transfers `tokenId` token from `from` to `to`.\n Requirements:\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 Emits a {Transfer} event."},"functionSelector":"b88d4fde","id":115,"implemented":false,"kind":"function","modifiers":[],"name":"safeTransferFrom","nameLocation":"1818:16:2","nodeType":"FunctionDefinition","parameters":{"id":113,"nodeType":"ParameterList","parameters":[{"constant":false,"id":106,"mutability":"mutable","name":"from","nameLocation":"1843:4:2","nodeType":"VariableDeclaration","scope":115,"src":"1835:12:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":105,"name":"address","nodeType":"ElementaryTypeName","src":"1835:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":108,"mutability":"mutable","name":"to","nameLocation":"1857:2:2","nodeType":"VariableDeclaration","scope":115,"src":"1849:10:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":107,"name":"address","nodeType":"ElementaryTypeName","src":"1849:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":110,"mutability":"mutable","name":"tokenId","nameLocation":"1869:7:2","nodeType":"VariableDeclaration","scope":115,"src":"1861:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":109,"name":"uint256","nodeType":"ElementaryTypeName","src":"1861:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":112,"mutability":"mutable","name":"data","nameLocation":"1893:4:2","nodeType":"VariableDeclaration","scope":115,"src":"1878:19:2","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":111,"name":"bytes","nodeType":"ElementaryTypeName","src":"1878:5:2","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1834:64:2"},"returnParameters":{"id":114,"nodeType":"ParameterList","parameters":[],"src":"1907:0:2"},"scope":170,"src":"1809:99:2","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":116,"nodeType":"StructuredDocumentation","src":"1914:687:2","text":" @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 Requirements:\n - `from` cannot be the zero address.\n - `to` cannot be the zero address.\n - `tokenId` token must exist and be owned by `from`.\n - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n Emits a {Transfer} event."},"functionSelector":"42842e0e","id":125,"implemented":false,"kind":"function","modifiers":[],"name":"safeTransferFrom","nameLocation":"2615:16:2","nodeType":"FunctionDefinition","parameters":{"id":123,"nodeType":"ParameterList","parameters":[{"constant":false,"id":118,"mutability":"mutable","name":"from","nameLocation":"2640:4:2","nodeType":"VariableDeclaration","scope":125,"src":"2632:12:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":117,"name":"address","nodeType":"ElementaryTypeName","src":"2632:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":120,"mutability":"mutable","name":"to","nameLocation":"2654:2:2","nodeType":"VariableDeclaration","scope":125,"src":"2646:10:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":119,"name":"address","nodeType":"ElementaryTypeName","src":"2646:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":122,"mutability":"mutable","name":"tokenId","nameLocation":"2666:7:2","nodeType":"VariableDeclaration","scope":125,"src":"2658:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":121,"name":"uint256","nodeType":"ElementaryTypeName","src":"2658:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2631:43:2"},"returnParameters":{"id":124,"nodeType":"ParameterList","parameters":[],"src":"2683:0:2"},"scope":170,"src":"2606:78:2","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":126,"nodeType":"StructuredDocumentation","src":"2690:732:2","text":" @dev Transfers `tokenId` token from `from` to `to`.\n WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n understand this adds an external call which potentially creates a reentrancy vulnerability.\n Requirements:\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 Emits a {Transfer} event."},"functionSelector":"23b872dd","id":135,"implemented":false,"kind":"function","modifiers":[],"name":"transferFrom","nameLocation":"3436:12:2","nodeType":"FunctionDefinition","parameters":{"id":133,"nodeType":"ParameterList","parameters":[{"constant":false,"id":128,"mutability":"mutable","name":"from","nameLocation":"3457:4:2","nodeType":"VariableDeclaration","scope":135,"src":"3449:12:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":127,"name":"address","nodeType":"ElementaryTypeName","src":"3449:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":130,"mutability":"mutable","name":"to","nameLocation":"3471:2:2","nodeType":"VariableDeclaration","scope":135,"src":"3463:10:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":129,"name":"address","nodeType":"ElementaryTypeName","src":"3463:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":132,"mutability":"mutable","name":"tokenId","nameLocation":"3483:7:2","nodeType":"VariableDeclaration","scope":135,"src":"3475:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":131,"name":"uint256","nodeType":"ElementaryTypeName","src":"3475:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3448:43:2"},"returnParameters":{"id":134,"nodeType":"ParameterList","parameters":[],"src":"3500:0:2"},"scope":170,"src":"3427:74:2","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":136,"nodeType":"StructuredDocumentation","src":"3507:452:2","text":" @dev Gives permission to `to` to transfer `tokenId` token to another account.\n The approval is cleared when the token is transferred.\n Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n Requirements:\n - The caller must own the token or be an approved operator.\n - `tokenId` must exist.\n Emits an {Approval} event."},"functionSelector":"095ea7b3","id":143,"implemented":false,"kind":"function","modifiers":[],"name":"approve","nameLocation":"3973:7:2","nodeType":"FunctionDefinition","parameters":{"id":141,"nodeType":"ParameterList","parameters":[{"constant":false,"id":138,"mutability":"mutable","name":"to","nameLocation":"3989:2:2","nodeType":"VariableDeclaration","scope":143,"src":"3981:10:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":137,"name":"address","nodeType":"ElementaryTypeName","src":"3981:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":140,"mutability":"mutable","name":"tokenId","nameLocation":"4001:7:2","nodeType":"VariableDeclaration","scope":143,"src":"3993:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":139,"name":"uint256","nodeType":"ElementaryTypeName","src":"3993:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3980:29:2"},"returnParameters":{"id":142,"nodeType":"ParameterList","parameters":[],"src":"4018:0:2"},"scope":170,"src":"3964:55:2","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":144,"nodeType":"StructuredDocumentation","src":"4025:309:2","text":" @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 Requirements:\n - The `operator` cannot be the caller.\n Emits an {ApprovalForAll} event."},"functionSelector":"a22cb465","id":151,"implemented":false,"kind":"function","modifiers":[],"name":"setApprovalForAll","nameLocation":"4348:17:2","nodeType":"FunctionDefinition","parameters":{"id":149,"nodeType":"ParameterList","parameters":[{"constant":false,"id":146,"mutability":"mutable","name":"operator","nameLocation":"4374:8:2","nodeType":"VariableDeclaration","scope":151,"src":"4366:16:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":145,"name":"address","nodeType":"ElementaryTypeName","src":"4366:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":148,"mutability":"mutable","name":"approved","nameLocation":"4389:8:2","nodeType":"VariableDeclaration","scope":151,"src":"4384:13:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":147,"name":"bool","nodeType":"ElementaryTypeName","src":"4384:4:2","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"4365:33:2"},"returnParameters":{"id":150,"nodeType":"ParameterList","parameters":[],"src":"4407:0:2"},"scope":170,"src":"4339:69:2","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":152,"nodeType":"StructuredDocumentation","src":"4414:139:2","text":" @dev Returns the account approved for `tokenId` token.\n Requirements:\n - `tokenId` must exist."},"functionSelector":"081812fc","id":159,"implemented":false,"kind":"function","modifiers":[],"name":"getApproved","nameLocation":"4567:11:2","nodeType":"FunctionDefinition","parameters":{"id":155,"nodeType":"ParameterList","parameters":[{"constant":false,"id":154,"mutability":"mutable","name":"tokenId","nameLocation":"4587:7:2","nodeType":"VariableDeclaration","scope":159,"src":"4579:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":153,"name":"uint256","nodeType":"ElementaryTypeName","src":"4579:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"4578:17:2"},"returnParameters":{"id":158,"nodeType":"ParameterList","parameters":[{"constant":false,"id":157,"mutability":"mutable","name":"operator","nameLocation":"4627:8:2","nodeType":"VariableDeclaration","scope":159,"src":"4619:16:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":156,"name":"address","nodeType":"ElementaryTypeName","src":"4619:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"4618:18:2"},"scope":170,"src":"4558:79:2","stateMutability":"view","virtual":false,"visibility":"external"},{"documentation":{"id":160,"nodeType":"StructuredDocumentation","src":"4643:138:2","text":" @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n See {setApprovalForAll}"},"functionSelector":"e985e9c5","id":169,"implemented":false,"kind":"function","modifiers":[],"name":"isApprovedForAll","nameLocation":"4795:16:2","nodeType":"FunctionDefinition","parameters":{"id":165,"nodeType":"ParameterList","parameters":[{"constant":false,"id":162,"mutability":"mutable","name":"owner","nameLocation":"4820:5:2","nodeType":"VariableDeclaration","scope":169,"src":"4812:13:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":161,"name":"address","nodeType":"ElementaryTypeName","src":"4812:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":164,"mutability":"mutable","name":"operator","nameLocation":"4835:8:2","nodeType":"VariableDeclaration","scope":169,"src":"4827:16:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":163,"name":"address","nodeType":"ElementaryTypeName","src":"4827:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"4811:33:2"},"returnParameters":{"id":168,"nodeType":"ParameterList","parameters":[{"constant":false,"id":167,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":169,"src":"4868:4:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":166,"name":"bool","nodeType":"ElementaryTypeName","src":"4868:4:2","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"4867:6:2"},"scope":170,"src":"4786:88:2","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":171,"src":"250:4626:2","usedErrors":[]}],"src":"108:4769:2"},"id":2},"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol","exportedSymbols":{"IERC721Receiver":[188]},"id":189,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":172,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"116:23:3"},{"abstract":false,"baseContracts":[],"canonicalName":"IERC721Receiver","contractDependencies":[],"contractKind":"interface","documentation":{"id":173,"nodeType":"StructuredDocumentation","src":"141:152:3","text":" @title ERC721 token receiver interface\n @dev Interface for any contract that wants to support safeTransfers\n from ERC721 asset contracts."},"fullyImplemented":false,"id":188,"linearizedBaseContracts":[188],"name":"IERC721Receiver","nameLocation":"304:15:3","nodeType":"ContractDefinition","nodes":[{"documentation":{"id":174,"nodeType":"StructuredDocumentation","src":"326:493:3","text":" @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n by `operator` from `from`, this function is called.\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 The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`."},"functionSelector":"150b7a02","id":187,"implemented":false,"kind":"function","modifiers":[],"name":"onERC721Received","nameLocation":"833:16:3","nodeType":"FunctionDefinition","parameters":{"id":183,"nodeType":"ParameterList","parameters":[{"constant":false,"id":176,"mutability":"mutable","name":"operator","nameLocation":"867:8:3","nodeType":"VariableDeclaration","scope":187,"src":"859:16:3","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":175,"name":"address","nodeType":"ElementaryTypeName","src":"859:7:3","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":178,"mutability":"mutable","name":"from","nameLocation":"893:4:3","nodeType":"VariableDeclaration","scope":187,"src":"885:12:3","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":177,"name":"address","nodeType":"ElementaryTypeName","src":"885:7:3","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":180,"mutability":"mutable","name":"tokenId","nameLocation":"915:7:3","nodeType":"VariableDeclaration","scope":187,"src":"907:15:3","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":179,"name":"uint256","nodeType":"ElementaryTypeName","src":"907:7:3","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":182,"mutability":"mutable","name":"data","nameLocation":"947:4:3","nodeType":"VariableDeclaration","scope":187,"src":"932:19:3","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":181,"name":"bytes","nodeType":"ElementaryTypeName","src":"932:5:3","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"849:108:3"},"returnParameters":{"id":186,"nodeType":"ParameterList","parameters":[{"constant":false,"id":185,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":187,"src":"976:6:3","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":184,"name":"bytes4","nodeType":"ElementaryTypeName","src":"976:6:3","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"975:8:3"},"scope":188,"src":"824:160:3","stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"scope":189,"src":"294:692:3","usedErrors":[]}],"src":"116:871:3"},"id":3},"@openzeppelin/contracts/utils/introspection/IERC165.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/utils/introspection/IERC165.sol","exportedSymbols":{"IERC165":[200]},"id":201,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":190,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"100:23:4"},{"abstract":false,"baseContracts":[],"canonicalName":"IERC165","contractDependencies":[],"contractKind":"interface","documentation":{"id":191,"nodeType":"StructuredDocumentation","src":"125:279:4","text":" @dev Interface of the ERC165 standard, as defined in the\n https://eips.ethereum.org/EIPS/eip-165[EIP].\n Implementers can declare support of contract interfaces, which can then be\n queried by others ({ERC165Checker}).\n For an implementation, see {ERC165}."},"fullyImplemented":false,"id":200,"linearizedBaseContracts":[200],"name":"IERC165","nameLocation":"415:7:4","nodeType":"ContractDefinition","nodes":[{"documentation":{"id":192,"nodeType":"StructuredDocumentation","src":"429:340:4","text":" @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 This function call must use less than 30 000 gas."},"functionSelector":"01ffc9a7","id":199,"implemented":false,"kind":"function","modifiers":[],"name":"supportsInterface","nameLocation":"783:17:4","nodeType":"FunctionDefinition","parameters":{"id":195,"nodeType":"ParameterList","parameters":[{"constant":false,"id":194,"mutability":"mutable","name":"interfaceId","nameLocation":"808:11:4","nodeType":"VariableDeclaration","scope":199,"src":"801:18:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":193,"name":"bytes4","nodeType":"ElementaryTypeName","src":"801:6:4","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"800:20:4"},"returnParameters":{"id":198,"nodeType":"ParameterList","parameters":[{"constant":false,"id":197,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":199,"src":"844:4:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":196,"name":"bool","nodeType":"ElementaryTypeName","src":"844:4:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"843:6:4"},"scope":200,"src":"774:76:4","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":201,"src":"405:447:4","usedErrors":[]}],"src":"100:753:4"},"id":4},"contracts/ChargedParticlesAccount.sol":{"ast":{"absolutePath":"contracts/ChargedParticlesAccount.sol","exportedSymbols":{"AccountLocked":[269],"ChargedParticlesAccount":[254],"ERC6551AccountLib":[890],"ExceedsMaxLockTime":[271],"IERC1155Receiver":[54],"IERC1271":[13],"IERC165":[200],"IERC6551Account":[835],"IERC6551AccountProxy":[797],"IERC721":[170],"IERC721Receiver":[188],"InvalidInput":[267],"MinimalisticAccount":[789],"NotAuthorized":[265],"OwnershipCycle":[275],"UntrustedImplementation":[273]},"id":255,"license":"UNLICENSED","nodeType":"SourceUnit","nodes":[{"id":202,"literals":["solidity","^","0.8",".13"],"nodeType":"PragmaDirective","src":"39:24:5"},{"absolutePath":"contracts/MinimalisticAccount.sol","file":"./MinimalisticAccount.sol","id":203,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":255,"sourceUnit":790,"src":"65:35:5","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721.sol","file":"@openzeppelin/contracts/token/ERC721/IERC721.sol","id":204,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":255,"sourceUnit":171,"src":"101:58:5","symbolAliases":[],"unitAlias":""},{"abstract":false,"baseContracts":[{"baseName":{"id":205,"name":"MinimalisticAccount","nameLocations":["197:19:5"],"nodeType":"IdentifierPath","referencedDeclaration":789,"src":"197:19:5"},"id":206,"nodeType":"InheritanceSpecifier","src":"197:19:5"}],"canonicalName":"ChargedParticlesAccount","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"id":254,"linearizedBaseContracts":[254,789,54,188,835,200],"name":"ChargedParticlesAccount","nameLocation":"170:23:5","nodeType":"ContractDefinition","nodes":[{"body":{"id":228,"nodeType":"Block","src":"353:171:5","statements":[{"expression":{"arguments":[{"expression":{"id":219,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"446:3:5","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":220,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"450:6:5","memberName":"sender","nodeType":"MemberAccess","src":"446:10:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"arguments":[{"id":223,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"478:4:5","typeDescriptions":{"typeIdentifier":"t_contract$_ChargedParticlesAccount_$254","typeString":"contract ChargedParticlesAccount"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ChargedParticlesAccount_$254","typeString":"contract ChargedParticlesAccount"}],"id":222,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"470:7:5","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":221,"name":"address","nodeType":"ElementaryTypeName","src":"470:7:5","typeDescriptions":{}}},"id":224,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"470:13:5","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":225,"name":"nftTokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":210,"src":"497:10:5","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"arguments":[{"id":216,"name":"nftTokenAddress","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":208,"src":"399:15:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":215,"name":"IERC721","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":170,"src":"391:7:5","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC721_$170_$","typeString":"type(contract IERC721)"}},"id":217,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"391:24:5","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_IERC721_$170","typeString":"contract IERC721"}},"id":218,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"416:16:5","memberName":"safeTransferFrom","nodeType":"MemberAccess","referencedDeclaration":125,"src":"391:41:5","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$","typeString":"function (address,address,uint256) external"}},"id":226,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"391:126:5","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":227,"nodeType":"ExpressionStatement","src":"391:126:5"}]},"functionSelector":"a737a299","id":229,"implemented":true,"kind":"function","modifiers":[],"name":"covalentBond","nameLocation":"232:12:5","nodeType":"FunctionDefinition","parameters":{"id":213,"nodeType":"ParameterList","parameters":[{"constant":false,"id":208,"mutability":"mutable","name":"nftTokenAddress","nameLocation":"262:15:5","nodeType":"VariableDeclaration","scope":229,"src":"254:23:5","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":207,"name":"address","nodeType":"ElementaryTypeName","src":"254:7:5","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":210,"mutability":"mutable","name":"nftTokenId","nameLocation":"295:10:5","nodeType":"VariableDeclaration","scope":229,"src":"287:18:5","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":209,"name":"uint256","nodeType":"ElementaryTypeName","src":"287:7:5","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":212,"mutability":"mutable","name":"nftTokenAmount","nameLocation":"323:14:5","nodeType":"VariableDeclaration","scope":229,"src":"315:22:5","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":211,"name":"uint256","nodeType":"ElementaryTypeName","src":"315:7:5","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"244:99:5"},"returnParameters":{"id":214,"nodeType":"ParameterList","parameters":[],"src":"353:0:5"},"scope":254,"src":"223:301:5","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":252,"nodeType":"Block","src":"691:95:5","statements":[{"expression":{"arguments":[{"arguments":[{"id":246,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"751:4:5","typeDescriptions":{"typeIdentifier":"t_contract$_ChargedParticlesAccount_$254","typeString":"contract ChargedParticlesAccount"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_ChargedParticlesAccount_$254","typeString":"contract ChargedParticlesAccount"}],"id":245,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"743:7:5","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":244,"name":"address","nodeType":"ElementaryTypeName","src":"743:7:5","typeDescriptions":{}}},"id":247,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"743:13:5","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":248,"name":"receiver","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":231,"src":"758:8:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":249,"name":"nftTokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":235,"src":"768:10:5","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"arguments":[{"id":241,"name":"nftTokenAddress","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":233,"src":"709:15:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":240,"name":"IERC721","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":170,"src":"701:7:5","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC721_$170_$","typeString":"type(contract IERC721)"}},"id":242,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"701:24:5","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_IERC721_$170","typeString":"contract IERC721"}},"id":243,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"726:16:5","memberName":"safeTransferFrom","nodeType":"MemberAccess","referencedDeclaration":125,"src":"701:41:5","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$","typeString":"function (address,address,uint256) external"}},"id":250,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"701:78:5","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":251,"nodeType":"ExpressionStatement","src":"701:78:5"}]},"functionSelector":"6b764e1b","id":253,"implemented":true,"kind":"function","modifiers":[],"name":"breakCovalentBond","nameLocation":"539:17:5","nodeType":"FunctionDefinition","parameters":{"id":238,"nodeType":"ParameterList","parameters":[{"constant":false,"id":231,"mutability":"mutable","name":"receiver","nameLocation":"574:8:5","nodeType":"VariableDeclaration","scope":253,"src":"566:16:5","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":230,"name":"address","nodeType":"ElementaryTypeName","src":"566:7:5","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":233,"mutability":"mutable","name":"nftTokenAddress","nameLocation":"600:15:5","nodeType":"VariableDeclaration","scope":253,"src":"592:23:5","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":232,"name":"address","nodeType":"ElementaryTypeName","src":"592:7:5","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":235,"mutability":"mutable","name":"nftTokenId","nameLocation":"633:10:5","nodeType":"VariableDeclaration","scope":253,"src":"625:18:5","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":234,"name":"uint256","nodeType":"ElementaryTypeName","src":"625:7:5","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":237,"mutability":"mutable","name":"nftTokenAmount","nameLocation":"661:14:5","nodeType":"VariableDeclaration","scope":253,"src":"653:22:5","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":236,"name":"uint256","nodeType":"ElementaryTypeName","src":"653:7:5","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"556:125:5"},"returnParameters":{"id":239,"nodeType":"ParameterList","parameters":[],"src":"691:0:5"},"scope":254,"src":"530:256:5","stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"scope":255,"src":"161:627:5","usedErrors":[265,267,269,271,275]}],"src":"39:750:5"},"id":5},"contracts/MinimalisticAccount.sol":{"ast":{"absolutePath":"contracts/MinimalisticAccount.sol","exportedSymbols":{"AccountLocked":[269],"ERC6551AccountLib":[890],"ExceedsMaxLockTime":[271],"IERC1155Receiver":[54],"IERC1271":[13],"IERC165":[200],"IERC6551Account":[835],"IERC6551AccountProxy":[797],"IERC721":[170],"IERC721Receiver":[188],"InvalidInput":[267],"MinimalisticAccount":[789],"NotAuthorized":[265],"OwnershipCycle":[275],"UntrustedImplementation":[273]},"id":790,"license":"UNLICENSED","nodeType":"SourceUnit","nodes":[{"id":256,"literals":["solidity","^","0.8",".13"],"nodeType":"PragmaDirective","src":"39:24:6"},{"absolutePath":"contracts/interfaces/IERC6551Account.sol","file":"./interfaces/IERC6551Account.sol","id":257,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":790,"sourceUnit":836,"src":"65:42:6","symbolAliases":[],"unitAlias":""},{"absolutePath":"contracts/lib/ERC6551AccountLib.sol","file":"./lib/ERC6551AccountLib.sol","id":258,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":790,"sourceUnit":891,"src":"108:37:6","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/utils/introspection/IERC165.sol","file":"@openzeppelin/contracts/utils/introspection/IERC165.sol","id":259,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":790,"sourceUnit":201,"src":"147:65:6","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721.sol","file":"@openzeppelin/contracts/token/ERC721/IERC721.sol","id":260,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":790,"sourceUnit":171,"src":"213:58:6","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol","file":"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol","id":261,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":790,"sourceUnit":189,"src":"272:66:6","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol","file":"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol","id":262,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":790,"sourceUnit":55,"src":"339:68:6","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/interfaces/IERC1271.sol","file":"@openzeppelin/contracts/interfaces/IERC1271.sol","id":263,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":790,"sourceUnit":14,"src":"408:57:6","symbolAliases":[],"unitAlias":""},{"errorSelector":"ea8e4eb5","id":265,"name":"NotAuthorized","nameLocation":"473:13:6","nodeType":"ErrorDefinition","parameters":{"id":264,"nodeType":"ParameterList","parameters":[],"src":"486:2:6"},"src":"467:22:6"},{"errorSelector":"b4fa3fb3","id":267,"name":"InvalidInput","nameLocation":"496:12:6","nodeType":"ErrorDefinition","parameters":{"id":266,"nodeType":"ParameterList","parameters":[],"src":"508:2:6"},"src":"490:21:6"},{"errorSelector":"6315bfbb","id":269,"name":"AccountLocked","nameLocation":"518:13:6","nodeType":"ErrorDefinition","parameters":{"id":268,"nodeType":"ParameterList","parameters":[],"src":"531:2:6"},"src":"512:22:6"},{"errorSelector":"0c0a7be8","id":271,"name":"ExceedsMaxLockTime","nameLocation":"541:18:6","nodeType":"ErrorDefinition","parameters":{"id":270,"nodeType":"ParameterList","parameters":[],"src":"559:2:6"},"src":"535:27:6"},{"errorSelector":"b57d5a5e","id":273,"name":"UntrustedImplementation","nameLocation":"569:23:6","nodeType":"ErrorDefinition","parameters":{"id":272,"nodeType":"ParameterList","parameters":[],"src":"592:2:6"},"src":"563:32:6"},{"errorSelector":"b79e3f3f","id":275,"name":"OwnershipCycle","nameLocation":"602:14:6","nodeType":"ErrorDefinition","parameters":{"id":274,"nodeType":"ParameterList","parameters":[],"src":"616:2:6"},"src":"596:23:6"},{"abstract":false,"baseContracts":[{"baseName":{"id":277,"name":"IERC165","nameLocations":["731:7:6"],"nodeType":"IdentifierPath","referencedDeclaration":200,"src":"731:7:6"},"id":278,"nodeType":"InheritanceSpecifier","src":"731:7:6"},{"baseName":{"id":279,"name":"IERC6551Account","nameLocations":["744:15:6"],"nodeType":"IdentifierPath","referencedDeclaration":835,"src":"744:15:6"},"id":280,"nodeType":"InheritanceSpecifier","src":"744:15:6"},{"baseName":{"id":281,"name":"IERC721Receiver","nameLocations":["765:15:6"],"nodeType":"IdentifierPath","referencedDeclaration":188,"src":"765:15:6"},"id":282,"nodeType":"InheritanceSpecifier","src":"765:15:6"},{"baseName":{"id":283,"name":"IERC1155Receiver","nameLocations":["786:16:6"],"nodeType":"IdentifierPath","referencedDeclaration":54,"src":"786:16:6"},"id":284,"nodeType":"InheritanceSpecifier","src":"786:16:6"}],"canonicalName":"MinimalisticAccount","contractDependencies":[],"contractKind":"contract","documentation":{"id":276,"nodeType":"StructuredDocumentation","src":"621:73:6","text":" @title A smart contract account owned by a single ERC721 token"},"fullyImplemented":true,"id":789,"linearizedBaseContracts":[789,54,188,835,200],"name":"MinimalisticAccount","nameLocation":"704:19:6","nodeType":"ContractDefinition","nodes":[{"constant":false,"documentation":{"id":285,"nodeType":"StructuredDocumentation","src":"809:57:6","text":"@dev timestamp at which this account will be unlocked"},"functionSelector":"ce0617ec","id":287,"mutability":"mutable","name":"lockedUntil","nameLocation":"886:11:6","nodeType":"VariableDeclaration","scope":789,"src":"871:26:6","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":286,"name":"uint256","nodeType":"ElementaryTypeName","src":"871:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"public"},{"constant":false,"documentation":{"id":288,"nodeType":"StructuredDocumentation","src":"904:56:6","text":"@dev mapping from owner => caller => has permissions"},"functionSelector":"1f9838b5","id":294,"mutability":"mutable","name":"permissions","nameLocation":"1017:11:6","nodeType":"VariableDeclaration","scope":789,"src":"965:63:6","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_mapping$_t_address_$_t_bool_$_$","typeString":"mapping(address => mapping(address => bool))"},"typeName":{"id":293,"keyType":{"id":289,"name":"address","nodeType":"ElementaryTypeName","src":"973:7:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"Mapping","src":"965:44:6","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_mapping$_t_address_$_t_bool_$_$","typeString":"mapping(address => mapping(address => bool))"},"valueType":{"id":292,"keyType":{"id":290,"name":"address","nodeType":"ElementaryTypeName","src":"992:7:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"Mapping","src":"984:24:6","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_bool_$","typeString":"mapping(address => bool)"},"valueType":{"id":291,"name":"bool","nodeType":"ElementaryTypeName","src":"1003:4:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}}},"visibility":"public"},{"anonymous":false,"eventSelector":"2c722487e90aca38ec1b074c3403210bd2bfb769b4da7f12f7bf0b9e37517c18","id":302,"name":"OverrideUpdated","nameLocation":"1041:15:6","nodeType":"EventDefinition","parameters":{"id":301,"nodeType":"ParameterList","parameters":[{"constant":false,"id":296,"indexed":false,"mutability":"mutable","name":"owner","nameLocation":"1074:5:6","nodeType":"VariableDeclaration","scope":302,"src":"1066:13:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":295,"name":"address","nodeType":"ElementaryTypeName","src":"1066:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":298,"indexed":false,"mutability":"mutable","name":"selector","nameLocation":"1096:8:6","nodeType":"VariableDeclaration","scope":302,"src":"1089:15:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":297,"name":"bytes4","nodeType":"ElementaryTypeName","src":"1089:6:6","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"},{"constant":false,"id":300,"indexed":false,"mutability":"mutable","name":"implementation","nameLocation":"1122:14:6","nodeType":"VariableDeclaration","scope":302,"src":"1114:22:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":299,"name":"address","nodeType":"ElementaryTypeName","src":"1114:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1056:86:6"},"src":"1035:108:6"},{"anonymous":false,"eventSelector":"394777a58092892d136a90c4bb7e4350c72ac50fba6a0208128677f36527dcf5","id":310,"name":"PermissionUpdated","nameLocation":"1155:17:6","nodeType":"EventDefinition","parameters":{"id":309,"nodeType":"ParameterList","parameters":[{"constant":false,"id":304,"indexed":false,"mutability":"mutable","name":"owner","nameLocation":"1181:5:6","nodeType":"VariableDeclaration","scope":310,"src":"1173:13:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":303,"name":"address","nodeType":"ElementaryTypeName","src":"1173:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":306,"indexed":false,"mutability":"mutable","name":"caller","nameLocation":"1196:6:6","nodeType":"VariableDeclaration","scope":310,"src":"1188:14:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":305,"name":"address","nodeType":"ElementaryTypeName","src":"1188:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":308,"indexed":false,"mutability":"mutable","name":"hasPermission","nameLocation":"1209:13:6","nodeType":"VariableDeclaration","scope":310,"src":"1204:18:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":307,"name":"bool","nodeType":"ElementaryTypeName","src":"1204:4:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1172:51:6"},"src":"1149:75:6"},{"anonymous":false,"eventSelector":"a7b24c66dd3269a292a60b3facdbb8f3e7557d1e19e64d99e0d6ee7250be63ad","id":314,"name":"LockUpdated","nameLocation":"1236:11:6","nodeType":"EventDefinition","parameters":{"id":313,"nodeType":"ParameterList","parameters":[{"constant":false,"id":312,"indexed":false,"mutability":"mutable","name":"lockedUntil","nameLocation":"1256:11:6","nodeType":"VariableDeclaration","scope":314,"src":"1248:19:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":311,"name":"uint256","nodeType":"ElementaryTypeName","src":"1248:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1247:21:6"},"src":"1230:39:6"},{"body":{"id":327,"nodeType":"Block","src":"1359:77:6","statements":[{"condition":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":321,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"expression":{"id":317,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"1373:3:6","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":318,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"1377:6:6","memberName":"sender","nodeType":"MemberAccess","src":"1373:10:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"!=","rightExpression":{"arguments":[],"expression":{"argumentTypes":[],"id":319,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":554,"src":"1387:5:6","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_address_$","typeString":"function () view returns (address)"}},"id":320,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1387:7:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"1373:21:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":325,"nodeType":"IfStatement","src":"1369:49:6","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":322,"name":"NotAuthorized","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":265,"src":"1403:13:6","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":323,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1403:15:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":324,"nodeType":"RevertStatement","src":"1396:22:6"}},{"id":326,"nodeType":"PlaceholderStatement","src":"1428:1:6"}]},"documentation":{"id":315,"nodeType":"StructuredDocumentation","src":"1275:58:6","text":"@dev reverts if caller is not the owner of the account"},"id":328,"name":"onlyOwner","nameLocation":"1347:9:6","nodeType":"ModifierDefinition","parameters":{"id":316,"nodeType":"ParameterList","parameters":[],"src":"1356:2:6"},"src":"1338:98:6","virtual":false,"visibility":"internal"},{"body":{"id":341,"nodeType":"Block","src":"1544:81:6","statements":[{"condition":{"id":335,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"!","prefix":true,"src":"1558:25:6","subExpression":{"arguments":[{"expression":{"id":332,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"1572:3:6","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":333,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"1576:6:6","memberName":"sender","nodeType":"MemberAccess","src":"1572:10:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":331,"name":"isAuthorized","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":596,"src":"1559:12:6","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_address_$returns$_t_bool_$","typeString":"function (address) view returns (bool)"}},"id":334,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1559:24:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":339,"nodeType":"IfStatement","src":"1554:53:6","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":336,"name":"NotAuthorized","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":265,"src":"1592:13:6","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":337,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1592:15:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":338,"nodeType":"RevertStatement","src":"1585:22:6"}},{"id":340,"nodeType":"PlaceholderStatement","src":"1617:1:6"}]},"documentation":{"id":329,"nodeType":"StructuredDocumentation","src":"1442:71:6","text":"@dev reverts if caller is not authorized to execute on this account"},"id":342,"name":"onlyAuthorized","nameLocation":"1527:14:6","nodeType":"ModifierDefinition","parameters":{"id":330,"nodeType":"ParameterList","parameters":[],"src":"1541:2:6"},"src":"1518:107:6","virtual":false,"visibility":"internal"},{"body":{"id":352,"nodeType":"Block","src":"1712:66:6","statements":[{"condition":{"arguments":[],"expression":{"argumentTypes":[],"id":345,"name":"isLocked","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":505,"src":"1726:8:6","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_bool_$","typeString":"function () view returns (bool)"}},"id":346,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1726:10:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":350,"nodeType":"IfStatement","src":"1722:38:6","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":347,"name":"AccountLocked","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":269,"src":"1745:13:6","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":348,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1745:15:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":349,"nodeType":"RevertStatement","src":"1738:22:6"}},{"id":351,"nodeType":"PlaceholderStatement","src":"1770:1:6"}]},"documentation":{"id":343,"nodeType":"StructuredDocumentation","src":"1631:52:6","text":"@dev reverts if this account is currently locked"},"id":353,"name":"onlyUnlocked","nameLocation":"1697:12:6","nodeType":"ModifierDefinition","parameters":{"id":344,"nodeType":"ParameterList","parameters":[],"src":"1709:2:6"},"src":"1688:90:6","virtual":false,"visibility":"internal"},{"body":{"id":356,"nodeType":"Block","src":"1798:2:6","statements":[]},"id":357,"implemented":true,"kind":"constructor","modifiers":[],"name":"","nameLocation":"-1:-1:-1","nodeType":"FunctionDefinition","parameters":{"id":354,"nodeType":"ParameterList","parameters":[],"src":"1795:2:6"},"returnParameters":{"id":355,"nodeType":"ParameterList","parameters":[],"src":"1798:0:6"},"scope":789,"src":"1784:16:6","stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"baseFunctions":[809],"body":{"id":361,"nodeType":"Block","src":"1916:7:6","statements":[]},"documentation":{"id":358,"nodeType":"StructuredDocumentation","src":"1806:78:6","text":"@dev allows eth transfers by default, but allows account owner to override"},"id":362,"implemented":true,"kind":"receive","modifiers":[],"name":"","nameLocation":"-1:-1:-1","nodeType":"FunctionDefinition","parameters":{"id":359,"nodeType":"ParameterList","parameters":[],"src":"1896:2:6"},"returnParameters":{"id":360,"nodeType":"ParameterList","parameters":[],"src":"1916:0:6"},"scope":789,"src":"1889:34:6","stateMutability":"payable","virtual":false,"visibility":"external"},{"baseFunctions":[820],"body":{"id":390,"nodeType":"Block","src":"2196:98:6","statements":[{"eventCall":{"arguments":[{"id":379,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":365,"src":"2231:2:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":380,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":367,"src":"2235:5:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":381,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":369,"src":"2242:4:6","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}],"id":378,"name":"TransactionExecuted","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":806,"src":"2211:19:6","typeDescriptions":{"typeIdentifier":"t_function_event_nonpayable$_t_address_$_t_uint256_$_t_bytes_memory_ptr_$returns$__$","typeString":"function (address,uint256,bytes memory)"}},"id":382,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2211:36:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":383,"nodeType":"EmitStatement","src":"2206:41:6"},{"expression":{"arguments":[{"id":385,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":365,"src":"2271:2:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":386,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":367,"src":"2275:5:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":387,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":369,"src":"2282:4:6","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}],"id":384,"name":"_call","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":760,"src":"2265:5:6","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_uint256_$_t_bytes_calldata_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (address,uint256,bytes calldata) returns (bytes memory)"}},"id":388,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2265:22:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"functionReturnParameters":377,"id":389,"nodeType":"Return","src":"2258:29:6"}]},"documentation":{"id":363,"nodeType":"StructuredDocumentation","src":"1929:95:6","text":"@dev executes a low-level call against an account if the caller is authorized to make calls"},"functionSelector":"9e5d4c49","id":391,"implemented":true,"kind":"function","modifiers":[{"id":372,"kind":"modifierInvocation","modifierName":{"id":371,"name":"onlyAuthorized","nameLocations":["2145:14:6"],"nodeType":"IdentifierPath","referencedDeclaration":342,"src":"2145:14:6"},"nodeType":"ModifierInvocation","src":"2145:14:6"},{"id":374,"kind":"modifierInvocation","modifierName":{"id":373,"name":"onlyUnlocked","nameLocations":["2160:12:6"],"nodeType":"IdentifierPath","referencedDeclaration":353,"src":"2160:12:6"},"nodeType":"ModifierInvocation","src":"2160:12:6"}],"name":"executeCall","nameLocation":"2038:11:6","nodeType":"FunctionDefinition","parameters":{"id":370,"nodeType":"ParameterList","parameters":[{"constant":false,"id":365,"mutability":"mutable","name":"to","nameLocation":"2067:2:6","nodeType":"VariableDeclaration","scope":391,"src":"2059:10:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":364,"name":"address","nodeType":"ElementaryTypeName","src":"2059:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":367,"mutability":"mutable","name":"value","nameLocation":"2087:5:6","nodeType":"VariableDeclaration","scope":391,"src":"2079:13:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":366,"name":"uint256","nodeType":"ElementaryTypeName","src":"2079:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":369,"mutability":"mutable","name":"data","nameLocation":"2117:4:6","nodeType":"VariableDeclaration","scope":391,"src":"2102:19:6","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":368,"name":"bytes","nodeType":"ElementaryTypeName","src":"2102:5:6","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"2049:78:6"},"returnParameters":{"id":377,"nodeType":"ParameterList","parameters":[{"constant":false,"id":376,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":391,"src":"2182:12:6","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":375,"name":"bytes","nodeType":"ElementaryTypeName","src":"2182:5:6","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"2181:14:6"},"scope":789,"src":"2029:265:6","stateMutability":"payable","virtual":false,"visibility":"external"},{"body":{"id":463,"nodeType":"Block","src":"2483:402:6","statements":[{"assignments":[404],"declarations":[{"constant":false,"id":404,"mutability":"mutable","name":"_owner","nameLocation":"2501:6:6","nodeType":"VariableDeclaration","scope":463,"src":"2493:14:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":403,"name":"address","nodeType":"ElementaryTypeName","src":"2493:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":407,"initialValue":{"arguments":[],"expression":{"argumentTypes":[],"id":405,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":554,"src":"2510:5:6","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_address_$","typeString":"function () view returns (address)"}},"id":406,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2510:7:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"2493:24:6"},{"condition":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":411,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"expression":{"id":408,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"2531:3:6","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":409,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"2535:6:6","memberName":"sender","nodeType":"MemberAccess","src":"2531:10:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"!=","rightExpression":{"id":410,"name":"_owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":404,"src":"2545:6:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"2531:20:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":415,"nodeType":"IfStatement","src":"2527:48:6","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":412,"name":"NotAuthorized","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":265,"src":"2560:13:6","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":413,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2560:15:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":414,"nodeType":"RevertStatement","src":"2553:22:6"}},{"assignments":[417],"declarations":[{"constant":false,"id":417,"mutability":"mutable","name":"length","nameLocation":"2594:6:6","nodeType":"VariableDeclaration","scope":463,"src":"2586:14:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":416,"name":"uint256","nodeType":"ElementaryTypeName","src":"2586:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":420,"initialValue":{"expression":{"id":418,"name":"callers","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":395,"src":"2603:7:6","typeDescriptions":{"typeIdentifier":"t_array$_t_address_$dyn_calldata_ptr","typeString":"address[] calldata"}},"id":419,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"2611:6:6","memberName":"length","nodeType":"MemberAccess","src":"2603:14:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"2586:31:6"},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":424,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"expression":{"id":421,"name":"_permissions","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":398,"src":"2632:12:6","typeDescriptions":{"typeIdentifier":"t_array$_t_bool_$dyn_calldata_ptr","typeString":"bool[] calldata"}},"id":422,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"2645:6:6","memberName":"length","nodeType":"MemberAccess","src":"2632:19:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"!=","rightExpression":{"id":423,"name":"length","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":417,"src":"2655:6:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"2632:29:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":428,"nodeType":"IfStatement","src":"2628:56:6","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":425,"name":"InvalidInput","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":267,"src":"2670:12:6","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":426,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2670:14:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":427,"nodeType":"RevertStatement","src":"2663:21:6"}},{"body":{"id":461,"nodeType":"Block","src":"2732:147:6","statements":[{"expression":{"id":449,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"baseExpression":{"baseExpression":{"id":439,"name":"permissions","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":294,"src":"2746:11:6","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_mapping$_t_address_$_t_bool_$_$","typeString":"mapping(address => mapping(address => bool))"}},"id":444,"indexExpression":{"id":440,"name":"_owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":404,"src":"2758:6:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"2746:19:6","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_bool_$","typeString":"mapping(address => bool)"}},"id":445,"indexExpression":{"baseExpression":{"id":441,"name":"callers","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":395,"src":"2766:7:6","typeDescriptions":{"typeIdentifier":"t_array$_t_address_$dyn_calldata_ptr","typeString":"address[] calldata"}},"id":443,"indexExpression":{"id":442,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":430,"src":"2774:1:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"2766:10:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"IndexAccess","src":"2746:31:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"baseExpression":{"id":446,"name":"_permissions","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":398,"src":"2780:12:6","typeDescriptions":{"typeIdentifier":"t_array$_t_bool_$dyn_calldata_ptr","typeString":"bool[] calldata"}},"id":448,"indexExpression":{"id":447,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":430,"src":"2793:1:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"2780:15:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"2746:49:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":450,"nodeType":"ExpressionStatement","src":"2746:49:6"},{"eventCall":{"arguments":[{"id":452,"name":"_owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":404,"src":"2832:6:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"baseExpression":{"id":453,"name":"callers","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":395,"src":"2840:7:6","typeDescriptions":{"typeIdentifier":"t_array$_t_address_$dyn_calldata_ptr","typeString":"address[] calldata"}},"id":455,"indexExpression":{"id":454,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":430,"src":"2848:1:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"2840:10:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"baseExpression":{"id":456,"name":"_permissions","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":398,"src":"2852:12:6","typeDescriptions":{"typeIdentifier":"t_array$_t_bool_$dyn_calldata_ptr","typeString":"bool[] calldata"}},"id":458,"indexExpression":{"id":457,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":430,"src":"2865:1:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"2852:15:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_bool","typeString":"bool"}],"id":451,"name":"PermissionUpdated","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":310,"src":"2814:17:6","typeDescriptions":{"typeIdentifier":"t_function_event_nonpayable$_t_address_$_t_address_$_t_bool_$returns$__$","typeString":"function (address,address,bool)"}},"id":459,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2814:54:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":460,"nodeType":"EmitStatement","src":"2809:59:6"}]},"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":435,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":433,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":430,"src":"2715:1:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"<","rightExpression":{"id":434,"name":"length","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":417,"src":"2719:6:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"2715:10:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":462,"initializationExpression":{"assignments":[430],"declarations":[{"constant":false,"id":430,"mutability":"mutable","name":"i","nameLocation":"2708:1:6","nodeType":"VariableDeclaration","scope":462,"src":"2700:9:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":429,"name":"uint256","nodeType":"ElementaryTypeName","src":"2700:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":432,"initialValue":{"hexValue":"30","id":431,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"2712:1:6","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"nodeType":"VariableDeclarationStatement","src":"2700:13:6"},"loopExpression":{"expression":{"id":437,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"++","prefix":false,"src":"2727:3:6","subExpression":{"id":436,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":430,"src":"2727:1:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":438,"nodeType":"ExpressionStatement","src":"2727:3:6"},"nodeType":"ForStatement","src":"2695:184:6"}]},"documentation":{"id":392,"nodeType":"StructuredDocumentation","src":"2300:52:6","text":"@dev grants a given caller execution permissions"},"functionSelector":"039721b1","id":464,"implemented":true,"kind":"function","modifiers":[{"id":401,"kind":"modifierInvocation","modifierName":{"id":400,"name":"onlyUnlocked","nameLocations":["2470:12:6"],"nodeType":"IdentifierPath","referencedDeclaration":353,"src":"2470:12:6"},"nodeType":"ModifierInvocation","src":"2470:12:6"}],"name":"setPermissions","nameLocation":"2366:14:6","nodeType":"FunctionDefinition","parameters":{"id":399,"nodeType":"ParameterList","parameters":[{"constant":false,"id":395,"mutability":"mutable","name":"callers","nameLocation":"2409:7:6","nodeType":"VariableDeclaration","scope":464,"src":"2390:26:6","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_array$_t_address_$dyn_calldata_ptr","typeString":"address[]"},"typeName":{"baseType":{"id":393,"name":"address","nodeType":"ElementaryTypeName","src":"2390:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":394,"nodeType":"ArrayTypeName","src":"2390:9:6","typeDescriptions":{"typeIdentifier":"t_array$_t_address_$dyn_storage_ptr","typeString":"address[]"}},"visibility":"internal"},{"constant":false,"id":398,"mutability":"mutable","name":"_permissions","nameLocation":"2442:12:6","nodeType":"VariableDeclaration","scope":464,"src":"2426:28:6","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_array$_t_bool_$dyn_calldata_ptr","typeString":"bool[]"},"typeName":{"baseType":{"id":396,"name":"bool","nodeType":"ElementaryTypeName","src":"2426:4:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":397,"nodeType":"ArrayTypeName","src":"2426:6:6","typeDescriptions":{"typeIdentifier":"t_array$_t_bool_$dyn_storage_ptr","typeString":"bool[]"}},"visibility":"internal"}],"src":"2380:80:6"},"returnParameters":{"id":402,"nodeType":"ParameterList","parameters":[],"src":"2483:0:6"},"scope":789,"src":"2357:528:6","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":492,"nodeType":"Block","src":"3016:181:6","statements":[{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":479,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":474,"name":"_lockedUntil","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":467,"src":"3030:12:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":478,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"expression":{"id":475,"name":"block","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-4,"src":"3045:5:6","typeDescriptions":{"typeIdentifier":"t_magic_block","typeString":"block"}},"id":476,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"3051:9:6","memberName":"timestamp","nodeType":"MemberAccess","src":"3045:15:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"hexValue":"333635","id":477,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3063:8:6","subdenomination":"days","typeDescriptions":{"typeIdentifier":"t_rational_31536000_by_1","typeString":"int_const 31536000"},"value":"365"},"src":"3045:26:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"3030:41:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":483,"nodeType":"IfStatement","src":"3026:86:6","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":480,"name":"ExceedsMaxLockTime","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":271,"src":"3092:18:6","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":481,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3092:20:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":482,"nodeType":"RevertStatement","src":"3085:27:6"}},{"expression":{"id":486,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":484,"name":"lockedUntil","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":287,"src":"3123:11:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":485,"name":"_lockedUntil","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":467,"src":"3137:12:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"3123:26:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":487,"nodeType":"ExpressionStatement","src":"3123:26:6"},{"eventCall":{"arguments":[{"id":489,"name":"_lockedUntil","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":467,"src":"3177:12:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":488,"name":"LockUpdated","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":314,"src":"3165:11:6","typeDescriptions":{"typeIdentifier":"t_function_event_nonpayable$_t_uint256_$returns$__$","typeString":"function (uint256)"}},"id":490,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3165:25:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":491,"nodeType":"EmitStatement","src":"3160:30:6"}]},"documentation":{"id":465,"nodeType":"StructuredDocumentation","src":"2891:52:6","text":"@dev locks the account until a certain timestamp"},"functionSelector":"dd467064","id":493,"implemented":true,"kind":"function","modifiers":[{"id":470,"kind":"modifierInvocation","modifierName":{"id":469,"name":"onlyOwner","nameLocations":["2993:9:6"],"nodeType":"IdentifierPath","referencedDeclaration":328,"src":"2993:9:6"},"nodeType":"ModifierInvocation","src":"2993:9:6"},{"id":472,"kind":"modifierInvocation","modifierName":{"id":471,"name":"onlyUnlocked","nameLocations":["3003:12:6"],"nodeType":"IdentifierPath","referencedDeclaration":353,"src":"3003:12:6"},"nodeType":"ModifierInvocation","src":"3003:12:6"}],"name":"lock","nameLocation":"2957:4:6","nodeType":"FunctionDefinition","parameters":{"id":468,"nodeType":"ParameterList","parameters":[{"constant":false,"id":467,"mutability":"mutable","name":"_lockedUntil","nameLocation":"2970:12:6","nodeType":"VariableDeclaration","scope":493,"src":"2962:20:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":466,"name":"uint256","nodeType":"ElementaryTypeName","src":"2962:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2961:22:6"},"returnParameters":{"id":473,"nodeType":"ParameterList","parameters":[],"src":"3016:0:6"},"scope":789,"src":"2948:249:6","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":504,"nodeType":"Block","src":"3323:53:6","statements":[{"expression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":502,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":499,"name":"lockedUntil","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":287,"src":"3340:11:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"expression":{"id":500,"name":"block","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-4,"src":"3354:5:6","typeDescriptions":{"typeIdentifier":"t_magic_block","typeString":"block"}},"id":501,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"3360:9:6","memberName":"timestamp","nodeType":"MemberAccess","src":"3354:15:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"3340:29:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"functionReturnParameters":498,"id":503,"nodeType":"Return","src":"3333:36:6"}]},"documentation":{"id":494,"nodeType":"StructuredDocumentation","src":"3203:68:6","text":"@dev returns the current lock status of the account as a boolean"},"functionSelector":"a4e2d634","id":505,"implemented":true,"kind":"function","modifiers":[],"name":"isLocked","nameLocation":"3285:8:6","nodeType":"FunctionDefinition","parameters":{"id":495,"nodeType":"ParameterList","parameters":[],"src":"3293:2:6"},"returnParameters":{"id":498,"nodeType":"ParameterList","parameters":[{"constant":false,"id":497,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":505,"src":"3317:4:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":496,"name":"bool","nodeType":"ElementaryTypeName","src":"3317:4:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"3316:6:6"},"scope":789,"src":"3276:100:6","stateMutability":"view","virtual":false,"visibility":"public"},{"baseFunctions":[829],"body":{"id":519,"nodeType":"Block","src":"3679:49:6","statements":[{"expression":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":515,"name":"ERC6551AccountLib","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":890,"src":"3696:17:6","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_ERC6551AccountLib_$890_$","typeString":"type(library ERC6551AccountLib)"}},"id":516,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"3714:5:6","memberName":"token","nodeType":"MemberAccess","referencedDeclaration":867,"src":"3696:23:6","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_uint256_$_t_address_$_t_uint256_$","typeString":"function () view returns (uint256,address,uint256)"}},"id":517,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3696:25:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_uint256_$_t_address_$_t_uint256_$","typeString":"tuple(uint256,address,uint256)"}},"functionReturnParameters":514,"id":518,"nodeType":"Return","src":"3689:32:6"}]},"documentation":{"id":506,"nodeType":"StructuredDocumentation","src":"3382:121:6","text":"@dev Returns the EIP-155 chain ID, token contract address, and token ID for the token that\n owns this account."},"functionSelector":"fc0c546a","id":520,"implemented":true,"kind":"function","modifiers":[],"name":"token","nameLocation":"3517:5:6","nodeType":"FunctionDefinition","parameters":{"id":507,"nodeType":"ParameterList","parameters":[],"src":"3522:2:6"},"returnParameters":{"id":514,"nodeType":"ParameterList","parameters":[{"constant":false,"id":509,"mutability":"mutable","name":"chainId","nameLocation":"3593:7:6","nodeType":"VariableDeclaration","scope":520,"src":"3585:15:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":508,"name":"uint256","nodeType":"ElementaryTypeName","src":"3585:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":511,"mutability":"mutable","name":"tokenContract","nameLocation":"3622:13:6","nodeType":"VariableDeclaration","scope":520,"src":"3614:21:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":510,"name":"address","nodeType":"ElementaryTypeName","src":"3614:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":513,"mutability":"mutable","name":"tokenId","nameLocation":"3657:7:6","nodeType":"VariableDeclaration","scope":520,"src":"3649:15:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":512,"name":"uint256","nodeType":"ElementaryTypeName","src":"3649:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3571:103:6"},"scope":789,"src":"3508:220:6","stateMutability":"view","virtual":false,"visibility":"external"},{"baseFunctions":[834],"body":{"id":553,"nodeType":"Block","src":"3938:263:6","statements":[{"assignments":[527,529,531],"declarations":[{"constant":false,"id":527,"mutability":"mutable","name":"chainId","nameLocation":"3970:7:6","nodeType":"VariableDeclaration","scope":553,"src":"3962:15:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":526,"name":"uint256","nodeType":"ElementaryTypeName","src":"3962:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":529,"mutability":"mutable","name":"tokenContract","nameLocation":"3999:13:6","nodeType":"VariableDeclaration","scope":553,"src":"3991:21:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":528,"name":"address","nodeType":"ElementaryTypeName","src":"3991:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":531,"mutability":"mutable","name":"tokenId","nameLocation":"4034:7:6","nodeType":"VariableDeclaration","scope":553,"src":"4026:15:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":530,"name":"uint256","nodeType":"ElementaryTypeName","src":"4026:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":535,"initialValue":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":532,"name":"ERC6551AccountLib","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":890,"src":"4054:17:6","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_ERC6551AccountLib_$890_$","typeString":"type(library ERC6551AccountLib)"}},"id":533,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"4072:5:6","memberName":"token","nodeType":"MemberAccess","referencedDeclaration":867,"src":"4054:23:6","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_uint256_$_t_address_$_t_uint256_$","typeString":"function () view returns (uint256,address,uint256)"}},"id":534,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4054:25:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_uint256_$_t_address_$_t_uint256_$","typeString":"tuple(uint256,address,uint256)"}},"nodeType":"VariableDeclarationStatement","src":"3948:131:6"},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":539,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":536,"name":"chainId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":527,"src":"4094:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"!=","rightExpression":{"expression":{"id":537,"name":"block","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-4,"src":"4105:5:6","typeDescriptions":{"typeIdentifier":"t_magic_block","typeString":"block"}},"id":538,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"4111:7:6","memberName":"chainid","nodeType":"MemberAccess","src":"4105:13:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"4094:24:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":545,"nodeType":"IfStatement","src":"4090:47:6","trueBody":{"expression":{"arguments":[{"hexValue":"30","id":542,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4135:1:6","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"id":541,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"4127:7:6","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":540,"name":"address","nodeType":"ElementaryTypeName","src":"4127:7:6","typeDescriptions":{}}},"id":543,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4127:10:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"functionReturnParameters":525,"id":544,"nodeType":"Return","src":"4120:17:6"}},{"expression":{"arguments":[{"id":550,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":531,"src":"4186:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"arguments":[{"id":547,"name":"tokenContract","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":529,"src":"4163:13:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":546,"name":"IERC721","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":170,"src":"4155:7:6","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC721_$170_$","typeString":"type(contract IERC721)"}},"id":548,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4155:22:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_IERC721_$170","typeString":"contract IERC721"}},"id":549,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"4178:7:6","memberName":"ownerOf","nodeType":"MemberAccess","referencedDeclaration":103,"src":"4155:30:6","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_uint256_$returns$_t_address_$","typeString":"function (uint256) view external returns (address)"}},"id":551,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4155:39:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"functionReturnParameters":525,"id":552,"nodeType":"Return","src":"4148:46:6"}]},"documentation":{"id":521,"nodeType":"StructuredDocumentation","src":"3734:152:6","text":"@dev Returns the owner of the ERC-721 token which owns this account. By default, the owner\n of the token has full permissions on the account."},"functionSelector":"8da5cb5b","id":554,"implemented":true,"kind":"function","modifiers":[],"name":"owner","nameLocation":"3900:5:6","nodeType":"FunctionDefinition","parameters":{"id":522,"nodeType":"ParameterList","parameters":[],"src":"3905:2:6"},"returnParameters":{"id":525,"nodeType":"ParameterList","parameters":[{"constant":false,"id":524,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":554,"src":"3929:7:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":523,"name":"address","nodeType":"ElementaryTypeName","src":"3929:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"3928:9:6"},"scope":789,"src":"3891:310:6","stateMutability":"view","virtual":false,"visibility":"public"},{"body":{"id":595,"nodeType":"Block","src":"4337:415:6","statements":[{"assignments":[null,563,565],"declarations":[null,{"constant":false,"id":563,"mutability":"mutable","name":"tokenContract","nameLocation":"4383:13:6","nodeType":"VariableDeclaration","scope":595,"src":"4375:21:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":562,"name":"address","nodeType":"ElementaryTypeName","src":"4375:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":565,"mutability":"mutable","name":"tokenId","nameLocation":"4418:7:6","nodeType":"VariableDeclaration","scope":595,"src":"4410:15:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":564,"name":"uint256","nodeType":"ElementaryTypeName","src":"4410:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":569,"initialValue":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":566,"name":"ERC6551AccountLib","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":890,"src":"4438:17:6","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_ERC6551AccountLib_$890_$","typeString":"type(library ERC6551AccountLib)"}},"id":567,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"4456:5:6","memberName":"token","nodeType":"MemberAccess","referencedDeclaration":867,"src":"4438:23:6","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_uint256_$_t_address_$_t_uint256_$","typeString":"function () view returns (uint256,address,uint256)"}},"id":568,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4438:25:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_uint256_$_t_address_$_t_uint256_$","typeString":"tuple(uint256,address,uint256)"}},"nodeType":"VariableDeclarationStatement","src":"4347:116:6"},{"assignments":[571],"declarations":[{"constant":false,"id":571,"mutability":"mutable","name":"_owner","nameLocation":"4481:6:6","nodeType":"VariableDeclaration","scope":595,"src":"4473:14:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":570,"name":"address","nodeType":"ElementaryTypeName","src":"4473:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":578,"initialValue":{"arguments":[{"id":576,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":565,"src":"4521:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"arguments":[{"id":573,"name":"tokenContract","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":563,"src":"4498:13:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":572,"name":"IERC721","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":170,"src":"4490:7:6","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC721_$170_$","typeString":"type(contract IERC721)"}},"id":574,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4490:22:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_IERC721_$170","typeString":"contract IERC721"}},"id":575,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"4513:7:6","memberName":"ownerOf","nodeType":"MemberAccess","referencedDeclaration":103,"src":"4490:30:6","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_uint256_$returns$_t_address_$","typeString":"function (uint256) view external returns (address)"}},"id":577,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4490:39:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"4473:56:6"},{"condition":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":581,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":579,"name":"caller","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":557,"src":"4577:6:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"id":580,"name":"_owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":571,"src":"4587:6:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"4577:16:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":584,"nodeType":"IfStatement","src":"4573:33:6","trueBody":{"expression":{"hexValue":"74727565","id":582,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"4602:4:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"true"},"functionReturnParameters":561,"id":583,"nodeType":"Return","src":"4595:11:6"}},{"condition":{"baseExpression":{"baseExpression":{"id":585,"name":"permissions","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":294,"src":"4682:11:6","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_mapping$_t_address_$_t_bool_$_$","typeString":"mapping(address => mapping(address => bool))"}},"id":587,"indexExpression":{"id":586,"name":"_owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":571,"src":"4694:6:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"4682:19:6","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_bool_$","typeString":"mapping(address => bool)"}},"id":589,"indexExpression":{"id":588,"name":"caller","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":557,"src":"4702:6:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"4682:27:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":592,"nodeType":"IfStatement","src":"4678:44:6","trueBody":{"expression":{"hexValue":"74727565","id":590,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"4718:4:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"true"},"functionReturnParameters":561,"id":591,"nodeType":"Return","src":"4711:11:6"}},{"expression":{"hexValue":"66616c7365","id":593,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"4740:5:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"},"functionReturnParameters":561,"id":594,"nodeType":"Return","src":"4733:12:6"}]},"documentation":{"id":555,"nodeType":"StructuredDocumentation","src":"4207:60:6","text":"@dev Returns the authorization status for a given caller"},"functionSelector":"fe9fbb80","id":596,"implemented":true,"kind":"function","modifiers":[],"name":"isAuthorized","nameLocation":"4281:12:6","nodeType":"FunctionDefinition","parameters":{"id":558,"nodeType":"ParameterList","parameters":[{"constant":false,"id":557,"mutability":"mutable","name":"caller","nameLocation":"4302:6:6","nodeType":"VariableDeclaration","scope":596,"src":"4294:14:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":556,"name":"address","nodeType":"ElementaryTypeName","src":"4294:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"4293:16:6"},"returnParameters":{"id":561,"nodeType":"ParameterList","parameters":[{"constant":false,"id":560,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":596,"src":"4331:4:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":559,"name":"bool","nodeType":"ElementaryTypeName","src":"4331:4:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"4330:6:6"},"scope":789,"src":"4272:480:6","stateMutability":"view","virtual":false,"visibility":"public"},{"baseFunctions":[199],"body":{"id":634,"nodeType":"Block","src":"5009:273:6","statements":[{"assignments":[606],"declarations":[{"constant":false,"id":606,"mutability":"mutable","name":"defaultSupport","nameLocation":"5024:14:6","nodeType":"VariableDeclaration","scope":634,"src":"5019:19:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":605,"name":"bool","nodeType":"ElementaryTypeName","src":"5019:4:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":627,"initialValue":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":626,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":619,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"id":612,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":607,"name":"interfaceId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":599,"src":"5041:11:6","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"arguments":[{"id":609,"name":"IERC165","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":200,"src":"5061:7:6","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC165_$200_$","typeString":"type(contract IERC165)"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_type$_t_contract$_IERC165_$200_$","typeString":"type(contract IERC165)"}],"id":608,"name":"type","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-27,"src":"5056:4:6","typeDescriptions":{"typeIdentifier":"t_function_metatype_pure$__$returns$__$","typeString":"function () pure"}},"id":610,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5056:13:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_magic_meta_type_t_contract$_IERC165_$200","typeString":"type(contract IERC165)"}},"id":611,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"5070:11:6","memberName":"interfaceId","nodeType":"MemberAccess","src":"5056:25:6","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"src":"5041:40:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"||","rightExpression":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"id":618,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":613,"name":"interfaceId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":599,"src":"5097:11:6","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"arguments":[{"id":615,"name":"IERC1155Receiver","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":54,"src":"5117:16:6","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC1155Receiver_$54_$","typeString":"type(contract IERC1155Receiver)"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_type$_t_contract$_IERC1155Receiver_$54_$","typeString":"type(contract IERC1155Receiver)"}],"id":614,"name":"type","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-27,"src":"5112:4:6","typeDescriptions":{"typeIdentifier":"t_function_metatype_pure$__$returns$__$","typeString":"function () pure"}},"id":616,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5112:22:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_magic_meta_type_t_contract$_IERC1155Receiver_$54","typeString":"type(contract IERC1155Receiver)"}},"id":617,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"5135:11:6","memberName":"interfaceId","nodeType":"MemberAccess","src":"5112:34:6","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"src":"5097:49:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"5041:105:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"||","rightExpression":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"id":625,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":620,"name":"interfaceId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":599,"src":"5162:11:6","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"arguments":[{"id":622,"name":"IERC6551Account","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":835,"src":"5182:15:6","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC6551Account_$835_$","typeString":"type(contract IERC6551Account)"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_type$_t_contract$_IERC6551Account_$835_$","typeString":"type(contract IERC6551Account)"}],"id":621,"name":"type","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-27,"src":"5177:4:6","typeDescriptions":{"typeIdentifier":"t_function_metatype_pure$__$returns$__$","typeString":"function () pure"}},"id":623,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5177:21:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_magic_meta_type_t_contract$_IERC6551Account_$835","typeString":"type(contract IERC6551Account)"}},"id":624,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"5199:11:6","memberName":"interfaceId","nodeType":"MemberAccess","src":"5177:33:6","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"src":"5162:48:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"5041:169:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"VariableDeclarationStatement","src":"5019:191:6"},{"condition":{"id":628,"name":"defaultSupport","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":606,"src":"5225:14:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":631,"nodeType":"IfStatement","src":"5221:31:6","trueBody":{"expression":{"hexValue":"74727565","id":629,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"5248:4:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"true"},"functionReturnParameters":604,"id":630,"nodeType":"Return","src":"5241:11:6"}},{"expression":{"hexValue":"66616c7365","id":632,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"5270:5:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"false"},"functionReturnParameters":604,"id":633,"nodeType":"Return","src":"5263:12:6"}]},"documentation":{"id":597,"nodeType":"StructuredDocumentation","src":"4758:126:6","text":"@dev Returns true if a given interfaceId is supported by this account. This method can be\n extended by an override."},"functionSelector":"01ffc9a7","id":635,"implemented":true,"kind":"function","modifiers":[],"name":"supportsInterface","nameLocation":"4898:17:6","nodeType":"FunctionDefinition","overrides":{"id":601,"nodeType":"OverrideSpecifier","overrides":[],"src":"4973:8:6"},"parameters":{"id":600,"nodeType":"ParameterList","parameters":[{"constant":false,"id":599,"mutability":"mutable","name":"interfaceId","nameLocation":"4923:11:6","nodeType":"VariableDeclaration","scope":635,"src":"4916:18:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":598,"name":"bytes4","nodeType":"ElementaryTypeName","src":"4916:6:6","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"4915:20:6"},"returnParameters":{"id":604,"nodeType":"ParameterList","parameters":[{"constant":false,"id":603,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":635,"src":"4999:4:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":602,"name":"bool","nodeType":"ElementaryTypeName","src":"4999:4:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"4998:6:6"},"scope":789,"src":"4889:393:6","stateMutability":"pure","virtual":false,"visibility":"public"},{"baseFunctions":[187],"body":{"id":681,"nodeType":"Block","src":"5586:367:6","statements":[{"assignments":[651,653,655],"declarations":[{"constant":false,"id":651,"mutability":"mutable","name":"chainId","nameLocation":"5618:7:6","nodeType":"VariableDeclaration","scope":681,"src":"5610:15:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":650,"name":"uint256","nodeType":"ElementaryTypeName","src":"5610:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":653,"mutability":"mutable","name":"tokenContract","nameLocation":"5647:13:6","nodeType":"VariableDeclaration","scope":681,"src":"5639:21:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":652,"name":"address","nodeType":"ElementaryTypeName","src":"5639:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":655,"mutability":"mutable","name":"tokenId","nameLocation":"5682:7:6","nodeType":"VariableDeclaration","scope":681,"src":"5674:15:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":654,"name":"uint256","nodeType":"ElementaryTypeName","src":"5674:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":659,"initialValue":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":656,"name":"ERC6551AccountLib","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":890,"src":"5702:17:6","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_ERC6551AccountLib_$890_$","typeString":"type(library ERC6551AccountLib)"}},"id":657,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"5720:5:6","memberName":"token","nodeType":"MemberAccess","referencedDeclaration":867,"src":"5702:23:6","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_uint256_$_t_address_$_t_uint256_$","typeString":"function () view returns (uint256,address,uint256)"}},"id":658,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5702:25:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_uint256_$_t_address_$_t_uint256_$","typeString":"tuple(uint256,address,uint256)"}},"nodeType":"VariableDeclarationStatement","src":"5596:131:6"},{"condition":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":672,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":668,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":663,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":660,"name":"chainId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":651,"src":"5755:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"id":661,"name":"block","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-4,"src":"5766:5:6","typeDescriptions":{"typeIdentifier":"t_magic_block","typeString":"block"}},"id":662,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"5772:7:6","memberName":"chainid","nodeType":"MemberAccess","src":"5766:13:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5755:24:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"&&","rightExpression":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":667,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":664,"name":"tokenContract","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":653,"src":"5795:13:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"id":665,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"5812:3:6","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":666,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"5816:6:6","memberName":"sender","nodeType":"MemberAccess","src":"5812:10:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"5795:27:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"5755:67:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"&&","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":671,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":669,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":655,"src":"5838:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"id":670,"name":"receivedTokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":642,"src":"5849:15:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5838:26:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"5755:109:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":676,"nodeType":"IfStatement","src":"5738:160:6","trueBody":{"errorCall":{"arguments":[],"expression":{"argumentTypes":[],"id":673,"name":"OwnershipCycle","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":275,"src":"5882:14:6","typeDescriptions":{"typeIdentifier":"t_function_error_pure$__$returns$__$","typeString":"function () pure"}},"id":674,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5882:16:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":675,"nodeType":"RevertStatement","src":"5875:23:6"}},{"expression":{"expression":{"expression":{"id":677,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"5916:4:6","typeDescriptions":{"typeIdentifier":"t_contract$_MinimalisticAccount_$789","typeString":"contract MinimalisticAccount"}},"id":678,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"5921:16:6","memberName":"onERC721Received","nodeType":"MemberAccess","referencedDeclaration":682,"src":"5916:21:6","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$_t_address_$_t_uint256_$_t_bytes_memory_ptr_$returns$_t_bytes4_$","typeString":"function (address,address,uint256,bytes memory) view external returns (bytes4)"}},"id":679,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"5938:8:6","memberName":"selector","nodeType":"MemberAccess","src":"5916:30:6","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"functionReturnParameters":649,"id":680,"nodeType":"Return","src":"5909:37:6"}]},"documentation":{"id":636,"nodeType":"StructuredDocumentation","src":"5288:134:6","text":"@dev Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle.\n This function can be overriden."},"functionSelector":"150b7a02","id":682,"implemented":true,"kind":"function","modifiers":[],"name":"onERC721Received","nameLocation":"5436:16:6","nodeType":"FunctionDefinition","overrides":{"id":646,"nodeType":"OverrideSpecifier","overrides":[],"src":"5560:8:6"},"parameters":{"id":645,"nodeType":"ParameterList","parameters":[{"constant":false,"id":638,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":682,"src":"5462:7:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":637,"name":"address","nodeType":"ElementaryTypeName","src":"5462:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":640,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":682,"src":"5479:7:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":639,"name":"address","nodeType":"ElementaryTypeName","src":"5479:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":642,"mutability":"mutable","name":"receivedTokenId","nameLocation":"5504:15:6","nodeType":"VariableDeclaration","scope":682,"src":"5496:23:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":641,"name":"uint256","nodeType":"ElementaryTypeName","src":"5496:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":644,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":682,"src":"5529:12:6","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":643,"name":"bytes","nodeType":"ElementaryTypeName","src":"5529:5:6","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"5452:95:6"},"returnParameters":{"id":649,"nodeType":"ParameterList","parameters":[{"constant":false,"id":648,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":682,"src":"5578:6:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":647,"name":"bytes4","nodeType":"ElementaryTypeName","src":"5578:6:6","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"5577:8:6"},"scope":789,"src":"5427:526:6","stateMutability":"view","virtual":false,"visibility":"public"},{"baseFunctions":[35],"body":{"id":703,"nodeType":"Block","src":"6204:55:6","statements":[{"expression":{"expression":{"expression":{"id":699,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"6221:4:6","typeDescriptions":{"typeIdentifier":"t_contract$_MinimalisticAccount_$789","typeString":"contract MinimalisticAccount"}},"id":700,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"6226:17:6","memberName":"onERC1155Received","nodeType":"MemberAccess","referencedDeclaration":704,"src":"6221:22:6","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_address_$_t_address_$_t_uint256_$_t_uint256_$_t_bytes_memory_ptr_$returns$_t_bytes4_$","typeString":"function (address,address,uint256,uint256,bytes memory) pure external returns (bytes4)"}},"id":701,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"6244:8:6","memberName":"selector","nodeType":"MemberAccess","src":"6221:31:6","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"functionReturnParameters":698,"id":702,"nodeType":"Return","src":"6214:38:6"}]},"documentation":{"id":683,"nodeType":"StructuredDocumentation","src":"5959:79:6","text":"@dev Allows ERC-1155 tokens to be received. This function can be overriden."},"functionSelector":"f23a6e61","id":704,"implemented":true,"kind":"function","modifiers":[],"name":"onERC1155Received","nameLocation":"6052:17:6","nodeType":"FunctionDefinition","overrides":{"id":695,"nodeType":"OverrideSpecifier","overrides":[],"src":"6178:8:6"},"parameters":{"id":694,"nodeType":"ParameterList","parameters":[{"constant":false,"id":685,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":704,"src":"6079:7:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":684,"name":"address","nodeType":"ElementaryTypeName","src":"6079:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":687,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":704,"src":"6096:7:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":686,"name":"address","nodeType":"ElementaryTypeName","src":"6096:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":689,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":704,"src":"6113:7:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":688,"name":"uint256","nodeType":"ElementaryTypeName","src":"6113:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":691,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":704,"src":"6130:7:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":690,"name":"uint256","nodeType":"ElementaryTypeName","src":"6130:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":693,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":704,"src":"6147:12:6","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":692,"name":"bytes","nodeType":"ElementaryTypeName","src":"6147:5:6","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"6069:96:6"},"returnParameters":{"id":698,"nodeType":"ParameterList","parameters":[{"constant":false,"id":697,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":704,"src":"6196:6:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":696,"name":"bytes4","nodeType":"ElementaryTypeName","src":"6196:6:6","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"6195:8:6"},"scope":789,"src":"6043:216:6","stateMutability":"pure","virtual":false,"visibility":"public"},{"baseFunctions":[53],"body":{"id":727,"nodeType":"Block","src":"6540:60:6","statements":[{"expression":{"expression":{"expression":{"id":723,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"6557:4:6","typeDescriptions":{"typeIdentifier":"t_contract$_MinimalisticAccount_$789","typeString":"contract MinimalisticAccount"}},"id":724,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"6562:22:6","memberName":"onERC1155BatchReceived","nodeType":"MemberAccess","referencedDeclaration":728,"src":"6557:27:6","typeDescriptions":{"typeIdentifier":"t_function_external_pure$_t_address_$_t_address_$_t_array$_t_uint256_$dyn_memory_ptr_$_t_array$_t_uint256_$dyn_memory_ptr_$_t_bytes_memory_ptr_$returns$_t_bytes4_$","typeString":"function (address,address,uint256[] memory,uint256[] memory,bytes memory) pure external returns (bytes4)"}},"id":725,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"6585:8:6","memberName":"selector","nodeType":"MemberAccess","src":"6557:36:6","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"functionReturnParameters":722,"id":726,"nodeType":"Return","src":"6550:43:6"}]},"documentation":{"id":705,"nodeType":"StructuredDocumentation","src":"6265:86:6","text":"@dev Allows ERC-1155 token batches to be received. This function can be overriden."},"functionSelector":"bc197c81","id":728,"implemented":true,"kind":"function","modifiers":[],"name":"onERC1155BatchReceived","nameLocation":"6365:22:6","nodeType":"FunctionDefinition","overrides":{"id":719,"nodeType":"OverrideSpecifier","overrides":[],"src":"6514:8:6"},"parameters":{"id":718,"nodeType":"ParameterList","parameters":[{"constant":false,"id":707,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":728,"src":"6397:7:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":706,"name":"address","nodeType":"ElementaryTypeName","src":"6397:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":709,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":728,"src":"6414:7:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":708,"name":"address","nodeType":"ElementaryTypeName","src":"6414:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":712,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":728,"src":"6431:16:6","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_memory_ptr","typeString":"uint256[]"},"typeName":{"baseType":{"id":710,"name":"uint256","nodeType":"ElementaryTypeName","src":"6431:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":711,"nodeType":"ArrayTypeName","src":"6431:9:6","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_storage_ptr","typeString":"uint256[]"}},"visibility":"internal"},{"constant":false,"id":715,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":728,"src":"6457:16:6","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_memory_ptr","typeString":"uint256[]"},"typeName":{"baseType":{"id":713,"name":"uint256","nodeType":"ElementaryTypeName","src":"6457:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":714,"nodeType":"ArrayTypeName","src":"6457:9:6","typeDescriptions":{"typeIdentifier":"t_array$_t_uint256_$dyn_storage_ptr","typeString":"uint256[]"}},"visibility":"internal"},{"constant":false,"id":717,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":728,"src":"6483:12:6","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":716,"name":"bytes","nodeType":"ElementaryTypeName","src":"6483:5:6","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"6387:114:6"},"returnParameters":{"id":722,"nodeType":"ParameterList","parameters":[{"constant":false,"id":721,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":728,"src":"6532:6:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":720,"name":"bytes4","nodeType":"ElementaryTypeName","src":"6532:6:6","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"6531:8:6"},"scope":789,"src":"6356:244:6","stateMutability":"pure","virtual":false,"visibility":"public"},{"body":{"id":759,"nodeType":"Block","src":"6777:213:6","statements":[{"assignments":[741],"declarations":[{"constant":false,"id":741,"mutability":"mutable","name":"success","nameLocation":"6792:7:6","nodeType":"VariableDeclaration","scope":759,"src":"6787:12:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":740,"name":"bool","nodeType":"ElementaryTypeName","src":"6787:4:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":742,"nodeType":"VariableDeclarationStatement","src":"6787:12:6"},{"expression":{"id":752,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"components":[{"id":743,"name":"success","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":741,"src":"6810:7:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"id":744,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":738,"src":"6819:6:6","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"id":745,"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"TupleExpression","src":"6809:17:6","typeDescriptions":{"typeIdentifier":"t_tuple$_t_bool_$_t_bytes_memory_ptr_$","typeString":"tuple(bool,bytes memory)"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"arguments":[{"id":750,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":735,"src":"6851:4:6","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}],"expression":{"id":746,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":731,"src":"6829:2:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":747,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"6832:4:6","memberName":"call","nodeType":"MemberAccess","src":"6829:7:6","typeDescriptions":{"typeIdentifier":"t_function_barecall_payable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$","typeString":"function (bytes memory) payable returns (bool,bytes memory)"}},"id":749,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"names":["value"],"nodeType":"FunctionCallOptions","options":[{"id":748,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":733,"src":"6844:5:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"src":"6829:21:6","typeDescriptions":{"typeIdentifier":"t_function_barecall_payable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$value","typeString":"function (bytes memory) payable returns (bool,bytes memory)"}},"id":751,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"6829:27:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_bool_$_t_bytes_memory_ptr_$","typeString":"tuple(bool,bytes memory)"}},"src":"6809:47:6","typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":753,"nodeType":"ExpressionStatement","src":"6809:47:6"},{"condition":{"id":755,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"!","prefix":true,"src":"6871:8:6","subExpression":{"id":754,"name":"success","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":741,"src":"6872:7:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":758,"nodeType":"IfStatement","src":"6867:117:6","trueBody":{"id":757,"nodeType":"Block","src":"6881:103:6","statements":[{"AST":{"nodeType":"YulBlock","src":"6904:70:6","statements":[{"expression":{"arguments":[{"arguments":[{"name":"result","nodeType":"YulIdentifier","src":"6933:6:6"},{"kind":"number","nodeType":"YulLiteral","src":"6941:2:6","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6929:3:6"},"nodeType":"YulFunctionCall","src":"6929:15:6"},{"arguments":[{"name":"result","nodeType":"YulIdentifier","src":"6952:6:6"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"6946:5:6"},"nodeType":"YulFunctionCall","src":"6946:13:6"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"6922:6:6"},"nodeType":"YulFunctionCall","src":"6922:38:6"},"nodeType":"YulExpressionStatement","src":"6922:38:6"}]},"evmVersion":"london","externalReferences":[{"declaration":738,"isOffset":false,"isSlot":false,"src":"6933:6:6","valueSize":1},{"declaration":738,"isOffset":false,"isSlot":false,"src":"6952:6:6","valueSize":1}],"id":756,"nodeType":"InlineAssembly","src":"6895:79:6"}]}}]},"documentation":{"id":729,"nodeType":"StructuredDocumentation","src":"6606:34:6","text":"@dev Executes a low-level call"},"id":760,"implemented":true,"kind":"function","modifiers":[],"name":"_call","nameLocation":"6654:5:6","nodeType":"FunctionDefinition","parameters":{"id":736,"nodeType":"ParameterList","parameters":[{"constant":false,"id":731,"mutability":"mutable","name":"to","nameLocation":"6677:2:6","nodeType":"VariableDeclaration","scope":760,"src":"6669:10:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":730,"name":"address","nodeType":"ElementaryTypeName","src":"6669:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":733,"mutability":"mutable","name":"value","nameLocation":"6697:5:6","nodeType":"VariableDeclaration","scope":760,"src":"6689:13:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":732,"name":"uint256","nodeType":"ElementaryTypeName","src":"6689:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":735,"mutability":"mutable","name":"data","nameLocation":"6727:4:6","nodeType":"VariableDeclaration","scope":760,"src":"6712:19:6","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":734,"name":"bytes","nodeType":"ElementaryTypeName","src":"6712:5:6","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"6659:78:6"},"returnParameters":{"id":739,"nodeType":"ParameterList","parameters":[{"constant":false,"id":738,"mutability":"mutable","name":"result","nameLocation":"6769:6:6","nodeType":"VariableDeclaration","scope":760,"src":"6756:19:6","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":737,"name":"bytes","nodeType":"ElementaryTypeName","src":"6756:5:6","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"6755:21:6"},"scope":789,"src":"6645:345:6","stateMutability":"nonpayable","virtual":false,"visibility":"internal"},{"body":{"id":787,"nodeType":"Block","src":"7168:205:6","statements":[{"assignments":[771],"declarations":[{"constant":false,"id":771,"mutability":"mutable","name":"success","nameLocation":"7183:7:6","nodeType":"VariableDeclaration","scope":787,"src":"7178:12:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":770,"name":"bool","nodeType":"ElementaryTypeName","src":"7178:4:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"id":772,"nodeType":"VariableDeclarationStatement","src":"7178:12:6"},{"expression":{"id":780,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"components":[{"id":773,"name":"success","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":771,"src":"7201:7:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"id":774,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":768,"src":"7210:6:6","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"id":775,"isConstant":false,"isInlineArray":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"TupleExpression","src":"7200:17:6","typeDescriptions":{"typeIdentifier":"t_tuple$_t_bool_$_t_bytes_memory_ptr_$","typeString":"tuple(bool,bytes memory)"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"arguments":[{"id":778,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":765,"src":"7234:4:6","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}],"expression":{"id":776,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":763,"src":"7220:2:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":777,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"7223:10:6","memberName":"staticcall","nodeType":"MemberAccess","src":"7220:13:6","typeDescriptions":{"typeIdentifier":"t_function_barestaticcall_view$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$","typeString":"function (bytes memory) view returns (bool,bytes memory)"}},"id":779,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"7220:19:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_bool_$_t_bytes_memory_ptr_$","typeString":"tuple(bool,bytes memory)"}},"src":"7200:39:6","typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":781,"nodeType":"ExpressionStatement","src":"7200:39:6"},{"condition":{"id":783,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"!","prefix":true,"src":"7254:8:6","subExpression":{"id":782,"name":"success","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":771,"src":"7255:7:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":786,"nodeType":"IfStatement","src":"7250:117:6","trueBody":{"id":785,"nodeType":"Block","src":"7264:103:6","statements":[{"AST":{"nodeType":"YulBlock","src":"7287:70:6","statements":[{"expression":{"arguments":[{"arguments":[{"name":"result","nodeType":"YulIdentifier","src":"7316:6:6"},{"kind":"number","nodeType":"YulLiteral","src":"7324:2:6","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7312:3:6"},"nodeType":"YulFunctionCall","src":"7312:15:6"},{"arguments":[{"name":"result","nodeType":"YulIdentifier","src":"7335:6:6"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"7329:5:6"},"nodeType":"YulFunctionCall","src":"7329:13:6"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7305:6:6"},"nodeType":"YulFunctionCall","src":"7305:38:6"},"nodeType":"YulExpressionStatement","src":"7305:38:6"}]},"evmVersion":"london","externalReferences":[{"declaration":768,"isOffset":false,"isSlot":false,"src":"7316:6:6","valueSize":1},{"declaration":768,"isOffset":false,"isSlot":false,"src":"7335:6:6","valueSize":1}],"id":784,"nodeType":"InlineAssembly","src":"7278:79:6"}]}}]},"documentation":{"id":761,"nodeType":"StructuredDocumentation","src":"6996:41:6","text":"@dev Executes a low-level static call"},"id":788,"implemented":true,"kind":"function","modifiers":[],"name":"_callStatic","nameLocation":"7051:11:6","nodeType":"FunctionDefinition","parameters":{"id":766,"nodeType":"ParameterList","parameters":[{"constant":false,"id":763,"mutability":"mutable","name":"to","nameLocation":"7071:2:6","nodeType":"VariableDeclaration","scope":788,"src":"7063:10:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":762,"name":"address","nodeType":"ElementaryTypeName","src":"7063:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":765,"mutability":"mutable","name":"data","nameLocation":"7090:4:6","nodeType":"VariableDeclaration","scope":788,"src":"7075:19:6","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":764,"name":"bytes","nodeType":"ElementaryTypeName","src":"7075:5:6","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"7062:33:6"},"returnParameters":{"id":769,"nodeType":"ParameterList","parameters":[{"constant":false,"id":768,"mutability":"mutable","name":"result","nameLocation":"7156:6:6","nodeType":"VariableDeclaration","scope":788,"src":"7143:19:6","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":767,"name":"bytes","nodeType":"ElementaryTypeName","src":"7143:5:6","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"7142:21:6"},"scope":789,"src":"7042:331:6","stateMutability":"view","virtual":false,"visibility":"internal"}],"scope":790,"src":"695:6680:6","usedErrors":[265,267,269,271,275]}],"src":"39:7337:6"},"id":6},"contracts/interfaces/IERC6551Account.sol":{"ast":{"absolutePath":"contracts/interfaces/IERC6551Account.sol","exportedSymbols":{"IERC6551Account":[835],"IERC6551AccountProxy":[797]},"id":836,"license":"UNLICENSED","nodeType":"SourceUnit","nodes":[{"id":791,"literals":["solidity","^","0.8",".13"],"nodeType":"PragmaDirective","src":"39:24:7"},{"abstract":false,"baseContracts":[],"canonicalName":"IERC6551AccountProxy","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"id":797,"linearizedBaseContracts":[797],"name":"IERC6551AccountProxy","nameLocation":"75:20:7","nodeType":"ContractDefinition","nodes":[{"functionSelector":"5c60da1b","id":796,"implemented":false,"kind":"function","modifiers":[],"name":"implementation","nameLocation":"111:14:7","nodeType":"FunctionDefinition","parameters":{"id":792,"nodeType":"ParameterList","parameters":[],"src":"125:2:7"},"returnParameters":{"id":795,"nodeType":"ParameterList","parameters":[{"constant":false,"id":794,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":796,"src":"151:7:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":793,"name":"address","nodeType":"ElementaryTypeName","src":"151:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"150:9:7"},"scope":797,"src":"102:58:7","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":836,"src":"65:97:7","usedErrors":[]},{"abstract":false,"baseContracts":[],"canonicalName":"IERC6551Account","contractDependencies":[],"contractKind":"interface","documentation":{"id":798,"nodeType":"StructuredDocumentation","src":"164:67:7","text":"@dev the ERC-165 identifier for this interface is `0xeff4d378`"},"fullyImplemented":false,"id":835,"linearizedBaseContracts":[835],"name":"IERC6551Account","nameLocation":"241:15:7","nodeType":"ContractDefinition","nodes":[{"anonymous":false,"eventSelector":"47d99ad340f52da66535aff7e10da1ceb85a32bcbd9fa1c42314d194545e14d2","id":806,"name":"TransactionExecuted","nameLocation":"269:19:7","nodeType":"EventDefinition","parameters":{"id":805,"nodeType":"ParameterList","parameters":[{"constant":false,"id":800,"indexed":true,"mutability":"mutable","name":"target","nameLocation":"305:6:7","nodeType":"VariableDeclaration","scope":806,"src":"289:22:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":799,"name":"address","nodeType":"ElementaryTypeName","src":"289:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":802,"indexed":true,"mutability":"mutable","name":"value","nameLocation":"329:5:7","nodeType":"VariableDeclaration","scope":806,"src":"313:21:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":801,"name":"uint256","nodeType":"ElementaryTypeName","src":"313:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":804,"indexed":false,"mutability":"mutable","name":"data","nameLocation":"342:4:7","nodeType":"VariableDeclaration","scope":806,"src":"336:10:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":803,"name":"bytes","nodeType":"ElementaryTypeName","src":"336:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"288:59:7"},"src":"263:85:7"},{"id":809,"implemented":false,"kind":"receive","modifiers":[],"name":"","nameLocation":"-1:-1:-1","nodeType":"FunctionDefinition","parameters":{"id":807,"nodeType":"ParameterList","parameters":[],"src":"361:2:7"},"returnParameters":{"id":808,"nodeType":"ParameterList","parameters":[],"src":"380:0:7"},"scope":835,"src":"354:27:7","stateMutability":"payable","virtual":false,"visibility":"external"},{"functionSelector":"9e5d4c49","id":820,"implemented":false,"kind":"function","modifiers":[],"name":"executeCall","nameLocation":"396:11:7","nodeType":"FunctionDefinition","parameters":{"id":816,"nodeType":"ParameterList","parameters":[{"constant":false,"id":811,"mutability":"mutable","name":"to","nameLocation":"425:2:7","nodeType":"VariableDeclaration","scope":820,"src":"417:10:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":810,"name":"address","nodeType":"ElementaryTypeName","src":"417:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":813,"mutability":"mutable","name":"value","nameLocation":"445:5:7","nodeType":"VariableDeclaration","scope":820,"src":"437:13:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":812,"name":"uint256","nodeType":"ElementaryTypeName","src":"437:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":815,"mutability":"mutable","name":"data","nameLocation":"475:4:7","nodeType":"VariableDeclaration","scope":820,"src":"460:19:7","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":814,"name":"bytes","nodeType":"ElementaryTypeName","src":"460:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"407:78:7"},"returnParameters":{"id":819,"nodeType":"ParameterList","parameters":[{"constant":false,"id":818,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":820,"src":"512:12:7","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":817,"name":"bytes","nodeType":"ElementaryTypeName","src":"512:5:7","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"511:14:7"},"scope":835,"src":"387:139:7","stateMutability":"payable","virtual":false,"visibility":"external"},{"functionSelector":"fc0c546a","id":829,"implemented":false,"kind":"function","modifiers":[],"name":"token","nameLocation":"541:5:7","nodeType":"FunctionDefinition","parameters":{"id":821,"nodeType":"ParameterList","parameters":[],"src":"546:2:7"},"returnParameters":{"id":828,"nodeType":"ParameterList","parameters":[{"constant":false,"id":823,"mutability":"mutable","name":"chainId","nameLocation":"604:7:7","nodeType":"VariableDeclaration","scope":829,"src":"596:15:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":822,"name":"uint256","nodeType":"ElementaryTypeName","src":"596:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":825,"mutability":"mutable","name":"tokenContract","nameLocation":"621:13:7","nodeType":"VariableDeclaration","scope":829,"src":"613:21:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":824,"name":"address","nodeType":"ElementaryTypeName","src":"613:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":827,"mutability":"mutable","name":"tokenId","nameLocation":"644:7:7","nodeType":"VariableDeclaration","scope":829,"src":"636:15:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":826,"name":"uint256","nodeType":"ElementaryTypeName","src":"636:7:7","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"595:57:7"},"scope":835,"src":"532:121:7","stateMutability":"view","virtual":false,"visibility":"external"},{"functionSelector":"8da5cb5b","id":834,"implemented":false,"kind":"function","modifiers":[],"name":"owner","nameLocation":"668:5:7","nodeType":"FunctionDefinition","parameters":{"id":830,"nodeType":"ParameterList","parameters":[],"src":"673:2:7"},"returnParameters":{"id":833,"nodeType":"ParameterList","parameters":[{"constant":false,"id":832,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":834,"src":"699:7:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":831,"name":"address","nodeType":"ElementaryTypeName","src":"699:7:7","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"698:9:7"},"scope":835,"src":"659:49:7","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":836,"src":"231:479:7","usedErrors":[]}],"src":"39:672:7"},"id":7},"contracts/lib/ERC6551AccountLib.sol":{"ast":{"absolutePath":"contracts/lib/ERC6551AccountLib.sol","exportedSymbols":{"ERC6551AccountLib":[890]},"id":891,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":837,"literals":["solidity","^","0.8",".13"],"nodeType":"PragmaDirective","src":"32:24:8"},{"abstract":false,"baseContracts":[],"canonicalName":"ERC6551AccountLib","contractDependencies":[],"contractKind":"library","fullyImplemented":true,"id":890,"linearizedBaseContracts":[890],"name":"ERC6551AccountLib","nameLocation":"66:17:8","nodeType":"ContractDefinition","nodes":[{"body":{"id":866,"nodeType":"Block","src":"231:265:8","statements":[{"assignments":[847],"declarations":[{"constant":false,"id":847,"mutability":"mutable","name":"footer","nameLocation":"254:6:8","nodeType":"VariableDeclaration","scope":866,"src":"241:19:8","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":846,"name":"bytes","nodeType":"ElementaryTypeName","src":"241:5:8","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"id":852,"initialValue":{"arguments":[{"hexValue":"30783630","id":850,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"273:4:8","typeDescriptions":{"typeIdentifier":"t_rational_96_by_1","typeString":"int_const 96"},"value":"0x60"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_96_by_1","typeString":"int_const 96"}],"id":849,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"NewExpression","src":"263:9:8","typeDescriptions":{"typeIdentifier":"t_function_objectcreation_pure$_t_uint256_$returns$_t_bytes_memory_ptr_$","typeString":"function (uint256) pure returns (bytes memory)"},"typeName":{"id":848,"name":"bytes","nodeType":"ElementaryTypeName","src":"267:5:8","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}}},"id":851,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"263:15:8","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"nodeType":"VariableDeclarationStatement","src":"241:37:8"},{"AST":{"nodeType":"YulBlock","src":"298:127:8","statements":[{"expression":{"arguments":[{"arguments":[],"functionName":{"name":"address","nodeType":"YulIdentifier","src":"374:7:8"},"nodeType":"YulFunctionCall","src":"374:9:8"},{"arguments":[{"name":"footer","nodeType":"YulIdentifier","src":"389:6:8"},{"kind":"number","nodeType":"YulLiteral","src":"397:4:8","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"385:3:8"},"nodeType":"YulFunctionCall","src":"385:17:8"},{"kind":"number","nodeType":"YulLiteral","src":"404:4:8","type":"","value":"0x4d"},{"kind":"number","nodeType":"YulLiteral","src":"410:4:8","type":"","value":"0xad"}],"functionName":{"name":"extcodecopy","nodeType":"YulIdentifier","src":"362:11:8"},"nodeType":"YulFunctionCall","src":"362:53:8"},"nodeType":"YulExpressionStatement","src":"362:53:8"}]},"evmVersion":"london","externalReferences":[{"declaration":847,"isOffset":false,"isSlot":false,"src":"389:6:8","valueSize":1}],"id":853,"nodeType":"InlineAssembly","src":"289:136:8"},{"expression":{"arguments":[{"id":856,"name":"footer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":847,"src":"453:6:8","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},{"components":[{"id":858,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"462:7:8","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":857,"name":"uint256","nodeType":"ElementaryTypeName","src":"462:7:8","typeDescriptions":{}}},{"id":860,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"471:7:8","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":859,"name":"address","nodeType":"ElementaryTypeName","src":"471:7:8","typeDescriptions":{}}},{"id":862,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"480:7:8","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":861,"name":"uint256","nodeType":"ElementaryTypeName","src":"480:7:8","typeDescriptions":{}}}],"id":863,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"TupleExpression","src":"461:27:8","typeDescriptions":{"typeIdentifier":"t_tuple$_t_type$_t_uint256_$_$_t_type$_t_address_$_$_t_type$_t_uint256_$_$","typeString":"tuple(type(uint256),type(address),type(uint256))"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"},{"typeIdentifier":"t_tuple$_t_type$_t_uint256_$_$_t_type$_t_address_$_$_t_type$_t_uint256_$_$","typeString":"tuple(type(uint256),type(address),type(uint256))"}],"expression":{"id":854,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"442:3:8","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":855,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"446:6:8","memberName":"decode","nodeType":"MemberAccess","src":"442:10:8","typeDescriptions":{"typeIdentifier":"t_function_abidecode_pure$__$returns$__$","typeString":"function () pure"}},"id":864,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"442:47:8","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_uint256_$_t_address_payable_$_t_uint256_$","typeString":"tuple(uint256,address payable,uint256)"}},"functionReturnParameters":845,"id":865,"nodeType":"Return","src":"435:54:8"}]},"id":867,"implemented":true,"kind":"function","modifiers":[],"name":"token","nameLocation":"99:5:8","nodeType":"FunctionDefinition","parameters":{"id":838,"nodeType":"ParameterList","parameters":[],"src":"104:2:8"},"returnParameters":{"id":845,"nodeType":"ParameterList","parameters":[{"constant":false,"id":840,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":867,"src":"167:7:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":839,"name":"uint256","nodeType":"ElementaryTypeName","src":"167:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":842,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":867,"src":"188:7:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":841,"name":"address","nodeType":"ElementaryTypeName","src":"188:7:8","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":844,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":867,"src":"209:7:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":843,"name":"uint256","nodeType":"ElementaryTypeName","src":"209:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"153:73:8"},"scope":890,"src":"90:406:8","stateMutability":"view","virtual":false,"visibility":"internal"},{"body":{"id":888,"nodeType":"Block","src":"550:253:8","statements":[{"assignments":[873],"declarations":[{"constant":false,"id":873,"mutability":"mutable","name":"footer","nameLocation":"573:6:8","nodeType":"VariableDeclaration","scope":888,"src":"560:19:8","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":872,"name":"bytes","nodeType":"ElementaryTypeName","src":"560:5:8","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"id":878,"initialValue":{"arguments":[{"hexValue":"30783230","id":876,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"592:4:8","typeDescriptions":{"typeIdentifier":"t_rational_32_by_1","typeString":"int_const 32"},"value":"0x20"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_32_by_1","typeString":"int_const 32"}],"id":875,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"NewExpression","src":"582:9:8","typeDescriptions":{"typeIdentifier":"t_function_objectcreation_pure$_t_uint256_$returns$_t_bytes_memory_ptr_$","typeString":"function (uint256) pure returns (bytes memory)"},"typeName":{"id":874,"name":"bytes","nodeType":"ElementaryTypeName","src":"586:5:8","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}}},"id":877,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"582:15:8","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"nodeType":"VariableDeclarationStatement","src":"560:37:8"},{"AST":{"nodeType":"YulBlock","src":"617:133:8","statements":[{"expression":{"arguments":[{"arguments":[],"functionName":{"name":"address","nodeType":"YulIdentifier","src":"699:7:8"},"nodeType":"YulFunctionCall","src":"699:9:8"},{"arguments":[{"name":"footer","nodeType":"YulIdentifier","src":"714:6:8"},{"kind":"number","nodeType":"YulLiteral","src":"722:4:8","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"710:3:8"},"nodeType":"YulFunctionCall","src":"710:17:8"},{"kind":"number","nodeType":"YulLiteral","src":"729:4:8","type":"","value":"0x2d"},{"kind":"number","nodeType":"YulLiteral","src":"735:4:8","type":"","value":"0x4d"}],"functionName":{"name":"extcodecopy","nodeType":"YulIdentifier","src":"687:11:8"},"nodeType":"YulFunctionCall","src":"687:53:8"},"nodeType":"YulExpressionStatement","src":"687:53:8"}]},"evmVersion":"london","externalReferences":[{"declaration":873,"isOffset":false,"isSlot":false,"src":"714:6:8","valueSize":1}],"id":879,"nodeType":"InlineAssembly","src":"608:142:8"},{"expression":{"arguments":[{"id":882,"name":"footer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":873,"src":"778:6:8","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},{"components":[{"id":884,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"787:7:8","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":883,"name":"uint256","nodeType":"ElementaryTypeName","src":"787:7:8","typeDescriptions":{}}}],"id":885,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"TupleExpression","src":"786:9:8","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"},{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"}],"expression":{"id":880,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"767:3:8","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":881,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"771:6:8","memberName":"decode","nodeType":"MemberAccess","src":"767:10:8","typeDescriptions":{"typeIdentifier":"t_function_abidecode_pure$__$returns$__$","typeString":"function () pure"}},"id":886,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"767:29:8","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"functionReturnParameters":871,"id":887,"nodeType":"Return","src":"760:36:8"}]},"id":889,"implemented":true,"kind":"function","modifiers":[],"name":"salt","nameLocation":"511:4:8","nodeType":"FunctionDefinition","parameters":{"id":868,"nodeType":"ParameterList","parameters":[],"src":"515:2:8"},"returnParameters":{"id":871,"nodeType":"ParameterList","parameters":[{"constant":false,"id":870,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":889,"src":"541:7:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":869,"name":"uint256","nodeType":"ElementaryTypeName","src":"541:7:8","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"540:9:8"},"scope":890,"src":"502:301:8","stateMutability":"view","virtual":false,"visibility":"internal"}],"scope":891,"src":"58:747:8","usedErrors":[]}],"src":"32:774:8"},"id":8}},"contracts":{"@openzeppelin/contracts/interfaces/IERC1271.sol":{"IERC1271":{"abi":[{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"magicValue","type":"bytes4"}],"stateMutability":"view","type":"function"}],"devdoc":{"details":"Interface of the ERC1271 standard signature validation method for contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271]. _Available since v4.1._","kind":"dev","methods":{"isValidSignature(bytes32,bytes)":{"details":"Should return whether the signature provided is valid for the provided data","params":{"hash":"Hash of the data to be signed","signature":"Signature byte array associated with _data"}}},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"isValidSignature(bytes32,bytes)":"1626ba7e"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Interface of the ERC1271 standard signature validation method for contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271]. _Available since v4.1._\",\"kind\":\"dev\",\"methods\":{\"isValidSignature(bytes32,bytes)\":{\"details\":\"Should return whether the signature provided is valid for the provided data\",\"params\":{\"hash\":\"Hash of the data to be signed\",\"signature\":\"Signature byte array associated with _data\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":\"IERC1271\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol":{"IERC1155Receiver":{"abi":[{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}],"devdoc":{"details":"_Available since v3.1._","kind":"dev","methods":{"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":{"details":"Handles the receipt of a multiple ERC1155 token types. This function is called at the end of a `safeBatchTransferFrom` after the balances have been updated. NOTE: To accept the transfer(s), this must return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` (i.e. 0xbc197c81, or its own function selector).","params":{"data":"Additional data with no specified format","from":"The address which previously owned the token","ids":"An array containing ids of each token being transferred (order and length must match values array)","operator":"The address which initiated the batch transfer (i.e. msg.sender)","values":"An array containing amounts of each token being transferred (order and length must match ids array)"},"returns":{"_0":"`bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed"}},"onERC1155Received(address,address,uint256,uint256,bytes)":{"details":"Handles the receipt of a single ERC1155 token type. This function is called at the end of a `safeTransferFrom` after the balance has been updated. NOTE: To accept the transfer, this must return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` (i.e. 0xf23a6e61, or its own function selector).","params":{"data":"Additional data with no specified format","from":"The address which previously owned the token","id":"The ID of the token being transferred","operator":"The address which initiated the transfer (i.e. msg.sender)","value":"The amount of tokens being transferred"},"returns":{"_0":"`bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed"}},"supportsInterface(bytes4)":{"details":"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas."}},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":"bc197c81","onERC1155Received(address,address,uint256,uint256,bytes)":"f23a6e61","supportsInterface(bytes4)":"01ffc9a7"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onERC1155BatchReceived\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onERC1155Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"_Available since v3.1._\",\"kind\":\"dev\",\"methods\":{\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"details\":\"Handles the receipt of a multiple ERC1155 token types. This function is called at the end of a `safeBatchTransferFrom` after the balances have been updated. NOTE: To accept the transfer(s), this must return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` (i.e. 0xbc197c81, or its own function selector).\",\"params\":{\"data\":\"Additional data with no specified format\",\"from\":\"The address which previously owned the token\",\"ids\":\"An array containing ids of each token being transferred (order and length must match values array)\",\"operator\":\"The address which initiated the batch transfer (i.e. msg.sender)\",\"values\":\"An array containing amounts of each token being transferred (order and length must match ids array)\"},\"returns\":{\"_0\":\"`bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\"}},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"details\":\"Handles the receipt of a single ERC1155 token type. This function is called at the end of a `safeTransferFrom` after the balance has been updated. NOTE: To accept the transfer, this must return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` (i.e. 0xf23a6e61, or its own function selector).\",\"params\":{\"data\":\"Additional data with no specified format\",\"from\":\"The address which previously owned the token\",\"id\":\"The ID of the token being transferred\",\"operator\":\"The address which initiated the transfer (i.e. msg.sender)\",\"value\":\"The amount of tokens being transferred\"},\"returns\":{\"_0\":\"`bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\"}},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":\"IERC1155Receiver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (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 *\\n * NOTE: 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 *\\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.\\n *\\n * NOTE: 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 *\\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\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/token/ERC721/IERC721.sol":{"IERC721":{"abi":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"operator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"details":"Required interface of an ERC721 compliant contract.","events":{"Approval(address,address,uint256)":{"details":"Emitted when `owner` enables `approved` to manage the `tokenId` token."},"ApprovalForAll(address,address,bool)":{"details":"Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets."},"Transfer(address,address,uint256)":{"details":"Emitted when `tokenId` token is transferred from `from` to `to`."}},"kind":"dev","methods":{"approve(address,uint256)":{"details":"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event."},"balanceOf(address)":{"details":"Returns the number of tokens in ``owner``'s account."},"getApproved(uint256)":{"details":"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist."},"isApprovedForAll(address,address)":{"details":"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}"},"ownerOf(uint256)":{"details":"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist."},"safeTransferFrom(address,address,uint256)":{"details":"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event."},"safeTransferFrom(address,address,uint256,bytes)":{"details":"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event."},"setApprovalForAll(address,bool)":{"details":"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the caller. Emits an {ApprovalForAll} event."},"supportsInterface(bytes4)":{"details":"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas."},"transferFrom(address,address,uint256)":{"details":"Transfers `tokenId` token from `from` to `to`. WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event."}},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"approve(address,uint256)":"095ea7b3","balanceOf(address)":"70a08231","getApproved(uint256)":"081812fc","isApprovedForAll(address,address)":"e985e9c5","ownerOf(uint256)":"6352211e","safeTransferFrom(address,address,uint256)":"42842e0e","safeTransferFrom(address,address,uint256,bytes)":"b88d4fde","setApprovalForAll(address,bool)":"a22cb465","supportsInterface(bytes4)":"01ffc9a7","transferFrom(address,address,uint256)":"23b872dd"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Required interface of an ERC721 compliant contract.\",\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when `owner` enables `approved` to manage the `tokenId` token.\"},\"ApprovalForAll(address,address,bool)\":{\"details\":\"Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\"},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `tokenId` token is transferred from `from` to `to`.\"}},\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"details\":\"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event.\"},\"balanceOf(address)\":{\"details\":\"Returns the number of tokens in ``owner``'s account.\"},\"getApproved(uint256)\":{\"details\":\"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist.\"},\"isApprovedForAll(address,address)\":{\"details\":\"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}\"},\"ownerOf(uint256)\":{\"details\":\"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the caller. Emits an {ApprovalForAll} event.\"},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"Transfers `tokenId` token from `from` to `to`. WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":\"IERC721\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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`.\\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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\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(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol":{"IERC721Receiver":{"abi":[{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"details":"Interface for any contract that wants to support safeTransfers from ERC721 asset contracts.","kind":"dev","methods":{"onERC721Received(address,address,uint256,bytes)":{"details":"Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} by `operator` from `from`, this function is called. It must return its Solidity selector to confirm the token transfer. If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`."}},"title":"ERC721 token receiver interface","version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"onERC721Received(address,address,uint256,bytes)":"150b7a02"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Interface for any contract that wants to support safeTransfers from ERC721 asset contracts.\",\"kind\":\"dev\",\"methods\":{\"onERC721Received(address,address,uint256,bytes)\":{\"details\":\"Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} by `operator` from `from`, this function is called. It must return its Solidity selector to confirm the token transfer. If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\"}},\"title\":\"ERC721 token receiver interface\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":\"IERC721Receiver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface 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 `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/utils/introspection/IERC165.sol":{"IERC165":{"abi":[{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}],"devdoc":{"details":"Interface of the ERC165 standard, as defined in the https://eips.ethereum.org/EIPS/eip-165[EIP]. Implementers can declare support of contract interfaces, which can then be queried by others ({ERC165Checker}). For an implementation, see {ERC165}.","kind":"dev","methods":{"supportsInterface(bytes4)":{"details":"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas."}},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"supportsInterface(bytes4)":"01ffc9a7"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Interface of the ERC165 standard, as defined in the https://eips.ethereum.org/EIPS/eip-165[EIP]. Implementers can declare support of contract interfaces, which can then be queried by others ({ERC165Checker}). For an implementation, see {ERC165}.\",\"kind\":\"dev\",\"methods\":{\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":\"IERC165\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/ChargedParticlesAccount.sol":{"ChargedParticlesAccount":{"abi":[{"inputs":[],"name":"AccountLocked","type":"error"},{"inputs":[],"name":"ExceedsMaxLockTime","type":"error"},{"inputs":[],"name":"InvalidInput","type":"error"},{"inputs":[],"name":"NotAuthorized","type":"error"},{"inputs":[],"name":"OwnershipCycle","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"lockedUntil","type":"uint256"}],"name":"LockUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"bytes4","name":"selector","type":"bytes4"},{"indexed":false,"internalType":"address","name":"implementation","type":"address"}],"name":"OverrideUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"bool","name":"hasPermission","type":"bool"}],"name":"PermissionUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":true,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"TransactionExecuted","type":"event"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"nftTokenAddress","type":"address"},{"internalType":"uint256","name":"nftTokenId","type":"uint256"},{"internalType":"uint256","name":"nftTokenAmount","type":"uint256"}],"name":"breakCovalentBond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"nftTokenAddress","type":"address"},{"internalType":"uint256","name":"nftTokenId","type":"uint256"},{"internalType":"uint256","name":"nftTokenAmount","type":"uint256"}],"name":"covalentBond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"executeCall","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"isAuthorized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lockedUntil","type":"uint256"}],"name":"lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockedUntil","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"receivedTokenId","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"permissions","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"callers","type":"address[]"},{"internalType":"bool[]","name":"_permissions","type":"bool[]"}],"name":"setPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}],"devdoc":{"kind":"dev","methods":{"executeCall(address,uint256,bytes)":{"details":"executes a low-level call against an account if the caller is authorized to make calls"},"isAuthorized(address)":{"details":"Returns the authorization status for a given caller"},"isLocked()":{"details":"returns the current lock status of the account as a boolean"},"lock(uint256)":{"details":"locks the account until a certain timestamp"},"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":{"details":"Allows ERC-1155 token batches to be received. This function can be overriden."},"onERC1155Received(address,address,uint256,uint256,bytes)":{"details":"Allows ERC-1155 tokens to be received. This function can be overriden."},"onERC721Received(address,address,uint256,bytes)":{"details":"Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle. This function can be overriden."},"owner()":{"details":"Returns the owner of the ERC-721 token which owns this account. By default, the owner of the token has full permissions on the account."},"setPermissions(address[],bool[])":{"details":"grants a given caller execution permissions"},"supportsInterface(bytes4)":{"details":"Returns true if a given interfaceId is supported by this account. This method can be extended by an override."},"token()":{"details":"Returns the EIP-155 chain ID, token contract address, and token ID for the token that owns this account."}},"version":1},"evm":{"bytecode":{"functionDebugData":{"@_357":{"entryPoint":null,"id":357,"parameterSlots":0,"returnSlots":0}},"generatedSources":[],"linkReferences":{},"object":"608060405234801561001057600080fd5b50611159806100206000396000f3fe6080604052600436106100ec5760003560e01c8063a4e2d6341161008a578063dd46706411610059578063dd467064146102b7578063f23a6e61146102d7578063fc0c546a14610303578063fe9fbb801461033b57600080fd5b8063a4e2d63414610230578063a737a29914610247578063bc197c8114610267578063ce0617ec1461029357600080fd5b80631f9838b5116100c65780631f9838b5146101885780636b764e1b146101c35780638da5cb5b146101e35780639e5d4c491461021057600080fd5b806301ffc9a7146100f8578063039721b11461012d578063150b7a021461014f57600080fd5b366100f357005b600080fd5b34801561010457600080fd5b50610118610113366004610a92565b61035b565b60405190151581526020015b60405180910390f35b34801561013957600080fd5b5061014d610148366004610b0f565b6103c2565b005b34801561015b57600080fd5b5061016f61016a366004610c4a565b61058b565b6040516001600160e01b03199091168152602001610124565b34801561019457600080fd5b506101186101a3366004610cb6565b600160209081526000928352604080842090915290825290205460ff1681565b3480156101cf57600080fd5b5061014d6101de366004610cef565b6105f3565b3480156101ef57600080fd5b506101f8610661565b6040516001600160a01b039091168152602001610124565b61022361021e366004610d35565b6106f7565b6040516101249190610dbe565b34801561023c57600080fd5b506000544210610118565b34801561025357600080fd5b5061014d610262366004610e0c565b61079b565b34801561027357600080fd5b5061016f610282366004610ec1565b63bc197c8160e01b95945050505050565b34801561029f57600080fd5b506102a960005481565b604051908152602001610124565b3480156102c357600080fd5b5061014d6102d2366004610f6f565b6107fd565b3480156102e357600080fd5b5061016f6102f2366004610f88565b63f23a6e6160e01b95945050505050565b34801561030f57600080fd5b506103186108c2565b604080519384526001600160a01b03909216602084015290820152606001610124565b34801561034757600080fd5b50610118610356366004610ff1565b6108da565b6000806001600160e01b031983166301ffc9a760e01b148061038d57506001600160e01b03198316630271189760e51b145b806103a857506001600160e01b03198316631dfe9a6f60e31b145b905080156103b95750600192915050565b50600092915050565b6000544210156103e557604051636315bfbb60e01b815260040160405180910390fd5b60006103ef610661565b9050336001600160a01b0382161461041a5760405163ea8e4eb560e01b815260040160405180910390fd5b8382811461043b5760405163b4fa3fb360e01b815260040160405180910390fd5b60005b81811015610582578484828181106104585761045861100e565b905060200201602081019061046d9190611024565b6001600160a01b0384166000908152600160205260408120908989858181106104985761049861100e565b90506020020160208101906104ad9190610ff1565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f394777a58092892d136a90c4bb7e4350c72ac50fba6a0208128677f36527dcf5838888848181106105095761050961100e565b905060200201602081019061051e9190610ff1565b8787858181106105305761053061100e565b90506020020160208101906105459190611024565b604080516001600160a01b03948516815293909216602084015215159082015260600160405180910390a18061057a8161105c565b91505061043e565b50505050505050565b6000806000806105996109c3565b92509250925046831480156105b657506001600160a01b03821633145b80156105c157508581145b156105df5760405163b79e3f3f60e01b815260040160405180910390fd5b50630a85bd0160e11b979650505050505050565b604051632142170760e11b81523060048201526001600160a01b038581166024830152604482018490528416906342842e0e90606401600060405180830381600087803b15801561064357600080fd5b505af1158015610657573d6000803e3d6000fd5b5050505050505050565b60008060008061066f6109c3565b925092509250468314610686576000935050505090565b6040516331a9108f60e11b8152600481018290526001600160a01b03831690636352211e90602401602060405180830381865afa1580156106cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ef9190611075565b935050505090565b6060610702336108da565b61071f5760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561074257604051636315bfbb60e01b815260040160405180910390fd5b83856001600160a01b03167f47d99ad340f52da66535aff7e10da1ceb85a32bcbd9fa1c42314d194545e14d2858560405161077e929190611092565b60405180910390a361079285858585610a16565b95945050505050565b604051632142170760e11b8152336004820152306024820152604481018390526001600160a01b038416906342842e0e90606401600060405180830381600087803b1580156107e957600080fd5b505af1158015610582573d6000803e3d6000fd5b610805610661565b6001600160a01b0316336001600160a01b0316146108365760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561085957604051636315bfbb60e01b815260040160405180910390fd5b610867426301e133806110c1565b811115610887576040516301814f7d60e31b815260040160405180910390fd5b60008190556040518181527fa7b24c66dd3269a292a60b3facdbb8f3e7557d1e19e64d99e0d6ee7250be63ad9060200160405180910390a150565b60008060006108cf6109c3565b925092509250909192565b60008060006108e76109c3565b6040516331a9108f60e11b8152600481018290529194509250600091506001600160a01b03841690636352211e90602401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109599190611075565b9050806001600160a01b0316856001600160a01b03160361097f57506001949350505050565b6001600160a01b0380821660009081526001602090815260408083209389168352929052205460ff16156109b857506001949350505050565b506000949350505050565b604080516060808252608082019092526000918291829182919060208201818036833701905050905060ad604d60208301303c80806020019051810190610a0a91906110da565b93509350935050909192565b60606000856001600160a01b0316858585604051610a35929190611113565b60006040518083038185875af1925050503d8060008114610a72576040519150601f19603f3d011682016040523d82523d6000602084013e610a77565b606091505b509250905080610a8957815160208301fd5b50949350505050565b600060208284031215610aa457600080fd5b81356001600160e01b031981168114610abc57600080fd5b9392505050565b60008083601f840112610ad557600080fd5b50813567ffffffffffffffff811115610aed57600080fd5b6020830191508360208260051b8501011115610b0857600080fd5b9250929050565b60008060008060408587031215610b2557600080fd5b843567ffffffffffffffff80821115610b3d57600080fd5b610b4988838901610ac3565b90965094506020870135915080821115610b6257600080fd5b50610b6f87828801610ac3565b95989497509550505050565b6001600160a01b0381168114610b9057600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610bd257610bd2610b93565b604052919050565b600082601f830112610beb57600080fd5b813567ffffffffffffffff811115610c0557610c05610b93565b610c18601f8201601f1916602001610ba9565b818152846020838601011115610c2d57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215610c6057600080fd5b8435610c6b81610b7b565b93506020850135610c7b81610b7b565b925060408501359150606085013567ffffffffffffffff811115610c9e57600080fd5b610caa87828801610bda565b91505092959194509250565b60008060408385031215610cc957600080fd5b8235610cd481610b7b565b91506020830135610ce481610b7b565b809150509250929050565b60008060008060808587031215610d0557600080fd5b8435610d1081610b7b565b93506020850135610d2081610b7b565b93969395505050506040820135916060013590565b60008060008060608587031215610d4b57600080fd5b8435610d5681610b7b565b935060208501359250604085013567ffffffffffffffff80821115610d7a57600080fd5b818701915087601f830112610d8e57600080fd5b813581811115610d9d57600080fd5b886020828501011115610daf57600080fd5b95989497505060200194505050565b600060208083528351808285015260005b81811015610deb57858101830151858201604001528201610dcf565b506000604082860101526040601f19601f8301168501019250505092915050565b600080600060608486031215610e2157600080fd5b8335610e2c81610b7b565b95602085013595506040909401359392505050565b600082601f830112610e5257600080fd5b8135602067ffffffffffffffff821115610e6e57610e6e610b93565b8160051b610e7d828201610ba9565b9283528481018201928281019087851115610e9757600080fd5b83870192505b84831015610eb657823582529183019190830190610e9d565b979650505050505050565b600080600080600060a08688031215610ed957600080fd5b8535610ee481610b7b565b94506020860135610ef481610b7b565b9350604086013567ffffffffffffffff80821115610f1157600080fd5b610f1d89838a01610e41565b94506060880135915080821115610f3357600080fd5b610f3f89838a01610e41565b93506080880135915080821115610f5557600080fd5b50610f6288828901610bda565b9150509295509295909350565b600060208284031215610f8157600080fd5b5035919050565b600080600080600060a08688031215610fa057600080fd5b8535610fab81610b7b565b94506020860135610fbb81610b7b565b93506040860135925060608601359150608086013567ffffffffffffffff811115610fe557600080fd5b610f6288828901610bda565b60006020828403121561100357600080fd5b8135610abc81610b7b565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561103657600080fd5b81358015158114610abc57600080fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161106e5761106e611046565b5060010190565b60006020828403121561108757600080fd5b8151610abc81610b7b565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b808201808211156110d4576110d4611046565b92915050565b6000806000606084860312156110ef57600080fd5b83519250602084015161110181610b7b565b80925050604084015190509250925092565b818382376000910190815291905056fea264697066735822122063e6912474b85020b5a9835811ba76231c769e7f9cde34faffb5d227a7ea56e564736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1159 DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xEC JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0xA4E2D634 GT PUSH2 0x8A JUMPI DUP1 PUSH4 0xDD467064 GT PUSH2 0x59 JUMPI DUP1 PUSH4 0xDD467064 EQ PUSH2 0x2B7 JUMPI DUP1 PUSH4 0xF23A6E61 EQ PUSH2 0x2D7 JUMPI DUP1 PUSH4 0xFC0C546A EQ PUSH2 0x303 JUMPI DUP1 PUSH4 0xFE9FBB80 EQ PUSH2 0x33B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0xA4E2D634 EQ PUSH2 0x230 JUMPI DUP1 PUSH4 0xA737A299 EQ PUSH2 0x247 JUMPI DUP1 PUSH4 0xBC197C81 EQ PUSH2 0x267 JUMPI DUP1 PUSH4 0xCE0617EC EQ PUSH2 0x293 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1F9838B5 GT PUSH2 0xC6 JUMPI DUP1 PUSH4 0x1F9838B5 EQ PUSH2 0x188 JUMPI DUP1 PUSH4 0x6B764E1B EQ PUSH2 0x1C3 JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x1E3 JUMPI DUP1 PUSH4 0x9E5D4C49 EQ PUSH2 0x210 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1FFC9A7 EQ PUSH2 0xF8 JUMPI DUP1 PUSH4 0x39721B1 EQ PUSH2 0x12D JUMPI DUP1 PUSH4 0x150B7A02 EQ PUSH2 0x14F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST CALLDATASIZE PUSH2 0xF3 JUMPI STOP JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x104 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x118 PUSH2 0x113 CALLDATASIZE PUSH1 0x4 PUSH2 0xA92 JUMP JUMPDEST PUSH2 0x35B JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x139 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x14D PUSH2 0x148 CALLDATASIZE PUSH1 0x4 PUSH2 0xB0F JUMP JUMPDEST PUSH2 0x3C2 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x15B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x16F PUSH2 0x16A CALLDATASIZE PUSH1 0x4 PUSH2 0xC4A JUMP JUMPDEST PUSH2 0x58B JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x124 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x194 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x118 PUSH2 0x1A3 CALLDATASIZE PUSH1 0x4 PUSH2 0xCB6 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1CF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x14D PUSH2 0x1DE CALLDATASIZE PUSH1 0x4 PUSH2 0xCEF JUMP JUMPDEST PUSH2 0x5F3 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1EF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1F8 PUSH2 0x661 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x124 JUMP JUMPDEST PUSH2 0x223 PUSH2 0x21E CALLDATASIZE PUSH1 0x4 PUSH2 0xD35 JUMP JUMPDEST PUSH2 0x6F7 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x124 SWAP2 SWAP1 PUSH2 0xDBE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x23C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x0 SLOAD TIMESTAMP LT PUSH2 0x118 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x253 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x14D PUSH2 0x262 CALLDATASIZE PUSH1 0x4 PUSH2 0xE0C JUMP JUMPDEST PUSH2 0x79B JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x273 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x16F PUSH2 0x282 CALLDATASIZE PUSH1 0x4 PUSH2 0xEC1 JUMP JUMPDEST PUSH4 0xBC197C81 PUSH1 0xE0 SHL SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x29F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2A9 PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x124 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2C3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x14D PUSH2 0x2D2 CALLDATASIZE PUSH1 0x4 PUSH2 0xF6F JUMP JUMPDEST PUSH2 0x7FD JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2E3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x16F PUSH2 0x2F2 CALLDATASIZE PUSH1 0x4 PUSH2 0xF88 JUMP JUMPDEST PUSH4 0xF23A6E61 PUSH1 0xE0 SHL SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x30F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x318 PUSH2 0x8C2 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP4 DUP5 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE SWAP1 DUP3 ADD MSTORE PUSH1 0x60 ADD PUSH2 0x124 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x347 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x118 PUSH2 0x356 CALLDATASIZE PUSH1 0x4 PUSH2 0xFF1 JUMP JUMPDEST PUSH2 0x8DA JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x1FFC9A7 PUSH1 0xE0 SHL EQ DUP1 PUSH2 0x38D JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x2711897 PUSH1 0xE5 SHL EQ JUMPDEST DUP1 PUSH2 0x3A8 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x1DFE9A6F PUSH1 0xE3 SHL EQ JUMPDEST SWAP1 POP DUP1 ISZERO PUSH2 0x3B9 JUMPI POP PUSH1 0x1 SWAP3 SWAP2 POP POP JUMP JUMPDEST POP PUSH1 0x0 SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x3E5 JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x3EF PUSH2 0x661 JUMP JUMPDEST SWAP1 POP CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND EQ PUSH2 0x41A JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 DUP3 DUP2 EQ PUSH2 0x43B JUMPI PUSH1 0x40 MLOAD PUSH4 0xB4FA3FB3 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x582 JUMPI DUP5 DUP5 DUP3 DUP2 DUP2 LT PUSH2 0x458 JUMPI PUSH2 0x458 PUSH2 0x100E JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x46D SWAP2 SWAP1 PUSH2 0x1024 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 SWAP1 DUP10 DUP10 DUP6 DUP2 DUP2 LT PUSH2 0x498 JUMPI PUSH2 0x498 PUSH2 0x100E JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x4AD SWAP2 SWAP1 PUSH2 0xFF1 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP2 MSTORE PUSH1 0x20 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 ADD PUSH1 0x0 KECCAK256 DUP1 SLOAD PUSH1 0xFF NOT AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH32 0x394777A58092892D136A90C4BB7E4350C72AC50FBA6A0208128677F36527DCF5 DUP4 DUP9 DUP9 DUP5 DUP2 DUP2 LT PUSH2 0x509 JUMPI PUSH2 0x509 PUSH2 0x100E JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x51E SWAP2 SWAP1 PUSH2 0xFF1 JUMP JUMPDEST DUP8 DUP8 DUP6 DUP2 DUP2 LT PUSH2 0x530 JUMPI PUSH2 0x530 PUSH2 0x100E JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x545 SWAP2 SWAP1 PUSH2 0x1024 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP5 DUP6 AND DUP2 MSTORE SWAP4 SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE ISZERO ISZERO SWAP1 DUP3 ADD MSTORE PUSH1 0x60 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 DUP1 PUSH2 0x57A DUP2 PUSH2 0x105C JUMP JUMPDEST SWAP2 POP POP PUSH2 0x43E JUMP JUMPDEST POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x599 PUSH2 0x9C3 JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP CHAINID DUP4 EQ DUP1 ISZERO PUSH2 0x5B6 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND CALLER EQ JUMPDEST DUP1 ISZERO PUSH2 0x5C1 JUMPI POP DUP6 DUP2 EQ JUMPDEST ISZERO PUSH2 0x5DF JUMPI PUSH1 0x40 MLOAD PUSH4 0xB79E3F3F PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP PUSH4 0xA85BD01 PUSH1 0xE1 SHL SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x21421707 PUSH1 0xE1 SHL DUP2 MSTORE ADDRESS PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP6 DUP2 AND PUSH1 0x24 DUP4 ADD MSTORE PUSH1 0x44 DUP3 ADD DUP5 SWAP1 MSTORE DUP5 AND SWAP1 PUSH4 0x42842E0E SWAP1 PUSH1 0x64 ADD PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x643 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x657 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x66F PUSH2 0x9C3 JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP CHAINID DUP4 EQ PUSH2 0x686 JUMPI PUSH1 0x0 SWAP4 POP POP POP POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x31A9108F PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND SWAP1 PUSH4 0x6352211E SWAP1 PUSH1 0x24 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x6CB JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x6EF SWAP2 SWAP1 PUSH2 0x1075 JUMP JUMPDEST SWAP4 POP POP POP POP SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH2 0x702 CALLER PUSH2 0x8DA JUMP JUMPDEST PUSH2 0x71F JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x742 JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH32 0x47D99AD340F52DA66535AFF7E10DA1CEB85A32BCBD9FA1C42314D194545E14D2 DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0x77E SWAP3 SWAP2 SWAP1 PUSH2 0x1092 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 PUSH2 0x792 DUP6 DUP6 DUP6 DUP6 PUSH2 0xA16 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x21421707 PUSH1 0xE1 SHL DUP2 MSTORE CALLER PUSH1 0x4 DUP3 ADD MSTORE ADDRESS PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x44 DUP2 ADD DUP4 SWAP1 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND SWAP1 PUSH4 0x42842E0E SWAP1 PUSH1 0x64 ADD PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x7E9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x582 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST PUSH2 0x805 PUSH2 0x661 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ PUSH2 0x836 JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x859 JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH2 0x867 TIMESTAMP PUSH4 0x1E13380 PUSH2 0x10C1 JUMP JUMPDEST DUP2 GT ISZERO PUSH2 0x887 JUMPI PUSH1 0x40 MLOAD PUSH4 0x1814F7D PUSH1 0xE3 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 DUP2 SWAP1 SSTORE PUSH1 0x40 MLOAD DUP2 DUP2 MSTORE PUSH32 0xA7B24C66DD3269A292A60B3FACDBB8F3E7557D1E19E64D99E0D6EE7250BE63AD SWAP1 PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x8CF PUSH2 0x9C3 JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP SWAP1 SWAP2 SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x8E7 PUSH2 0x9C3 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x31A9108F PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE SWAP2 SWAP5 POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND SWAP1 PUSH4 0x6352211E SWAP1 PUSH1 0x24 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x935 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x959 SWAP2 SWAP1 PUSH2 0x1075 JUMP JUMPDEST SWAP1 POP DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SUB PUSH2 0x97F JUMPI POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP1 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP10 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x9B8 JUMPI POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST POP PUSH1 0x0 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 DUP1 DUP3 MSTORE PUSH1 0x80 DUP3 ADD SWAP1 SWAP3 MSTORE PUSH1 0x0 SWAP2 DUP3 SWAP2 DUP3 SWAP2 DUP3 SWAP2 SWAP1 PUSH1 0x20 DUP3 ADD DUP2 DUP1 CALLDATASIZE DUP4 CALLDATACOPY ADD SWAP1 POP POP SWAP1 POP PUSH1 0xAD PUSH1 0x4D PUSH1 0x20 DUP4 ADD ADDRESS EXTCODECOPY DUP1 DUP1 PUSH1 0x20 ADD SWAP1 MLOAD DUP2 ADD SWAP1 PUSH2 0xA0A SWAP2 SWAP1 PUSH2 0x10DA JUMP JUMPDEST SWAP4 POP SWAP4 POP SWAP4 POP POP SWAP1 SWAP2 SWAP3 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP6 DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0xA35 SWAP3 SWAP2 SWAP1 PUSH2 0x1113 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 GAS CALL SWAP3 POP POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0xA72 JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0xA77 JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP3 POP SWAP1 POP DUP1 PUSH2 0xA89 JUMPI DUP2 MLOAD PUSH1 0x20 DUP4 ADD REVERT JUMPDEST POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xAA4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP2 AND DUP2 EQ PUSH2 0xABC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0xAD5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xAED JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 PUSH1 0x5 SHL DUP6 ADD ADD GT ISZERO PUSH2 0xB08 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x40 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xB25 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xB3D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xB49 DUP9 DUP4 DUP10 ADD PUSH2 0xAC3 JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP PUSH1 0x20 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xB62 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB6F DUP8 DUP3 DUP9 ADD PUSH2 0xAC3 JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0xB90 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT AND DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0xBD2 JUMPI PUSH2 0xBD2 PUSH2 0xB93 JUMP JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xBEB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xC05 JUMPI PUSH2 0xC05 PUSH2 0xB93 JUMP JUMPDEST PUSH2 0xC18 PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT AND PUSH1 0x20 ADD PUSH2 0xBA9 JUMP JUMPDEST DUP2 DUP2 MSTORE DUP5 PUSH1 0x20 DUP4 DUP7 ADD ADD GT ISZERO PUSH2 0xC2D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 PUSH1 0x20 DUP6 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 SWAP2 DUP2 ADD PUSH1 0x20 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xC60 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xC6B DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH2 0xC7B DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD SWAP2 POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xC9E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xCAA DUP8 DUP3 DUP9 ADD PUSH2 0xBDA JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xCC9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH2 0xCD4 DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP2 POP PUSH1 0x20 DUP4 ADD CALLDATALOAD PUSH2 0xCE4 DUP2 PUSH2 0xB7B JUMP JUMPDEST DUP1 SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xD05 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xD10 DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH2 0xD20 DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP4 SWAP7 SWAP4 SWAP6 POP POP POP POP PUSH1 0x40 DUP3 ADD CALLDATALOAD SWAP2 PUSH1 0x60 ADD CALLDATALOAD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x60 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xD4B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xD56 DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xD7A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP8 ADD SWAP2 POP DUP8 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xD8E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP2 DUP2 GT ISZERO PUSH2 0xD9D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP9 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0xDAF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP POP PUSH1 0x20 ADD SWAP5 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 MSTORE DUP4 MLOAD DUP1 DUP3 DUP6 ADD MSTORE PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xDEB JUMPI DUP6 DUP2 ADD DUP4 ADD MLOAD DUP6 DUP3 ADD PUSH1 0x40 ADD MSTORE DUP3 ADD PUSH2 0xDCF JUMP JUMPDEST POP PUSH1 0x0 PUSH1 0x40 DUP3 DUP7 ADD ADD MSTORE PUSH1 0x40 PUSH1 0x1F NOT PUSH1 0x1F DUP4 ADD AND DUP6 ADD ADD SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xE21 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH2 0xE2C DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP6 PUSH1 0x20 DUP6 ADD CALLDATALOAD SWAP6 POP PUSH1 0x40 SWAP1 SWAP5 ADD CALLDATALOAD SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xE52 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH1 0x20 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0xE6E JUMPI PUSH2 0xE6E PUSH2 0xB93 JUMP JUMPDEST DUP2 PUSH1 0x5 SHL PUSH2 0xE7D DUP3 DUP3 ADD PUSH2 0xBA9 JUMP JUMPDEST SWAP3 DUP4 MSTORE DUP5 DUP2 ADD DUP3 ADD SWAP3 DUP3 DUP2 ADD SWAP1 DUP8 DUP6 GT ISZERO PUSH2 0xE97 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 DUP8 ADD SWAP3 POP JUMPDEST DUP5 DUP4 LT ISZERO PUSH2 0xEB6 JUMPI DUP3 CALLDATALOAD DUP3 MSTORE SWAP2 DUP4 ADD SWAP2 SWAP1 DUP4 ADD SWAP1 PUSH2 0xE9D JUMP JUMPDEST SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xED9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xEE4 DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH2 0xEF4 DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xF11 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xF1D DUP10 DUP4 DUP11 ADD PUSH2 0xE41 JUMP JUMPDEST SWAP5 POP PUSH1 0x60 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xF33 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xF3F DUP10 DUP4 DUP11 ADD PUSH2 0xE41 JUMP JUMPDEST SWAP4 POP PUSH1 0x80 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xF55 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xF62 DUP9 DUP3 DUP10 ADD PUSH2 0xBDA JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 SWAP1 SWAP4 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xF81 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xFA0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xFAB DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH2 0xFBB DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD SWAP3 POP PUSH1 0x60 DUP7 ADD CALLDATALOAD SWAP2 POP PUSH1 0x80 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xFE5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xF62 DUP9 DUP3 DUP10 ADD PUSH2 0xBDA JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1003 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0xABC DUP2 PUSH2 0xB7B JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x32 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1036 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP1 ISZERO ISZERO DUP2 EQ PUSH2 0xABC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x11 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x1 DUP3 ADD PUSH2 0x106E JUMPI PUSH2 0x106E PUSH2 0x1046 JUMP JUMPDEST POP PUSH1 0x1 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1087 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0xABC DUP2 PUSH2 0xB7B JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE DUP2 PUSH1 0x20 DUP3 ADD MSTORE DUP2 DUP4 PUSH1 0x40 DUP4 ADD CALLDATACOPY PUSH1 0x0 DUP2 DUP4 ADD PUSH1 0x40 SWAP1 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x1F SWAP1 SWAP3 ADD PUSH1 0x1F NOT AND ADD ADD SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 DUP3 ADD DUP1 DUP3 GT ISZERO PUSH2 0x10D4 JUMPI PUSH2 0x10D4 PUSH2 0x1046 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x10EF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 MLOAD SWAP3 POP PUSH1 0x20 DUP5 ADD MLOAD PUSH2 0x1101 DUP2 PUSH2 0xB7B JUMP JUMPDEST DUP1 SWAP3 POP POP PUSH1 0x40 DUP5 ADD MLOAD SWAP1 POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST DUP2 DUP4 DUP3 CALLDATACOPY PUSH1 0x0 SWAP2 ADD SWAP1 DUP2 MSTORE SWAP2 SWAP1 POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 PUSH4 0xE6912474 0xB8 POP KECCAK256 0xB5 0xA9 DUP4 PC GT 0xBA PUSH23 0x231C769E7F9CDE34FAFFB5D227A7EA56E564736F6C6343 STOP ADDMOD GT STOP CALLER ","sourceMap":"161:627:5:-:0;;;;;;;;;;;;;;;;;;;"},"deployedBytecode":{"functionDebugData":{"@_362":{"entryPoint":null,"id":362,"parameterSlots":0,"returnSlots":0},"@_call_760":{"entryPoint":2582,"id":760,"parameterSlots":4,"returnSlots":1},"@breakCovalentBond_253":{"entryPoint":1523,"id":253,"parameterSlots":4,"returnSlots":0},"@covalentBond_229":{"entryPoint":1947,"id":229,"parameterSlots":3,"returnSlots":0},"@executeCall_391":{"entryPoint":1783,"id":391,"parameterSlots":4,"returnSlots":1},"@isAuthorized_596":{"entryPoint":2266,"id":596,"parameterSlots":1,"returnSlots":1},"@isLocked_505":{"entryPoint":null,"id":505,"parameterSlots":0,"returnSlots":1},"@lock_493":{"entryPoint":2045,"id":493,"parameterSlots":1,"returnSlots":0},"@lockedUntil_287":{"entryPoint":null,"id":287,"parameterSlots":0,"returnSlots":0},"@onERC1155BatchReceived_728":{"entryPoint":null,"id":728,"parameterSlots":5,"returnSlots":1},"@onERC1155Received_704":{"entryPoint":null,"id":704,"parameterSlots":5,"returnSlots":1},"@onERC721Received_682":{"entryPoint":1419,"id":682,"parameterSlots":4,"returnSlots":1},"@owner_554":{"entryPoint":1633,"id":554,"parameterSlots":0,"returnSlots":1},"@permissions_294":{"entryPoint":null,"id":294,"parameterSlots":0,"returnSlots":0},"@setPermissions_464":{"entryPoint":962,"id":464,"parameterSlots":4,"returnSlots":0},"@supportsInterface_635":{"entryPoint":859,"id":635,"parameterSlots":1,"returnSlots":1},"@token_520":{"entryPoint":2242,"id":520,"parameterSlots":0,"returnSlots":3},"@token_867":{"entryPoint":2499,"id":867,"parameterSlots":0,"returnSlots":3},"abi_decode_array_address_dyn_calldata":{"entryPoint":2755,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_array_uint256_dyn":{"entryPoint":3649,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_bytes":{"entryPoint":3034,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_address":{"entryPoint":4081,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_address_fromMemory":{"entryPoint":4213,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_addresst_address":{"entryPoint":3254,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_tuple_t_addresst_addresst_array$_t_uint256_$dyn_memory_ptrt_array$_t_uint256_$dyn_memory_ptrt_bytes_memory_ptr":{"entryPoint":3777,"id":null,"parameterSlots":2,"returnSlots":5},"abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr":{"entryPoint":3146,"id":null,"parameterSlots":2,"returnSlots":4},"abi_decode_tuple_t_addresst_addresst_uint256t_uint256":{"entryPoint":3311,"id":null,"parameterSlots":2,"returnSlots":4},"abi_decode_tuple_t_addresst_addresst_uint256t_uint256t_bytes_memory_ptr":{"entryPoint":3976,"id":null,"parameterSlots":2,"returnSlots":5},"abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptr":{"entryPoint":3381,"id":null,"parameterSlots":2,"returnSlots":4},"abi_decode_tuple_t_addresst_uint256t_uint256":{"entryPoint":3596,"id":null,"parameterSlots":2,"returnSlots":3},"abi_decode_tuple_t_array$_t_address_$dyn_calldata_ptrt_array$_t_bool_$dyn_calldata_ptr":{"entryPoint":2831,"id":null,"parameterSlots":2,"returnSlots":4},"abi_decode_tuple_t_bool":{"entryPoint":4132,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_bytes4":{"entryPoint":2706,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_uint256":{"entryPoint":3951,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_uint256t_address_payablet_uint256_fromMemory":{"entryPoint":4314,"id":null,"parameterSlots":2,"returnSlots":3},"abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed":{"entryPoint":4371,"id":null,"parameterSlots":3,"returnSlots":1},"abi_encode_tuple_t_address__to_t_address__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_address_t_address_t_bool__to_t_address_t_address_t_bool__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":4,"returnSlots":1},"abi_encode_tuple_t_address_t_address_t_uint256__to_t_address_t_address_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":4,"returnSlots":1},"abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed":{"entryPoint":4242,"id":null,"parameterSlots":3,"returnSlots":1},"abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed":{"entryPoint":3518,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_uint256_t_address_t_uint256__to_t_uint256_t_address_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":4,"returnSlots":1},"allocate_memory":{"entryPoint":2985,"id":null,"parameterSlots":1,"returnSlots":1},"checked_add_t_uint256":{"entryPoint":4289,"id":null,"parameterSlots":2,"returnSlots":1},"increment_t_uint256":{"entryPoint":4188,"id":null,"parameterSlots":1,"returnSlots":1},"panic_error_0x11":{"entryPoint":4166,"id":null,"parameterSlots":0,"returnSlots":0},"panic_error_0x32":{"entryPoint":4110,"id":null,"parameterSlots":0,"returnSlots":0},"panic_error_0x41":{"entryPoint":2963,"id":null,"parameterSlots":0,"returnSlots":0},"validator_revert_address":{"entryPoint":2939,"id":null,"parameterSlots":1,"returnSlots":0}},"generatedSources":[{"ast":{"nodeType":"YulBlock","src":"0:12864:9","statements":[{"nodeType":"YulBlock","src":"6:3:9","statements":[]},{"body":{"nodeType":"YulBlock","src":"83:217:9","statements":[{"body":{"nodeType":"YulBlock","src":"129:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"138:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"141:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"131:6:9"},"nodeType":"YulFunctionCall","src":"131:12:9"},"nodeType":"YulExpressionStatement","src":"131:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"104:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"113:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"100:3:9"},"nodeType":"YulFunctionCall","src":"100:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"125:2:9","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"96:3:9"},"nodeType":"YulFunctionCall","src":"96:32:9"},"nodeType":"YulIf","src":"93:52:9"},{"nodeType":"YulVariableDeclaration","src":"154:36:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"180:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"167:12:9"},"nodeType":"YulFunctionCall","src":"167:23:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"158:5:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"254:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"263:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"266:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"256:6:9"},"nodeType":"YulFunctionCall","src":"256:12:9"},"nodeType":"YulExpressionStatement","src":"256:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"212:5:9"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"223:5:9"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"234:3:9","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"239:10:9","type":"","value":"0xffffffff"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"230:3:9"},"nodeType":"YulFunctionCall","src":"230:20:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"219:3:9"},"nodeType":"YulFunctionCall","src":"219:32:9"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"209:2:9"},"nodeType":"YulFunctionCall","src":"209:43:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"202:6:9"},"nodeType":"YulFunctionCall","src":"202:51:9"},"nodeType":"YulIf","src":"199:71:9"},{"nodeType":"YulAssignment","src":"279:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"289:5:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"279:6:9"}]}]},"name":"abi_decode_tuple_t_bytes4","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"49:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"60:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"72:6:9","type":""}],"src":"14:286:9"},{"body":{"nodeType":"YulBlock","src":"400:92:9","statements":[{"nodeType":"YulAssignment","src":"410:26:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"422:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"433:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"418:3:9"},"nodeType":"YulFunctionCall","src":"418:18:9"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"410:4:9"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"452:9:9"},{"arguments":[{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"477:6:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"470:6:9"},"nodeType":"YulFunctionCall","src":"470:14:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"463:6:9"},"nodeType":"YulFunctionCall","src":"463:22:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"445:6:9"},"nodeType":"YulFunctionCall","src":"445:41:9"},"nodeType":"YulExpressionStatement","src":"445:41:9"}]},"name":"abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"369:9:9","type":""},{"name":"value0","nodeType":"YulTypedName","src":"380:6:9","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"391:4:9","type":""}],"src":"305:187:9"},{"body":{"nodeType":"YulBlock","src":"581:283:9","statements":[{"body":{"nodeType":"YulBlock","src":"630:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"639:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"642:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"632:6:9"},"nodeType":"YulFunctionCall","src":"632:12:9"},"nodeType":"YulExpressionStatement","src":"632:12:9"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"609:6:9"},{"kind":"number","nodeType":"YulLiteral","src":"617:4:9","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"605:3:9"},"nodeType":"YulFunctionCall","src":"605:17:9"},{"name":"end","nodeType":"YulIdentifier","src":"624:3:9"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"601:3:9"},"nodeType":"YulFunctionCall","src":"601:27:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"594:6:9"},"nodeType":"YulFunctionCall","src":"594:35:9"},"nodeType":"YulIf","src":"591:55:9"},{"nodeType":"YulAssignment","src":"655:30:9","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"678:6:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"665:12:9"},"nodeType":"YulFunctionCall","src":"665:20:9"},"variableNames":[{"name":"length","nodeType":"YulIdentifier","src":"655:6:9"}]},{"body":{"nodeType":"YulBlock","src":"728:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"737:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"740:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"730:6:9"},"nodeType":"YulFunctionCall","src":"730:12:9"},"nodeType":"YulExpressionStatement","src":"730:12:9"}]},"condition":{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"700:6:9"},{"kind":"number","nodeType":"YulLiteral","src":"708:18:9","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"697:2:9"},"nodeType":"YulFunctionCall","src":"697:30:9"},"nodeType":"YulIf","src":"694:50:9"},{"nodeType":"YulAssignment","src":"753:29:9","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"769:6:9"},{"kind":"number","nodeType":"YulLiteral","src":"777:4:9","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"765:3:9"},"nodeType":"YulFunctionCall","src":"765:17:9"},"variableNames":[{"name":"arrayPos","nodeType":"YulIdentifier","src":"753:8:9"}]},{"body":{"nodeType":"YulBlock","src":"842:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"851:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"854:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"844:6:9"},"nodeType":"YulFunctionCall","src":"844:12:9"},"nodeType":"YulExpressionStatement","src":"844:12:9"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"805:6:9"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"817:1:9","type":"","value":"5"},{"name":"length","nodeType":"YulIdentifier","src":"820:6:9"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"813:3:9"},"nodeType":"YulFunctionCall","src":"813:14:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"801:3:9"},"nodeType":"YulFunctionCall","src":"801:27:9"},{"kind":"number","nodeType":"YulLiteral","src":"830:4:9","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"797:3:9"},"nodeType":"YulFunctionCall","src":"797:38:9"},{"name":"end","nodeType":"YulIdentifier","src":"837:3:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"794:2:9"},"nodeType":"YulFunctionCall","src":"794:47:9"},"nodeType":"YulIf","src":"791:67:9"}]},"name":"abi_decode_array_address_dyn_calldata","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"544:6:9","type":""},{"name":"end","nodeType":"YulTypedName","src":"552:3:9","type":""}],"returnVariables":[{"name":"arrayPos","nodeType":"YulTypedName","src":"560:8:9","type":""},{"name":"length","nodeType":"YulTypedName","src":"570:6:9","type":""}],"src":"497:367:9"},{"body":{"nodeType":"YulBlock","src":"1023:616:9","statements":[{"body":{"nodeType":"YulBlock","src":"1069:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1078:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1081:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1071:6:9"},"nodeType":"YulFunctionCall","src":"1071:12:9"},"nodeType":"YulExpressionStatement","src":"1071:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"1044:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"1053:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1040:3:9"},"nodeType":"YulFunctionCall","src":"1040:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"1065:2:9","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"1036:3:9"},"nodeType":"YulFunctionCall","src":"1036:32:9"},"nodeType":"YulIf","src":"1033:52:9"},{"nodeType":"YulVariableDeclaration","src":"1094:37:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1121:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1108:12:9"},"nodeType":"YulFunctionCall","src":"1108:23:9"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"1098:6:9","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1140:28:9","value":{"kind":"number","nodeType":"YulLiteral","src":"1150:18:9","type":"","value":"0xffffffffffffffff"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"1144:2:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"1195:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1204:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1207:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1197:6:9"},"nodeType":"YulFunctionCall","src":"1197:12:9"},"nodeType":"YulExpressionStatement","src":"1197:12:9"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"1183:6:9"},{"name":"_1","nodeType":"YulIdentifier","src":"1191:2:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"1180:2:9"},"nodeType":"YulFunctionCall","src":"1180:14:9"},"nodeType":"YulIf","src":"1177:34:9"},{"nodeType":"YulVariableDeclaration","src":"1220:96:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1288:9:9"},{"name":"offset","nodeType":"YulIdentifier","src":"1299:6:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1284:3:9"},"nodeType":"YulFunctionCall","src":"1284:22:9"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"1308:7:9"}],"functionName":{"name":"abi_decode_array_address_dyn_calldata","nodeType":"YulIdentifier","src":"1246:37:9"},"nodeType":"YulFunctionCall","src":"1246:70:9"},"variables":[{"name":"value0_1","nodeType":"YulTypedName","src":"1224:8:9","type":""},{"name":"value1_1","nodeType":"YulTypedName","src":"1234:8:9","type":""}]},{"nodeType":"YulAssignment","src":"1325:18:9","value":{"name":"value0_1","nodeType":"YulIdentifier","src":"1335:8:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"1325:6:9"}]},{"nodeType":"YulAssignment","src":"1352:18:9","value":{"name":"value1_1","nodeType":"YulIdentifier","src":"1362:8:9"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"1352:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"1379:48:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1412:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"1423:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1408:3:9"},"nodeType":"YulFunctionCall","src":"1408:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1395:12:9"},"nodeType":"YulFunctionCall","src":"1395:32:9"},"variables":[{"name":"offset_1","nodeType":"YulTypedName","src":"1383:8:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"1456:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1465:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1468:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1458:6:9"},"nodeType":"YulFunctionCall","src":"1458:12:9"},"nodeType":"YulExpressionStatement","src":"1458:12:9"}]},"condition":{"arguments":[{"name":"offset_1","nodeType":"YulIdentifier","src":"1442:8:9"},{"name":"_1","nodeType":"YulIdentifier","src":"1452:2:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"1439:2:9"},"nodeType":"YulFunctionCall","src":"1439:16:9"},"nodeType":"YulIf","src":"1436:36:9"},{"nodeType":"YulVariableDeclaration","src":"1481:98:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1549:9:9"},{"name":"offset_1","nodeType":"YulIdentifier","src":"1560:8:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1545:3:9"},"nodeType":"YulFunctionCall","src":"1545:24:9"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"1571:7:9"}],"functionName":{"name":"abi_decode_array_address_dyn_calldata","nodeType":"YulIdentifier","src":"1507:37:9"},"nodeType":"YulFunctionCall","src":"1507:72:9"},"variables":[{"name":"value2_1","nodeType":"YulTypedName","src":"1485:8:9","type":""},{"name":"value3_1","nodeType":"YulTypedName","src":"1495:8:9","type":""}]},{"nodeType":"YulAssignment","src":"1588:18:9","value":{"name":"value2_1","nodeType":"YulIdentifier","src":"1598:8:9"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"1588:6:9"}]},{"nodeType":"YulAssignment","src":"1615:18:9","value":{"name":"value3_1","nodeType":"YulIdentifier","src":"1625:8:9"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"1615:6:9"}]}]},"name":"abi_decode_tuple_t_array$_t_address_$dyn_calldata_ptrt_array$_t_bool_$dyn_calldata_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"965:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"976:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"988:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"996:6:9","type":""},{"name":"value2","nodeType":"YulTypedName","src":"1004:6:9","type":""},{"name":"value3","nodeType":"YulTypedName","src":"1012:6:9","type":""}],"src":"869:770:9"},{"body":{"nodeType":"YulBlock","src":"1689:86:9","statements":[{"body":{"nodeType":"YulBlock","src":"1753:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1762:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1765:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1755:6:9"},"nodeType":"YulFunctionCall","src":"1755:12:9"},"nodeType":"YulExpressionStatement","src":"1755:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1712:5:9"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1723:5:9"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1738:3:9","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"1743:1:9","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1734:3:9"},"nodeType":"YulFunctionCall","src":"1734:11:9"},{"kind":"number","nodeType":"YulLiteral","src":"1747:1:9","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1730:3:9"},"nodeType":"YulFunctionCall","src":"1730:19:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1719:3:9"},"nodeType":"YulFunctionCall","src":"1719:31:9"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"1709:2:9"},"nodeType":"YulFunctionCall","src":"1709:42:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"1702:6:9"},"nodeType":"YulFunctionCall","src":"1702:50:9"},"nodeType":"YulIf","src":"1699:70:9"}]},"name":"validator_revert_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"value","nodeType":"YulTypedName","src":"1678:5:9","type":""}],"src":"1644:131:9"},{"body":{"nodeType":"YulBlock","src":"1812:95:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1829:1:9","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1836:3:9","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"1841:10:9","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1832:3:9"},"nodeType":"YulFunctionCall","src":"1832:20:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1822:6:9"},"nodeType":"YulFunctionCall","src":"1822:31:9"},"nodeType":"YulExpressionStatement","src":"1822:31:9"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1869:1:9","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"1872:4:9","type":"","value":"0x41"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1862:6:9"},"nodeType":"YulFunctionCall","src":"1862:15:9"},"nodeType":"YulExpressionStatement","src":"1862:15:9"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1893:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1896:4:9","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1886:6:9"},"nodeType":"YulFunctionCall","src":"1886:15:9"},"nodeType":"YulExpressionStatement","src":"1886:15:9"}]},"name":"panic_error_0x41","nodeType":"YulFunctionDefinition","src":"1780:127:9"},{"body":{"nodeType":"YulBlock","src":"1957:230:9","statements":[{"nodeType":"YulAssignment","src":"1967:19:9","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1983:2:9","type":"","value":"64"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"1977:5:9"},"nodeType":"YulFunctionCall","src":"1977:9:9"},"variableNames":[{"name":"memPtr","nodeType":"YulIdentifier","src":"1967:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"1995:58:9","value":{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"2017:6:9"},{"arguments":[{"arguments":[{"name":"size","nodeType":"YulIdentifier","src":"2033:4:9"},{"kind":"number","nodeType":"YulLiteral","src":"2039:2:9","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2029:3:9"},"nodeType":"YulFunctionCall","src":"2029:13:9"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2048:2:9","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"2044:3:9"},"nodeType":"YulFunctionCall","src":"2044:7:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"2025:3:9"},"nodeType":"YulFunctionCall","src":"2025:27:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2013:3:9"},"nodeType":"YulFunctionCall","src":"2013:40:9"},"variables":[{"name":"newFreePtr","nodeType":"YulTypedName","src":"1999:10:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"2128:22:9","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"2130:16:9"},"nodeType":"YulFunctionCall","src":"2130:18:9"},"nodeType":"YulExpressionStatement","src":"2130:18:9"}]},"condition":{"arguments":[{"arguments":[{"name":"newFreePtr","nodeType":"YulIdentifier","src":"2071:10:9"},{"kind":"number","nodeType":"YulLiteral","src":"2083:18:9","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2068:2:9"},"nodeType":"YulFunctionCall","src":"2068:34:9"},{"arguments":[{"name":"newFreePtr","nodeType":"YulIdentifier","src":"2107:10:9"},{"name":"memPtr","nodeType":"YulIdentifier","src":"2119:6:9"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"2104:2:9"},"nodeType":"YulFunctionCall","src":"2104:22:9"}],"functionName":{"name":"or","nodeType":"YulIdentifier","src":"2065:2:9"},"nodeType":"YulFunctionCall","src":"2065:62:9"},"nodeType":"YulIf","src":"2062:88:9"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2166:2:9","type":"","value":"64"},{"name":"newFreePtr","nodeType":"YulIdentifier","src":"2170:10:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2159:6:9"},"nodeType":"YulFunctionCall","src":"2159:22:9"},"nodeType":"YulExpressionStatement","src":"2159:22:9"}]},"name":"allocate_memory","nodeType":"YulFunctionDefinition","parameters":[{"name":"size","nodeType":"YulTypedName","src":"1937:4:9","type":""}],"returnVariables":[{"name":"memPtr","nodeType":"YulTypedName","src":"1946:6:9","type":""}],"src":"1912:275:9"},{"body":{"nodeType":"YulBlock","src":"2244:478:9","statements":[{"body":{"nodeType":"YulBlock","src":"2293:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2302:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2305:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2295:6:9"},"nodeType":"YulFunctionCall","src":"2295:12:9"},"nodeType":"YulExpressionStatement","src":"2295:12:9"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2272:6:9"},{"kind":"number","nodeType":"YulLiteral","src":"2280:4:9","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2268:3:9"},"nodeType":"YulFunctionCall","src":"2268:17:9"},{"name":"end","nodeType":"YulIdentifier","src":"2287:3:9"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"2264:3:9"},"nodeType":"YulFunctionCall","src":"2264:27:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"2257:6:9"},"nodeType":"YulFunctionCall","src":"2257:35:9"},"nodeType":"YulIf","src":"2254:55:9"},{"nodeType":"YulVariableDeclaration","src":"2318:30:9","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2341:6:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2328:12:9"},"nodeType":"YulFunctionCall","src":"2328:20:9"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"2322:2:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"2387:22:9","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"2389:16:9"},"nodeType":"YulFunctionCall","src":"2389:18:9"},"nodeType":"YulExpressionStatement","src":"2389:18:9"}]},"condition":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"2363:2:9"},{"kind":"number","nodeType":"YulLiteral","src":"2367:18:9","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2360:2:9"},"nodeType":"YulFunctionCall","src":"2360:26:9"},"nodeType":"YulIf","src":"2357:52:9"},{"nodeType":"YulVariableDeclaration","src":"2418:70:9","value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"2461:2:9"},{"kind":"number","nodeType":"YulLiteral","src":"2465:4:9","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2457:3:9"},"nodeType":"YulFunctionCall","src":"2457:13:9"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2476:2:9","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"2472:3:9"},"nodeType":"YulFunctionCall","src":"2472:7:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"2453:3:9"},"nodeType":"YulFunctionCall","src":"2453:27:9"},{"kind":"number","nodeType":"YulLiteral","src":"2482:4:9","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2449:3:9"},"nodeType":"YulFunctionCall","src":"2449:38:9"}],"functionName":{"name":"allocate_memory","nodeType":"YulIdentifier","src":"2433:15:9"},"nodeType":"YulFunctionCall","src":"2433:55:9"},"variables":[{"name":"array_1","nodeType":"YulTypedName","src":"2422:7:9","type":""}]},{"expression":{"arguments":[{"name":"array_1","nodeType":"YulIdentifier","src":"2504:7:9"},{"name":"_1","nodeType":"YulIdentifier","src":"2513:2:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2497:6:9"},"nodeType":"YulFunctionCall","src":"2497:19:9"},"nodeType":"YulExpressionStatement","src":"2497:19:9"},{"body":{"nodeType":"YulBlock","src":"2564:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2573:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2576:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2566:6:9"},"nodeType":"YulFunctionCall","src":"2566:12:9"},"nodeType":"YulExpressionStatement","src":"2566:12:9"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2539:6:9"},{"name":"_1","nodeType":"YulIdentifier","src":"2547:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2535:3:9"},"nodeType":"YulFunctionCall","src":"2535:15:9"},{"kind":"number","nodeType":"YulLiteral","src":"2552:4:9","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2531:3:9"},"nodeType":"YulFunctionCall","src":"2531:26:9"},{"name":"end","nodeType":"YulIdentifier","src":"2559:3:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2528:2:9"},"nodeType":"YulFunctionCall","src":"2528:35:9"},"nodeType":"YulIf","src":"2525:55:9"},{"expression":{"arguments":[{"arguments":[{"name":"array_1","nodeType":"YulIdentifier","src":"2606:7:9"},{"kind":"number","nodeType":"YulLiteral","src":"2615:4:9","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2602:3:9"},"nodeType":"YulFunctionCall","src":"2602:18:9"},{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2626:6:9"},{"kind":"number","nodeType":"YulLiteral","src":"2634:4:9","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2622:3:9"},"nodeType":"YulFunctionCall","src":"2622:17:9"},{"name":"_1","nodeType":"YulIdentifier","src":"2641:2:9"}],"functionName":{"name":"calldatacopy","nodeType":"YulIdentifier","src":"2589:12:9"},"nodeType":"YulFunctionCall","src":"2589:55:9"},"nodeType":"YulExpressionStatement","src":"2589:55:9"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"array_1","nodeType":"YulIdentifier","src":"2668:7:9"},{"name":"_1","nodeType":"YulIdentifier","src":"2677:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2664:3:9"},"nodeType":"YulFunctionCall","src":"2664:16:9"},{"kind":"number","nodeType":"YulLiteral","src":"2682:4:9","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2660:3:9"},"nodeType":"YulFunctionCall","src":"2660:27:9"},{"kind":"number","nodeType":"YulLiteral","src":"2689:1:9","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2653:6:9"},"nodeType":"YulFunctionCall","src":"2653:38:9"},"nodeType":"YulExpressionStatement","src":"2653:38:9"},{"nodeType":"YulAssignment","src":"2700:16:9","value":{"name":"array_1","nodeType":"YulIdentifier","src":"2709:7:9"},"variableNames":[{"name":"array","nodeType":"YulIdentifier","src":"2700:5:9"}]}]},"name":"abi_decode_bytes","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"2218:6:9","type":""},{"name":"end","nodeType":"YulTypedName","src":"2226:3:9","type":""}],"returnVariables":[{"name":"array","nodeType":"YulTypedName","src":"2234:5:9","type":""}],"src":"2192:530:9"},{"body":{"nodeType":"YulBlock","src":"2857:535:9","statements":[{"body":{"nodeType":"YulBlock","src":"2904:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2913:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2916:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2906:6:9"},"nodeType":"YulFunctionCall","src":"2906:12:9"},"nodeType":"YulExpressionStatement","src":"2906:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"2878:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"2887:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"2874:3:9"},"nodeType":"YulFunctionCall","src":"2874:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"2899:3:9","type":"","value":"128"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"2870:3:9"},"nodeType":"YulFunctionCall","src":"2870:33:9"},"nodeType":"YulIf","src":"2867:53:9"},{"nodeType":"YulVariableDeclaration","src":"2929:36:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2955:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2942:12:9"},"nodeType":"YulFunctionCall","src":"2942:23:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"2933:5:9","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"2999:5:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"2974:24:9"},"nodeType":"YulFunctionCall","src":"2974:31:9"},"nodeType":"YulExpressionStatement","src":"2974:31:9"},{"nodeType":"YulAssignment","src":"3014:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"3024:5:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"3014:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"3038:47:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3070:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"3081:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3066:3:9"},"nodeType":"YulFunctionCall","src":"3066:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3053:12:9"},"nodeType":"YulFunctionCall","src":"3053:32:9"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"3042:7:9","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"3119:7:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"3094:24:9"},"nodeType":"YulFunctionCall","src":"3094:33:9"},"nodeType":"YulExpressionStatement","src":"3094:33:9"},{"nodeType":"YulAssignment","src":"3136:17:9","value":{"name":"value_1","nodeType":"YulIdentifier","src":"3146:7:9"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"3136:6:9"}]},{"nodeType":"YulAssignment","src":"3162:42:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3189:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"3200:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3185:3:9"},"nodeType":"YulFunctionCall","src":"3185:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3172:12:9"},"nodeType":"YulFunctionCall","src":"3172:32:9"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"3162:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"3213:46:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3244:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"3255:2:9","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3240:3:9"},"nodeType":"YulFunctionCall","src":"3240:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3227:12:9"},"nodeType":"YulFunctionCall","src":"3227:32:9"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"3217:6:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"3302:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3311:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3314:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3304:6:9"},"nodeType":"YulFunctionCall","src":"3304:12:9"},"nodeType":"YulExpressionStatement","src":"3304:12:9"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"3274:6:9"},{"kind":"number","nodeType":"YulLiteral","src":"3282:18:9","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"3271:2:9"},"nodeType":"YulFunctionCall","src":"3271:30:9"},"nodeType":"YulIf","src":"3268:50:9"},{"nodeType":"YulAssignment","src":"3327:59:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3358:9:9"},{"name":"offset","nodeType":"YulIdentifier","src":"3369:6:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3354:3:9"},"nodeType":"YulFunctionCall","src":"3354:22:9"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"3378:7:9"}],"functionName":{"name":"abi_decode_bytes","nodeType":"YulIdentifier","src":"3337:16:9"},"nodeType":"YulFunctionCall","src":"3337:49:9"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"3327:6:9"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"2799:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"2810:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"2822:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"2830:6:9","type":""},{"name":"value2","nodeType":"YulTypedName","src":"2838:6:9","type":""},{"name":"value3","nodeType":"YulTypedName","src":"2846:6:9","type":""}],"src":"2727:665:9"},{"body":{"nodeType":"YulBlock","src":"3496:103:9","statements":[{"nodeType":"YulAssignment","src":"3506:26:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3518:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"3529:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3514:3:9"},"nodeType":"YulFunctionCall","src":"3514:18:9"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"3506:4:9"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3548:9:9"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"3563:6:9"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3575:3:9","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"3580:10:9","type":"","value":"0xffffffff"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"3571:3:9"},"nodeType":"YulFunctionCall","src":"3571:20:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"3559:3:9"},"nodeType":"YulFunctionCall","src":"3559:33:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"3541:6:9"},"nodeType":"YulFunctionCall","src":"3541:52:9"},"nodeType":"YulExpressionStatement","src":"3541:52:9"}]},"name":"abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"3465:9:9","type":""},{"name":"value0","nodeType":"YulTypedName","src":"3476:6:9","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"3487:4:9","type":""}],"src":"3397:202:9"},{"body":{"nodeType":"YulBlock","src":"3691:301:9","statements":[{"body":{"nodeType":"YulBlock","src":"3737:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3746:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3749:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3739:6:9"},"nodeType":"YulFunctionCall","src":"3739:12:9"},"nodeType":"YulExpressionStatement","src":"3739:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"3712:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"3721:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"3708:3:9"},"nodeType":"YulFunctionCall","src":"3708:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"3733:2:9","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"3704:3:9"},"nodeType":"YulFunctionCall","src":"3704:32:9"},"nodeType":"YulIf","src":"3701:52:9"},{"nodeType":"YulVariableDeclaration","src":"3762:36:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3788:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3775:12:9"},"nodeType":"YulFunctionCall","src":"3775:23:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"3766:5:9","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"3832:5:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"3807:24:9"},"nodeType":"YulFunctionCall","src":"3807:31:9"},"nodeType":"YulExpressionStatement","src":"3807:31:9"},{"nodeType":"YulAssignment","src":"3847:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"3857:5:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"3847:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"3871:47:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3903:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"3914:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3899:3:9"},"nodeType":"YulFunctionCall","src":"3899:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3886:12:9"},"nodeType":"YulFunctionCall","src":"3886:32:9"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"3875:7:9","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"3952:7:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"3927:24:9"},"nodeType":"YulFunctionCall","src":"3927:33:9"},"nodeType":"YulExpressionStatement","src":"3927:33:9"},{"nodeType":"YulAssignment","src":"3969:17:9","value":{"name":"value_1","nodeType":"YulIdentifier","src":"3979:7:9"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"3969:6:9"}]}]},"name":"abi_decode_tuple_t_addresst_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"3649:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"3660:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"3672:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"3680:6:9","type":""}],"src":"3604:388:9"},{"body":{"nodeType":"YulBlock","src":"4118:404:9","statements":[{"body":{"nodeType":"YulBlock","src":"4165:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4174:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4177:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4167:6:9"},"nodeType":"YulFunctionCall","src":"4167:12:9"},"nodeType":"YulExpressionStatement","src":"4167:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"4139:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"4148:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"4135:3:9"},"nodeType":"YulFunctionCall","src":"4135:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"4160:3:9","type":"","value":"128"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"4131:3:9"},"nodeType":"YulFunctionCall","src":"4131:33:9"},"nodeType":"YulIf","src":"4128:53:9"},{"nodeType":"YulVariableDeclaration","src":"4190:36:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4216:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4203:12:9"},"nodeType":"YulFunctionCall","src":"4203:23:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"4194:5:9","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"4260:5:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"4235:24:9"},"nodeType":"YulFunctionCall","src":"4235:31:9"},"nodeType":"YulExpressionStatement","src":"4235:31:9"},{"nodeType":"YulAssignment","src":"4275:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"4285:5:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"4275:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"4299:47:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4331:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"4342:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4327:3:9"},"nodeType":"YulFunctionCall","src":"4327:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4314:12:9"},"nodeType":"YulFunctionCall","src":"4314:32:9"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"4303:7:9","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"4380:7:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"4355:24:9"},"nodeType":"YulFunctionCall","src":"4355:33:9"},"nodeType":"YulExpressionStatement","src":"4355:33:9"},{"nodeType":"YulAssignment","src":"4397:17:9","value":{"name":"value_1","nodeType":"YulIdentifier","src":"4407:7:9"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"4397:6:9"}]},{"nodeType":"YulAssignment","src":"4423:42:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4450:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"4461:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4446:3:9"},"nodeType":"YulFunctionCall","src":"4446:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4433:12:9"},"nodeType":"YulFunctionCall","src":"4433:32:9"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"4423:6:9"}]},{"nodeType":"YulAssignment","src":"4474:42:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4501:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"4512:2:9","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4497:3:9"},"nodeType":"YulFunctionCall","src":"4497:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4484:12:9"},"nodeType":"YulFunctionCall","src":"4484:32:9"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"4474:6:9"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"4060:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"4071:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"4083:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"4091:6:9","type":""},{"name":"value2","nodeType":"YulTypedName","src":"4099:6:9","type":""},{"name":"value3","nodeType":"YulTypedName","src":"4107:6:9","type":""}],"src":"3997:525:9"},{"body":{"nodeType":"YulBlock","src":"4628:102:9","statements":[{"nodeType":"YulAssignment","src":"4638:26:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4650:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"4661:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4646:3:9"},"nodeType":"YulFunctionCall","src":"4646:18:9"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"4638:4:9"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4680:9:9"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"4695:6:9"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4711:3:9","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"4716:1:9","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"4707:3:9"},"nodeType":"YulFunctionCall","src":"4707:11:9"},{"kind":"number","nodeType":"YulLiteral","src":"4720:1:9","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"4703:3:9"},"nodeType":"YulFunctionCall","src":"4703:19:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"4691:3:9"},"nodeType":"YulFunctionCall","src":"4691:32:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"4673:6:9"},"nodeType":"YulFunctionCall","src":"4673:51:9"},"nodeType":"YulExpressionStatement","src":"4673:51:9"}]},"name":"abi_encode_tuple_t_address__to_t_address__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"4597:9:9","type":""},{"name":"value0","nodeType":"YulTypedName","src":"4608:6:9","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"4619:4:9","type":""}],"src":"4527:203:9"},{"body":{"nodeType":"YulBlock","src":"4858:671:9","statements":[{"body":{"nodeType":"YulBlock","src":"4904:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4913:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4916:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4906:6:9"},"nodeType":"YulFunctionCall","src":"4906:12:9"},"nodeType":"YulExpressionStatement","src":"4906:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"4879:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"4888:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"4875:3:9"},"nodeType":"YulFunctionCall","src":"4875:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"4900:2:9","type":"","value":"96"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"4871:3:9"},"nodeType":"YulFunctionCall","src":"4871:32:9"},"nodeType":"YulIf","src":"4868:52:9"},{"nodeType":"YulVariableDeclaration","src":"4929:36:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4955:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4942:12:9"},"nodeType":"YulFunctionCall","src":"4942:23:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"4933:5:9","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"4999:5:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"4974:24:9"},"nodeType":"YulFunctionCall","src":"4974:31:9"},"nodeType":"YulExpressionStatement","src":"4974:31:9"},{"nodeType":"YulAssignment","src":"5014:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"5024:5:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"5014:6:9"}]},{"nodeType":"YulAssignment","src":"5038:42:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5065:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"5076:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5061:3:9"},"nodeType":"YulFunctionCall","src":"5061:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5048:12:9"},"nodeType":"YulFunctionCall","src":"5048:32:9"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"5038:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"5089:46:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5120:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"5131:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5116:3:9"},"nodeType":"YulFunctionCall","src":"5116:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5103:12:9"},"nodeType":"YulFunctionCall","src":"5103:32:9"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"5093:6:9","type":""}]},{"nodeType":"YulVariableDeclaration","src":"5144:28:9","value":{"kind":"number","nodeType":"YulLiteral","src":"5154:18:9","type":"","value":"0xffffffffffffffff"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"5148:2:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"5199:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5208:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"5211:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"5201:6:9"},"nodeType":"YulFunctionCall","src":"5201:12:9"},"nodeType":"YulExpressionStatement","src":"5201:12:9"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"5187:6:9"},{"name":"_1","nodeType":"YulIdentifier","src":"5195:2:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"5184:2:9"},"nodeType":"YulFunctionCall","src":"5184:14:9"},"nodeType":"YulIf","src":"5181:34:9"},{"nodeType":"YulVariableDeclaration","src":"5224:32:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5238:9:9"},{"name":"offset","nodeType":"YulIdentifier","src":"5249:6:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5234:3:9"},"nodeType":"YulFunctionCall","src":"5234:22:9"},"variables":[{"name":"_2","nodeType":"YulTypedName","src":"5228:2:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"5304:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5313:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"5316:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"5306:6:9"},"nodeType":"YulFunctionCall","src":"5306:12:9"},"nodeType":"YulExpressionStatement","src":"5306:12:9"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"5283:2:9"},{"kind":"number","nodeType":"YulLiteral","src":"5287:4:9","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5279:3:9"},"nodeType":"YulFunctionCall","src":"5279:13:9"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"5294:7:9"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"5275:3:9"},"nodeType":"YulFunctionCall","src":"5275:27:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"5268:6:9"},"nodeType":"YulFunctionCall","src":"5268:35:9"},"nodeType":"YulIf","src":"5265:55:9"},{"nodeType":"YulVariableDeclaration","src":"5329:30:9","value":{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"5356:2:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5343:12:9"},"nodeType":"YulFunctionCall","src":"5343:16:9"},"variables":[{"name":"length","nodeType":"YulTypedName","src":"5333:6:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"5386:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5395:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"5398:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"5388:6:9"},"nodeType":"YulFunctionCall","src":"5388:12:9"},"nodeType":"YulExpressionStatement","src":"5388:12:9"}]},"condition":{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"5374:6:9"},{"name":"_1","nodeType":"YulIdentifier","src":"5382:2:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"5371:2:9"},"nodeType":"YulFunctionCall","src":"5371:14:9"},"nodeType":"YulIf","src":"5368:34:9"},{"body":{"nodeType":"YulBlock","src":"5452:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5461:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"5464:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"5454:6:9"},"nodeType":"YulFunctionCall","src":"5454:12:9"},"nodeType":"YulExpressionStatement","src":"5454:12:9"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"5425:2:9"},{"name":"length","nodeType":"YulIdentifier","src":"5429:6:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5421:3:9"},"nodeType":"YulFunctionCall","src":"5421:15:9"},{"kind":"number","nodeType":"YulLiteral","src":"5438:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5417:3:9"},"nodeType":"YulFunctionCall","src":"5417:24:9"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"5443:7:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"5414:2:9"},"nodeType":"YulFunctionCall","src":"5414:37:9"},"nodeType":"YulIf","src":"5411:57:9"},{"nodeType":"YulAssignment","src":"5477:21:9","value":{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"5491:2:9"},{"kind":"number","nodeType":"YulLiteral","src":"5495:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5487:3:9"},"nodeType":"YulFunctionCall","src":"5487:11:9"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"5477:6:9"}]},{"nodeType":"YulAssignment","src":"5507:16:9","value":{"name":"length","nodeType":"YulIdentifier","src":"5517:6:9"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"5507:6:9"}]}]},"name":"abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"4800:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"4811:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"4823:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"4831:6:9","type":""},{"name":"value2","nodeType":"YulTypedName","src":"4839:6:9","type":""},{"name":"value3","nodeType":"YulTypedName","src":"4847:6:9","type":""}],"src":"4735:794:9"},{"body":{"nodeType":"YulBlock","src":"5653:427:9","statements":[{"nodeType":"YulVariableDeclaration","src":"5663:12:9","value":{"kind":"number","nodeType":"YulLiteral","src":"5673:2:9","type":"","value":"32"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"5667:2:9","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5691:9:9"},{"name":"_1","nodeType":"YulIdentifier","src":"5702:2:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5684:6:9"},"nodeType":"YulFunctionCall","src":"5684:21:9"},"nodeType":"YulExpressionStatement","src":"5684:21:9"},{"nodeType":"YulVariableDeclaration","src":"5714:27:9","value":{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"5734:6:9"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"5728:5:9"},"nodeType":"YulFunctionCall","src":"5728:13:9"},"variables":[{"name":"length","nodeType":"YulTypedName","src":"5718:6:9","type":""}]},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5761:9:9"},{"name":"_1","nodeType":"YulIdentifier","src":"5772:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5757:3:9"},"nodeType":"YulFunctionCall","src":"5757:18:9"},{"name":"length","nodeType":"YulIdentifier","src":"5777:6:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5750:6:9"},"nodeType":"YulFunctionCall","src":"5750:34:9"},"nodeType":"YulExpressionStatement","src":"5750:34:9"},{"nodeType":"YulVariableDeclaration","src":"5793:10:9","value":{"kind":"number","nodeType":"YulLiteral","src":"5802:1:9","type":"","value":"0"},"variables":[{"name":"i","nodeType":"YulTypedName","src":"5797:1:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"5862:90:9","statements":[{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5891:9:9"},{"name":"i","nodeType":"YulIdentifier","src":"5902:1:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5887:3:9"},"nodeType":"YulFunctionCall","src":"5887:17:9"},{"kind":"number","nodeType":"YulLiteral","src":"5906:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5883:3:9"},"nodeType":"YulFunctionCall","src":"5883:26:9"},{"arguments":[{"arguments":[{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"5925:6:9"},{"name":"i","nodeType":"YulIdentifier","src":"5933:1:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5921:3:9"},"nodeType":"YulFunctionCall","src":"5921:14:9"},{"name":"_1","nodeType":"YulIdentifier","src":"5937:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5917:3:9"},"nodeType":"YulFunctionCall","src":"5917:23:9"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"5911:5:9"},"nodeType":"YulFunctionCall","src":"5911:30:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5876:6:9"},"nodeType":"YulFunctionCall","src":"5876:66:9"},"nodeType":"YulExpressionStatement","src":"5876:66:9"}]},"condition":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"5823:1:9"},{"name":"length","nodeType":"YulIdentifier","src":"5826:6:9"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"5820:2:9"},"nodeType":"YulFunctionCall","src":"5820:13:9"},"nodeType":"YulForLoop","post":{"nodeType":"YulBlock","src":"5834:19:9","statements":[{"nodeType":"YulAssignment","src":"5836:15:9","value":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"5845:1:9"},{"name":"_1","nodeType":"YulIdentifier","src":"5848:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5841:3:9"},"nodeType":"YulFunctionCall","src":"5841:10:9"},"variableNames":[{"name":"i","nodeType":"YulIdentifier","src":"5836:1:9"}]}]},"pre":{"nodeType":"YulBlock","src":"5816:3:9","statements":[]},"src":"5812:140:9"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5976:9:9"},{"name":"length","nodeType":"YulIdentifier","src":"5987:6:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5972:3:9"},"nodeType":"YulFunctionCall","src":"5972:22:9"},{"kind":"number","nodeType":"YulLiteral","src":"5996:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5968:3:9"},"nodeType":"YulFunctionCall","src":"5968:31:9"},{"kind":"number","nodeType":"YulLiteral","src":"6001:1:9","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5961:6:9"},"nodeType":"YulFunctionCall","src":"5961:42:9"},"nodeType":"YulExpressionStatement","src":"5961:42:9"},{"nodeType":"YulAssignment","src":"6012:62:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6028:9:9"},{"arguments":[{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"6047:6:9"},{"kind":"number","nodeType":"YulLiteral","src":"6055:2:9","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6043:3:9"},"nodeType":"YulFunctionCall","src":"6043:15:9"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6064:2:9","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"6060:3:9"},"nodeType":"YulFunctionCall","src":"6060:7:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"6039:3:9"},"nodeType":"YulFunctionCall","src":"6039:29:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6024:3:9"},"nodeType":"YulFunctionCall","src":"6024:45:9"},{"kind":"number","nodeType":"YulLiteral","src":"6071:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6020:3:9"},"nodeType":"YulFunctionCall","src":"6020:54:9"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"6012:4:9"}]}]},"name":"abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"5622:9:9","type":""},{"name":"value0","nodeType":"YulTypedName","src":"5633:6:9","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"5644:4:9","type":""}],"src":"5534:546:9"},{"body":{"nodeType":"YulBlock","src":"6189:279:9","statements":[{"body":{"nodeType":"YulBlock","src":"6235:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6244:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"6247:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"6237:6:9"},"nodeType":"YulFunctionCall","src":"6237:12:9"},"nodeType":"YulExpressionStatement","src":"6237:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"6210:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"6219:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"6206:3:9"},"nodeType":"YulFunctionCall","src":"6206:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"6231:2:9","type":"","value":"96"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"6202:3:9"},"nodeType":"YulFunctionCall","src":"6202:32:9"},"nodeType":"YulIf","src":"6199:52:9"},{"nodeType":"YulVariableDeclaration","src":"6260:36:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6286:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6273:12:9"},"nodeType":"YulFunctionCall","src":"6273:23:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"6264:5:9","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"6330:5:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"6305:24:9"},"nodeType":"YulFunctionCall","src":"6305:31:9"},"nodeType":"YulExpressionStatement","src":"6305:31:9"},{"nodeType":"YulAssignment","src":"6345:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"6355:5:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"6345:6:9"}]},{"nodeType":"YulAssignment","src":"6369:42:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6396:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"6407:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6392:3:9"},"nodeType":"YulFunctionCall","src":"6392:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6379:12:9"},"nodeType":"YulFunctionCall","src":"6379:32:9"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"6369:6:9"}]},{"nodeType":"YulAssignment","src":"6420:42:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6447:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"6458:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6443:3:9"},"nodeType":"YulFunctionCall","src":"6443:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6430:12:9"},"nodeType":"YulFunctionCall","src":"6430:32:9"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"6420:6:9"}]}]},"name":"abi_decode_tuple_t_addresst_uint256t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"6139:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"6150:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"6162:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"6170:6:9","type":""},{"name":"value2","nodeType":"YulTypedName","src":"6178:6:9","type":""}],"src":"6085:383:9"},{"body":{"nodeType":"YulBlock","src":"6537:648:9","statements":[{"body":{"nodeType":"YulBlock","src":"6586:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6595:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"6598:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"6588:6:9"},"nodeType":"YulFunctionCall","src":"6588:12:9"},"nodeType":"YulExpressionStatement","src":"6588:12:9"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"6565:6:9"},{"kind":"number","nodeType":"YulLiteral","src":"6573:4:9","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6561:3:9"},"nodeType":"YulFunctionCall","src":"6561:17:9"},{"name":"end","nodeType":"YulIdentifier","src":"6580:3:9"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"6557:3:9"},"nodeType":"YulFunctionCall","src":"6557:27:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"6550:6:9"},"nodeType":"YulFunctionCall","src":"6550:35:9"},"nodeType":"YulIf","src":"6547:55:9"},{"nodeType":"YulVariableDeclaration","src":"6611:30:9","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"6634:6:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6621:12:9"},"nodeType":"YulFunctionCall","src":"6621:20:9"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"6615:2:9","type":""}]},{"nodeType":"YulVariableDeclaration","src":"6650:14:9","value":{"kind":"number","nodeType":"YulLiteral","src":"6660:4:9","type":"","value":"0x20"},"variables":[{"name":"_2","nodeType":"YulTypedName","src":"6654:2:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"6703:22:9","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"6705:16:9"},"nodeType":"YulFunctionCall","src":"6705:18:9"},"nodeType":"YulExpressionStatement","src":"6705:18:9"}]},"condition":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"6679:2:9"},{"kind":"number","nodeType":"YulLiteral","src":"6683:18:9","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"6676:2:9"},"nodeType":"YulFunctionCall","src":"6676:26:9"},"nodeType":"YulIf","src":"6673:52:9"},{"nodeType":"YulVariableDeclaration","src":"6734:20:9","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6748:1:9","type":"","value":"5"},{"name":"_1","nodeType":"YulIdentifier","src":"6751:2:9"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"6744:3:9"},"nodeType":"YulFunctionCall","src":"6744:10:9"},"variables":[{"name":"_3","nodeType":"YulTypedName","src":"6738:2:9","type":""}]},{"nodeType":"YulVariableDeclaration","src":"6763:39:9","value":{"arguments":[{"arguments":[{"name":"_3","nodeType":"YulIdentifier","src":"6794:2:9"},{"name":"_2","nodeType":"YulIdentifier","src":"6798:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6790:3:9"},"nodeType":"YulFunctionCall","src":"6790:11:9"}],"functionName":{"name":"allocate_memory","nodeType":"YulIdentifier","src":"6774:15:9"},"nodeType":"YulFunctionCall","src":"6774:28:9"},"variables":[{"name":"dst","nodeType":"YulTypedName","src":"6767:3:9","type":""}]},{"nodeType":"YulVariableDeclaration","src":"6811:16:9","value":{"name":"dst","nodeType":"YulIdentifier","src":"6824:3:9"},"variables":[{"name":"dst_1","nodeType":"YulTypedName","src":"6815:5:9","type":""}]},{"expression":{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"6843:3:9"},{"name":"_1","nodeType":"YulIdentifier","src":"6848:2:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6836:6:9"},"nodeType":"YulFunctionCall","src":"6836:15:9"},"nodeType":"YulExpressionStatement","src":"6836:15:9"},{"nodeType":"YulAssignment","src":"6860:19:9","value":{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"6871:3:9"},{"name":"_2","nodeType":"YulIdentifier","src":"6876:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6867:3:9"},"nodeType":"YulFunctionCall","src":"6867:12:9"},"variableNames":[{"name":"dst","nodeType":"YulIdentifier","src":"6860:3:9"}]},{"nodeType":"YulVariableDeclaration","src":"6888:38:9","value":{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"6910:6:9"},{"name":"_3","nodeType":"YulIdentifier","src":"6918:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6906:3:9"},"nodeType":"YulFunctionCall","src":"6906:15:9"},{"name":"_2","nodeType":"YulIdentifier","src":"6923:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6902:3:9"},"nodeType":"YulFunctionCall","src":"6902:24:9"},"variables":[{"name":"srcEnd","nodeType":"YulTypedName","src":"6892:6:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"6954:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6963:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"6966:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"6956:6:9"},"nodeType":"YulFunctionCall","src":"6956:12:9"},"nodeType":"YulExpressionStatement","src":"6956:12:9"}]},"condition":{"arguments":[{"name":"srcEnd","nodeType":"YulIdentifier","src":"6941:6:9"},{"name":"end","nodeType":"YulIdentifier","src":"6949:3:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"6938:2:9"},"nodeType":"YulFunctionCall","src":"6938:15:9"},"nodeType":"YulIf","src":"6935:35:9"},{"nodeType":"YulVariableDeclaration","src":"6979:26:9","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"6994:6:9"},{"name":"_2","nodeType":"YulIdentifier","src":"7002:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6990:3:9"},"nodeType":"YulFunctionCall","src":"6990:15:9"},"variables":[{"name":"src","nodeType":"YulTypedName","src":"6983:3:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"7070:86:9","statements":[{"expression":{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"7091:3:9"},{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"7109:3:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7096:12:9"},"nodeType":"YulFunctionCall","src":"7096:17:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7084:6:9"},"nodeType":"YulFunctionCall","src":"7084:30:9"},"nodeType":"YulExpressionStatement","src":"7084:30:9"},{"nodeType":"YulAssignment","src":"7127:19:9","value":{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"7138:3:9"},{"name":"_2","nodeType":"YulIdentifier","src":"7143:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7134:3:9"},"nodeType":"YulFunctionCall","src":"7134:12:9"},"variableNames":[{"name":"dst","nodeType":"YulIdentifier","src":"7127:3:9"}]}]},"condition":{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"7025:3:9"},{"name":"srcEnd","nodeType":"YulIdentifier","src":"7030:6:9"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"7022:2:9"},"nodeType":"YulFunctionCall","src":"7022:15:9"},"nodeType":"YulForLoop","post":{"nodeType":"YulBlock","src":"7038:23:9","statements":[{"nodeType":"YulAssignment","src":"7040:19:9","value":{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"7051:3:9"},{"name":"_2","nodeType":"YulIdentifier","src":"7056:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7047:3:9"},"nodeType":"YulFunctionCall","src":"7047:12:9"},"variableNames":[{"name":"src","nodeType":"YulIdentifier","src":"7040:3:9"}]}]},"pre":{"nodeType":"YulBlock","src":"7018:3:9","statements":[]},"src":"7014:142:9"},{"nodeType":"YulAssignment","src":"7165:14:9","value":{"name":"dst_1","nodeType":"YulIdentifier","src":"7174:5:9"},"variableNames":[{"name":"array","nodeType":"YulIdentifier","src":"7165:5:9"}]}]},"name":"abi_decode_array_uint256_dyn","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"6511:6:9","type":""},{"name":"end","nodeType":"YulTypedName","src":"6519:3:9","type":""}],"returnVariables":[{"name":"array","nodeType":"YulTypedName","src":"6527:5:9","type":""}],"src":"6473:712:9"},{"body":{"nodeType":"YulBlock","src":"7387:874:9","statements":[{"body":{"nodeType":"YulBlock","src":"7434:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7443:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"7446:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7436:6:9"},"nodeType":"YulFunctionCall","src":"7436:12:9"},"nodeType":"YulExpressionStatement","src":"7436:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"7408:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"7417:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"7404:3:9"},"nodeType":"YulFunctionCall","src":"7404:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"7429:3:9","type":"","value":"160"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"7400:3:9"},"nodeType":"YulFunctionCall","src":"7400:33:9"},"nodeType":"YulIf","src":"7397:53:9"},{"nodeType":"YulVariableDeclaration","src":"7459:36:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7485:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7472:12:9"},"nodeType":"YulFunctionCall","src":"7472:23:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"7463:5:9","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"7529:5:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"7504:24:9"},"nodeType":"YulFunctionCall","src":"7504:31:9"},"nodeType":"YulExpressionStatement","src":"7504:31:9"},{"nodeType":"YulAssignment","src":"7544:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"7554:5:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"7544:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"7568:47:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7600:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"7611:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7596:3:9"},"nodeType":"YulFunctionCall","src":"7596:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7583:12:9"},"nodeType":"YulFunctionCall","src":"7583:32:9"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"7572:7:9","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"7649:7:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"7624:24:9"},"nodeType":"YulFunctionCall","src":"7624:33:9"},"nodeType":"YulExpressionStatement","src":"7624:33:9"},{"nodeType":"YulAssignment","src":"7666:17:9","value":{"name":"value_1","nodeType":"YulIdentifier","src":"7676:7:9"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"7666:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"7692:46:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7723:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"7734:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7719:3:9"},"nodeType":"YulFunctionCall","src":"7719:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7706:12:9"},"nodeType":"YulFunctionCall","src":"7706:32:9"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"7696:6:9","type":""}]},{"nodeType":"YulVariableDeclaration","src":"7747:28:9","value":{"kind":"number","nodeType":"YulLiteral","src":"7757:18:9","type":"","value":"0xffffffffffffffff"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"7751:2:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"7802:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7811:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"7814:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7804:6:9"},"nodeType":"YulFunctionCall","src":"7804:12:9"},"nodeType":"YulExpressionStatement","src":"7804:12:9"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"7790:6:9"},{"name":"_1","nodeType":"YulIdentifier","src":"7798:2:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"7787:2:9"},"nodeType":"YulFunctionCall","src":"7787:14:9"},"nodeType":"YulIf","src":"7784:34:9"},{"nodeType":"YulAssignment","src":"7827:71:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7870:9:9"},{"name":"offset","nodeType":"YulIdentifier","src":"7881:6:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7866:3:9"},"nodeType":"YulFunctionCall","src":"7866:22:9"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"7890:7:9"}],"functionName":{"name":"abi_decode_array_uint256_dyn","nodeType":"YulIdentifier","src":"7837:28:9"},"nodeType":"YulFunctionCall","src":"7837:61:9"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"7827:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"7907:48:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7940:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"7951:2:9","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7936:3:9"},"nodeType":"YulFunctionCall","src":"7936:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7923:12:9"},"nodeType":"YulFunctionCall","src":"7923:32:9"},"variables":[{"name":"offset_1","nodeType":"YulTypedName","src":"7911:8:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"7984:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7993:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"7996:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7986:6:9"},"nodeType":"YulFunctionCall","src":"7986:12:9"},"nodeType":"YulExpressionStatement","src":"7986:12:9"}]},"condition":{"arguments":[{"name":"offset_1","nodeType":"YulIdentifier","src":"7970:8:9"},{"name":"_1","nodeType":"YulIdentifier","src":"7980:2:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"7967:2:9"},"nodeType":"YulFunctionCall","src":"7967:16:9"},"nodeType":"YulIf","src":"7964:36:9"},{"nodeType":"YulAssignment","src":"8009:73:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8052:9:9"},{"name":"offset_1","nodeType":"YulIdentifier","src":"8063:8:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8048:3:9"},"nodeType":"YulFunctionCall","src":"8048:24:9"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"8074:7:9"}],"functionName":{"name":"abi_decode_array_uint256_dyn","nodeType":"YulIdentifier","src":"8019:28:9"},"nodeType":"YulFunctionCall","src":"8019:63:9"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"8009:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"8091:49:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8124:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"8135:3:9","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8120:3:9"},"nodeType":"YulFunctionCall","src":"8120:19:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8107:12:9"},"nodeType":"YulFunctionCall","src":"8107:33:9"},"variables":[{"name":"offset_2","nodeType":"YulTypedName","src":"8095:8:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"8169:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"8178:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"8181:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"8171:6:9"},"nodeType":"YulFunctionCall","src":"8171:12:9"},"nodeType":"YulExpressionStatement","src":"8171:12:9"}]},"condition":{"arguments":[{"name":"offset_2","nodeType":"YulIdentifier","src":"8155:8:9"},{"name":"_1","nodeType":"YulIdentifier","src":"8165:2:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"8152:2:9"},"nodeType":"YulFunctionCall","src":"8152:16:9"},"nodeType":"YulIf","src":"8149:36:9"},{"nodeType":"YulAssignment","src":"8194:61:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8225:9:9"},{"name":"offset_2","nodeType":"YulIdentifier","src":"8236:8:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8221:3:9"},"nodeType":"YulFunctionCall","src":"8221:24:9"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"8247:7:9"}],"functionName":{"name":"abi_decode_bytes","nodeType":"YulIdentifier","src":"8204:16:9"},"nodeType":"YulFunctionCall","src":"8204:51:9"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"8194:6:9"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_array$_t_uint256_$dyn_memory_ptrt_array$_t_uint256_$dyn_memory_ptrt_bytes_memory_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"7321:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"7332:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"7344:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"7352:6:9","type":""},{"name":"value2","nodeType":"YulTypedName","src":"7360:6:9","type":""},{"name":"value3","nodeType":"YulTypedName","src":"7368:6:9","type":""},{"name":"value4","nodeType":"YulTypedName","src":"7376:6:9","type":""}],"src":"7190:1071:9"},{"body":{"nodeType":"YulBlock","src":"8367:76:9","statements":[{"nodeType":"YulAssignment","src":"8377:26:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8389:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"8400:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8385:3:9"},"nodeType":"YulFunctionCall","src":"8385:18:9"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"8377:4:9"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8419:9:9"},{"name":"value0","nodeType":"YulIdentifier","src":"8430:6:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8412:6:9"},"nodeType":"YulFunctionCall","src":"8412:25:9"},"nodeType":"YulExpressionStatement","src":"8412:25:9"}]},"name":"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"8336:9:9","type":""},{"name":"value0","nodeType":"YulTypedName","src":"8347:6:9","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"8358:4:9","type":""}],"src":"8266:177:9"},{"body":{"nodeType":"YulBlock","src":"8518:110:9","statements":[{"body":{"nodeType":"YulBlock","src":"8564:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"8573:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"8576:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"8566:6:9"},"nodeType":"YulFunctionCall","src":"8566:12:9"},"nodeType":"YulExpressionStatement","src":"8566:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"8539:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"8548:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"8535:3:9"},"nodeType":"YulFunctionCall","src":"8535:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"8560:2:9","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"8531:3:9"},"nodeType":"YulFunctionCall","src":"8531:32:9"},"nodeType":"YulIf","src":"8528:52:9"},{"nodeType":"YulAssignment","src":"8589:33:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8612:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8599:12:9"},"nodeType":"YulFunctionCall","src":"8599:23:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"8589:6:9"}]}]},"name":"abi_decode_tuple_t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"8484:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"8495:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"8507:6:9","type":""}],"src":"8448:180:9"},{"body":{"nodeType":"YulBlock","src":"8780:587:9","statements":[{"body":{"nodeType":"YulBlock","src":"8827:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"8836:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"8839:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"8829:6:9"},"nodeType":"YulFunctionCall","src":"8829:12:9"},"nodeType":"YulExpressionStatement","src":"8829:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"8801:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"8810:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"8797:3:9"},"nodeType":"YulFunctionCall","src":"8797:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"8822:3:9","type":"","value":"160"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"8793:3:9"},"nodeType":"YulFunctionCall","src":"8793:33:9"},"nodeType":"YulIf","src":"8790:53:9"},{"nodeType":"YulVariableDeclaration","src":"8852:36:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8878:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8865:12:9"},"nodeType":"YulFunctionCall","src":"8865:23:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"8856:5:9","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"8922:5:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"8897:24:9"},"nodeType":"YulFunctionCall","src":"8897:31:9"},"nodeType":"YulExpressionStatement","src":"8897:31:9"},{"nodeType":"YulAssignment","src":"8937:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"8947:5:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"8937:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"8961:47:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8993:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"9004:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8989:3:9"},"nodeType":"YulFunctionCall","src":"8989:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8976:12:9"},"nodeType":"YulFunctionCall","src":"8976:32:9"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"8965:7:9","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"9042:7:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"9017:24:9"},"nodeType":"YulFunctionCall","src":"9017:33:9"},"nodeType":"YulExpressionStatement","src":"9017:33:9"},{"nodeType":"YulAssignment","src":"9059:17:9","value":{"name":"value_1","nodeType":"YulIdentifier","src":"9069:7:9"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"9059:6:9"}]},{"nodeType":"YulAssignment","src":"9085:42:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9112:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"9123:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9108:3:9"},"nodeType":"YulFunctionCall","src":"9108:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"9095:12:9"},"nodeType":"YulFunctionCall","src":"9095:32:9"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"9085:6:9"}]},{"nodeType":"YulAssignment","src":"9136:42:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9163:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"9174:2:9","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9159:3:9"},"nodeType":"YulFunctionCall","src":"9159:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"9146:12:9"},"nodeType":"YulFunctionCall","src":"9146:32:9"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"9136:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"9187:47:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9218:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"9229:3:9","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9214:3:9"},"nodeType":"YulFunctionCall","src":"9214:19:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"9201:12:9"},"nodeType":"YulFunctionCall","src":"9201:33:9"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"9191:6:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"9277:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9286:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"9289:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"9279:6:9"},"nodeType":"YulFunctionCall","src":"9279:12:9"},"nodeType":"YulExpressionStatement","src":"9279:12:9"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"9249:6:9"},{"kind":"number","nodeType":"YulLiteral","src":"9257:18:9","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"9246:2:9"},"nodeType":"YulFunctionCall","src":"9246:30:9"},"nodeType":"YulIf","src":"9243:50:9"},{"nodeType":"YulAssignment","src":"9302:59:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9333:9:9"},{"name":"offset","nodeType":"YulIdentifier","src":"9344:6:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9329:3:9"},"nodeType":"YulFunctionCall","src":"9329:22:9"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"9353:7:9"}],"functionName":{"name":"abi_decode_bytes","nodeType":"YulIdentifier","src":"9312:16:9"},"nodeType":"YulFunctionCall","src":"9312:49:9"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"9302:6:9"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256t_uint256t_bytes_memory_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"8714:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"8725:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"8737:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"8745:6:9","type":""},{"name":"value2","nodeType":"YulTypedName","src":"8753:6:9","type":""},{"name":"value3","nodeType":"YulTypedName","src":"8761:6:9","type":""},{"name":"value4","nodeType":"YulTypedName","src":"8769:6:9","type":""}],"src":"8633:734:9"},{"body":{"nodeType":"YulBlock","src":"9529:188:9","statements":[{"nodeType":"YulAssignment","src":"9539:26:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9551:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"9562:2:9","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9547:3:9"},"nodeType":"YulFunctionCall","src":"9547:18:9"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"9539:4:9"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9581:9:9"},{"name":"value0","nodeType":"YulIdentifier","src":"9592:6:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9574:6:9"},"nodeType":"YulFunctionCall","src":"9574:25:9"},"nodeType":"YulExpressionStatement","src":"9574:25:9"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9619:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"9630:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9615:3:9"},"nodeType":"YulFunctionCall","src":"9615:18:9"},{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"9639:6:9"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9655:3:9","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"9660:1:9","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"9651:3:9"},"nodeType":"YulFunctionCall","src":"9651:11:9"},{"kind":"number","nodeType":"YulLiteral","src":"9664:1:9","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"9647:3:9"},"nodeType":"YulFunctionCall","src":"9647:19:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"9635:3:9"},"nodeType":"YulFunctionCall","src":"9635:32:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9608:6:9"},"nodeType":"YulFunctionCall","src":"9608:60:9"},"nodeType":"YulExpressionStatement","src":"9608:60:9"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9688:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"9699:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9684:3:9"},"nodeType":"YulFunctionCall","src":"9684:18:9"},{"name":"value2","nodeType":"YulIdentifier","src":"9704:6:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9677:6:9"},"nodeType":"YulFunctionCall","src":"9677:34:9"},"nodeType":"YulExpressionStatement","src":"9677:34:9"}]},"name":"abi_encode_tuple_t_uint256_t_address_t_uint256__to_t_uint256_t_address_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"9482:9:9","type":""},{"name":"value2","nodeType":"YulTypedName","src":"9493:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"9501:6:9","type":""},{"name":"value0","nodeType":"YulTypedName","src":"9509:6:9","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"9520:4:9","type":""}],"src":"9372:345:9"},{"body":{"nodeType":"YulBlock","src":"9792:177:9","statements":[{"body":{"nodeType":"YulBlock","src":"9838:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9847:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"9850:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"9840:6:9"},"nodeType":"YulFunctionCall","src":"9840:12:9"},"nodeType":"YulExpressionStatement","src":"9840:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"9813:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"9822:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"9809:3:9"},"nodeType":"YulFunctionCall","src":"9809:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"9834:2:9","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"9805:3:9"},"nodeType":"YulFunctionCall","src":"9805:32:9"},"nodeType":"YulIf","src":"9802:52:9"},{"nodeType":"YulVariableDeclaration","src":"9863:36:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9889:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"9876:12:9"},"nodeType":"YulFunctionCall","src":"9876:23:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"9867:5:9","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"9933:5:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"9908:24:9"},"nodeType":"YulFunctionCall","src":"9908:31:9"},"nodeType":"YulExpressionStatement","src":"9908:31:9"},{"nodeType":"YulAssignment","src":"9948:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"9958:5:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"9948:6:9"}]}]},"name":"abi_decode_tuple_t_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"9758:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"9769:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"9781:6:9","type":""}],"src":"9722:247:9"},{"body":{"nodeType":"YulBlock","src":"10006:95:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10023:1:9","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10030:3:9","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"10035:10:9","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"10026:3:9"},"nodeType":"YulFunctionCall","src":"10026:20:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10016:6:9"},"nodeType":"YulFunctionCall","src":"10016:31:9"},"nodeType":"YulExpressionStatement","src":"10016:31:9"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10063:1:9","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"10066:4:9","type":"","value":"0x32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10056:6:9"},"nodeType":"YulFunctionCall","src":"10056:15:9"},"nodeType":"YulExpressionStatement","src":"10056:15:9"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10087:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"10090:4:9","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"10080:6:9"},"nodeType":"YulFunctionCall","src":"10080:15:9"},"nodeType":"YulExpressionStatement","src":"10080:15:9"}]},"name":"panic_error_0x32","nodeType":"YulFunctionDefinition","src":"9974:127:9"},{"body":{"nodeType":"YulBlock","src":"10173:206:9","statements":[{"body":{"nodeType":"YulBlock","src":"10219:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10228:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"10231:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"10221:6:9"},"nodeType":"YulFunctionCall","src":"10221:12:9"},"nodeType":"YulExpressionStatement","src":"10221:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"10194:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"10203:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"10190:3:9"},"nodeType":"YulFunctionCall","src":"10190:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"10215:2:9","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"10186:3:9"},"nodeType":"YulFunctionCall","src":"10186:32:9"},"nodeType":"YulIf","src":"10183:52:9"},{"nodeType":"YulVariableDeclaration","src":"10244:36:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10270:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"10257:12:9"},"nodeType":"YulFunctionCall","src":"10257:23:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"10248:5:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"10333:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10342:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"10345:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"10335:6:9"},"nodeType":"YulFunctionCall","src":"10335:12:9"},"nodeType":"YulExpressionStatement","src":"10335:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"10302:5:9"},{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"10323:5:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"10316:6:9"},"nodeType":"YulFunctionCall","src":"10316:13:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"10309:6:9"},"nodeType":"YulFunctionCall","src":"10309:21:9"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"10299:2:9"},"nodeType":"YulFunctionCall","src":"10299:32:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"10292:6:9"},"nodeType":"YulFunctionCall","src":"10292:40:9"},"nodeType":"YulIf","src":"10289:60:9"},{"nodeType":"YulAssignment","src":"10358:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"10368:5:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"10358:6:9"}]}]},"name":"abi_decode_tuple_t_bool","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"10139:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"10150:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"10162:6:9","type":""}],"src":"10106:273:9"},{"body":{"nodeType":"YulBlock","src":"10535:234:9","statements":[{"nodeType":"YulAssignment","src":"10545:26:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10557:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"10568:2:9","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10553:3:9"},"nodeType":"YulFunctionCall","src":"10553:18:9"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"10545:4:9"}]},{"nodeType":"YulVariableDeclaration","src":"10580:29:9","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10598:3:9","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"10603:1:9","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"10594:3:9"},"nodeType":"YulFunctionCall","src":"10594:11:9"},{"kind":"number","nodeType":"YulLiteral","src":"10607:1:9","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"10590:3:9"},"nodeType":"YulFunctionCall","src":"10590:19:9"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"10584:2:9","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10625:9:9"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"10640:6:9"},{"name":"_1","nodeType":"YulIdentifier","src":"10648:2:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"10636:3:9"},"nodeType":"YulFunctionCall","src":"10636:15:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10618:6:9"},"nodeType":"YulFunctionCall","src":"10618:34:9"},"nodeType":"YulExpressionStatement","src":"10618:34:9"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10672:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"10683:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10668:3:9"},"nodeType":"YulFunctionCall","src":"10668:18:9"},{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"10692:6:9"},{"name":"_1","nodeType":"YulIdentifier","src":"10700:2:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"10688:3:9"},"nodeType":"YulFunctionCall","src":"10688:15:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10661:6:9"},"nodeType":"YulFunctionCall","src":"10661:43:9"},"nodeType":"YulExpressionStatement","src":"10661:43:9"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10724:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"10735:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10720:3:9"},"nodeType":"YulFunctionCall","src":"10720:18:9"},{"arguments":[{"arguments":[{"name":"value2","nodeType":"YulIdentifier","src":"10754:6:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"10747:6:9"},"nodeType":"YulFunctionCall","src":"10747:14:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"10740:6:9"},"nodeType":"YulFunctionCall","src":"10740:22:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10713:6:9"},"nodeType":"YulFunctionCall","src":"10713:50:9"},"nodeType":"YulExpressionStatement","src":"10713:50:9"}]},"name":"abi_encode_tuple_t_address_t_address_t_bool__to_t_address_t_address_t_bool__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"10488:9:9","type":""},{"name":"value2","nodeType":"YulTypedName","src":"10499:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"10507:6:9","type":""},{"name":"value0","nodeType":"YulTypedName","src":"10515:6:9","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"10526:4:9","type":""}],"src":"10384:385:9"},{"body":{"nodeType":"YulBlock","src":"10806:95:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10823:1:9","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10830:3:9","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"10835:10:9","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"10826:3:9"},"nodeType":"YulFunctionCall","src":"10826:20:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10816:6:9"},"nodeType":"YulFunctionCall","src":"10816:31:9"},"nodeType":"YulExpressionStatement","src":"10816:31:9"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10863:1:9","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"10866:4:9","type":"","value":"0x11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10856:6:9"},"nodeType":"YulFunctionCall","src":"10856:15:9"},"nodeType":"YulExpressionStatement","src":"10856:15:9"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10887:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"10890:4:9","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"10880:6:9"},"nodeType":"YulFunctionCall","src":"10880:15:9"},"nodeType":"YulExpressionStatement","src":"10880:15:9"}]},"name":"panic_error_0x11","nodeType":"YulFunctionDefinition","src":"10774:127:9"},{"body":{"nodeType":"YulBlock","src":"10953:88:9","statements":[{"body":{"nodeType":"YulBlock","src":"10984:22:9","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x11","nodeType":"YulIdentifier","src":"10986:16:9"},"nodeType":"YulFunctionCall","src":"10986:18:9"},"nodeType":"YulExpressionStatement","src":"10986:18:9"}]},"condition":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"10969:5:9"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10980:1:9","type":"","value":"0"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"10976:3:9"},"nodeType":"YulFunctionCall","src":"10976:6:9"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"10966:2:9"},"nodeType":"YulFunctionCall","src":"10966:17:9"},"nodeType":"YulIf","src":"10963:43:9"},{"nodeType":"YulAssignment","src":"11015:20:9","value":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"11026:5:9"},{"kind":"number","nodeType":"YulLiteral","src":"11033:1:9","type":"","value":"1"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11022:3:9"},"nodeType":"YulFunctionCall","src":"11022:13:9"},"variableNames":[{"name":"ret","nodeType":"YulIdentifier","src":"11015:3:9"}]}]},"name":"increment_t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"value","nodeType":"YulTypedName","src":"10935:5:9","type":""}],"returnVariables":[{"name":"ret","nodeType":"YulTypedName","src":"10945:3:9","type":""}],"src":"10906:135:9"},{"body":{"nodeType":"YulBlock","src":"11203:218:9","statements":[{"nodeType":"YulAssignment","src":"11213:26:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11225:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"11236:2:9","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11221:3:9"},"nodeType":"YulFunctionCall","src":"11221:18:9"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"11213:4:9"}]},{"nodeType":"YulVariableDeclaration","src":"11248:29:9","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"11266:3:9","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"11271:1:9","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"11262:3:9"},"nodeType":"YulFunctionCall","src":"11262:11:9"},{"kind":"number","nodeType":"YulLiteral","src":"11275:1:9","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"11258:3:9"},"nodeType":"YulFunctionCall","src":"11258:19:9"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"11252:2:9","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11293:9:9"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"11308:6:9"},{"name":"_1","nodeType":"YulIdentifier","src":"11316:2:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"11304:3:9"},"nodeType":"YulFunctionCall","src":"11304:15:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"11286:6:9"},"nodeType":"YulFunctionCall","src":"11286:34:9"},"nodeType":"YulExpressionStatement","src":"11286:34:9"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11340:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"11351:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11336:3:9"},"nodeType":"YulFunctionCall","src":"11336:18:9"},{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"11360:6:9"},{"name":"_1","nodeType":"YulIdentifier","src":"11368:2:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"11356:3:9"},"nodeType":"YulFunctionCall","src":"11356:15:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"11329:6:9"},"nodeType":"YulFunctionCall","src":"11329:43:9"},"nodeType":"YulExpressionStatement","src":"11329:43:9"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11392:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"11403:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11388:3:9"},"nodeType":"YulFunctionCall","src":"11388:18:9"},{"name":"value2","nodeType":"YulIdentifier","src":"11408:6:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"11381:6:9"},"nodeType":"YulFunctionCall","src":"11381:34:9"},"nodeType":"YulExpressionStatement","src":"11381:34:9"}]},"name":"abi_encode_tuple_t_address_t_address_t_uint256__to_t_address_t_address_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"11156:9:9","type":""},{"name":"value2","nodeType":"YulTypedName","src":"11167:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"11175:6:9","type":""},{"name":"value0","nodeType":"YulTypedName","src":"11183:6:9","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"11194:4:9","type":""}],"src":"11046:375:9"},{"body":{"nodeType":"YulBlock","src":"11507:170:9","statements":[{"body":{"nodeType":"YulBlock","src":"11553:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"11562:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"11565:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"11555:6:9"},"nodeType":"YulFunctionCall","src":"11555:12:9"},"nodeType":"YulExpressionStatement","src":"11555:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"11528:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"11537:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"11524:3:9"},"nodeType":"YulFunctionCall","src":"11524:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"11549:2:9","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"11520:3:9"},"nodeType":"YulFunctionCall","src":"11520:32:9"},"nodeType":"YulIf","src":"11517:52:9"},{"nodeType":"YulVariableDeclaration","src":"11578:29:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11597:9:9"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"11591:5:9"},"nodeType":"YulFunctionCall","src":"11591:16:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"11582:5:9","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"11641:5:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"11616:24:9"},"nodeType":"YulFunctionCall","src":"11616:31:9"},"nodeType":"YulExpressionStatement","src":"11616:31:9"},{"nodeType":"YulAssignment","src":"11656:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"11666:5:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"11656:6:9"}]}]},"name":"abi_decode_tuple_t_address_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"11473:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"11484:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"11496:6:9","type":""}],"src":"11426:251:9"},{"body":{"nodeType":"YulBlock","src":"11811:259:9","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11828:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"11839:2:9","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"11821:6:9"},"nodeType":"YulFunctionCall","src":"11821:21:9"},"nodeType":"YulExpressionStatement","src":"11821:21:9"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11862:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"11873:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11858:3:9"},"nodeType":"YulFunctionCall","src":"11858:18:9"},{"name":"value1","nodeType":"YulIdentifier","src":"11878:6:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"11851:6:9"},"nodeType":"YulFunctionCall","src":"11851:34:9"},"nodeType":"YulExpressionStatement","src":"11851:34:9"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11911:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"11922:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11907:3:9"},"nodeType":"YulFunctionCall","src":"11907:18:9"},{"name":"value0","nodeType":"YulIdentifier","src":"11927:6:9"},{"name":"value1","nodeType":"YulIdentifier","src":"11935:6:9"}],"functionName":{"name":"calldatacopy","nodeType":"YulIdentifier","src":"11894:12:9"},"nodeType":"YulFunctionCall","src":"11894:48:9"},"nodeType":"YulExpressionStatement","src":"11894:48:9"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11966:9:9"},{"name":"value1","nodeType":"YulIdentifier","src":"11977:6:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11962:3:9"},"nodeType":"YulFunctionCall","src":"11962:22:9"},{"kind":"number","nodeType":"YulLiteral","src":"11986:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11958:3:9"},"nodeType":"YulFunctionCall","src":"11958:31:9"},{"kind":"number","nodeType":"YulLiteral","src":"11991:1:9","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"11951:6:9"},"nodeType":"YulFunctionCall","src":"11951:42:9"},"nodeType":"YulExpressionStatement","src":"11951:42:9"},{"nodeType":"YulAssignment","src":"12002:62:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"12018:9:9"},{"arguments":[{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"12037:6:9"},{"kind":"number","nodeType":"YulLiteral","src":"12045:2:9","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"12033:3:9"},"nodeType":"YulFunctionCall","src":"12033:15:9"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"12054:2:9","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"12050:3:9"},"nodeType":"YulFunctionCall","src":"12050:7:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"12029:3:9"},"nodeType":"YulFunctionCall","src":"12029:29:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"12014:3:9"},"nodeType":"YulFunctionCall","src":"12014:45:9"},{"kind":"number","nodeType":"YulLiteral","src":"12061:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"12010:3:9"},"nodeType":"YulFunctionCall","src":"12010:54:9"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"12002:4:9"}]}]},"name":"abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"11772:9:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"11783:6:9","type":""},{"name":"value0","nodeType":"YulTypedName","src":"11791:6:9","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"11802:4:9","type":""}],"src":"11682:388:9"},{"body":{"nodeType":"YulBlock","src":"12123:77:9","statements":[{"nodeType":"YulAssignment","src":"12133:16:9","value":{"arguments":[{"name":"x","nodeType":"YulIdentifier","src":"12144:1:9"},{"name":"y","nodeType":"YulIdentifier","src":"12147:1:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"12140:3:9"},"nodeType":"YulFunctionCall","src":"12140:9:9"},"variableNames":[{"name":"sum","nodeType":"YulIdentifier","src":"12133:3:9"}]},{"body":{"nodeType":"YulBlock","src":"12172:22:9","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x11","nodeType":"YulIdentifier","src":"12174:16:9"},"nodeType":"YulFunctionCall","src":"12174:18:9"},"nodeType":"YulExpressionStatement","src":"12174:18:9"}]},"condition":{"arguments":[{"name":"x","nodeType":"YulIdentifier","src":"12164:1:9"},{"name":"sum","nodeType":"YulIdentifier","src":"12167:3:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"12161:2:9"},"nodeType":"YulFunctionCall","src":"12161:10:9"},"nodeType":"YulIf","src":"12158:36:9"}]},"name":"checked_add_t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"x","nodeType":"YulTypedName","src":"12106:1:9","type":""},{"name":"y","nodeType":"YulTypedName","src":"12109:1:9","type":""}],"returnVariables":[{"name":"sum","nodeType":"YulTypedName","src":"12115:3:9","type":""}],"src":"12075:125:9"},{"body":{"nodeType":"YulBlock","src":"12328:258:9","statements":[{"body":{"nodeType":"YulBlock","src":"12374:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"12383:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"12386:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"12376:6:9"},"nodeType":"YulFunctionCall","src":"12376:12:9"},"nodeType":"YulExpressionStatement","src":"12376:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"12349:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"12358:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"12345:3:9"},"nodeType":"YulFunctionCall","src":"12345:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"12370:2:9","type":"","value":"96"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"12341:3:9"},"nodeType":"YulFunctionCall","src":"12341:32:9"},"nodeType":"YulIf","src":"12338:52:9"},{"nodeType":"YulAssignment","src":"12399:26:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"12415:9:9"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"12409:5:9"},"nodeType":"YulFunctionCall","src":"12409:16:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"12399:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"12434:38:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"12457:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"12468:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"12453:3:9"},"nodeType":"YulFunctionCall","src":"12453:18:9"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"12447:5:9"},"nodeType":"YulFunctionCall","src":"12447:25:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"12438:5:9","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"12506:5:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"12481:24:9"},"nodeType":"YulFunctionCall","src":"12481:31:9"},"nodeType":"YulExpressionStatement","src":"12481:31:9"},{"nodeType":"YulAssignment","src":"12521:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"12531:5:9"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"12521:6:9"}]},{"nodeType":"YulAssignment","src":"12545:35:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"12565:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"12576:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"12561:3:9"},"nodeType":"YulFunctionCall","src":"12561:18:9"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"12555:5:9"},"nodeType":"YulFunctionCall","src":"12555:25:9"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"12545:6:9"}]}]},"name":"abi_decode_tuple_t_uint256t_address_payablet_uint256_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"12278:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"12289:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"12301:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"12309:6:9","type":""},{"name":"value2","nodeType":"YulTypedName","src":"12317:6:9","type":""}],"src":"12205:381:9"},{"body":{"nodeType":"YulBlock","src":"12738:124:9","statements":[{"expression":{"arguments":[{"name":"pos","nodeType":"YulIdentifier","src":"12761:3:9"},{"name":"value0","nodeType":"YulIdentifier","src":"12766:6:9"},{"name":"value1","nodeType":"YulIdentifier","src":"12774:6:9"}],"functionName":{"name":"calldatacopy","nodeType":"YulIdentifier","src":"12748:12:9"},"nodeType":"YulFunctionCall","src":"12748:33:9"},"nodeType":"YulExpressionStatement","src":"12748:33:9"},{"nodeType":"YulVariableDeclaration","src":"12790:26:9","value":{"arguments":[{"name":"pos","nodeType":"YulIdentifier","src":"12804:3:9"},{"name":"value1","nodeType":"YulIdentifier","src":"12809:6:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"12800:3:9"},"nodeType":"YulFunctionCall","src":"12800:16:9"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"12794:2:9","type":""}]},{"expression":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"12832:2:9"},{"kind":"number","nodeType":"YulLiteral","src":"12836:1:9","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"12825:6:9"},"nodeType":"YulFunctionCall","src":"12825:13:9"},"nodeType":"YulExpressionStatement","src":"12825:13:9"},{"nodeType":"YulAssignment","src":"12847:9:9","value":{"name":"_1","nodeType":"YulIdentifier","src":"12854:2:9"},"variableNames":[{"name":"end","nodeType":"YulIdentifier","src":"12847:3:9"}]}]},"name":"abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"pos","nodeType":"YulTypedName","src":"12706:3:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"12711:6:9","type":""},{"name":"value0","nodeType":"YulTypedName","src":"12719:6:9","type":""}],"returnVariables":[{"name":"end","nodeType":"YulTypedName","src":"12730:3:9","type":""}],"src":"12591:271:9"}]},"contents":"{\n { }\n function abi_decode_tuple_t_bytes4(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := calldataload(headStart)\n if iszero(eq(value, and(value, shl(224, 0xffffffff)))) { revert(0, 0) }\n value0 := value\n }\n function abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, iszero(iszero(value0)))\n }\n function abi_decode_array_address_dyn_calldata(offset, end) -> arrayPos, length\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n length := calldataload(offset)\n if gt(length, 0xffffffffffffffff) { revert(0, 0) }\n arrayPos := add(offset, 0x20)\n if gt(add(add(offset, shl(5, length)), 0x20), end) { revert(0, 0) }\n }\n function abi_decode_tuple_t_array$_t_address_$dyn_calldata_ptrt_array$_t_bool_$dyn_calldata_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n let offset := calldataload(headStart)\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n let value0_1, value1_1 := abi_decode_array_address_dyn_calldata(add(headStart, offset), dataEnd)\n value0 := value0_1\n value1 := value1_1\n let offset_1 := calldataload(add(headStart, 32))\n if gt(offset_1, _1) { revert(0, 0) }\n let value2_1, value3_1 := abi_decode_array_address_dyn_calldata(add(headStart, offset_1), dataEnd)\n value2 := value2_1\n value3 := value3_1\n }\n function validator_revert_address(value)\n {\n if iszero(eq(value, and(value, sub(shl(160, 1), 1)))) { revert(0, 0) }\n }\n function panic_error_0x41()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x41)\n revert(0, 0x24)\n }\n function allocate_memory(size) -> memPtr\n {\n memPtr := mload(64)\n let newFreePtr := add(memPtr, and(add(size, 31), not(31)))\n if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n mstore(64, newFreePtr)\n }\n function abi_decode_bytes(offset, end) -> array\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n let _1 := calldataload(offset)\n if gt(_1, 0xffffffffffffffff) { panic_error_0x41() }\n let array_1 := allocate_memory(add(and(add(_1, 0x1f), not(31)), 0x20))\n mstore(array_1, _1)\n if gt(add(add(offset, _1), 0x20), end) { revert(0, 0) }\n calldatacopy(add(array_1, 0x20), add(offset, 0x20), _1)\n mstore(add(add(array_1, _1), 0x20), 0)\n array := array_1\n }\n function abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 128) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n value2 := calldataload(add(headStart, 64))\n let offset := calldataload(add(headStart, 96))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n value3 := abi_decode_bytes(add(headStart, offset), dataEnd)\n }\n function abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, shl(224, 0xffffffff)))\n }\n function abi_decode_tuple_t_addresst_address(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n }\n function abi_decode_tuple_t_addresst_addresst_uint256t_uint256(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 128) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n value2 := calldataload(add(headStart, 64))\n value3 := calldataload(add(headStart, 96))\n }\n function abi_encode_tuple_t_address__to_t_address__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, sub(shl(160, 1), 1)))\n }\n function abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 96) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n value1 := calldataload(add(headStart, 32))\n let offset := calldataload(add(headStart, 64))\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n let _2 := add(headStart, offset)\n if iszero(slt(add(_2, 0x1f), dataEnd)) { revert(0, 0) }\n let length := calldataload(_2)\n if gt(length, _1) { revert(0, 0) }\n if gt(add(add(_2, length), 32), dataEnd) { revert(0, 0) }\n value2 := add(_2, 32)\n value3 := length\n }\n function abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value0) -> tail\n {\n let _1 := 32\n mstore(headStart, _1)\n let length := mload(value0)\n mstore(add(headStart, _1), length)\n let i := 0\n for { } lt(i, length) { i := add(i, _1) }\n {\n mstore(add(add(headStart, i), 64), mload(add(add(value0, i), _1)))\n }\n mstore(add(add(headStart, length), 64), 0)\n tail := add(add(headStart, and(add(length, 31), not(31))), 64)\n }\n function abi_decode_tuple_t_addresst_uint256t_uint256(headStart, dataEnd) -> value0, value1, value2\n {\n if slt(sub(dataEnd, headStart), 96) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n value1 := calldataload(add(headStart, 32))\n value2 := calldataload(add(headStart, 64))\n }\n function abi_decode_array_uint256_dyn(offset, end) -> array\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n let _1 := calldataload(offset)\n let _2 := 0x20\n if gt(_1, 0xffffffffffffffff) { panic_error_0x41() }\n let _3 := shl(5, _1)\n let dst := allocate_memory(add(_3, _2))\n let dst_1 := dst\n mstore(dst, _1)\n dst := add(dst, _2)\n let srcEnd := add(add(offset, _3), _2)\n if gt(srcEnd, end) { revert(0, 0) }\n let src := add(offset, _2)\n for { } lt(src, srcEnd) { src := add(src, _2) }\n {\n mstore(dst, calldataload(src))\n dst := add(dst, _2)\n }\n array := dst_1\n }\n function abi_decode_tuple_t_addresst_addresst_array$_t_uint256_$dyn_memory_ptrt_array$_t_uint256_$dyn_memory_ptrt_bytes_memory_ptr(headStart, dataEnd) -> value0, value1, value2, value3, value4\n {\n if slt(sub(dataEnd, headStart), 160) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n let offset := calldataload(add(headStart, 64))\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n value2 := abi_decode_array_uint256_dyn(add(headStart, offset), dataEnd)\n let offset_1 := calldataload(add(headStart, 96))\n if gt(offset_1, _1) { revert(0, 0) }\n value3 := abi_decode_array_uint256_dyn(add(headStart, offset_1), dataEnd)\n let offset_2 := calldataload(add(headStart, 128))\n if gt(offset_2, _1) { revert(0, 0) }\n value4 := abi_decode_bytes(add(headStart, offset_2), dataEnd)\n }\n function abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, value0)\n }\n function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n value0 := calldataload(headStart)\n }\n function abi_decode_tuple_t_addresst_addresst_uint256t_uint256t_bytes_memory_ptr(headStart, dataEnd) -> value0, value1, value2, value3, value4\n {\n if slt(sub(dataEnd, headStart), 160) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n value2 := calldataload(add(headStart, 64))\n value3 := calldataload(add(headStart, 96))\n let offset := calldataload(add(headStart, 128))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n value4 := abi_decode_bytes(add(headStart, offset), dataEnd)\n }\n function abi_encode_tuple_t_uint256_t_address_t_uint256__to_t_uint256_t_address_t_uint256__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n tail := add(headStart, 96)\n mstore(headStart, value0)\n mstore(add(headStart, 32), and(value1, sub(shl(160, 1), 1)))\n mstore(add(headStart, 64), value2)\n }\n function abi_decode_tuple_t_address(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n }\n function panic_error_0x32()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x32)\n revert(0, 0x24)\n }\n function abi_decode_tuple_t_bool(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := calldataload(headStart)\n if iszero(eq(value, iszero(iszero(value)))) { revert(0, 0) }\n value0 := value\n }\n function abi_encode_tuple_t_address_t_address_t_bool__to_t_address_t_address_t_bool__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n tail := add(headStart, 96)\n let _1 := sub(shl(160, 1), 1)\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), and(value1, _1))\n mstore(add(headStart, 64), iszero(iszero(value2)))\n }\n function panic_error_0x11()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x11)\n revert(0, 0x24)\n }\n function increment_t_uint256(value) -> ret\n {\n if eq(value, not(0)) { panic_error_0x11() }\n ret := add(value, 1)\n }\n function abi_encode_tuple_t_address_t_address_t_uint256__to_t_address_t_address_t_uint256__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n tail := add(headStart, 96)\n let _1 := sub(shl(160, 1), 1)\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), and(value1, _1))\n mstore(add(headStart, 64), value2)\n }\n function abi_decode_tuple_t_address_fromMemory(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := mload(headStart)\n validator_revert_address(value)\n value0 := value\n }\n function abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value1, value0) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), value1)\n calldatacopy(add(headStart, 64), value0, value1)\n mstore(add(add(headStart, value1), 64), 0)\n tail := add(add(headStart, and(add(value1, 31), not(31))), 64)\n }\n function checked_add_t_uint256(x, y) -> sum\n {\n sum := add(x, y)\n if gt(x, sum) { panic_error_0x11() }\n }\n function abi_decode_tuple_t_uint256t_address_payablet_uint256_fromMemory(headStart, dataEnd) -> value0, value1, value2\n {\n if slt(sub(dataEnd, headStart), 96) { revert(0, 0) }\n value0 := mload(headStart)\n let value := mload(add(headStart, 32))\n validator_revert_address(value)\n value1 := value\n value2 := mload(add(headStart, 64))\n }\n function abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed(pos, value1, value0) -> end\n {\n calldatacopy(pos, value0, value1)\n let _1 := add(pos, value1)\n mstore(_1, 0)\n end := _1\n }\n}","id":9,"language":"Yul","name":"#utility.yul"}],"immutableReferences":{},"linkReferences":{},"object":"6080604052600436106100ec5760003560e01c8063a4e2d6341161008a578063dd46706411610059578063dd467064146102b7578063f23a6e61146102d7578063fc0c546a14610303578063fe9fbb801461033b57600080fd5b8063a4e2d63414610230578063a737a29914610247578063bc197c8114610267578063ce0617ec1461029357600080fd5b80631f9838b5116100c65780631f9838b5146101885780636b764e1b146101c35780638da5cb5b146101e35780639e5d4c491461021057600080fd5b806301ffc9a7146100f8578063039721b11461012d578063150b7a021461014f57600080fd5b366100f357005b600080fd5b34801561010457600080fd5b50610118610113366004610a92565b61035b565b60405190151581526020015b60405180910390f35b34801561013957600080fd5b5061014d610148366004610b0f565b6103c2565b005b34801561015b57600080fd5b5061016f61016a366004610c4a565b61058b565b6040516001600160e01b03199091168152602001610124565b34801561019457600080fd5b506101186101a3366004610cb6565b600160209081526000928352604080842090915290825290205460ff1681565b3480156101cf57600080fd5b5061014d6101de366004610cef565b6105f3565b3480156101ef57600080fd5b506101f8610661565b6040516001600160a01b039091168152602001610124565b61022361021e366004610d35565b6106f7565b6040516101249190610dbe565b34801561023c57600080fd5b506000544210610118565b34801561025357600080fd5b5061014d610262366004610e0c565b61079b565b34801561027357600080fd5b5061016f610282366004610ec1565b63bc197c8160e01b95945050505050565b34801561029f57600080fd5b506102a960005481565b604051908152602001610124565b3480156102c357600080fd5b5061014d6102d2366004610f6f565b6107fd565b3480156102e357600080fd5b5061016f6102f2366004610f88565b63f23a6e6160e01b95945050505050565b34801561030f57600080fd5b506103186108c2565b604080519384526001600160a01b03909216602084015290820152606001610124565b34801561034757600080fd5b50610118610356366004610ff1565b6108da565b6000806001600160e01b031983166301ffc9a760e01b148061038d57506001600160e01b03198316630271189760e51b145b806103a857506001600160e01b03198316631dfe9a6f60e31b145b905080156103b95750600192915050565b50600092915050565b6000544210156103e557604051636315bfbb60e01b815260040160405180910390fd5b60006103ef610661565b9050336001600160a01b0382161461041a5760405163ea8e4eb560e01b815260040160405180910390fd5b8382811461043b5760405163b4fa3fb360e01b815260040160405180910390fd5b60005b81811015610582578484828181106104585761045861100e565b905060200201602081019061046d9190611024565b6001600160a01b0384166000908152600160205260408120908989858181106104985761049861100e565b90506020020160208101906104ad9190610ff1565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f394777a58092892d136a90c4bb7e4350c72ac50fba6a0208128677f36527dcf5838888848181106105095761050961100e565b905060200201602081019061051e9190610ff1565b8787858181106105305761053061100e565b90506020020160208101906105459190611024565b604080516001600160a01b03948516815293909216602084015215159082015260600160405180910390a18061057a8161105c565b91505061043e565b50505050505050565b6000806000806105996109c3565b92509250925046831480156105b657506001600160a01b03821633145b80156105c157508581145b156105df5760405163b79e3f3f60e01b815260040160405180910390fd5b50630a85bd0160e11b979650505050505050565b604051632142170760e11b81523060048201526001600160a01b038581166024830152604482018490528416906342842e0e90606401600060405180830381600087803b15801561064357600080fd5b505af1158015610657573d6000803e3d6000fd5b5050505050505050565b60008060008061066f6109c3565b925092509250468314610686576000935050505090565b6040516331a9108f60e11b8152600481018290526001600160a01b03831690636352211e90602401602060405180830381865afa1580156106cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ef9190611075565b935050505090565b6060610702336108da565b61071f5760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561074257604051636315bfbb60e01b815260040160405180910390fd5b83856001600160a01b03167f47d99ad340f52da66535aff7e10da1ceb85a32bcbd9fa1c42314d194545e14d2858560405161077e929190611092565b60405180910390a361079285858585610a16565b95945050505050565b604051632142170760e11b8152336004820152306024820152604481018390526001600160a01b038416906342842e0e90606401600060405180830381600087803b1580156107e957600080fd5b505af1158015610582573d6000803e3d6000fd5b610805610661565b6001600160a01b0316336001600160a01b0316146108365760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561085957604051636315bfbb60e01b815260040160405180910390fd5b610867426301e133806110c1565b811115610887576040516301814f7d60e31b815260040160405180910390fd5b60008190556040518181527fa7b24c66dd3269a292a60b3facdbb8f3e7557d1e19e64d99e0d6ee7250be63ad9060200160405180910390a150565b60008060006108cf6109c3565b925092509250909192565b60008060006108e76109c3565b6040516331a9108f60e11b8152600481018290529194509250600091506001600160a01b03841690636352211e90602401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109599190611075565b9050806001600160a01b0316856001600160a01b03160361097f57506001949350505050565b6001600160a01b0380821660009081526001602090815260408083209389168352929052205460ff16156109b857506001949350505050565b506000949350505050565b604080516060808252608082019092526000918291829182919060208201818036833701905050905060ad604d60208301303c80806020019051810190610a0a91906110da565b93509350935050909192565b60606000856001600160a01b0316858585604051610a35929190611113565b60006040518083038185875af1925050503d8060008114610a72576040519150601f19603f3d011682016040523d82523d6000602084013e610a77565b606091505b509250905080610a8957815160208301fd5b50949350505050565b600060208284031215610aa457600080fd5b81356001600160e01b031981168114610abc57600080fd5b9392505050565b60008083601f840112610ad557600080fd5b50813567ffffffffffffffff811115610aed57600080fd5b6020830191508360208260051b8501011115610b0857600080fd5b9250929050565b60008060008060408587031215610b2557600080fd5b843567ffffffffffffffff80821115610b3d57600080fd5b610b4988838901610ac3565b90965094506020870135915080821115610b6257600080fd5b50610b6f87828801610ac3565b95989497509550505050565b6001600160a01b0381168114610b9057600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610bd257610bd2610b93565b604052919050565b600082601f830112610beb57600080fd5b813567ffffffffffffffff811115610c0557610c05610b93565b610c18601f8201601f1916602001610ba9565b818152846020838601011115610c2d57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215610c6057600080fd5b8435610c6b81610b7b565b93506020850135610c7b81610b7b565b925060408501359150606085013567ffffffffffffffff811115610c9e57600080fd5b610caa87828801610bda565b91505092959194509250565b60008060408385031215610cc957600080fd5b8235610cd481610b7b565b91506020830135610ce481610b7b565b809150509250929050565b60008060008060808587031215610d0557600080fd5b8435610d1081610b7b565b93506020850135610d2081610b7b565b93969395505050506040820135916060013590565b60008060008060608587031215610d4b57600080fd5b8435610d5681610b7b565b935060208501359250604085013567ffffffffffffffff80821115610d7a57600080fd5b818701915087601f830112610d8e57600080fd5b813581811115610d9d57600080fd5b886020828501011115610daf57600080fd5b95989497505060200194505050565b600060208083528351808285015260005b81811015610deb57858101830151858201604001528201610dcf565b506000604082860101526040601f19601f8301168501019250505092915050565b600080600060608486031215610e2157600080fd5b8335610e2c81610b7b565b95602085013595506040909401359392505050565b600082601f830112610e5257600080fd5b8135602067ffffffffffffffff821115610e6e57610e6e610b93565b8160051b610e7d828201610ba9565b9283528481018201928281019087851115610e9757600080fd5b83870192505b84831015610eb657823582529183019190830190610e9d565b979650505050505050565b600080600080600060a08688031215610ed957600080fd5b8535610ee481610b7b565b94506020860135610ef481610b7b565b9350604086013567ffffffffffffffff80821115610f1157600080fd5b610f1d89838a01610e41565b94506060880135915080821115610f3357600080fd5b610f3f89838a01610e41565b93506080880135915080821115610f5557600080fd5b50610f6288828901610bda565b9150509295509295909350565b600060208284031215610f8157600080fd5b5035919050565b600080600080600060a08688031215610fa057600080fd5b8535610fab81610b7b565b94506020860135610fbb81610b7b565b93506040860135925060608601359150608086013567ffffffffffffffff811115610fe557600080fd5b610f6288828901610bda565b60006020828403121561100357600080fd5b8135610abc81610b7b565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561103657600080fd5b81358015158114610abc57600080fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161106e5761106e611046565b5060010190565b60006020828403121561108757600080fd5b8151610abc81610b7b565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b808201808211156110d4576110d4611046565b92915050565b6000806000606084860312156110ef57600080fd5b83519250602084015161110181610b7b565b80925050604084015190509250925092565b818382376000910190815291905056fea264697066735822122063e6912474b85020b5a9835811ba76231c769e7f9cde34faffb5d227a7ea56e564736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xEC JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0xA4E2D634 GT PUSH2 0x8A JUMPI DUP1 PUSH4 0xDD467064 GT PUSH2 0x59 JUMPI DUP1 PUSH4 0xDD467064 EQ PUSH2 0x2B7 JUMPI DUP1 PUSH4 0xF23A6E61 EQ PUSH2 0x2D7 JUMPI DUP1 PUSH4 0xFC0C546A EQ PUSH2 0x303 JUMPI DUP1 PUSH4 0xFE9FBB80 EQ PUSH2 0x33B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0xA4E2D634 EQ PUSH2 0x230 JUMPI DUP1 PUSH4 0xA737A299 EQ PUSH2 0x247 JUMPI DUP1 PUSH4 0xBC197C81 EQ PUSH2 0x267 JUMPI DUP1 PUSH4 0xCE0617EC EQ PUSH2 0x293 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1F9838B5 GT PUSH2 0xC6 JUMPI DUP1 PUSH4 0x1F9838B5 EQ PUSH2 0x188 JUMPI DUP1 PUSH4 0x6B764E1B EQ PUSH2 0x1C3 JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x1E3 JUMPI DUP1 PUSH4 0x9E5D4C49 EQ PUSH2 0x210 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1FFC9A7 EQ PUSH2 0xF8 JUMPI DUP1 PUSH4 0x39721B1 EQ PUSH2 0x12D JUMPI DUP1 PUSH4 0x150B7A02 EQ PUSH2 0x14F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST CALLDATASIZE PUSH2 0xF3 JUMPI STOP JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x104 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x118 PUSH2 0x113 CALLDATASIZE PUSH1 0x4 PUSH2 0xA92 JUMP JUMPDEST PUSH2 0x35B JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x139 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x14D PUSH2 0x148 CALLDATASIZE PUSH1 0x4 PUSH2 0xB0F JUMP JUMPDEST PUSH2 0x3C2 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x15B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x16F PUSH2 0x16A CALLDATASIZE PUSH1 0x4 PUSH2 0xC4A JUMP JUMPDEST PUSH2 0x58B JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x124 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x194 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x118 PUSH2 0x1A3 CALLDATASIZE PUSH1 0x4 PUSH2 0xCB6 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1CF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x14D PUSH2 0x1DE CALLDATASIZE PUSH1 0x4 PUSH2 0xCEF JUMP JUMPDEST PUSH2 0x5F3 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1EF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1F8 PUSH2 0x661 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x124 JUMP JUMPDEST PUSH2 0x223 PUSH2 0x21E CALLDATASIZE PUSH1 0x4 PUSH2 0xD35 JUMP JUMPDEST PUSH2 0x6F7 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x124 SWAP2 SWAP1 PUSH2 0xDBE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x23C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x0 SLOAD TIMESTAMP LT PUSH2 0x118 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x253 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x14D PUSH2 0x262 CALLDATASIZE PUSH1 0x4 PUSH2 0xE0C JUMP JUMPDEST PUSH2 0x79B JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x273 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x16F PUSH2 0x282 CALLDATASIZE PUSH1 0x4 PUSH2 0xEC1 JUMP JUMPDEST PUSH4 0xBC197C81 PUSH1 0xE0 SHL SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x29F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2A9 PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x124 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2C3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x14D PUSH2 0x2D2 CALLDATASIZE PUSH1 0x4 PUSH2 0xF6F JUMP JUMPDEST PUSH2 0x7FD JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2E3 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x16F PUSH2 0x2F2 CALLDATASIZE PUSH1 0x4 PUSH2 0xF88 JUMP JUMPDEST PUSH4 0xF23A6E61 PUSH1 0xE0 SHL SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x30F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x318 PUSH2 0x8C2 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP4 DUP5 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE SWAP1 DUP3 ADD MSTORE PUSH1 0x60 ADD PUSH2 0x124 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x347 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x118 PUSH2 0x356 CALLDATASIZE PUSH1 0x4 PUSH2 0xFF1 JUMP JUMPDEST PUSH2 0x8DA JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x1FFC9A7 PUSH1 0xE0 SHL EQ DUP1 PUSH2 0x38D JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x2711897 PUSH1 0xE5 SHL EQ JUMPDEST DUP1 PUSH2 0x3A8 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x1DFE9A6F PUSH1 0xE3 SHL EQ JUMPDEST SWAP1 POP DUP1 ISZERO PUSH2 0x3B9 JUMPI POP PUSH1 0x1 SWAP3 SWAP2 POP POP JUMP JUMPDEST POP PUSH1 0x0 SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x3E5 JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x3EF PUSH2 0x661 JUMP JUMPDEST SWAP1 POP CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND EQ PUSH2 0x41A JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 DUP3 DUP2 EQ PUSH2 0x43B JUMPI PUSH1 0x40 MLOAD PUSH4 0xB4FA3FB3 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x582 JUMPI DUP5 DUP5 DUP3 DUP2 DUP2 LT PUSH2 0x458 JUMPI PUSH2 0x458 PUSH2 0x100E JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x46D SWAP2 SWAP1 PUSH2 0x1024 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 SWAP1 DUP10 DUP10 DUP6 DUP2 DUP2 LT PUSH2 0x498 JUMPI PUSH2 0x498 PUSH2 0x100E JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x4AD SWAP2 SWAP1 PUSH2 0xFF1 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP2 MSTORE PUSH1 0x20 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 ADD PUSH1 0x0 KECCAK256 DUP1 SLOAD PUSH1 0xFF NOT AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH32 0x394777A58092892D136A90C4BB7E4350C72AC50FBA6A0208128677F36527DCF5 DUP4 DUP9 DUP9 DUP5 DUP2 DUP2 LT PUSH2 0x509 JUMPI PUSH2 0x509 PUSH2 0x100E JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x51E SWAP2 SWAP1 PUSH2 0xFF1 JUMP JUMPDEST DUP8 DUP8 DUP6 DUP2 DUP2 LT PUSH2 0x530 JUMPI PUSH2 0x530 PUSH2 0x100E JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x545 SWAP2 SWAP1 PUSH2 0x1024 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP5 DUP6 AND DUP2 MSTORE SWAP4 SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE ISZERO ISZERO SWAP1 DUP3 ADD MSTORE PUSH1 0x60 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 DUP1 PUSH2 0x57A DUP2 PUSH2 0x105C JUMP JUMPDEST SWAP2 POP POP PUSH2 0x43E JUMP JUMPDEST POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x599 PUSH2 0x9C3 JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP CHAINID DUP4 EQ DUP1 ISZERO PUSH2 0x5B6 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND CALLER EQ JUMPDEST DUP1 ISZERO PUSH2 0x5C1 JUMPI POP DUP6 DUP2 EQ JUMPDEST ISZERO PUSH2 0x5DF JUMPI PUSH1 0x40 MLOAD PUSH4 0xB79E3F3F PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP PUSH4 0xA85BD01 PUSH1 0xE1 SHL SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x21421707 PUSH1 0xE1 SHL DUP2 MSTORE ADDRESS PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP6 DUP2 AND PUSH1 0x24 DUP4 ADD MSTORE PUSH1 0x44 DUP3 ADD DUP5 SWAP1 MSTORE DUP5 AND SWAP1 PUSH4 0x42842E0E SWAP1 PUSH1 0x64 ADD PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x643 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x657 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x66F PUSH2 0x9C3 JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP CHAINID DUP4 EQ PUSH2 0x686 JUMPI PUSH1 0x0 SWAP4 POP POP POP POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x31A9108F PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND SWAP1 PUSH4 0x6352211E SWAP1 PUSH1 0x24 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x6CB JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x6EF SWAP2 SWAP1 PUSH2 0x1075 JUMP JUMPDEST SWAP4 POP POP POP POP SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH2 0x702 CALLER PUSH2 0x8DA JUMP JUMPDEST PUSH2 0x71F JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x742 JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH32 0x47D99AD340F52DA66535AFF7E10DA1CEB85A32BCBD9FA1C42314D194545E14D2 DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0x77E SWAP3 SWAP2 SWAP1 PUSH2 0x1092 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 PUSH2 0x792 DUP6 DUP6 DUP6 DUP6 PUSH2 0xA16 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x21421707 PUSH1 0xE1 SHL DUP2 MSTORE CALLER PUSH1 0x4 DUP3 ADD MSTORE ADDRESS PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x44 DUP2 ADD DUP4 SWAP1 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND SWAP1 PUSH4 0x42842E0E SWAP1 PUSH1 0x64 ADD PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x7E9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x582 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST PUSH2 0x805 PUSH2 0x661 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ PUSH2 0x836 JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x859 JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH2 0x867 TIMESTAMP PUSH4 0x1E13380 PUSH2 0x10C1 JUMP JUMPDEST DUP2 GT ISZERO PUSH2 0x887 JUMPI PUSH1 0x40 MLOAD PUSH4 0x1814F7D PUSH1 0xE3 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 DUP2 SWAP1 SSTORE PUSH1 0x40 MLOAD DUP2 DUP2 MSTORE PUSH32 0xA7B24C66DD3269A292A60B3FACDBB8F3E7557D1E19E64D99E0D6EE7250BE63AD SWAP1 PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x8CF PUSH2 0x9C3 JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP SWAP1 SWAP2 SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x8E7 PUSH2 0x9C3 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x31A9108F PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE SWAP2 SWAP5 POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND SWAP1 PUSH4 0x6352211E SWAP1 PUSH1 0x24 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x935 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x959 SWAP2 SWAP1 PUSH2 0x1075 JUMP JUMPDEST SWAP1 POP DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SUB PUSH2 0x97F JUMPI POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP1 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP10 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x9B8 JUMPI POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST POP PUSH1 0x0 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 DUP1 DUP3 MSTORE PUSH1 0x80 DUP3 ADD SWAP1 SWAP3 MSTORE PUSH1 0x0 SWAP2 DUP3 SWAP2 DUP3 SWAP2 DUP3 SWAP2 SWAP1 PUSH1 0x20 DUP3 ADD DUP2 DUP1 CALLDATASIZE DUP4 CALLDATACOPY ADD SWAP1 POP POP SWAP1 POP PUSH1 0xAD PUSH1 0x4D PUSH1 0x20 DUP4 ADD ADDRESS EXTCODECOPY DUP1 DUP1 PUSH1 0x20 ADD SWAP1 MLOAD DUP2 ADD SWAP1 PUSH2 0xA0A SWAP2 SWAP1 PUSH2 0x10DA JUMP JUMPDEST SWAP4 POP SWAP4 POP SWAP4 POP POP SWAP1 SWAP2 SWAP3 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP6 DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0xA35 SWAP3 SWAP2 SWAP1 PUSH2 0x1113 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 GAS CALL SWAP3 POP POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0xA72 JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0xA77 JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP3 POP SWAP1 POP DUP1 PUSH2 0xA89 JUMPI DUP2 MLOAD PUSH1 0x20 DUP4 ADD REVERT JUMPDEST POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xAA4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP2 AND DUP2 EQ PUSH2 0xABC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0xAD5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xAED JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 PUSH1 0x5 SHL DUP6 ADD ADD GT ISZERO PUSH2 0xB08 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x40 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xB25 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xB3D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xB49 DUP9 DUP4 DUP10 ADD PUSH2 0xAC3 JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP PUSH1 0x20 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xB62 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xB6F DUP8 DUP3 DUP9 ADD PUSH2 0xAC3 JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0xB90 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT AND DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0xBD2 JUMPI PUSH2 0xBD2 PUSH2 0xB93 JUMP JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xBEB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xC05 JUMPI PUSH2 0xC05 PUSH2 0xB93 JUMP JUMPDEST PUSH2 0xC18 PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT AND PUSH1 0x20 ADD PUSH2 0xBA9 JUMP JUMPDEST DUP2 DUP2 MSTORE DUP5 PUSH1 0x20 DUP4 DUP7 ADD ADD GT ISZERO PUSH2 0xC2D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 PUSH1 0x20 DUP6 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 SWAP2 DUP2 ADD PUSH1 0x20 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xC60 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xC6B DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH2 0xC7B DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD SWAP2 POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xC9E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xCAA DUP8 DUP3 DUP9 ADD PUSH2 0xBDA JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xCC9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH2 0xCD4 DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP2 POP PUSH1 0x20 DUP4 ADD CALLDATALOAD PUSH2 0xCE4 DUP2 PUSH2 0xB7B JUMP JUMPDEST DUP1 SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xD05 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xD10 DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH2 0xD20 DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP4 SWAP7 SWAP4 SWAP6 POP POP POP POP PUSH1 0x40 DUP3 ADD CALLDATALOAD SWAP2 PUSH1 0x60 ADD CALLDATALOAD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x60 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xD4B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xD56 DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xD7A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP8 ADD SWAP2 POP DUP8 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xD8E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP2 DUP2 GT ISZERO PUSH2 0xD9D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP9 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0xDAF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP POP PUSH1 0x20 ADD SWAP5 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 MSTORE DUP4 MLOAD DUP1 DUP3 DUP6 ADD MSTORE PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xDEB JUMPI DUP6 DUP2 ADD DUP4 ADD MLOAD DUP6 DUP3 ADD PUSH1 0x40 ADD MSTORE DUP3 ADD PUSH2 0xDCF JUMP JUMPDEST POP PUSH1 0x0 PUSH1 0x40 DUP3 DUP7 ADD ADD MSTORE PUSH1 0x40 PUSH1 0x1F NOT PUSH1 0x1F DUP4 ADD AND DUP6 ADD ADD SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xE21 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD PUSH2 0xE2C DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP6 PUSH1 0x20 DUP6 ADD CALLDATALOAD SWAP6 POP PUSH1 0x40 SWAP1 SWAP5 ADD CALLDATALOAD SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xE52 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH1 0x20 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0xE6E JUMPI PUSH2 0xE6E PUSH2 0xB93 JUMP JUMPDEST DUP2 PUSH1 0x5 SHL PUSH2 0xE7D DUP3 DUP3 ADD PUSH2 0xBA9 JUMP JUMPDEST SWAP3 DUP4 MSTORE DUP5 DUP2 ADD DUP3 ADD SWAP3 DUP3 DUP2 ADD SWAP1 DUP8 DUP6 GT ISZERO PUSH2 0xE97 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 DUP8 ADD SWAP3 POP JUMPDEST DUP5 DUP4 LT ISZERO PUSH2 0xEB6 JUMPI DUP3 CALLDATALOAD DUP3 MSTORE SWAP2 DUP4 ADD SWAP2 SWAP1 DUP4 ADD SWAP1 PUSH2 0xE9D JUMP JUMPDEST SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xED9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xEE4 DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH2 0xEF4 DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xF11 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xF1D DUP10 DUP4 DUP11 ADD PUSH2 0xE41 JUMP JUMPDEST SWAP5 POP PUSH1 0x60 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xF33 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xF3F DUP10 DUP4 DUP11 ADD PUSH2 0xE41 JUMP JUMPDEST SWAP4 POP PUSH1 0x80 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xF55 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xF62 DUP9 DUP3 DUP10 ADD PUSH2 0xBDA JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 SWAP1 SWAP4 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xF81 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xFA0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xFAB DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH2 0xFBB DUP2 PUSH2 0xB7B JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD SWAP3 POP PUSH1 0x60 DUP7 ADD CALLDATALOAD SWAP2 POP PUSH1 0x80 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xFE5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xF62 DUP9 DUP3 DUP10 ADD PUSH2 0xBDA JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1003 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0xABC DUP2 PUSH2 0xB7B JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x32 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1036 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP1 ISZERO ISZERO DUP2 EQ PUSH2 0xABC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x11 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x1 DUP3 ADD PUSH2 0x106E JUMPI PUSH2 0x106E PUSH2 0x1046 JUMP JUMPDEST POP PUSH1 0x1 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1087 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0xABC DUP2 PUSH2 0xB7B JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE DUP2 PUSH1 0x20 DUP3 ADD MSTORE DUP2 DUP4 PUSH1 0x40 DUP4 ADD CALLDATACOPY PUSH1 0x0 DUP2 DUP4 ADD PUSH1 0x40 SWAP1 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x1F SWAP1 SWAP3 ADD PUSH1 0x1F NOT AND ADD ADD SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 DUP3 ADD DUP1 DUP3 GT ISZERO PUSH2 0x10D4 JUMPI PUSH2 0x10D4 PUSH2 0x1046 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x10EF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 MLOAD SWAP3 POP PUSH1 0x20 DUP5 ADD MLOAD PUSH2 0x1101 DUP2 PUSH2 0xB7B JUMP JUMPDEST DUP1 SWAP3 POP POP PUSH1 0x40 DUP5 ADD MLOAD SWAP1 POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST DUP2 DUP4 DUP3 CALLDATACOPY PUSH1 0x0 SWAP2 ADD SWAP1 DUP2 MSTORE SWAP2 SWAP1 POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 PUSH4 0xE6912474 0xB8 POP KECCAK256 0xB5 0xA9 DUP4 PC GT 0xBA PUSH23 0x231C769E7F9CDE34FAFFB5D227A7EA56E564736F6C6343 STOP ADDMOD GT STOP CALLER ","sourceMap":"161:627:5:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4889:393:6;;;;;;;;;;-1:-1:-1;4889:393:6;;;;;:::i;:::-;;:::i;:::-;;;470:14:9;;463:22;445:41;;433:2;418:18;4889:393:6;;;;;;;;2357:528;;;;;;;;;;-1:-1:-1;2357:528:6;;;;;:::i;:::-;;:::i;:::-;;5427:526;;;;;;;;;;-1:-1:-1;5427:526:6;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;;3559:33:9;;;3541:52;;3529:2;3514:18;5427:526:6;3397:202:9;965:63:6;;;;;;;;;;-1:-1:-1;965:63:6;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;530:256:5;;;;;;;;;;-1:-1:-1;530:256:5;;;;;:::i;:::-;;:::i;3891:310:6:-;;;;;;;;;;;;;:::i;:::-;;;-1:-1:-1;;;;;4691:32:9;;;4673:51;;4661:2;4646:18;3891:310:6;4527:203:9;2029:265:6;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;3276:100::-;;;;;;;;;;-1:-1:-1;3317:4:6;3340:11;3354:15;-1:-1:-1;3276:100:6;;223:301:5;;;;;;;;;;-1:-1:-1;223:301:5;;;;;:::i;:::-;;:::i;6356:244:6:-;;;;;;;;;;-1:-1:-1;6356:244:6;;;;;:::i;:::-;-1:-1:-1;;;6356:244:6;;;;;;;;871:26;;;;;;;;;;;;;;;;;;;8412:25:9;;;8400:2;8385:18;871:26:6;8266:177:9;2948:249:6;;;;;;;;;;-1:-1:-1;2948:249:6;;;;;:::i;:::-;;:::i;6043:216::-;;;;;;;;;;-1:-1:-1;6043:216:6;;;;;:::i;:::-;-1:-1:-1;;;6043:216:6;;;;;;;;3508:220;;;;;;;;;;;;;:::i;:::-;;;;9574:25:9;;;-1:-1:-1;;;;;9635:32:9;;;9630:2;9615:18;;9608:60;9684:18;;;9677:34;9562:2;9547:18;3508:220:6;9372:345:9;4272:480:6;;;;;;;;;;-1:-1:-1;4272:480:6;;;;;:::i;:::-;;:::i;4889:393::-;4999:4;;-1:-1:-1;;;;;;5041:40:6;;-1:-1:-1;;;5041:40:6;;:105;;-1:-1:-1;;;;;;;5097:49:6;;-1:-1:-1;;;5097:49:6;5041:105;:169;;;-1:-1:-1;;;;;;;5162:48:6;;-1:-1:-1;;;5162:48:6;5041:169;5019:191;;5225:14;5221:31;;;-1:-1:-1;5248:4:6;;4889:393;-1:-1:-1;;4889:393:6:o;5221:31::-;-1:-1:-1;5270:5:6;;4889:393;-1:-1:-1;;4889:393:6:o;2357:528::-;3317:4;3340:11;3354:15;-1:-1:-1;1722:38:6;;;1745:15;;-1:-1:-1;;;1745:15:6;;;;;;;;;;;1722:38;2493:14:::1;2510:7;:5;:7::i;:::-;2493:24:::0;-1:-1:-1;2531:10:6::1;-1:-1:-1::0;;;;;2531:20:6;::::1;;2527:48;;2560:15;;-1:-1:-1::0;;;2560:15:6::1;;;;;;;;;;;2527:48;2603:7:::0;2632:29;;::::1;2628:56;;2670:14;;-1:-1:-1::0;;;2670:14:6::1;;;;;;;;;;;2628:56;2700:9;2695:184;2719:6;2715:1;:10;2695:184;;;2780:12;;2793:1;2780:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;2746:19:6;::::1;;::::0;;;:11:::1;:19;::::0;;;;;2766:7;;2774:1;2766:10;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;2746:31:6::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;2746:31:6;:49;;-1:-1:-1;;2746:49:6::1;::::0;::::1;;::::0;;;::::1;::::0;;2814:54:::1;2832:6:::0;2840:7;;2848:1;2840:10;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;2852:12;;2865:1;2852:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;2814:54;::::0;;-1:-1:-1;;;;;10636:15:9;;;10618:34;;10688:15;;;;10683:2;10668:18;;10661:43;10747:14;10740:22;10720:18;;;10713:50;10568:2;10553:18;2814:54:6::1;;;;;;;2727:3:::0;::::1;::::0;::::1;:::i;:::-;;;;2695:184;;;;2483:402;;2357:528:::0;;;;:::o;5427:526::-;5578:6;5610:15;5639:21;5674:15;5702:25;:23;:25::i;:::-;5596:131;;;;;;5766:13;5755:7;:24;:67;;;;-1:-1:-1;;;;;;5795:27:6;;5812:10;5795:27;5755:67;:109;;;;;5849:15;5838:7;:26;5755:109;5738:160;;;5882:16;;-1:-1:-1;;;5882:16:6;;;;;;;;;;;5738:160;-1:-1:-1;;;;5916:30:6;5427:526;-1:-1:-1;;;;;;;5427:526:6:o;530:256:5:-;701:78;;-1:-1:-1;;;701:78:5;;751:4;701:78;;;11286:34:9;-1:-1:-1;;;;;11356:15:9;;;11336:18;;;11329:43;11388:18;;;11381:34;;;701:41:5;;;;;11221:18:9;;701:78:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;530:256;;;;:::o;3891:310:6:-;3929:7;3962:15;3991:21;4026:15;4054:25;:23;:25::i;:::-;3948:131;;;;;;4105:13;4094:7;:24;4090:47;;4135:1;4120:17;;;;;3891:310;:::o;4090:47::-;4155:39;;-1:-1:-1;;;4155:39:6;;;;;8412:25:9;;;-1:-1:-1;;;;;4155:30:6;;;;;8385:18:9;;4155:39:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4148:46;;;;;3891:310;:::o;2029:265::-;2182:12;1559:24;1572:10;1559:12;:24::i;:::-;1554:53;;1592:15;;-1:-1:-1;;;1592:15:6;;;;;;;;;;;1554:53;3317:4;3340:11;3354:15;-1:-1:-1;1722:38:6::1;;;1745:15;;-1:-1:-1::0;;;1745:15:6::1;;;;;;;;;;;1722:38;2235:5:::2;2231:2;-1:-1:-1::0;;;;;2211:36:6::2;;2242:4;;2211:36;;;;;;;:::i;:::-;;;;;;;;2265:22;2271:2;2275:5;2282:4;;2265:5;:22::i;:::-;2258:29:::0;2029:265;-1:-1:-1;;;;;2029:265:6:o;223:301:5:-;391:126;;-1:-1:-1;;;391:126:5;;446:10;391:126;;;11286:34:9;478:4:5;11336:18:9;;;11329:43;11388:18;;;11381:34;;;-1:-1:-1;;;;;391:41:5;;;;;11221:18:9;;391:126:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2948:249:6;1387:7;:5;:7::i;:::-;-1:-1:-1;;;;;1373:21:6;:10;-1:-1:-1;;;;;1373:21:6;;1369:49;;1403:15;;-1:-1:-1;;;1403:15:6;;;;;;;;;;;1369:49;3317:4;3340:11;3354:15;-1:-1:-1;1722:38:6::1;;;1745:15;;-1:-1:-1::0;;;1745:15:6::1;;;;;;;;;;;1722:38;3045:26:::2;:15;3063:8;3045:26;:::i;:::-;3030:12;:41;3026:86;;;3092:20;;-1:-1:-1::0;;;3092:20:6::2;;;;;;;;;;;3026:86;3123:11;:26:::0;;;3165:25:::2;::::0;8412::9;;;3165::6::2;::::0;8400:2:9;8385:18;3165:25:6::2;;;;;;;2948:249:::0;:::o;3508:220::-;3585:15;3614:21;3649:15;3696:25;:23;:25::i;:::-;3689:32;;;;;;3508:220;;;:::o;4272:480::-;4331:4;4375:21;4410:15;4438:25;:23;:25::i;:::-;4490:39;;-1:-1:-1;;;4490:39:6;;;;;8412:25:9;;;4347:116:6;;-1:-1:-1;4347:116:6;-1:-1:-1;4473:14:6;;-1:-1:-1;;;;;;4490:30:6;;;;;8385:18:9;;4490:39:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4473:56;;4587:6;-1:-1:-1;;;;;4577:16:6;:6;-1:-1:-1;;;;;4577:16:6;;4573:33;;-1:-1:-1;4602:4:6;;4272:480;-1:-1:-1;;;;4272:480:6:o;4573:33::-;-1:-1:-1;;;;;4682:19:6;;;;;;;:11;:19;;;;;;;;:27;;;;;;;;;;;;4678:44;;;-1:-1:-1;4718:4:6;;4272:480;-1:-1:-1;;;;4272:480:6:o;4678:44::-;-1:-1:-1;4740:5:6;;4272:480;-1:-1:-1;;;;4272:480:6:o;90:406:8:-;263:15;;;273:4;263:15;;;;;;;;;167:7;;;;;;;;263:15;;;;;;;;;;;-1:-1:-1;263:15:8;241:37;;410:4;404;397;389:6;385:17;374:9;362:53;453:6;442:47;;;;;;;;;;;;:::i;:::-;435:54;;;;;;;90:406;;;:::o;6645:345:6:-;6756:19;6787:12;6829:2;-1:-1:-1;;;;;6829:7:6;6844:5;6851:4;;6829:27;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6809:47:6;-1:-1:-1;6809:47:6;-1:-1:-1;6809:47:6;6867:117;;6952:6;6946:13;6941:2;6933:6;6929:15;6922:38;6867:117;6777:213;6645:345;;;;;;:::o;14:286:9:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:9;;209:43;;199:71;;266:1;263;256:12;199:71;289:5;14:286;-1:-1:-1;;;14:286:9:o;497:367::-;560:8;570:6;624:3;617:4;609:6;605:17;601:27;591:55;;642:1;639;632:12;591:55;-1:-1:-1;665:20:9;;708:18;697:30;;694:50;;;740:1;737;730:12;694:50;777:4;769:6;765:17;753:29;;837:3;830:4;820:6;817:1;813:14;805:6;801:27;797:38;794:47;791:67;;;854:1;851;844:12;791:67;497:367;;;;;:::o;869:770::-;988:6;996;1004;1012;1065:2;1053:9;1044:7;1040:23;1036:32;1033:52;;;1081:1;1078;1071:12;1033:52;1121:9;1108:23;1150:18;1191:2;1183:6;1180:14;1177:34;;;1207:1;1204;1197:12;1177:34;1246:70;1308:7;1299:6;1288:9;1284:22;1246:70;:::i;:::-;1335:8;;-1:-1:-1;1220:96:9;-1:-1:-1;1423:2:9;1408:18;;1395:32;;-1:-1:-1;1439:16:9;;;1436:36;;;1468:1;1465;1458:12;1436:36;;1507:72;1571:7;1560:8;1549:9;1545:24;1507:72;:::i;:::-;869:770;;;;-1:-1:-1;1598:8:9;-1:-1:-1;;;;869:770:9:o;1644:131::-;-1:-1:-1;;;;;1719:31:9;;1709:42;;1699:70;;1765:1;1762;1755:12;1699:70;1644:131;:::o;1780:127::-;1841:10;1836:3;1832:20;1829:1;1822:31;1872:4;1869:1;1862:15;1896:4;1893:1;1886:15;1912:275;1983:2;1977:9;2048:2;2029:13;;-1:-1:-1;;2025:27:9;2013:40;;2083:18;2068:34;;2104:22;;;2065:62;2062:88;;;2130:18;;:::i;:::-;2166:2;2159:22;1912:275;;-1:-1:-1;1912:275:9:o;2192:530::-;2234:5;2287:3;2280:4;2272:6;2268:17;2264:27;2254:55;;2305:1;2302;2295:12;2254:55;2341:6;2328:20;2367:18;2363:2;2360:26;2357:52;;;2389:18;;:::i;:::-;2433:55;2476:2;2457:13;;-1:-1:-1;;2453:27:9;2482:4;2449:38;2433:55;:::i;:::-;2513:2;2504:7;2497:19;2559:3;2552:4;2547:2;2539:6;2535:15;2531:26;2528:35;2525:55;;;2576:1;2573;2566:12;2525:55;2641:2;2634:4;2626:6;2622:17;2615:4;2606:7;2602:18;2589:55;2689:1;2664:16;;;2682:4;2660:27;2653:38;;;;2668:7;2192:530;-1:-1:-1;;;2192:530:9:o;2727:665::-;2822:6;2830;2838;2846;2899:3;2887:9;2878:7;2874:23;2870:33;2867:53;;;2916:1;2913;2906:12;2867:53;2955:9;2942:23;2974:31;2999:5;2974:31;:::i;:::-;3024:5;-1:-1:-1;3081:2:9;3066:18;;3053:32;3094:33;3053:32;3094:33;:::i;:::-;3146:7;-1:-1:-1;3200:2:9;3185:18;;3172:32;;-1:-1:-1;3255:2:9;3240:18;;3227:32;3282:18;3271:30;;3268:50;;;3314:1;3311;3304:12;3268:50;3337:49;3378:7;3369:6;3358:9;3354:22;3337:49;:::i;:::-;3327:59;;;2727:665;;;;;;;:::o;3604:388::-;3672:6;3680;3733:2;3721:9;3712:7;3708:23;3704:32;3701:52;;;3749:1;3746;3739:12;3701:52;3788:9;3775:23;3807:31;3832:5;3807:31;:::i;:::-;3857:5;-1:-1:-1;3914:2:9;3899:18;;3886:32;3927:33;3886:32;3927:33;:::i;:::-;3979:7;3969:17;;;3604:388;;;;;:::o;3997:525::-;4083:6;4091;4099;4107;4160:3;4148:9;4139:7;4135:23;4131:33;4128:53;;;4177:1;4174;4167:12;4128:53;4216:9;4203:23;4235:31;4260:5;4235:31;:::i;:::-;4285:5;-1:-1:-1;4342:2:9;4327:18;;4314:32;4355:33;4314:32;4355:33;:::i;:::-;3997:525;;4407:7;;-1:-1:-1;;;;4461:2:9;4446:18;;4433:32;;4512:2;4497:18;4484:32;;3997:525::o;4735:794::-;4823:6;4831;4839;4847;4900:2;4888:9;4879:7;4875:23;4871:32;4868:52;;;4916:1;4913;4906:12;4868:52;4955:9;4942:23;4974:31;4999:5;4974:31;:::i;:::-;5024:5;-1:-1:-1;5076:2:9;5061:18;;5048:32;;-1:-1:-1;5131:2:9;5116:18;;5103:32;5154:18;5184:14;;;5181:34;;;5211:1;5208;5201:12;5181:34;5249:6;5238:9;5234:22;5224:32;;5294:7;5287:4;5283:2;5279:13;5275:27;5265:55;;5316:1;5313;5306:12;5265:55;5356:2;5343:16;5382:2;5374:6;5371:14;5368:34;;;5398:1;5395;5388:12;5368:34;5443:7;5438:2;5429:6;5425:2;5421:15;5417:24;5414:37;5411:57;;;5464:1;5461;5454:12;5411:57;4735:794;;;;-1:-1:-1;;5495:2:9;5487:11;;-1:-1:-1;;;4735:794:9:o;5534:546::-;5644:4;5673:2;5702;5691:9;5684:21;5734:6;5728:13;5777:6;5772:2;5761:9;5757:18;5750:34;5802:1;5812:140;5826:6;5823:1;5820:13;5812:140;;;5921:14;;;5917:23;;5911:30;5887:17;;;5906:2;5883:26;5876:66;5841:10;;5812:140;;;5816:3;6001:1;5996:2;5987:6;5976:9;5972:22;5968:31;5961:42;6071:2;6064;6060:7;6055:2;6047:6;6043:15;6039:29;6028:9;6024:45;6020:54;6012:62;;;;5534:546;;;;:::o;6085:383::-;6162:6;6170;6178;6231:2;6219:9;6210:7;6206:23;6202:32;6199:52;;;6247:1;6244;6237:12;6199:52;6286:9;6273:23;6305:31;6330:5;6305:31;:::i;:::-;6355:5;6407:2;6392:18;;6379:32;;-1:-1:-1;6458:2:9;6443:18;;;6430:32;;6085:383;-1:-1:-1;;;6085:383:9:o;6473:712::-;6527:5;6580:3;6573:4;6565:6;6561:17;6557:27;6547:55;;6598:1;6595;6588:12;6547:55;6634:6;6621:20;6660:4;6683:18;6679:2;6676:26;6673:52;;;6705:18;;:::i;:::-;6751:2;6748:1;6744:10;6774:28;6798:2;6794;6790:11;6774:28;:::i;:::-;6836:15;;;6906;;;6902:24;;;6867:12;;;;6938:15;;;6935:35;;;6966:1;6963;6956:12;6935:35;7002:2;6994:6;6990:15;6979:26;;7014:142;7030:6;7025:3;7022:15;7014:142;;;7096:17;;7084:30;;7047:12;;;;7134;;;;7014:142;;;7174:5;6473:712;-1:-1:-1;;;;;;;6473:712:9:o;7190:1071::-;7344:6;7352;7360;7368;7376;7429:3;7417:9;7408:7;7404:23;7400:33;7397:53;;;7446:1;7443;7436:12;7397:53;7485:9;7472:23;7504:31;7529:5;7504:31;:::i;:::-;7554:5;-1:-1:-1;7611:2:9;7596:18;;7583:32;7624:33;7583:32;7624:33;:::i;:::-;7676:7;-1:-1:-1;7734:2:9;7719:18;;7706:32;7757:18;7787:14;;;7784:34;;;7814:1;7811;7804:12;7784:34;7837:61;7890:7;7881:6;7870:9;7866:22;7837:61;:::i;:::-;7827:71;;7951:2;7940:9;7936:18;7923:32;7907:48;;7980:2;7970:8;7967:16;7964:36;;;7996:1;7993;7986:12;7964:36;8019:63;8074:7;8063:8;8052:9;8048:24;8019:63;:::i;:::-;8009:73;;8135:3;8124:9;8120:19;8107:33;8091:49;;8165:2;8155:8;8152:16;8149:36;;;8181:1;8178;8171:12;8149:36;;8204:51;8247:7;8236:8;8225:9;8221:24;8204:51;:::i;:::-;8194:61;;;7190:1071;;;;;;;;:::o;8448:180::-;8507:6;8560:2;8548:9;8539:7;8535:23;8531:32;8528:52;;;8576:1;8573;8566:12;8528:52;-1:-1:-1;8599:23:9;;8448:180;-1:-1:-1;8448:180:9:o;8633:734::-;8737:6;8745;8753;8761;8769;8822:3;8810:9;8801:7;8797:23;8793:33;8790:53;;;8839:1;8836;8829:12;8790:53;8878:9;8865:23;8897:31;8922:5;8897:31;:::i;:::-;8947:5;-1:-1:-1;9004:2:9;8989:18;;8976:32;9017:33;8976:32;9017:33;:::i;:::-;9069:7;-1:-1:-1;9123:2:9;9108:18;;9095:32;;-1:-1:-1;9174:2:9;9159:18;;9146:32;;-1:-1:-1;9229:3:9;9214:19;;9201:33;9257:18;9246:30;;9243:50;;;9289:1;9286;9279:12;9243:50;9312:49;9353:7;9344:6;9333:9;9329:22;9312:49;:::i;9722:247::-;9781:6;9834:2;9822:9;9813:7;9809:23;9805:32;9802:52;;;9850:1;9847;9840:12;9802:52;9889:9;9876:23;9908:31;9933:5;9908:31;:::i;9974:127::-;10035:10;10030:3;10026:20;10023:1;10016:31;10066:4;10063:1;10056:15;10090:4;10087:1;10080:15;10106:273;10162:6;10215:2;10203:9;10194:7;10190:23;10186:32;10183:52;;;10231:1;10228;10221:12;10183:52;10270:9;10257:23;10323:5;10316:13;10309:21;10302:5;10299:32;10289:60;;10345:1;10342;10335:12;10774:127;10835:10;10830:3;10826:20;10823:1;10816:31;10866:4;10863:1;10856:15;10890:4;10887:1;10880:15;10906:135;10945:3;10966:17;;;10963:43;;10986:18;;:::i;:::-;-1:-1:-1;11033:1:9;11022:13;;10906:135::o;11426:251::-;11496:6;11549:2;11537:9;11528:7;11524:23;11520:32;11517:52;;;11565:1;11562;11555:12;11517:52;11597:9;11591:16;11616:31;11641:5;11616:31;:::i;11682:388::-;11839:2;11828:9;11821:21;11878:6;11873:2;11862:9;11858:18;11851:34;11935:6;11927;11922:2;11911:9;11907:18;11894:48;11991:1;11962:22;;;11986:2;11958:31;;;11951:42;;;;12054:2;12033:15;;;-1:-1:-1;;12029:29:9;12014:45;12010:54;;11682:388;-1:-1:-1;11682:388:9:o;12075:125::-;12140:9;;;12161:10;;;12158:36;;;12174:18;;:::i;:::-;12075:125;;;;:::o;12205:381::-;12301:6;12309;12317;12370:2;12358:9;12349:7;12345:23;12341:32;12338:52;;;12386:1;12383;12376:12;12338:52;12415:9;12409:16;12399:26;;12468:2;12457:9;12453:18;12447:25;12481:31;12506:5;12481:31;:::i;:::-;12531:5;12521:15;;;12576:2;12565:9;12561:18;12555:25;12545:35;;12205:381;;;;;:::o;12591:271::-;12774:6;12766;12761:3;12748:33;12730:3;12800:16;;12825:13;;;12800:16;12591:271;-1:-1:-1;12591:271:9:o"},"gasEstimates":{"creation":{"codeDepositCost":"888200","executionCost":"922","totalCost":"889122"},"external":{"breakCovalentBond(address,address,uint256,uint256)":"infinite","covalentBond(address,uint256,uint256)":"infinite","executeCall(address,uint256,bytes)":"infinite","isAuthorized(address)":"infinite","isLocked()":"2315","lock(uint256)":"infinite","lockedUntil()":"2384","onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":"infinite","onERC1155Received(address,address,uint256,uint256,bytes)":"infinite","onERC721Received(address,address,uint256,bytes)":"infinite","owner()":"infinite","permissions(address,address)":"infinite","setPermissions(address[],bool[])":"infinite","supportsInterface(bytes4)":"538","token()":"infinite"}},"methodIdentifiers":{"breakCovalentBond(address,address,uint256,uint256)":"6b764e1b","covalentBond(address,uint256,uint256)":"a737a299","executeCall(address,uint256,bytes)":"9e5d4c49","isAuthorized(address)":"fe9fbb80","isLocked()":"a4e2d634","lock(uint256)":"dd467064","lockedUntil()":"ce0617ec","onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":"bc197c81","onERC1155Received(address,address,uint256,uint256,bytes)":"f23a6e61","onERC721Received(address,address,uint256,bytes)":"150b7a02","owner()":"8da5cb5b","permissions(address,address)":"1f9838b5","setPermissions(address[],bool[])":"039721b1","supportsInterface(bytes4)":"01ffc9a7","token()":"fc0c546a"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"AccountLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExceedsMaxLockTime\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInput\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAuthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnershipCycle\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lockedUntil\",\"type\":\"uint256\"}],\"name\":\"LockUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"OverrideUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"hasPermission\",\"type\":\"bool\"}],\"name\":\"PermissionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"TransactionExecuted\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"breakCovalentBond\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"covalentBond\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"executeCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"isAuthorized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isLocked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_lockedUntil\",\"type\":\"uint256\"}],\"name\":\"lock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lockedUntil\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"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\":\"receivedTokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"permissions\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"callers\",\"type\":\"address[]\"},{\"internalType\":\"bool[]\",\"name\":\"_permissions\",\"type\":\"bool[]\"}],\"name\":\"setPermissions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"executeCall(address,uint256,bytes)\":{\"details\":\"executes a low-level call against an account if the caller is authorized to make calls\"},\"isAuthorized(address)\":{\"details\":\"Returns the authorization status for a given caller\"},\"isLocked()\":{\"details\":\"returns the current lock status of the account as a boolean\"},\"lock(uint256)\":{\"details\":\"locks the account until a certain timestamp\"},\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"details\":\"Allows ERC-1155 token batches to be received. This function can be overriden.\"},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"details\":\"Allows ERC-1155 tokens to be received. This function can be overriden.\"},\"onERC721Received(address,address,uint256,bytes)\":{\"details\":\"Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle. This function can be overriden.\"},\"owner()\":{\"details\":\"Returns the owner of the ERC-721 token which owns this account. By default, the owner of the token has full permissions on the account.\"},\"setPermissions(address[],bool[])\":{\"details\":\"grants a given caller execution permissions\"},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if a given interfaceId is supported by this account. This method can be extended by an override.\"},\"token()\":{\"details\":\"Returns the EIP-155 chain ID, token contract address, and token ID for the token that owns this account.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ChargedParticlesAccount.sol\":\"ChargedParticlesAccount\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (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 *\\n * NOTE: 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 *\\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.\\n *\\n * NOTE: 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 *\\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\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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`.\\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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\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(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface 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 `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/ChargedParticlesAccount.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\nimport \\\"./MinimalisticAccount.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\ncontract ChargedParticlesAccount is MinimalisticAccount {\\n function covalentBond(\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external {\\n // Transfer to self\\n IERC721(nftTokenAddress).safeTransferFrom(\\n msg.sender,\\n address(this),\\n nftTokenId\\n );\\n }\\n\\n function breakCovalentBond(\\n address receiver,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external {\\n IERC721(nftTokenAddress).safeTransferFrom(address(this), receiver, nftTokenId);\\n }\\n}\\n\",\"keccak256\":\"0x0fac20d5900e5fafc5ac28307f1bfc585fb0c5c2d3921ccc4ac98eb68d97d54d\",\"license\":\"UNLICENSED\"},\"contracts/MinimalisticAccount.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\nimport \\\"./interfaces/IERC6551Account.sol\\\";\\nimport \\\"./lib/ERC6551AccountLib.sol\\\";\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/interfaces/IERC1271.sol\\\";\\n\\nerror NotAuthorized();\\nerror InvalidInput();\\nerror AccountLocked();\\nerror ExceedsMaxLockTime();\\nerror UntrustedImplementation();\\nerror OwnershipCycle();\\n\\n/**\\n * @title A smart contract account owned by a single ERC721 token\\n */\\ncontract MinimalisticAccount is\\n IERC165,\\n IERC6551Account,\\n IERC721Receiver,\\n IERC1155Receiver\\n{\\n /// @dev timestamp at which this account will be unlocked\\n uint256 public lockedUntil;\\n\\n /// @dev mapping from owner => caller => has permissions\\n mapping(address => mapping(address => bool)) public permissions;\\n\\n event OverrideUpdated(\\n address owner,\\n bytes4 selector,\\n address implementation\\n );\\n\\n event PermissionUpdated(address owner, address caller, bool hasPermission);\\n\\n event LockUpdated(uint256 lockedUntil);\\n\\n /// @dev reverts if caller is not the owner of the account\\n modifier onlyOwner() {\\n if (msg.sender != owner()) revert NotAuthorized();\\n _;\\n }\\n\\n /// @dev reverts if caller is not authorized to execute on this account\\n modifier onlyAuthorized() {\\n if (!isAuthorized(msg.sender)) revert NotAuthorized();\\n _;\\n }\\n\\n /// @dev reverts if this account is currently locked\\n modifier onlyUnlocked() {\\n if (isLocked()) revert AccountLocked();\\n _;\\n }\\n\\n constructor() {}\\n\\n /// @dev allows eth transfers by default, but allows account owner to override\\n receive() external payable {\\n }\\n\\n /// @dev executes a low-level call against an account if the caller is authorized to make calls\\n function executeCall(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) external payable onlyAuthorized onlyUnlocked returns (bytes memory) {\\n emit TransactionExecuted(to, value, data);\\n\\n return _call(to, value, data);\\n }\\n\\n /// @dev grants a given caller execution permissions\\n function setPermissions(\\n address[] calldata callers,\\n bool[] calldata _permissions\\n ) external onlyUnlocked {\\n address _owner = owner();\\n if (msg.sender != _owner) revert NotAuthorized();\\n\\n uint256 length = callers.length;\\n\\n if (_permissions.length != length) revert InvalidInput();\\n\\n for (uint256 i = 0; i < length; i++) {\\n permissions[_owner][callers[i]] = _permissions[i];\\n emit PermissionUpdated(_owner, callers[i], _permissions[i]);\\n }\\n }\\n\\n /// @dev locks the account until a certain timestamp\\n function lock(uint256 _lockedUntil) external onlyOwner onlyUnlocked {\\n if (_lockedUntil > block.timestamp + 365 days)\\n revert ExceedsMaxLockTime();\\n\\n lockedUntil = _lockedUntil;\\n\\n emit LockUpdated(_lockedUntil);\\n }\\n\\n /// @dev returns the current lock status of the account as a boolean\\n function isLocked() public view returns (bool) {\\n return lockedUntil > block.timestamp;\\n }\\n\\n /// @dev Returns the EIP-155 chain ID, token contract address, and token ID for the token that\\n /// owns this account.\\n function token()\\n external\\n view\\n returns (\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n )\\n {\\n return ERC6551AccountLib.token();\\n }\\n\\n /// @dev Returns the owner of the ERC-721 token which owns this account. By default, the owner\\n /// of the token has full permissions on the account.\\n function owner() public view returns (address) {\\n (\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) = ERC6551AccountLib.token();\\n\\n if (chainId != block.chainid) return address(0);\\n\\n return IERC721(tokenContract).ownerOf(tokenId);\\n }\\n\\n /// @dev Returns the authorization status for a given caller\\n function isAuthorized(address caller) public view returns (bool) {\\n (\\n ,\\n address tokenContract,\\n uint256 tokenId\\n ) = ERC6551AccountLib.token();\\n address _owner = IERC721(tokenContract).ownerOf(tokenId);\\n\\n // authorize token owner\\n if (caller == _owner) return true;\\n\\n // authorize caller if owner has granted permissions\\n if (permissions[_owner][caller]) return true;\\n\\n return false;\\n }\\n\\n /// @dev Returns true if a given interfaceId is supported by this account. This method can be\\n /// extended by an override.\\n function supportsInterface(bytes4 interfaceId)\\n public\\n pure \\n override\\n returns (bool)\\n {\\n bool defaultSupport = interfaceId == type(IERC165).interfaceId ||\\n interfaceId == type(IERC1155Receiver).interfaceId ||\\n interfaceId == type(IERC6551Account).interfaceId;\\n\\n if (defaultSupport) return true;\\n\\n return false;\\n }\\n\\n /// @dev Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle.\\n /// This function can be overriden.\\n function onERC721Received(\\n address,\\n address,\\n uint256 receivedTokenId,\\n bytes memory\\n ) public view override returns (bytes4) {\\n (\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) = ERC6551AccountLib.token();\\n\\n if (\\n chainId == block.chainid &&\\n tokenContract == msg.sender &&\\n tokenId == receivedTokenId\\n ) revert OwnershipCycle();\\n\\n return this.onERC721Received.selector;\\n }\\n\\n /// @dev Allows ERC-1155 tokens to be received. This function can be overriden.\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes memory\\n ) public pure override returns (bytes4) {\\n return this.onERC1155Received.selector;\\n }\\n\\n /// @dev Allows ERC-1155 token batches to be received. This function can be overriden.\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] memory,\\n uint256[] memory,\\n bytes memory\\n ) public pure override returns (bytes4) {\\n return this.onERC1155BatchReceived.selector;\\n }\\n\\n /// @dev Executes a low-level call\\n function _call(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) internal returns (bytes memory result) {\\n bool success;\\n (success, result) = to.call{value: value}(data);\\n\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /// @dev Executes a low-level static call\\n function _callStatic(address to, bytes calldata data)\\n internal\\n view\\n returns (bytes memory result)\\n {\\n bool success;\\n (success, result) = to.staticcall(data);\\n\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xed537db66c8c88618b283b038ec6e1b55b56c1ad4006658a1fef0fe8e60fb528\",\"license\":\"UNLICENSED\"},\"contracts/interfaces/IERC6551Account.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\ninterface IERC6551AccountProxy {\\n function implementation() external view returns (address);\\n}\\n\\n/// @dev the ERC-165 identifier for this interface is `0xeff4d378`\\ninterface IERC6551Account {\\n event TransactionExecuted(address indexed target, uint256 indexed value, bytes data);\\n\\n receive() external payable;\\n\\n function executeCall(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) external payable returns (bytes memory);\\n\\n function token()\\n external\\n view\\n returns (uint256 chainId, address tokenContract, uint256 tokenId);\\n\\n function owner() external view returns (address);\\n}\\n\",\"keccak256\":\"0x5fe2dca745f8e753d414778980a0846c1bbcbb26a09d7cd7fb712c7db7939582\",\"license\":\"UNLICENSED\"},\"contracts/lib/ERC6551AccountLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.13;\\n\\nlibrary ERC6551AccountLib {\\n function token()\\n internal\\n view\\n returns (\\n uint256,\\n address,\\n uint256\\n )\\n {\\n bytes memory footer = new bytes(0x60);\\n\\n assembly {\\n // copy 0x60 bytes from end of footer\\n extcodecopy(address(), add(footer, 0x20), 0x4d, 0xad)\\n }\\n\\n return abi.decode(footer, (uint256, address, uint256));\\n }\\n\\n function salt() internal view returns (uint256) {\\n bytes memory footer = new bytes(0x20);\\n\\n assembly {\\n // copy 0x20 bytes from beginning of footer\\n extcodecopy(address(), add(footer, 0x20), 0x2d, 0x4d)\\n }\\n\\n return abi.decode(footer, (uint256));\\n }\\n}\\n\",\"keccak256\":\"0xf7a8eb3b4fb63068eb8ed2a1a129e4676af842541f43c1a1dc96a9f295060c45\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[{"astId":287,"contract":"contracts/ChargedParticlesAccount.sol:ChargedParticlesAccount","label":"lockedUntil","offset":0,"slot":"0","type":"t_uint256"},{"astId":294,"contract":"contracts/ChargedParticlesAccount.sol:ChargedParticlesAccount","label":"permissions","offset":0,"slot":"1","type":"t_mapping(t_address,t_mapping(t_address,t_bool))"}],"types":{"t_address":{"encoding":"inplace","label":"address","numberOfBytes":"20"},"t_bool":{"encoding":"inplace","label":"bool","numberOfBytes":"1"},"t_mapping(t_address,t_bool)":{"encoding":"mapping","key":"t_address","label":"mapping(address => bool)","numberOfBytes":"32","value":"t_bool"},"t_mapping(t_address,t_mapping(t_address,t_bool))":{"encoding":"mapping","key":"t_address","label":"mapping(address => mapping(address => bool))","numberOfBytes":"32","value":"t_mapping(t_address,t_bool)"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/MinimalisticAccount.sol":{"MinimalisticAccount":{"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccountLocked","type":"error"},{"inputs":[],"name":"ExceedsMaxLockTime","type":"error"},{"inputs":[],"name":"InvalidInput","type":"error"},{"inputs":[],"name":"NotAuthorized","type":"error"},{"inputs":[],"name":"OwnershipCycle","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"lockedUntil","type":"uint256"}],"name":"LockUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"bytes4","name":"selector","type":"bytes4"},{"indexed":false,"internalType":"address","name":"implementation","type":"address"}],"name":"OverrideUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"bool","name":"hasPermission","type":"bool"}],"name":"PermissionUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":true,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"TransactionExecuted","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"executeCall","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"isAuthorized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lockedUntil","type":"uint256"}],"name":"lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockedUntil","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"receivedTokenId","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"permissions","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"callers","type":"address[]"},{"internalType":"bool[]","name":"_permissions","type":"bool[]"}],"name":"setPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}],"devdoc":{"kind":"dev","methods":{"executeCall(address,uint256,bytes)":{"details":"executes a low-level call against an account if the caller is authorized to make calls"},"isAuthorized(address)":{"details":"Returns the authorization status for a given caller"},"isLocked()":{"details":"returns the current lock status of the account as a boolean"},"lock(uint256)":{"details":"locks the account until a certain timestamp"},"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":{"details":"Allows ERC-1155 token batches to be received. This function can be overriden."},"onERC1155Received(address,address,uint256,uint256,bytes)":{"details":"Allows ERC-1155 tokens to be received. This function can be overriden."},"onERC721Received(address,address,uint256,bytes)":{"details":"Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle. This function can be overriden."},"owner()":{"details":"Returns the owner of the ERC-721 token which owns this account. By default, the owner of the token has full permissions on the account."},"setPermissions(address[],bool[])":{"details":"grants a given caller execution permissions"},"supportsInterface(bytes4)":{"details":"Returns true if a given interfaceId is supported by this account. This method can be extended by an override."},"token()":{"details":"Returns the EIP-155 chain ID, token contract address, and token ID for the token that owns this account."}},"stateVariables":{"lockedUntil":{"details":"timestamp at which this account will be unlocked"},"permissions":{"details":"mapping from owner => caller => has permissions"}},"title":"A smart contract account owned by a single ERC721 token","version":1},"evm":{"bytecode":{"functionDebugData":{"@_357":{"entryPoint":null,"id":357,"parameterSlots":0,"returnSlots":0}},"generatedSources":[],"linkReferences":{},"object":"608060405234801561001057600080fd5b50610fa8806100206000396000f3fe6080604052600436106100c65760003560e01c8063a4e2d6341161007f578063dd46706411610059578063dd46706414610251578063f23a6e6114610271578063fc0c546a1461029d578063fe9fbb80146102d557600080fd5b8063a4e2d634146101ea578063bc197c8114610201578063ce0617ec1461022d57600080fd5b806301ffc9a7146100d2578063039721b114610107578063150b7a02146101295780631f9838b5146101625780638da5cb5b1461019d5780639e5d4c49146101ca57600080fd5b366100cd57005b600080fd5b3480156100de57600080fd5b506100f26100ed36600461095c565b6102f5565b60405190151581526020015b60405180910390f35b34801561011357600080fd5b506101276101223660046109d9565b61035c565b005b34801561013557600080fd5b50610149610144366004610b14565b610525565b6040516001600160e01b031990911681526020016100fe565b34801561016e57600080fd5b506100f261017d366004610b80565b600160209081526000928352604080842090915290825290205460ff1681565b3480156101a957600080fd5b506101b261058d565b6040516001600160a01b0390911681526020016100fe565b6101dd6101d8366004610bb9565b610623565b6040516100fe9190610c42565b3480156101f657600080fd5b5060005442106100f2565b34801561020d57600080fd5b5061014961021c366004610d10565b63bc197c8160e01b95945050505050565b34801561023957600080fd5b5061024360005481565b6040519081526020016100fe565b34801561025d57600080fd5b5061012761026c366004610dbe565b6106c7565b34801561027d57600080fd5b5061014961028c366004610dd7565b63f23a6e6160e01b95945050505050565b3480156102a957600080fd5b506102b261078c565b604080519384526001600160a01b039092166020840152908201526060016100fe565b3480156102e157600080fd5b506100f26102f0366004610e40565b6107a4565b6000806001600160e01b031983166301ffc9a760e01b148061032757506001600160e01b03198316630271189760e51b145b8061034257506001600160e01b03198316631dfe9a6f60e31b145b905080156103535750600192915050565b50600092915050565b60005442101561037f57604051636315bfbb60e01b815260040160405180910390fd5b600061038961058d565b9050336001600160a01b038216146103b45760405163ea8e4eb560e01b815260040160405180910390fd5b838281146103d55760405163b4fa3fb360e01b815260040160405180910390fd5b60005b8181101561051c578484828181106103f2576103f2610e5d565b90506020020160208101906104079190610e73565b6001600160a01b03841660009081526001602052604081209089898581811061043257610432610e5d565b90506020020160208101906104479190610e40565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f394777a58092892d136a90c4bb7e4350c72ac50fba6a0208128677f36527dcf5838888848181106104a3576104a3610e5d565b90506020020160208101906104b89190610e40565b8787858181106104ca576104ca610e5d565b90506020020160208101906104df9190610e73565b604080516001600160a01b03948516815293909216602084015215159082015260600160405180910390a18061051481610eab565b9150506103d8565b50505050505050565b60008060008061053361088d565b925092509250468314801561055057506001600160a01b03821633145b801561055b57508581145b156105795760405163b79e3f3f60e01b815260040160405180910390fd5b50630a85bd0160e11b979650505050505050565b60008060008061059b61088d565b9250925092504683146105b2576000935050505090565b6040516331a9108f60e11b8152600481018290526001600160a01b03831690636352211e90602401602060405180830381865afa1580156105f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061b9190610ec4565b935050505090565b606061062e336107a4565b61064b5760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561066e57604051636315bfbb60e01b815260040160405180910390fd5b83856001600160a01b03167f47d99ad340f52da66535aff7e10da1ceb85a32bcbd9fa1c42314d194545e14d285856040516106aa929190610ee1565b60405180910390a36106be858585856108e0565b95945050505050565b6106cf61058d565b6001600160a01b0316336001600160a01b0316146107005760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561072357604051636315bfbb60e01b815260040160405180910390fd5b610731426301e13380610f10565b811115610751576040516301814f7d60e31b815260040160405180910390fd5b60008190556040518181527fa7b24c66dd3269a292a60b3facdbb8f3e7557d1e19e64d99e0d6ee7250be63ad9060200160405180910390a150565b600080600061079961088d565b925092509250909192565b60008060006107b161088d565b6040516331a9108f60e11b8152600481018290529194509250600091506001600160a01b03841690636352211e90602401602060405180830381865afa1580156107ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108239190610ec4565b9050806001600160a01b0316856001600160a01b03160361084957506001949350505050565b6001600160a01b0380821660009081526001602090815260408083209389168352929052205460ff161561088257506001949350505050565b506000949350505050565b604080516060808252608082019092526000918291829182919060208201818036833701905050905060ad604d60208301303c808060200190518101906108d49190610f29565b93509350935050909192565b60606000856001600160a01b03168585856040516108ff929190610f62565b60006040518083038185875af1925050503d806000811461093c576040519150601f19603f3d011682016040523d82523d6000602084013e610941565b606091505b50925090508061095357815160208301fd5b50949350505050565b60006020828403121561096e57600080fd5b81356001600160e01b03198116811461098657600080fd5b9392505050565b60008083601f84011261099f57600080fd5b50813567ffffffffffffffff8111156109b757600080fd5b6020830191508360208260051b85010111156109d257600080fd5b9250929050565b600080600080604085870312156109ef57600080fd5b843567ffffffffffffffff80821115610a0757600080fd5b610a138883890161098d565b90965094506020870135915080821115610a2c57600080fd5b50610a398782880161098d565b95989497509550505050565b6001600160a01b0381168114610a5a57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610a9c57610a9c610a5d565b604052919050565b600082601f830112610ab557600080fd5b813567ffffffffffffffff811115610acf57610acf610a5d565b610ae2601f8201601f1916602001610a73565b818152846020838601011115610af757600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215610b2a57600080fd5b8435610b3581610a45565b93506020850135610b4581610a45565b925060408501359150606085013567ffffffffffffffff811115610b6857600080fd5b610b7487828801610aa4565b91505092959194509250565b60008060408385031215610b9357600080fd5b8235610b9e81610a45565b91506020830135610bae81610a45565b809150509250929050565b60008060008060608587031215610bcf57600080fd5b8435610bda81610a45565b935060208501359250604085013567ffffffffffffffff80821115610bfe57600080fd5b818701915087601f830112610c1257600080fd5b813581811115610c2157600080fd5b886020828501011115610c3357600080fd5b95989497505060200194505050565b600060208083528351808285015260005b81811015610c6f57858101830151858201604001528201610c53565b506000604082860101526040601f19601f8301168501019250505092915050565b600082601f830112610ca157600080fd5b8135602067ffffffffffffffff821115610cbd57610cbd610a5d565b8160051b610ccc828201610a73565b9283528481018201928281019087851115610ce657600080fd5b83870192505b84831015610d0557823582529183019190830190610cec565b979650505050505050565b600080600080600060a08688031215610d2857600080fd5b8535610d3381610a45565b94506020860135610d4381610a45565b9350604086013567ffffffffffffffff80821115610d6057600080fd5b610d6c89838a01610c90565b94506060880135915080821115610d8257600080fd5b610d8e89838a01610c90565b93506080880135915080821115610da457600080fd5b50610db188828901610aa4565b9150509295509295909350565b600060208284031215610dd057600080fd5b5035919050565b600080600080600060a08688031215610def57600080fd5b8535610dfa81610a45565b94506020860135610e0a81610a45565b93506040860135925060608601359150608086013567ffffffffffffffff811115610e3457600080fd5b610db188828901610aa4565b600060208284031215610e5257600080fd5b813561098681610a45565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610e8557600080fd5b8135801515811461098657600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610ebd57610ebd610e95565b5060010190565b600060208284031215610ed657600080fd5b815161098681610a45565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b80820180821115610f2357610f23610e95565b92915050565b600080600060608486031215610f3e57600080fd5b835192506020840151610f5081610a45565b80925050604084015190509250925092565b818382376000910190815291905056fea26469706673582212208586a5aa87cff87a1d8e1dc4952c1d3b167ebfafab4c2b56ed97ed8a5ec5921664736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xFA8 DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xC6 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0xA4E2D634 GT PUSH2 0x7F JUMPI DUP1 PUSH4 0xDD467064 GT PUSH2 0x59 JUMPI DUP1 PUSH4 0xDD467064 EQ PUSH2 0x251 JUMPI DUP1 PUSH4 0xF23A6E61 EQ PUSH2 0x271 JUMPI DUP1 PUSH4 0xFC0C546A EQ PUSH2 0x29D JUMPI DUP1 PUSH4 0xFE9FBB80 EQ PUSH2 0x2D5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0xA4E2D634 EQ PUSH2 0x1EA JUMPI DUP1 PUSH4 0xBC197C81 EQ PUSH2 0x201 JUMPI DUP1 PUSH4 0xCE0617EC EQ PUSH2 0x22D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1FFC9A7 EQ PUSH2 0xD2 JUMPI DUP1 PUSH4 0x39721B1 EQ PUSH2 0x107 JUMPI DUP1 PUSH4 0x150B7A02 EQ PUSH2 0x129 JUMPI DUP1 PUSH4 0x1F9838B5 EQ PUSH2 0x162 JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x19D JUMPI DUP1 PUSH4 0x9E5D4C49 EQ PUSH2 0x1CA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST CALLDATASIZE PUSH2 0xCD JUMPI STOP JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xDE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xF2 PUSH2 0xED CALLDATASIZE PUSH1 0x4 PUSH2 0x95C JUMP JUMPDEST PUSH2 0x2F5 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x113 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x127 PUSH2 0x122 CALLDATASIZE PUSH1 0x4 PUSH2 0x9D9 JUMP JUMPDEST PUSH2 0x35C JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x135 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x149 PUSH2 0x144 CALLDATASIZE PUSH1 0x4 PUSH2 0xB14 JUMP JUMPDEST PUSH2 0x525 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xFE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x16E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xF2 PUSH2 0x17D CALLDATASIZE PUSH1 0x4 PUSH2 0xB80 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1A9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B2 PUSH2 0x58D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xFE JUMP JUMPDEST PUSH2 0x1DD PUSH2 0x1D8 CALLDATASIZE PUSH1 0x4 PUSH2 0xBB9 JUMP JUMPDEST PUSH2 0x623 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xFE SWAP2 SWAP1 PUSH2 0xC42 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1F6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x0 SLOAD TIMESTAMP LT PUSH2 0xF2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x20D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x149 PUSH2 0x21C CALLDATASIZE PUSH1 0x4 PUSH2 0xD10 JUMP JUMPDEST PUSH4 0xBC197C81 PUSH1 0xE0 SHL SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x239 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x243 PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xFE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x25D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x127 PUSH2 0x26C CALLDATASIZE PUSH1 0x4 PUSH2 0xDBE JUMP JUMPDEST PUSH2 0x6C7 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x27D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x149 PUSH2 0x28C CALLDATASIZE PUSH1 0x4 PUSH2 0xDD7 JUMP JUMPDEST PUSH4 0xF23A6E61 PUSH1 0xE0 SHL SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2A9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2B2 PUSH2 0x78C JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP4 DUP5 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE SWAP1 DUP3 ADD MSTORE PUSH1 0x60 ADD PUSH2 0xFE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2E1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xF2 PUSH2 0x2F0 CALLDATASIZE PUSH1 0x4 PUSH2 0xE40 JUMP JUMPDEST PUSH2 0x7A4 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x1FFC9A7 PUSH1 0xE0 SHL EQ DUP1 PUSH2 0x327 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x2711897 PUSH1 0xE5 SHL EQ JUMPDEST DUP1 PUSH2 0x342 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x1DFE9A6F PUSH1 0xE3 SHL EQ JUMPDEST SWAP1 POP DUP1 ISZERO PUSH2 0x353 JUMPI POP PUSH1 0x1 SWAP3 SWAP2 POP POP JUMP JUMPDEST POP PUSH1 0x0 SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x37F JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x389 PUSH2 0x58D JUMP JUMPDEST SWAP1 POP CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND EQ PUSH2 0x3B4 JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 DUP3 DUP2 EQ PUSH2 0x3D5 JUMPI PUSH1 0x40 MLOAD PUSH4 0xB4FA3FB3 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x51C JUMPI DUP5 DUP5 DUP3 DUP2 DUP2 LT PUSH2 0x3F2 JUMPI PUSH2 0x3F2 PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x407 SWAP2 SWAP1 PUSH2 0xE73 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 SWAP1 DUP10 DUP10 DUP6 DUP2 DUP2 LT PUSH2 0x432 JUMPI PUSH2 0x432 PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x447 SWAP2 SWAP1 PUSH2 0xE40 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP2 MSTORE PUSH1 0x20 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 ADD PUSH1 0x0 KECCAK256 DUP1 SLOAD PUSH1 0xFF NOT AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH32 0x394777A58092892D136A90C4BB7E4350C72AC50FBA6A0208128677F36527DCF5 DUP4 DUP9 DUP9 DUP5 DUP2 DUP2 LT PUSH2 0x4A3 JUMPI PUSH2 0x4A3 PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x4B8 SWAP2 SWAP1 PUSH2 0xE40 JUMP JUMPDEST DUP8 DUP8 DUP6 DUP2 DUP2 LT PUSH2 0x4CA JUMPI PUSH2 0x4CA PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x4DF SWAP2 SWAP1 PUSH2 0xE73 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP5 DUP6 AND DUP2 MSTORE SWAP4 SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE ISZERO ISZERO SWAP1 DUP3 ADD MSTORE PUSH1 0x60 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 DUP1 PUSH2 0x514 DUP2 PUSH2 0xEAB JUMP JUMPDEST SWAP2 POP POP PUSH2 0x3D8 JUMP JUMPDEST POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x533 PUSH2 0x88D JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP CHAINID DUP4 EQ DUP1 ISZERO PUSH2 0x550 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND CALLER EQ JUMPDEST DUP1 ISZERO PUSH2 0x55B JUMPI POP DUP6 DUP2 EQ JUMPDEST ISZERO PUSH2 0x579 JUMPI PUSH1 0x40 MLOAD PUSH4 0xB79E3F3F PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP PUSH4 0xA85BD01 PUSH1 0xE1 SHL SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x59B PUSH2 0x88D JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP CHAINID DUP4 EQ PUSH2 0x5B2 JUMPI PUSH1 0x0 SWAP4 POP POP POP POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x31A9108F PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND SWAP1 PUSH4 0x6352211E SWAP1 PUSH1 0x24 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x5F7 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x61B SWAP2 SWAP1 PUSH2 0xEC4 JUMP JUMPDEST SWAP4 POP POP POP POP SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH2 0x62E CALLER PUSH2 0x7A4 JUMP JUMPDEST PUSH2 0x64B JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x66E JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH32 0x47D99AD340F52DA66535AFF7E10DA1CEB85A32BCBD9FA1C42314D194545E14D2 DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0x6AA SWAP3 SWAP2 SWAP1 PUSH2 0xEE1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 PUSH2 0x6BE DUP6 DUP6 DUP6 DUP6 PUSH2 0x8E0 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0x6CF PUSH2 0x58D JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ PUSH2 0x700 JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x723 JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH2 0x731 TIMESTAMP PUSH4 0x1E13380 PUSH2 0xF10 JUMP JUMPDEST DUP2 GT ISZERO PUSH2 0x751 JUMPI PUSH1 0x40 MLOAD PUSH4 0x1814F7D PUSH1 0xE3 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 DUP2 SWAP1 SSTORE PUSH1 0x40 MLOAD DUP2 DUP2 MSTORE PUSH32 0xA7B24C66DD3269A292A60B3FACDBB8F3E7557D1E19E64D99E0D6EE7250BE63AD SWAP1 PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x799 PUSH2 0x88D JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP SWAP1 SWAP2 SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x7B1 PUSH2 0x88D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x31A9108F PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE SWAP2 SWAP5 POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND SWAP1 PUSH4 0x6352211E SWAP1 PUSH1 0x24 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x7FF JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x823 SWAP2 SWAP1 PUSH2 0xEC4 JUMP JUMPDEST SWAP1 POP DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SUB PUSH2 0x849 JUMPI POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP1 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP10 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x882 JUMPI POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST POP PUSH1 0x0 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 DUP1 DUP3 MSTORE PUSH1 0x80 DUP3 ADD SWAP1 SWAP3 MSTORE PUSH1 0x0 SWAP2 DUP3 SWAP2 DUP3 SWAP2 DUP3 SWAP2 SWAP1 PUSH1 0x20 DUP3 ADD DUP2 DUP1 CALLDATASIZE DUP4 CALLDATACOPY ADD SWAP1 POP POP SWAP1 POP PUSH1 0xAD PUSH1 0x4D PUSH1 0x20 DUP4 ADD ADDRESS EXTCODECOPY DUP1 DUP1 PUSH1 0x20 ADD SWAP1 MLOAD DUP2 ADD SWAP1 PUSH2 0x8D4 SWAP2 SWAP1 PUSH2 0xF29 JUMP JUMPDEST SWAP4 POP SWAP4 POP SWAP4 POP POP SWAP1 SWAP2 SWAP3 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP6 DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0x8FF SWAP3 SWAP2 SWAP1 PUSH2 0xF62 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 GAS CALL SWAP3 POP POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0x93C JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0x941 JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP3 POP SWAP1 POP DUP1 PUSH2 0x953 JUMPI DUP2 MLOAD PUSH1 0x20 DUP4 ADD REVERT JUMPDEST POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x96E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP2 AND DUP2 EQ PUSH2 0x986 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x99F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x9B7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 PUSH1 0x5 SHL DUP6 ADD ADD GT ISZERO PUSH2 0x9D2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x40 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x9EF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xA07 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xA13 DUP9 DUP4 DUP10 ADD PUSH2 0x98D JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP PUSH1 0x20 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xA2C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xA39 DUP8 DUP3 DUP9 ADD PUSH2 0x98D JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0xA5A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT AND DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0xA9C JUMPI PUSH2 0xA9C PUSH2 0xA5D JUMP JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xAB5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xACF JUMPI PUSH2 0xACF PUSH2 0xA5D JUMP JUMPDEST PUSH2 0xAE2 PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT AND PUSH1 0x20 ADD PUSH2 0xA73 JUMP JUMPDEST DUP2 DUP2 MSTORE DUP5 PUSH1 0x20 DUP4 DUP7 ADD ADD GT ISZERO PUSH2 0xAF7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 PUSH1 0x20 DUP6 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 SWAP2 DUP2 ADD PUSH1 0x20 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xB2A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xB35 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH2 0xB45 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD SWAP2 POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xB68 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xB74 DUP8 DUP3 DUP9 ADD PUSH2 0xAA4 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xB93 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH2 0xB9E DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP2 POP PUSH1 0x20 DUP4 ADD CALLDATALOAD PUSH2 0xBAE DUP2 PUSH2 0xA45 JUMP JUMPDEST DUP1 SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x60 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xBCF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xBDA DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xBFE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP8 ADD SWAP2 POP DUP8 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xC12 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP2 DUP2 GT ISZERO PUSH2 0xC21 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP9 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0xC33 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP POP PUSH1 0x20 ADD SWAP5 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 MSTORE DUP4 MLOAD DUP1 DUP3 DUP6 ADD MSTORE PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xC6F JUMPI DUP6 DUP2 ADD DUP4 ADD MLOAD DUP6 DUP3 ADD PUSH1 0x40 ADD MSTORE DUP3 ADD PUSH2 0xC53 JUMP JUMPDEST POP PUSH1 0x0 PUSH1 0x40 DUP3 DUP7 ADD ADD MSTORE PUSH1 0x40 PUSH1 0x1F NOT PUSH1 0x1F DUP4 ADD AND DUP6 ADD ADD SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xCA1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH1 0x20 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0xCBD JUMPI PUSH2 0xCBD PUSH2 0xA5D JUMP JUMPDEST DUP2 PUSH1 0x5 SHL PUSH2 0xCCC DUP3 DUP3 ADD PUSH2 0xA73 JUMP JUMPDEST SWAP3 DUP4 MSTORE DUP5 DUP2 ADD DUP3 ADD SWAP3 DUP3 DUP2 ADD SWAP1 DUP8 DUP6 GT ISZERO PUSH2 0xCE6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 DUP8 ADD SWAP3 POP JUMPDEST DUP5 DUP4 LT ISZERO PUSH2 0xD05 JUMPI DUP3 CALLDATALOAD DUP3 MSTORE SWAP2 DUP4 ADD SWAP2 SWAP1 DUP4 ADD SWAP1 PUSH2 0xCEC JUMP JUMPDEST SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xD28 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xD33 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH2 0xD43 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xD60 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD6C DUP10 DUP4 DUP11 ADD PUSH2 0xC90 JUMP JUMPDEST SWAP5 POP PUSH1 0x60 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xD82 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD8E DUP10 DUP4 DUP11 ADD PUSH2 0xC90 JUMP JUMPDEST SWAP4 POP PUSH1 0x80 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xDA4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xDB1 DUP9 DUP3 DUP10 ADD PUSH2 0xAA4 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 SWAP1 SWAP4 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xDD0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xDEF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xDFA DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH2 0xE0A DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD SWAP3 POP PUSH1 0x60 DUP7 ADD CALLDATALOAD SWAP2 POP PUSH1 0x80 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xE34 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xDB1 DUP9 DUP3 DUP10 ADD PUSH2 0xAA4 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xE52 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x986 DUP2 PUSH2 0xA45 JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x32 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xE85 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP1 ISZERO ISZERO DUP2 EQ PUSH2 0x986 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x11 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x1 DUP3 ADD PUSH2 0xEBD JUMPI PUSH2 0xEBD PUSH2 0xE95 JUMP JUMPDEST POP PUSH1 0x1 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xED6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x986 DUP2 PUSH2 0xA45 JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE DUP2 PUSH1 0x20 DUP3 ADD MSTORE DUP2 DUP4 PUSH1 0x40 DUP4 ADD CALLDATACOPY PUSH1 0x0 DUP2 DUP4 ADD PUSH1 0x40 SWAP1 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x1F SWAP1 SWAP3 ADD PUSH1 0x1F NOT AND ADD ADD SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 DUP3 ADD DUP1 DUP3 GT ISZERO PUSH2 0xF23 JUMPI PUSH2 0xF23 PUSH2 0xE95 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xF3E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 MLOAD SWAP3 POP PUSH1 0x20 DUP5 ADD MLOAD PUSH2 0xF50 DUP2 PUSH2 0xA45 JUMP JUMPDEST DUP1 SWAP3 POP POP PUSH1 0x40 DUP5 ADD MLOAD SWAP1 POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST DUP2 DUP4 DUP3 CALLDATACOPY PUSH1 0x0 SWAP2 ADD SWAP1 DUP2 MSTORE SWAP2 SWAP1 POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 DUP6 DUP7 0xA5 0xAA DUP8 0xCF 0xF8 PUSH27 0x1D8E1DC4952C1D3B167EBFAFAB4C2B56ED97ED8A5EC5921664736F PUSH13 0x63430008110033000000000000 ","sourceMap":"695:6680:6:-:0;;;1784:16;;;;;;;;;;695:6680;;;;;;"},"deployedBytecode":{"functionDebugData":{"@_362":{"entryPoint":null,"id":362,"parameterSlots":0,"returnSlots":0},"@_call_760":{"entryPoint":2272,"id":760,"parameterSlots":4,"returnSlots":1},"@executeCall_391":{"entryPoint":1571,"id":391,"parameterSlots":4,"returnSlots":1},"@isAuthorized_596":{"entryPoint":1956,"id":596,"parameterSlots":1,"returnSlots":1},"@isLocked_505":{"entryPoint":null,"id":505,"parameterSlots":0,"returnSlots":1},"@lock_493":{"entryPoint":1735,"id":493,"parameterSlots":1,"returnSlots":0},"@lockedUntil_287":{"entryPoint":null,"id":287,"parameterSlots":0,"returnSlots":0},"@onERC1155BatchReceived_728":{"entryPoint":null,"id":728,"parameterSlots":5,"returnSlots":1},"@onERC1155Received_704":{"entryPoint":null,"id":704,"parameterSlots":5,"returnSlots":1},"@onERC721Received_682":{"entryPoint":1317,"id":682,"parameterSlots":4,"returnSlots":1},"@owner_554":{"entryPoint":1421,"id":554,"parameterSlots":0,"returnSlots":1},"@permissions_294":{"entryPoint":null,"id":294,"parameterSlots":0,"returnSlots":0},"@setPermissions_464":{"entryPoint":860,"id":464,"parameterSlots":4,"returnSlots":0},"@supportsInterface_635":{"entryPoint":757,"id":635,"parameterSlots":1,"returnSlots":1},"@token_520":{"entryPoint":1932,"id":520,"parameterSlots":0,"returnSlots":3},"@token_867":{"entryPoint":2189,"id":867,"parameterSlots":0,"returnSlots":3},"abi_decode_array_address_dyn_calldata":{"entryPoint":2445,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_array_uint256_dyn":{"entryPoint":3216,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_bytes":{"entryPoint":2724,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_address":{"entryPoint":3648,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_address_fromMemory":{"entryPoint":3780,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_addresst_address":{"entryPoint":2944,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_tuple_t_addresst_addresst_array$_t_uint256_$dyn_memory_ptrt_array$_t_uint256_$dyn_memory_ptrt_bytes_memory_ptr":{"entryPoint":3344,"id":null,"parameterSlots":2,"returnSlots":5},"abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr":{"entryPoint":2836,"id":null,"parameterSlots":2,"returnSlots":4},"abi_decode_tuple_t_addresst_addresst_uint256t_uint256t_bytes_memory_ptr":{"entryPoint":3543,"id":null,"parameterSlots":2,"returnSlots":5},"abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptr":{"entryPoint":3001,"id":null,"parameterSlots":2,"returnSlots":4},"abi_decode_tuple_t_array$_t_address_$dyn_calldata_ptrt_array$_t_bool_$dyn_calldata_ptr":{"entryPoint":2521,"id":null,"parameterSlots":2,"returnSlots":4},"abi_decode_tuple_t_bool":{"entryPoint":3699,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_bytes4":{"entryPoint":2396,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_uint256":{"entryPoint":3518,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_uint256t_address_payablet_uint256_fromMemory":{"entryPoint":3881,"id":null,"parameterSlots":2,"returnSlots":3},"abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed":{"entryPoint":3938,"id":null,"parameterSlots":3,"returnSlots":1},"abi_encode_tuple_t_address__to_t_address__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_address_t_address_t_bool__to_t_address_t_address_t_bool__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":4,"returnSlots":1},"abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed":{"entryPoint":3809,"id":null,"parameterSlots":3,"returnSlots":1},"abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed":{"entryPoint":3138,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_uint256_t_address_t_uint256__to_t_uint256_t_address_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":4,"returnSlots":1},"allocate_memory":{"entryPoint":2675,"id":null,"parameterSlots":1,"returnSlots":1},"checked_add_t_uint256":{"entryPoint":3856,"id":null,"parameterSlots":2,"returnSlots":1},"increment_t_uint256":{"entryPoint":3755,"id":null,"parameterSlots":1,"returnSlots":1},"panic_error_0x11":{"entryPoint":3733,"id":null,"parameterSlots":0,"returnSlots":0},"panic_error_0x32":{"entryPoint":3677,"id":null,"parameterSlots":0,"returnSlots":0},"panic_error_0x41":{"entryPoint":2653,"id":null,"parameterSlots":0,"returnSlots":0},"validator_revert_address":{"entryPoint":2629,"id":null,"parameterSlots":1,"returnSlots":0}},"generatedSources":[{"ast":{"nodeType":"YulBlock","src":"0:11566:9","statements":[{"nodeType":"YulBlock","src":"6:3:9","statements":[]},{"body":{"nodeType":"YulBlock","src":"83:217:9","statements":[{"body":{"nodeType":"YulBlock","src":"129:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"138:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"141:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"131:6:9"},"nodeType":"YulFunctionCall","src":"131:12:9"},"nodeType":"YulExpressionStatement","src":"131:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"104:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"113:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"100:3:9"},"nodeType":"YulFunctionCall","src":"100:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"125:2:9","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"96:3:9"},"nodeType":"YulFunctionCall","src":"96:32:9"},"nodeType":"YulIf","src":"93:52:9"},{"nodeType":"YulVariableDeclaration","src":"154:36:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"180:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"167:12:9"},"nodeType":"YulFunctionCall","src":"167:23:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"158:5:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"254:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"263:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"266:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"256:6:9"},"nodeType":"YulFunctionCall","src":"256:12:9"},"nodeType":"YulExpressionStatement","src":"256:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"212:5:9"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"223:5:9"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"234:3:9","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"239:10:9","type":"","value":"0xffffffff"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"230:3:9"},"nodeType":"YulFunctionCall","src":"230:20:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"219:3:9"},"nodeType":"YulFunctionCall","src":"219:32:9"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"209:2:9"},"nodeType":"YulFunctionCall","src":"209:43:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"202:6:9"},"nodeType":"YulFunctionCall","src":"202:51:9"},"nodeType":"YulIf","src":"199:71:9"},{"nodeType":"YulAssignment","src":"279:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"289:5:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"279:6:9"}]}]},"name":"abi_decode_tuple_t_bytes4","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"49:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"60:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"72:6:9","type":""}],"src":"14:286:9"},{"body":{"nodeType":"YulBlock","src":"400:92:9","statements":[{"nodeType":"YulAssignment","src":"410:26:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"422:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"433:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"418:3:9"},"nodeType":"YulFunctionCall","src":"418:18:9"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"410:4:9"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"452:9:9"},{"arguments":[{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"477:6:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"470:6:9"},"nodeType":"YulFunctionCall","src":"470:14:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"463:6:9"},"nodeType":"YulFunctionCall","src":"463:22:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"445:6:9"},"nodeType":"YulFunctionCall","src":"445:41:9"},"nodeType":"YulExpressionStatement","src":"445:41:9"}]},"name":"abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"369:9:9","type":""},{"name":"value0","nodeType":"YulTypedName","src":"380:6:9","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"391:4:9","type":""}],"src":"305:187:9"},{"body":{"nodeType":"YulBlock","src":"581:283:9","statements":[{"body":{"nodeType":"YulBlock","src":"630:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"639:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"642:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"632:6:9"},"nodeType":"YulFunctionCall","src":"632:12:9"},"nodeType":"YulExpressionStatement","src":"632:12:9"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"609:6:9"},{"kind":"number","nodeType":"YulLiteral","src":"617:4:9","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"605:3:9"},"nodeType":"YulFunctionCall","src":"605:17:9"},{"name":"end","nodeType":"YulIdentifier","src":"624:3:9"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"601:3:9"},"nodeType":"YulFunctionCall","src":"601:27:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"594:6:9"},"nodeType":"YulFunctionCall","src":"594:35:9"},"nodeType":"YulIf","src":"591:55:9"},{"nodeType":"YulAssignment","src":"655:30:9","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"678:6:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"665:12:9"},"nodeType":"YulFunctionCall","src":"665:20:9"},"variableNames":[{"name":"length","nodeType":"YulIdentifier","src":"655:6:9"}]},{"body":{"nodeType":"YulBlock","src":"728:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"737:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"740:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"730:6:9"},"nodeType":"YulFunctionCall","src":"730:12:9"},"nodeType":"YulExpressionStatement","src":"730:12:9"}]},"condition":{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"700:6:9"},{"kind":"number","nodeType":"YulLiteral","src":"708:18:9","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"697:2:9"},"nodeType":"YulFunctionCall","src":"697:30:9"},"nodeType":"YulIf","src":"694:50:9"},{"nodeType":"YulAssignment","src":"753:29:9","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"769:6:9"},{"kind":"number","nodeType":"YulLiteral","src":"777:4:9","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"765:3:9"},"nodeType":"YulFunctionCall","src":"765:17:9"},"variableNames":[{"name":"arrayPos","nodeType":"YulIdentifier","src":"753:8:9"}]},{"body":{"nodeType":"YulBlock","src":"842:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"851:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"854:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"844:6:9"},"nodeType":"YulFunctionCall","src":"844:12:9"},"nodeType":"YulExpressionStatement","src":"844:12:9"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"805:6:9"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"817:1:9","type":"","value":"5"},{"name":"length","nodeType":"YulIdentifier","src":"820:6:9"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"813:3:9"},"nodeType":"YulFunctionCall","src":"813:14:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"801:3:9"},"nodeType":"YulFunctionCall","src":"801:27:9"},{"kind":"number","nodeType":"YulLiteral","src":"830:4:9","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"797:3:9"},"nodeType":"YulFunctionCall","src":"797:38:9"},{"name":"end","nodeType":"YulIdentifier","src":"837:3:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"794:2:9"},"nodeType":"YulFunctionCall","src":"794:47:9"},"nodeType":"YulIf","src":"791:67:9"}]},"name":"abi_decode_array_address_dyn_calldata","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"544:6:9","type":""},{"name":"end","nodeType":"YulTypedName","src":"552:3:9","type":""}],"returnVariables":[{"name":"arrayPos","nodeType":"YulTypedName","src":"560:8:9","type":""},{"name":"length","nodeType":"YulTypedName","src":"570:6:9","type":""}],"src":"497:367:9"},{"body":{"nodeType":"YulBlock","src":"1023:616:9","statements":[{"body":{"nodeType":"YulBlock","src":"1069:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1078:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1081:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1071:6:9"},"nodeType":"YulFunctionCall","src":"1071:12:9"},"nodeType":"YulExpressionStatement","src":"1071:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"1044:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"1053:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1040:3:9"},"nodeType":"YulFunctionCall","src":"1040:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"1065:2:9","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"1036:3:9"},"nodeType":"YulFunctionCall","src":"1036:32:9"},"nodeType":"YulIf","src":"1033:52:9"},{"nodeType":"YulVariableDeclaration","src":"1094:37:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1121:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1108:12:9"},"nodeType":"YulFunctionCall","src":"1108:23:9"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"1098:6:9","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1140:28:9","value":{"kind":"number","nodeType":"YulLiteral","src":"1150:18:9","type":"","value":"0xffffffffffffffff"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"1144:2:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"1195:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1204:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1207:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1197:6:9"},"nodeType":"YulFunctionCall","src":"1197:12:9"},"nodeType":"YulExpressionStatement","src":"1197:12:9"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"1183:6:9"},{"name":"_1","nodeType":"YulIdentifier","src":"1191:2:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"1180:2:9"},"nodeType":"YulFunctionCall","src":"1180:14:9"},"nodeType":"YulIf","src":"1177:34:9"},{"nodeType":"YulVariableDeclaration","src":"1220:96:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1288:9:9"},{"name":"offset","nodeType":"YulIdentifier","src":"1299:6:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1284:3:9"},"nodeType":"YulFunctionCall","src":"1284:22:9"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"1308:7:9"}],"functionName":{"name":"abi_decode_array_address_dyn_calldata","nodeType":"YulIdentifier","src":"1246:37:9"},"nodeType":"YulFunctionCall","src":"1246:70:9"},"variables":[{"name":"value0_1","nodeType":"YulTypedName","src":"1224:8:9","type":""},{"name":"value1_1","nodeType":"YulTypedName","src":"1234:8:9","type":""}]},{"nodeType":"YulAssignment","src":"1325:18:9","value":{"name":"value0_1","nodeType":"YulIdentifier","src":"1335:8:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"1325:6:9"}]},{"nodeType":"YulAssignment","src":"1352:18:9","value":{"name":"value1_1","nodeType":"YulIdentifier","src":"1362:8:9"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"1352:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"1379:48:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1412:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"1423:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1408:3:9"},"nodeType":"YulFunctionCall","src":"1408:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1395:12:9"},"nodeType":"YulFunctionCall","src":"1395:32:9"},"variables":[{"name":"offset_1","nodeType":"YulTypedName","src":"1383:8:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"1456:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1465:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1468:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1458:6:9"},"nodeType":"YulFunctionCall","src":"1458:12:9"},"nodeType":"YulExpressionStatement","src":"1458:12:9"}]},"condition":{"arguments":[{"name":"offset_1","nodeType":"YulIdentifier","src":"1442:8:9"},{"name":"_1","nodeType":"YulIdentifier","src":"1452:2:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"1439:2:9"},"nodeType":"YulFunctionCall","src":"1439:16:9"},"nodeType":"YulIf","src":"1436:36:9"},{"nodeType":"YulVariableDeclaration","src":"1481:98:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1549:9:9"},{"name":"offset_1","nodeType":"YulIdentifier","src":"1560:8:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1545:3:9"},"nodeType":"YulFunctionCall","src":"1545:24:9"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"1571:7:9"}],"functionName":{"name":"abi_decode_array_address_dyn_calldata","nodeType":"YulIdentifier","src":"1507:37:9"},"nodeType":"YulFunctionCall","src":"1507:72:9"},"variables":[{"name":"value2_1","nodeType":"YulTypedName","src":"1485:8:9","type":""},{"name":"value3_1","nodeType":"YulTypedName","src":"1495:8:9","type":""}]},{"nodeType":"YulAssignment","src":"1588:18:9","value":{"name":"value2_1","nodeType":"YulIdentifier","src":"1598:8:9"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"1588:6:9"}]},{"nodeType":"YulAssignment","src":"1615:18:9","value":{"name":"value3_1","nodeType":"YulIdentifier","src":"1625:8:9"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"1615:6:9"}]}]},"name":"abi_decode_tuple_t_array$_t_address_$dyn_calldata_ptrt_array$_t_bool_$dyn_calldata_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"965:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"976:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"988:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"996:6:9","type":""},{"name":"value2","nodeType":"YulTypedName","src":"1004:6:9","type":""},{"name":"value3","nodeType":"YulTypedName","src":"1012:6:9","type":""}],"src":"869:770:9"},{"body":{"nodeType":"YulBlock","src":"1689:86:9","statements":[{"body":{"nodeType":"YulBlock","src":"1753:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1762:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1765:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1755:6:9"},"nodeType":"YulFunctionCall","src":"1755:12:9"},"nodeType":"YulExpressionStatement","src":"1755:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1712:5:9"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1723:5:9"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1738:3:9","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"1743:1:9","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1734:3:9"},"nodeType":"YulFunctionCall","src":"1734:11:9"},{"kind":"number","nodeType":"YulLiteral","src":"1747:1:9","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1730:3:9"},"nodeType":"YulFunctionCall","src":"1730:19:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1719:3:9"},"nodeType":"YulFunctionCall","src":"1719:31:9"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"1709:2:9"},"nodeType":"YulFunctionCall","src":"1709:42:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"1702:6:9"},"nodeType":"YulFunctionCall","src":"1702:50:9"},"nodeType":"YulIf","src":"1699:70:9"}]},"name":"validator_revert_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"value","nodeType":"YulTypedName","src":"1678:5:9","type":""}],"src":"1644:131:9"},{"body":{"nodeType":"YulBlock","src":"1812:95:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1829:1:9","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1836:3:9","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"1841:10:9","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1832:3:9"},"nodeType":"YulFunctionCall","src":"1832:20:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1822:6:9"},"nodeType":"YulFunctionCall","src":"1822:31:9"},"nodeType":"YulExpressionStatement","src":"1822:31:9"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1869:1:9","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"1872:4:9","type":"","value":"0x41"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1862:6:9"},"nodeType":"YulFunctionCall","src":"1862:15:9"},"nodeType":"YulExpressionStatement","src":"1862:15:9"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1893:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1896:4:9","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1886:6:9"},"nodeType":"YulFunctionCall","src":"1886:15:9"},"nodeType":"YulExpressionStatement","src":"1886:15:9"}]},"name":"panic_error_0x41","nodeType":"YulFunctionDefinition","src":"1780:127:9"},{"body":{"nodeType":"YulBlock","src":"1957:230:9","statements":[{"nodeType":"YulAssignment","src":"1967:19:9","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1983:2:9","type":"","value":"64"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"1977:5:9"},"nodeType":"YulFunctionCall","src":"1977:9:9"},"variableNames":[{"name":"memPtr","nodeType":"YulIdentifier","src":"1967:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"1995:58:9","value":{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"2017:6:9"},{"arguments":[{"arguments":[{"name":"size","nodeType":"YulIdentifier","src":"2033:4:9"},{"kind":"number","nodeType":"YulLiteral","src":"2039:2:9","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2029:3:9"},"nodeType":"YulFunctionCall","src":"2029:13:9"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2048:2:9","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"2044:3:9"},"nodeType":"YulFunctionCall","src":"2044:7:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"2025:3:9"},"nodeType":"YulFunctionCall","src":"2025:27:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2013:3:9"},"nodeType":"YulFunctionCall","src":"2013:40:9"},"variables":[{"name":"newFreePtr","nodeType":"YulTypedName","src":"1999:10:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"2128:22:9","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"2130:16:9"},"nodeType":"YulFunctionCall","src":"2130:18:9"},"nodeType":"YulExpressionStatement","src":"2130:18:9"}]},"condition":{"arguments":[{"arguments":[{"name":"newFreePtr","nodeType":"YulIdentifier","src":"2071:10:9"},{"kind":"number","nodeType":"YulLiteral","src":"2083:18:9","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2068:2:9"},"nodeType":"YulFunctionCall","src":"2068:34:9"},{"arguments":[{"name":"newFreePtr","nodeType":"YulIdentifier","src":"2107:10:9"},{"name":"memPtr","nodeType":"YulIdentifier","src":"2119:6:9"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"2104:2:9"},"nodeType":"YulFunctionCall","src":"2104:22:9"}],"functionName":{"name":"or","nodeType":"YulIdentifier","src":"2065:2:9"},"nodeType":"YulFunctionCall","src":"2065:62:9"},"nodeType":"YulIf","src":"2062:88:9"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2166:2:9","type":"","value":"64"},{"name":"newFreePtr","nodeType":"YulIdentifier","src":"2170:10:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2159:6:9"},"nodeType":"YulFunctionCall","src":"2159:22:9"},"nodeType":"YulExpressionStatement","src":"2159:22:9"}]},"name":"allocate_memory","nodeType":"YulFunctionDefinition","parameters":[{"name":"size","nodeType":"YulTypedName","src":"1937:4:9","type":""}],"returnVariables":[{"name":"memPtr","nodeType":"YulTypedName","src":"1946:6:9","type":""}],"src":"1912:275:9"},{"body":{"nodeType":"YulBlock","src":"2244:478:9","statements":[{"body":{"nodeType":"YulBlock","src":"2293:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2302:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2305:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2295:6:9"},"nodeType":"YulFunctionCall","src":"2295:12:9"},"nodeType":"YulExpressionStatement","src":"2295:12:9"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2272:6:9"},{"kind":"number","nodeType":"YulLiteral","src":"2280:4:9","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2268:3:9"},"nodeType":"YulFunctionCall","src":"2268:17:9"},{"name":"end","nodeType":"YulIdentifier","src":"2287:3:9"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"2264:3:9"},"nodeType":"YulFunctionCall","src":"2264:27:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"2257:6:9"},"nodeType":"YulFunctionCall","src":"2257:35:9"},"nodeType":"YulIf","src":"2254:55:9"},{"nodeType":"YulVariableDeclaration","src":"2318:30:9","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2341:6:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2328:12:9"},"nodeType":"YulFunctionCall","src":"2328:20:9"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"2322:2:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"2387:22:9","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"2389:16:9"},"nodeType":"YulFunctionCall","src":"2389:18:9"},"nodeType":"YulExpressionStatement","src":"2389:18:9"}]},"condition":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"2363:2:9"},{"kind":"number","nodeType":"YulLiteral","src":"2367:18:9","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2360:2:9"},"nodeType":"YulFunctionCall","src":"2360:26:9"},"nodeType":"YulIf","src":"2357:52:9"},{"nodeType":"YulVariableDeclaration","src":"2418:70:9","value":{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"2461:2:9"},{"kind":"number","nodeType":"YulLiteral","src":"2465:4:9","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2457:3:9"},"nodeType":"YulFunctionCall","src":"2457:13:9"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2476:2:9","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"2472:3:9"},"nodeType":"YulFunctionCall","src":"2472:7:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"2453:3:9"},"nodeType":"YulFunctionCall","src":"2453:27:9"},{"kind":"number","nodeType":"YulLiteral","src":"2482:4:9","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2449:3:9"},"nodeType":"YulFunctionCall","src":"2449:38:9"}],"functionName":{"name":"allocate_memory","nodeType":"YulIdentifier","src":"2433:15:9"},"nodeType":"YulFunctionCall","src":"2433:55:9"},"variables":[{"name":"array_1","nodeType":"YulTypedName","src":"2422:7:9","type":""}]},{"expression":{"arguments":[{"name":"array_1","nodeType":"YulIdentifier","src":"2504:7:9"},{"name":"_1","nodeType":"YulIdentifier","src":"2513:2:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2497:6:9"},"nodeType":"YulFunctionCall","src":"2497:19:9"},"nodeType":"YulExpressionStatement","src":"2497:19:9"},{"body":{"nodeType":"YulBlock","src":"2564:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2573:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2576:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2566:6:9"},"nodeType":"YulFunctionCall","src":"2566:12:9"},"nodeType":"YulExpressionStatement","src":"2566:12:9"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2539:6:9"},{"name":"_1","nodeType":"YulIdentifier","src":"2547:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2535:3:9"},"nodeType":"YulFunctionCall","src":"2535:15:9"},{"kind":"number","nodeType":"YulLiteral","src":"2552:4:9","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2531:3:9"},"nodeType":"YulFunctionCall","src":"2531:26:9"},{"name":"end","nodeType":"YulIdentifier","src":"2559:3:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2528:2:9"},"nodeType":"YulFunctionCall","src":"2528:35:9"},"nodeType":"YulIf","src":"2525:55:9"},{"expression":{"arguments":[{"arguments":[{"name":"array_1","nodeType":"YulIdentifier","src":"2606:7:9"},{"kind":"number","nodeType":"YulLiteral","src":"2615:4:9","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2602:3:9"},"nodeType":"YulFunctionCall","src":"2602:18:9"},{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2626:6:9"},{"kind":"number","nodeType":"YulLiteral","src":"2634:4:9","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2622:3:9"},"nodeType":"YulFunctionCall","src":"2622:17:9"},{"name":"_1","nodeType":"YulIdentifier","src":"2641:2:9"}],"functionName":{"name":"calldatacopy","nodeType":"YulIdentifier","src":"2589:12:9"},"nodeType":"YulFunctionCall","src":"2589:55:9"},"nodeType":"YulExpressionStatement","src":"2589:55:9"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"array_1","nodeType":"YulIdentifier","src":"2668:7:9"},{"name":"_1","nodeType":"YulIdentifier","src":"2677:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2664:3:9"},"nodeType":"YulFunctionCall","src":"2664:16:9"},{"kind":"number","nodeType":"YulLiteral","src":"2682:4:9","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2660:3:9"},"nodeType":"YulFunctionCall","src":"2660:27:9"},{"kind":"number","nodeType":"YulLiteral","src":"2689:1:9","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2653:6:9"},"nodeType":"YulFunctionCall","src":"2653:38:9"},"nodeType":"YulExpressionStatement","src":"2653:38:9"},{"nodeType":"YulAssignment","src":"2700:16:9","value":{"name":"array_1","nodeType":"YulIdentifier","src":"2709:7:9"},"variableNames":[{"name":"array","nodeType":"YulIdentifier","src":"2700:5:9"}]}]},"name":"abi_decode_bytes","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"2218:6:9","type":""},{"name":"end","nodeType":"YulTypedName","src":"2226:3:9","type":""}],"returnVariables":[{"name":"array","nodeType":"YulTypedName","src":"2234:5:9","type":""}],"src":"2192:530:9"},{"body":{"nodeType":"YulBlock","src":"2857:535:9","statements":[{"body":{"nodeType":"YulBlock","src":"2904:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2913:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2916:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2906:6:9"},"nodeType":"YulFunctionCall","src":"2906:12:9"},"nodeType":"YulExpressionStatement","src":"2906:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"2878:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"2887:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"2874:3:9"},"nodeType":"YulFunctionCall","src":"2874:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"2899:3:9","type":"","value":"128"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"2870:3:9"},"nodeType":"YulFunctionCall","src":"2870:33:9"},"nodeType":"YulIf","src":"2867:53:9"},{"nodeType":"YulVariableDeclaration","src":"2929:36:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2955:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2942:12:9"},"nodeType":"YulFunctionCall","src":"2942:23:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"2933:5:9","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"2999:5:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"2974:24:9"},"nodeType":"YulFunctionCall","src":"2974:31:9"},"nodeType":"YulExpressionStatement","src":"2974:31:9"},{"nodeType":"YulAssignment","src":"3014:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"3024:5:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"3014:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"3038:47:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3070:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"3081:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3066:3:9"},"nodeType":"YulFunctionCall","src":"3066:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3053:12:9"},"nodeType":"YulFunctionCall","src":"3053:32:9"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"3042:7:9","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"3119:7:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"3094:24:9"},"nodeType":"YulFunctionCall","src":"3094:33:9"},"nodeType":"YulExpressionStatement","src":"3094:33:9"},{"nodeType":"YulAssignment","src":"3136:17:9","value":{"name":"value_1","nodeType":"YulIdentifier","src":"3146:7:9"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"3136:6:9"}]},{"nodeType":"YulAssignment","src":"3162:42:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3189:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"3200:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3185:3:9"},"nodeType":"YulFunctionCall","src":"3185:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3172:12:9"},"nodeType":"YulFunctionCall","src":"3172:32:9"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"3162:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"3213:46:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3244:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"3255:2:9","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3240:3:9"},"nodeType":"YulFunctionCall","src":"3240:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3227:12:9"},"nodeType":"YulFunctionCall","src":"3227:32:9"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"3217:6:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"3302:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3311:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3314:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3304:6:9"},"nodeType":"YulFunctionCall","src":"3304:12:9"},"nodeType":"YulExpressionStatement","src":"3304:12:9"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"3274:6:9"},{"kind":"number","nodeType":"YulLiteral","src":"3282:18:9","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"3271:2:9"},"nodeType":"YulFunctionCall","src":"3271:30:9"},"nodeType":"YulIf","src":"3268:50:9"},{"nodeType":"YulAssignment","src":"3327:59:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3358:9:9"},{"name":"offset","nodeType":"YulIdentifier","src":"3369:6:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3354:3:9"},"nodeType":"YulFunctionCall","src":"3354:22:9"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"3378:7:9"}],"functionName":{"name":"abi_decode_bytes","nodeType":"YulIdentifier","src":"3337:16:9"},"nodeType":"YulFunctionCall","src":"3337:49:9"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"3327:6:9"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"2799:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"2810:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"2822:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"2830:6:9","type":""},{"name":"value2","nodeType":"YulTypedName","src":"2838:6:9","type":""},{"name":"value3","nodeType":"YulTypedName","src":"2846:6:9","type":""}],"src":"2727:665:9"},{"body":{"nodeType":"YulBlock","src":"3496:103:9","statements":[{"nodeType":"YulAssignment","src":"3506:26:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3518:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"3529:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3514:3:9"},"nodeType":"YulFunctionCall","src":"3514:18:9"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"3506:4:9"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3548:9:9"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"3563:6:9"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3575:3:9","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"3580:10:9","type":"","value":"0xffffffff"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"3571:3:9"},"nodeType":"YulFunctionCall","src":"3571:20:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"3559:3:9"},"nodeType":"YulFunctionCall","src":"3559:33:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"3541:6:9"},"nodeType":"YulFunctionCall","src":"3541:52:9"},"nodeType":"YulExpressionStatement","src":"3541:52:9"}]},"name":"abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"3465:9:9","type":""},{"name":"value0","nodeType":"YulTypedName","src":"3476:6:9","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"3487:4:9","type":""}],"src":"3397:202:9"},{"body":{"nodeType":"YulBlock","src":"3691:301:9","statements":[{"body":{"nodeType":"YulBlock","src":"3737:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3746:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3749:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3739:6:9"},"nodeType":"YulFunctionCall","src":"3739:12:9"},"nodeType":"YulExpressionStatement","src":"3739:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"3712:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"3721:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"3708:3:9"},"nodeType":"YulFunctionCall","src":"3708:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"3733:2:9","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"3704:3:9"},"nodeType":"YulFunctionCall","src":"3704:32:9"},"nodeType":"YulIf","src":"3701:52:9"},{"nodeType":"YulVariableDeclaration","src":"3762:36:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3788:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3775:12:9"},"nodeType":"YulFunctionCall","src":"3775:23:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"3766:5:9","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"3832:5:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"3807:24:9"},"nodeType":"YulFunctionCall","src":"3807:31:9"},"nodeType":"YulExpressionStatement","src":"3807:31:9"},{"nodeType":"YulAssignment","src":"3847:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"3857:5:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"3847:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"3871:47:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3903:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"3914:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3899:3:9"},"nodeType":"YulFunctionCall","src":"3899:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3886:12:9"},"nodeType":"YulFunctionCall","src":"3886:32:9"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"3875:7:9","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"3952:7:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"3927:24:9"},"nodeType":"YulFunctionCall","src":"3927:33:9"},"nodeType":"YulExpressionStatement","src":"3927:33:9"},{"nodeType":"YulAssignment","src":"3969:17:9","value":{"name":"value_1","nodeType":"YulIdentifier","src":"3979:7:9"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"3969:6:9"}]}]},"name":"abi_decode_tuple_t_addresst_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"3649:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"3660:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"3672:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"3680:6:9","type":""}],"src":"3604:388:9"},{"body":{"nodeType":"YulBlock","src":"4098:102:9","statements":[{"nodeType":"YulAssignment","src":"4108:26:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4120:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"4131:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4116:3:9"},"nodeType":"YulFunctionCall","src":"4116:18:9"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"4108:4:9"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4150:9:9"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"4165:6:9"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4181:3:9","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"4186:1:9","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"4177:3:9"},"nodeType":"YulFunctionCall","src":"4177:11:9"},{"kind":"number","nodeType":"YulLiteral","src":"4190:1:9","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"4173:3:9"},"nodeType":"YulFunctionCall","src":"4173:19:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"4161:3:9"},"nodeType":"YulFunctionCall","src":"4161:32:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"4143:6:9"},"nodeType":"YulFunctionCall","src":"4143:51:9"},"nodeType":"YulExpressionStatement","src":"4143:51:9"}]},"name":"abi_encode_tuple_t_address__to_t_address__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"4067:9:9","type":""},{"name":"value0","nodeType":"YulTypedName","src":"4078:6:9","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"4089:4:9","type":""}],"src":"3997:203:9"},{"body":{"nodeType":"YulBlock","src":"4328:671:9","statements":[{"body":{"nodeType":"YulBlock","src":"4374:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4383:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4386:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4376:6:9"},"nodeType":"YulFunctionCall","src":"4376:12:9"},"nodeType":"YulExpressionStatement","src":"4376:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"4349:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"4358:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"4345:3:9"},"nodeType":"YulFunctionCall","src":"4345:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"4370:2:9","type":"","value":"96"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"4341:3:9"},"nodeType":"YulFunctionCall","src":"4341:32:9"},"nodeType":"YulIf","src":"4338:52:9"},{"nodeType":"YulVariableDeclaration","src":"4399:36:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4425:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4412:12:9"},"nodeType":"YulFunctionCall","src":"4412:23:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"4403:5:9","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"4469:5:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"4444:24:9"},"nodeType":"YulFunctionCall","src":"4444:31:9"},"nodeType":"YulExpressionStatement","src":"4444:31:9"},{"nodeType":"YulAssignment","src":"4484:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"4494:5:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"4484:6:9"}]},{"nodeType":"YulAssignment","src":"4508:42:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4535:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"4546:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4531:3:9"},"nodeType":"YulFunctionCall","src":"4531:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4518:12:9"},"nodeType":"YulFunctionCall","src":"4518:32:9"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"4508:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"4559:46:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4590:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"4601:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4586:3:9"},"nodeType":"YulFunctionCall","src":"4586:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4573:12:9"},"nodeType":"YulFunctionCall","src":"4573:32:9"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"4563:6:9","type":""}]},{"nodeType":"YulVariableDeclaration","src":"4614:28:9","value":{"kind":"number","nodeType":"YulLiteral","src":"4624:18:9","type":"","value":"0xffffffffffffffff"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"4618:2:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"4669:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4678:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4681:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4671:6:9"},"nodeType":"YulFunctionCall","src":"4671:12:9"},"nodeType":"YulExpressionStatement","src":"4671:12:9"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"4657:6:9"},{"name":"_1","nodeType":"YulIdentifier","src":"4665:2:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"4654:2:9"},"nodeType":"YulFunctionCall","src":"4654:14:9"},"nodeType":"YulIf","src":"4651:34:9"},{"nodeType":"YulVariableDeclaration","src":"4694:32:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4708:9:9"},{"name":"offset","nodeType":"YulIdentifier","src":"4719:6:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4704:3:9"},"nodeType":"YulFunctionCall","src":"4704:22:9"},"variables":[{"name":"_2","nodeType":"YulTypedName","src":"4698:2:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"4774:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4783:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4786:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4776:6:9"},"nodeType":"YulFunctionCall","src":"4776:12:9"},"nodeType":"YulExpressionStatement","src":"4776:12:9"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"4753:2:9"},{"kind":"number","nodeType":"YulLiteral","src":"4757:4:9","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4749:3:9"},"nodeType":"YulFunctionCall","src":"4749:13:9"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"4764:7:9"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"4745:3:9"},"nodeType":"YulFunctionCall","src":"4745:27:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"4738:6:9"},"nodeType":"YulFunctionCall","src":"4738:35:9"},"nodeType":"YulIf","src":"4735:55:9"},{"nodeType":"YulVariableDeclaration","src":"4799:30:9","value":{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"4826:2:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4813:12:9"},"nodeType":"YulFunctionCall","src":"4813:16:9"},"variables":[{"name":"length","nodeType":"YulTypedName","src":"4803:6:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"4856:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4865:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4868:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4858:6:9"},"nodeType":"YulFunctionCall","src":"4858:12:9"},"nodeType":"YulExpressionStatement","src":"4858:12:9"}]},"condition":{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"4844:6:9"},{"name":"_1","nodeType":"YulIdentifier","src":"4852:2:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"4841:2:9"},"nodeType":"YulFunctionCall","src":"4841:14:9"},"nodeType":"YulIf","src":"4838:34:9"},{"body":{"nodeType":"YulBlock","src":"4922:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4931:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4934:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4924:6:9"},"nodeType":"YulFunctionCall","src":"4924:12:9"},"nodeType":"YulExpressionStatement","src":"4924:12:9"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"4895:2:9"},{"name":"length","nodeType":"YulIdentifier","src":"4899:6:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4891:3:9"},"nodeType":"YulFunctionCall","src":"4891:15:9"},{"kind":"number","nodeType":"YulLiteral","src":"4908:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4887:3:9"},"nodeType":"YulFunctionCall","src":"4887:24:9"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"4913:7:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"4884:2:9"},"nodeType":"YulFunctionCall","src":"4884:37:9"},"nodeType":"YulIf","src":"4881:57:9"},{"nodeType":"YulAssignment","src":"4947:21:9","value":{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"4961:2:9"},{"kind":"number","nodeType":"YulLiteral","src":"4965:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4957:3:9"},"nodeType":"YulFunctionCall","src":"4957:11:9"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"4947:6:9"}]},{"nodeType":"YulAssignment","src":"4977:16:9","value":{"name":"length","nodeType":"YulIdentifier","src":"4987:6:9"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"4977:6:9"}]}]},"name":"abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"4270:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"4281:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"4293:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"4301:6:9","type":""},{"name":"value2","nodeType":"YulTypedName","src":"4309:6:9","type":""},{"name":"value3","nodeType":"YulTypedName","src":"4317:6:9","type":""}],"src":"4205:794:9"},{"body":{"nodeType":"YulBlock","src":"5123:427:9","statements":[{"nodeType":"YulVariableDeclaration","src":"5133:12:9","value":{"kind":"number","nodeType":"YulLiteral","src":"5143:2:9","type":"","value":"32"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"5137:2:9","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5161:9:9"},{"name":"_1","nodeType":"YulIdentifier","src":"5172:2:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5154:6:9"},"nodeType":"YulFunctionCall","src":"5154:21:9"},"nodeType":"YulExpressionStatement","src":"5154:21:9"},{"nodeType":"YulVariableDeclaration","src":"5184:27:9","value":{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"5204:6:9"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"5198:5:9"},"nodeType":"YulFunctionCall","src":"5198:13:9"},"variables":[{"name":"length","nodeType":"YulTypedName","src":"5188:6:9","type":""}]},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5231:9:9"},{"name":"_1","nodeType":"YulIdentifier","src":"5242:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5227:3:9"},"nodeType":"YulFunctionCall","src":"5227:18:9"},{"name":"length","nodeType":"YulIdentifier","src":"5247:6:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5220:6:9"},"nodeType":"YulFunctionCall","src":"5220:34:9"},"nodeType":"YulExpressionStatement","src":"5220:34:9"},{"nodeType":"YulVariableDeclaration","src":"5263:10:9","value":{"kind":"number","nodeType":"YulLiteral","src":"5272:1:9","type":"","value":"0"},"variables":[{"name":"i","nodeType":"YulTypedName","src":"5267:1:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"5332:90:9","statements":[{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5361:9:9"},{"name":"i","nodeType":"YulIdentifier","src":"5372:1:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5357:3:9"},"nodeType":"YulFunctionCall","src":"5357:17:9"},{"kind":"number","nodeType":"YulLiteral","src":"5376:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5353:3:9"},"nodeType":"YulFunctionCall","src":"5353:26:9"},{"arguments":[{"arguments":[{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"5395:6:9"},{"name":"i","nodeType":"YulIdentifier","src":"5403:1:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5391:3:9"},"nodeType":"YulFunctionCall","src":"5391:14:9"},{"name":"_1","nodeType":"YulIdentifier","src":"5407:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5387:3:9"},"nodeType":"YulFunctionCall","src":"5387:23:9"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"5381:5:9"},"nodeType":"YulFunctionCall","src":"5381:30:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5346:6:9"},"nodeType":"YulFunctionCall","src":"5346:66:9"},"nodeType":"YulExpressionStatement","src":"5346:66:9"}]},"condition":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"5293:1:9"},{"name":"length","nodeType":"YulIdentifier","src":"5296:6:9"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"5290:2:9"},"nodeType":"YulFunctionCall","src":"5290:13:9"},"nodeType":"YulForLoop","post":{"nodeType":"YulBlock","src":"5304:19:9","statements":[{"nodeType":"YulAssignment","src":"5306:15:9","value":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"5315:1:9"},{"name":"_1","nodeType":"YulIdentifier","src":"5318:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5311:3:9"},"nodeType":"YulFunctionCall","src":"5311:10:9"},"variableNames":[{"name":"i","nodeType":"YulIdentifier","src":"5306:1:9"}]}]},"pre":{"nodeType":"YulBlock","src":"5286:3:9","statements":[]},"src":"5282:140:9"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5446:9:9"},{"name":"length","nodeType":"YulIdentifier","src":"5457:6:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5442:3:9"},"nodeType":"YulFunctionCall","src":"5442:22:9"},{"kind":"number","nodeType":"YulLiteral","src":"5466:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5438:3:9"},"nodeType":"YulFunctionCall","src":"5438:31:9"},{"kind":"number","nodeType":"YulLiteral","src":"5471:1:9","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5431:6:9"},"nodeType":"YulFunctionCall","src":"5431:42:9"},"nodeType":"YulExpressionStatement","src":"5431:42:9"},{"nodeType":"YulAssignment","src":"5482:62:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5498:9:9"},{"arguments":[{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"5517:6:9"},{"kind":"number","nodeType":"YulLiteral","src":"5525:2:9","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5513:3:9"},"nodeType":"YulFunctionCall","src":"5513:15:9"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5534:2:9","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"5530:3:9"},"nodeType":"YulFunctionCall","src":"5530:7:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"5509:3:9"},"nodeType":"YulFunctionCall","src":"5509:29:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5494:3:9"},"nodeType":"YulFunctionCall","src":"5494:45:9"},{"kind":"number","nodeType":"YulLiteral","src":"5541:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5490:3:9"},"nodeType":"YulFunctionCall","src":"5490:54:9"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"5482:4:9"}]}]},"name":"abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"5092:9:9","type":""},{"name":"value0","nodeType":"YulTypedName","src":"5103:6:9","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"5114:4:9","type":""}],"src":"5004:546:9"},{"body":{"nodeType":"YulBlock","src":"5619:648:9","statements":[{"body":{"nodeType":"YulBlock","src":"5668:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5677:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"5680:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"5670:6:9"},"nodeType":"YulFunctionCall","src":"5670:12:9"},"nodeType":"YulExpressionStatement","src":"5670:12:9"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"5647:6:9"},{"kind":"number","nodeType":"YulLiteral","src":"5655:4:9","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5643:3:9"},"nodeType":"YulFunctionCall","src":"5643:17:9"},{"name":"end","nodeType":"YulIdentifier","src":"5662:3:9"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"5639:3:9"},"nodeType":"YulFunctionCall","src":"5639:27:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"5632:6:9"},"nodeType":"YulFunctionCall","src":"5632:35:9"},"nodeType":"YulIf","src":"5629:55:9"},{"nodeType":"YulVariableDeclaration","src":"5693:30:9","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"5716:6:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5703:12:9"},"nodeType":"YulFunctionCall","src":"5703:20:9"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"5697:2:9","type":""}]},{"nodeType":"YulVariableDeclaration","src":"5732:14:9","value":{"kind":"number","nodeType":"YulLiteral","src":"5742:4:9","type":"","value":"0x20"},"variables":[{"name":"_2","nodeType":"YulTypedName","src":"5736:2:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"5785:22:9","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"5787:16:9"},"nodeType":"YulFunctionCall","src":"5787:18:9"},"nodeType":"YulExpressionStatement","src":"5787:18:9"}]},"condition":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"5761:2:9"},{"kind":"number","nodeType":"YulLiteral","src":"5765:18:9","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"5758:2:9"},"nodeType":"YulFunctionCall","src":"5758:26:9"},"nodeType":"YulIf","src":"5755:52:9"},{"nodeType":"YulVariableDeclaration","src":"5816:20:9","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5830:1:9","type":"","value":"5"},{"name":"_1","nodeType":"YulIdentifier","src":"5833:2:9"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"5826:3:9"},"nodeType":"YulFunctionCall","src":"5826:10:9"},"variables":[{"name":"_3","nodeType":"YulTypedName","src":"5820:2:9","type":""}]},{"nodeType":"YulVariableDeclaration","src":"5845:39:9","value":{"arguments":[{"arguments":[{"name":"_3","nodeType":"YulIdentifier","src":"5876:2:9"},{"name":"_2","nodeType":"YulIdentifier","src":"5880:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5872:3:9"},"nodeType":"YulFunctionCall","src":"5872:11:9"}],"functionName":{"name":"allocate_memory","nodeType":"YulIdentifier","src":"5856:15:9"},"nodeType":"YulFunctionCall","src":"5856:28:9"},"variables":[{"name":"dst","nodeType":"YulTypedName","src":"5849:3:9","type":""}]},{"nodeType":"YulVariableDeclaration","src":"5893:16:9","value":{"name":"dst","nodeType":"YulIdentifier","src":"5906:3:9"},"variables":[{"name":"dst_1","nodeType":"YulTypedName","src":"5897:5:9","type":""}]},{"expression":{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"5925:3:9"},{"name":"_1","nodeType":"YulIdentifier","src":"5930:2:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5918:6:9"},"nodeType":"YulFunctionCall","src":"5918:15:9"},"nodeType":"YulExpressionStatement","src":"5918:15:9"},{"nodeType":"YulAssignment","src":"5942:19:9","value":{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"5953:3:9"},{"name":"_2","nodeType":"YulIdentifier","src":"5958:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5949:3:9"},"nodeType":"YulFunctionCall","src":"5949:12:9"},"variableNames":[{"name":"dst","nodeType":"YulIdentifier","src":"5942:3:9"}]},{"nodeType":"YulVariableDeclaration","src":"5970:38:9","value":{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"5992:6:9"},{"name":"_3","nodeType":"YulIdentifier","src":"6000:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5988:3:9"},"nodeType":"YulFunctionCall","src":"5988:15:9"},{"name":"_2","nodeType":"YulIdentifier","src":"6005:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5984:3:9"},"nodeType":"YulFunctionCall","src":"5984:24:9"},"variables":[{"name":"srcEnd","nodeType":"YulTypedName","src":"5974:6:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"6036:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6045:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"6048:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"6038:6:9"},"nodeType":"YulFunctionCall","src":"6038:12:9"},"nodeType":"YulExpressionStatement","src":"6038:12:9"}]},"condition":{"arguments":[{"name":"srcEnd","nodeType":"YulIdentifier","src":"6023:6:9"},{"name":"end","nodeType":"YulIdentifier","src":"6031:3:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"6020:2:9"},"nodeType":"YulFunctionCall","src":"6020:15:9"},"nodeType":"YulIf","src":"6017:35:9"},{"nodeType":"YulVariableDeclaration","src":"6061:26:9","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"6076:6:9"},{"name":"_2","nodeType":"YulIdentifier","src":"6084:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6072:3:9"},"nodeType":"YulFunctionCall","src":"6072:15:9"},"variables":[{"name":"src","nodeType":"YulTypedName","src":"6065:3:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"6152:86:9","statements":[{"expression":{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"6173:3:9"},{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"6191:3:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6178:12:9"},"nodeType":"YulFunctionCall","src":"6178:17:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6166:6:9"},"nodeType":"YulFunctionCall","src":"6166:30:9"},"nodeType":"YulExpressionStatement","src":"6166:30:9"},{"nodeType":"YulAssignment","src":"6209:19:9","value":{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"6220:3:9"},{"name":"_2","nodeType":"YulIdentifier","src":"6225:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6216:3:9"},"nodeType":"YulFunctionCall","src":"6216:12:9"},"variableNames":[{"name":"dst","nodeType":"YulIdentifier","src":"6209:3:9"}]}]},"condition":{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"6107:3:9"},{"name":"srcEnd","nodeType":"YulIdentifier","src":"6112:6:9"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"6104:2:9"},"nodeType":"YulFunctionCall","src":"6104:15:9"},"nodeType":"YulForLoop","post":{"nodeType":"YulBlock","src":"6120:23:9","statements":[{"nodeType":"YulAssignment","src":"6122:19:9","value":{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"6133:3:9"},{"name":"_2","nodeType":"YulIdentifier","src":"6138:2:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6129:3:9"},"nodeType":"YulFunctionCall","src":"6129:12:9"},"variableNames":[{"name":"src","nodeType":"YulIdentifier","src":"6122:3:9"}]}]},"pre":{"nodeType":"YulBlock","src":"6100:3:9","statements":[]},"src":"6096:142:9"},{"nodeType":"YulAssignment","src":"6247:14:9","value":{"name":"dst_1","nodeType":"YulIdentifier","src":"6256:5:9"},"variableNames":[{"name":"array","nodeType":"YulIdentifier","src":"6247:5:9"}]}]},"name":"abi_decode_array_uint256_dyn","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"5593:6:9","type":""},{"name":"end","nodeType":"YulTypedName","src":"5601:3:9","type":""}],"returnVariables":[{"name":"array","nodeType":"YulTypedName","src":"5609:5:9","type":""}],"src":"5555:712:9"},{"body":{"nodeType":"YulBlock","src":"6469:874:9","statements":[{"body":{"nodeType":"YulBlock","src":"6516:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6525:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"6528:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"6518:6:9"},"nodeType":"YulFunctionCall","src":"6518:12:9"},"nodeType":"YulExpressionStatement","src":"6518:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"6490:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"6499:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"6486:3:9"},"nodeType":"YulFunctionCall","src":"6486:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"6511:3:9","type":"","value":"160"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"6482:3:9"},"nodeType":"YulFunctionCall","src":"6482:33:9"},"nodeType":"YulIf","src":"6479:53:9"},{"nodeType":"YulVariableDeclaration","src":"6541:36:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6567:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6554:12:9"},"nodeType":"YulFunctionCall","src":"6554:23:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"6545:5:9","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"6611:5:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"6586:24:9"},"nodeType":"YulFunctionCall","src":"6586:31:9"},"nodeType":"YulExpressionStatement","src":"6586:31:9"},{"nodeType":"YulAssignment","src":"6626:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"6636:5:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"6626:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"6650:47:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6682:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"6693:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6678:3:9"},"nodeType":"YulFunctionCall","src":"6678:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6665:12:9"},"nodeType":"YulFunctionCall","src":"6665:32:9"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"6654:7:9","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"6731:7:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"6706:24:9"},"nodeType":"YulFunctionCall","src":"6706:33:9"},"nodeType":"YulExpressionStatement","src":"6706:33:9"},{"nodeType":"YulAssignment","src":"6748:17:9","value":{"name":"value_1","nodeType":"YulIdentifier","src":"6758:7:9"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"6748:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"6774:46:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6805:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"6816:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6801:3:9"},"nodeType":"YulFunctionCall","src":"6801:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6788:12:9"},"nodeType":"YulFunctionCall","src":"6788:32:9"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"6778:6:9","type":""}]},{"nodeType":"YulVariableDeclaration","src":"6829:28:9","value":{"kind":"number","nodeType":"YulLiteral","src":"6839:18:9","type":"","value":"0xffffffffffffffff"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"6833:2:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"6884:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6893:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"6896:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"6886:6:9"},"nodeType":"YulFunctionCall","src":"6886:12:9"},"nodeType":"YulExpressionStatement","src":"6886:12:9"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"6872:6:9"},{"name":"_1","nodeType":"YulIdentifier","src":"6880:2:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"6869:2:9"},"nodeType":"YulFunctionCall","src":"6869:14:9"},"nodeType":"YulIf","src":"6866:34:9"},{"nodeType":"YulAssignment","src":"6909:71:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6952:9:9"},{"name":"offset","nodeType":"YulIdentifier","src":"6963:6:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6948:3:9"},"nodeType":"YulFunctionCall","src":"6948:22:9"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"6972:7:9"}],"functionName":{"name":"abi_decode_array_uint256_dyn","nodeType":"YulIdentifier","src":"6919:28:9"},"nodeType":"YulFunctionCall","src":"6919:61:9"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"6909:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"6989:48:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7022:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"7033:2:9","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7018:3:9"},"nodeType":"YulFunctionCall","src":"7018:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7005:12:9"},"nodeType":"YulFunctionCall","src":"7005:32:9"},"variables":[{"name":"offset_1","nodeType":"YulTypedName","src":"6993:8:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"7066:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7075:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"7078:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7068:6:9"},"nodeType":"YulFunctionCall","src":"7068:12:9"},"nodeType":"YulExpressionStatement","src":"7068:12:9"}]},"condition":{"arguments":[{"name":"offset_1","nodeType":"YulIdentifier","src":"7052:8:9"},{"name":"_1","nodeType":"YulIdentifier","src":"7062:2:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"7049:2:9"},"nodeType":"YulFunctionCall","src":"7049:16:9"},"nodeType":"YulIf","src":"7046:36:9"},{"nodeType":"YulAssignment","src":"7091:73:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7134:9:9"},{"name":"offset_1","nodeType":"YulIdentifier","src":"7145:8:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7130:3:9"},"nodeType":"YulFunctionCall","src":"7130:24:9"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"7156:7:9"}],"functionName":{"name":"abi_decode_array_uint256_dyn","nodeType":"YulIdentifier","src":"7101:28:9"},"nodeType":"YulFunctionCall","src":"7101:63:9"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"7091:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"7173:49:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7206:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"7217:3:9","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7202:3:9"},"nodeType":"YulFunctionCall","src":"7202:19:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7189:12:9"},"nodeType":"YulFunctionCall","src":"7189:33:9"},"variables":[{"name":"offset_2","nodeType":"YulTypedName","src":"7177:8:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"7251:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7260:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"7263:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7253:6:9"},"nodeType":"YulFunctionCall","src":"7253:12:9"},"nodeType":"YulExpressionStatement","src":"7253:12:9"}]},"condition":{"arguments":[{"name":"offset_2","nodeType":"YulIdentifier","src":"7237:8:9"},{"name":"_1","nodeType":"YulIdentifier","src":"7247:2:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"7234:2:9"},"nodeType":"YulFunctionCall","src":"7234:16:9"},"nodeType":"YulIf","src":"7231:36:9"},{"nodeType":"YulAssignment","src":"7276:61:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7307:9:9"},{"name":"offset_2","nodeType":"YulIdentifier","src":"7318:8:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7303:3:9"},"nodeType":"YulFunctionCall","src":"7303:24:9"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"7329:7:9"}],"functionName":{"name":"abi_decode_bytes","nodeType":"YulIdentifier","src":"7286:16:9"},"nodeType":"YulFunctionCall","src":"7286:51:9"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"7276:6:9"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_array$_t_uint256_$dyn_memory_ptrt_array$_t_uint256_$dyn_memory_ptrt_bytes_memory_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"6403:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"6414:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"6426:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"6434:6:9","type":""},{"name":"value2","nodeType":"YulTypedName","src":"6442:6:9","type":""},{"name":"value3","nodeType":"YulTypedName","src":"6450:6:9","type":""},{"name":"value4","nodeType":"YulTypedName","src":"6458:6:9","type":""}],"src":"6272:1071:9"},{"body":{"nodeType":"YulBlock","src":"7449:76:9","statements":[{"nodeType":"YulAssignment","src":"7459:26:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7471:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"7482:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7467:3:9"},"nodeType":"YulFunctionCall","src":"7467:18:9"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"7459:4:9"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7501:9:9"},{"name":"value0","nodeType":"YulIdentifier","src":"7512:6:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7494:6:9"},"nodeType":"YulFunctionCall","src":"7494:25:9"},"nodeType":"YulExpressionStatement","src":"7494:25:9"}]},"name":"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"7418:9:9","type":""},{"name":"value0","nodeType":"YulTypedName","src":"7429:6:9","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"7440:4:9","type":""}],"src":"7348:177:9"},{"body":{"nodeType":"YulBlock","src":"7600:110:9","statements":[{"body":{"nodeType":"YulBlock","src":"7646:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7655:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"7658:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7648:6:9"},"nodeType":"YulFunctionCall","src":"7648:12:9"},"nodeType":"YulExpressionStatement","src":"7648:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"7621:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"7630:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"7617:3:9"},"nodeType":"YulFunctionCall","src":"7617:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"7642:2:9","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"7613:3:9"},"nodeType":"YulFunctionCall","src":"7613:32:9"},"nodeType":"YulIf","src":"7610:52:9"},{"nodeType":"YulAssignment","src":"7671:33:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7694:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7681:12:9"},"nodeType":"YulFunctionCall","src":"7681:23:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"7671:6:9"}]}]},"name":"abi_decode_tuple_t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"7566:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"7577:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"7589:6:9","type":""}],"src":"7530:180:9"},{"body":{"nodeType":"YulBlock","src":"7862:587:9","statements":[{"body":{"nodeType":"YulBlock","src":"7909:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7918:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"7921:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7911:6:9"},"nodeType":"YulFunctionCall","src":"7911:12:9"},"nodeType":"YulExpressionStatement","src":"7911:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"7883:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"7892:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"7879:3:9"},"nodeType":"YulFunctionCall","src":"7879:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"7904:3:9","type":"","value":"160"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"7875:3:9"},"nodeType":"YulFunctionCall","src":"7875:33:9"},"nodeType":"YulIf","src":"7872:53:9"},{"nodeType":"YulVariableDeclaration","src":"7934:36:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7960:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"7947:12:9"},"nodeType":"YulFunctionCall","src":"7947:23:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"7938:5:9","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"8004:5:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"7979:24:9"},"nodeType":"YulFunctionCall","src":"7979:31:9"},"nodeType":"YulExpressionStatement","src":"7979:31:9"},{"nodeType":"YulAssignment","src":"8019:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"8029:5:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"8019:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"8043:47:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8075:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"8086:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8071:3:9"},"nodeType":"YulFunctionCall","src":"8071:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8058:12:9"},"nodeType":"YulFunctionCall","src":"8058:32:9"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"8047:7:9","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"8124:7:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"8099:24:9"},"nodeType":"YulFunctionCall","src":"8099:33:9"},"nodeType":"YulExpressionStatement","src":"8099:33:9"},{"nodeType":"YulAssignment","src":"8141:17:9","value":{"name":"value_1","nodeType":"YulIdentifier","src":"8151:7:9"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"8141:6:9"}]},{"nodeType":"YulAssignment","src":"8167:42:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8194:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"8205:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8190:3:9"},"nodeType":"YulFunctionCall","src":"8190:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8177:12:9"},"nodeType":"YulFunctionCall","src":"8177:32:9"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"8167:6:9"}]},{"nodeType":"YulAssignment","src":"8218:42:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8245:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"8256:2:9","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8241:3:9"},"nodeType":"YulFunctionCall","src":"8241:18:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8228:12:9"},"nodeType":"YulFunctionCall","src":"8228:32:9"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"8218:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"8269:47:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8300:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"8311:3:9","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8296:3:9"},"nodeType":"YulFunctionCall","src":"8296:19:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8283:12:9"},"nodeType":"YulFunctionCall","src":"8283:33:9"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"8273:6:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"8359:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"8368:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"8371:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"8361:6:9"},"nodeType":"YulFunctionCall","src":"8361:12:9"},"nodeType":"YulExpressionStatement","src":"8361:12:9"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"8331:6:9"},{"kind":"number","nodeType":"YulLiteral","src":"8339:18:9","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"8328:2:9"},"nodeType":"YulFunctionCall","src":"8328:30:9"},"nodeType":"YulIf","src":"8325:50:9"},{"nodeType":"YulAssignment","src":"8384:59:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8415:9:9"},{"name":"offset","nodeType":"YulIdentifier","src":"8426:6:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8411:3:9"},"nodeType":"YulFunctionCall","src":"8411:22:9"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"8435:7:9"}],"functionName":{"name":"abi_decode_bytes","nodeType":"YulIdentifier","src":"8394:16:9"},"nodeType":"YulFunctionCall","src":"8394:49:9"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"8384:6:9"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256t_uint256t_bytes_memory_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"7796:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"7807:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"7819:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"7827:6:9","type":""},{"name":"value2","nodeType":"YulTypedName","src":"7835:6:9","type":""},{"name":"value3","nodeType":"YulTypedName","src":"7843:6:9","type":""},{"name":"value4","nodeType":"YulTypedName","src":"7851:6:9","type":""}],"src":"7715:734:9"},{"body":{"nodeType":"YulBlock","src":"8611:188:9","statements":[{"nodeType":"YulAssignment","src":"8621:26:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8633:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"8644:2:9","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8629:3:9"},"nodeType":"YulFunctionCall","src":"8629:18:9"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"8621:4:9"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8663:9:9"},{"name":"value0","nodeType":"YulIdentifier","src":"8674:6:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8656:6:9"},"nodeType":"YulFunctionCall","src":"8656:25:9"},"nodeType":"YulExpressionStatement","src":"8656:25:9"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8701:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"8712:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8697:3:9"},"nodeType":"YulFunctionCall","src":"8697:18:9"},{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"8721:6:9"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"8737:3:9","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"8742:1:9","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"8733:3:9"},"nodeType":"YulFunctionCall","src":"8733:11:9"},{"kind":"number","nodeType":"YulLiteral","src":"8746:1:9","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"8729:3:9"},"nodeType":"YulFunctionCall","src":"8729:19:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"8717:3:9"},"nodeType":"YulFunctionCall","src":"8717:32:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8690:6:9"},"nodeType":"YulFunctionCall","src":"8690:60:9"},"nodeType":"YulExpressionStatement","src":"8690:60:9"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8770:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"8781:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8766:3:9"},"nodeType":"YulFunctionCall","src":"8766:18:9"},{"name":"value2","nodeType":"YulIdentifier","src":"8786:6:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8759:6:9"},"nodeType":"YulFunctionCall","src":"8759:34:9"},"nodeType":"YulExpressionStatement","src":"8759:34:9"}]},"name":"abi_encode_tuple_t_uint256_t_address_t_uint256__to_t_uint256_t_address_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"8564:9:9","type":""},{"name":"value2","nodeType":"YulTypedName","src":"8575:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"8583:6:9","type":""},{"name":"value0","nodeType":"YulTypedName","src":"8591:6:9","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"8602:4:9","type":""}],"src":"8454:345:9"},{"body":{"nodeType":"YulBlock","src":"8874:177:9","statements":[{"body":{"nodeType":"YulBlock","src":"8920:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"8929:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"8932:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"8922:6:9"},"nodeType":"YulFunctionCall","src":"8922:12:9"},"nodeType":"YulExpressionStatement","src":"8922:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"8895:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"8904:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"8891:3:9"},"nodeType":"YulFunctionCall","src":"8891:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"8916:2:9","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"8887:3:9"},"nodeType":"YulFunctionCall","src":"8887:32:9"},"nodeType":"YulIf","src":"8884:52:9"},{"nodeType":"YulVariableDeclaration","src":"8945:36:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8971:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"8958:12:9"},"nodeType":"YulFunctionCall","src":"8958:23:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"8949:5:9","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"9015:5:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"8990:24:9"},"nodeType":"YulFunctionCall","src":"8990:31:9"},"nodeType":"YulExpressionStatement","src":"8990:31:9"},{"nodeType":"YulAssignment","src":"9030:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"9040:5:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"9030:6:9"}]}]},"name":"abi_decode_tuple_t_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"8840:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"8851:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"8863:6:9","type":""}],"src":"8804:247:9"},{"body":{"nodeType":"YulBlock","src":"9088:95:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9105:1:9","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9112:3:9","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"9117:10:9","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"9108:3:9"},"nodeType":"YulFunctionCall","src":"9108:20:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9098:6:9"},"nodeType":"YulFunctionCall","src":"9098:31:9"},"nodeType":"YulExpressionStatement","src":"9098:31:9"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9145:1:9","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"9148:4:9","type":"","value":"0x32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9138:6:9"},"nodeType":"YulFunctionCall","src":"9138:15:9"},"nodeType":"YulExpressionStatement","src":"9138:15:9"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9169:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"9172:4:9","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"9162:6:9"},"nodeType":"YulFunctionCall","src":"9162:15:9"},"nodeType":"YulExpressionStatement","src":"9162:15:9"}]},"name":"panic_error_0x32","nodeType":"YulFunctionDefinition","src":"9056:127:9"},{"body":{"nodeType":"YulBlock","src":"9255:206:9","statements":[{"body":{"nodeType":"YulBlock","src":"9301:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9310:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"9313:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"9303:6:9"},"nodeType":"YulFunctionCall","src":"9303:12:9"},"nodeType":"YulExpressionStatement","src":"9303:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"9276:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"9285:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"9272:3:9"},"nodeType":"YulFunctionCall","src":"9272:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"9297:2:9","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"9268:3:9"},"nodeType":"YulFunctionCall","src":"9268:32:9"},"nodeType":"YulIf","src":"9265:52:9"},{"nodeType":"YulVariableDeclaration","src":"9326:36:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9352:9:9"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"9339:12:9"},"nodeType":"YulFunctionCall","src":"9339:23:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"9330:5:9","type":""}]},{"body":{"nodeType":"YulBlock","src":"9415:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9424:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"9427:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"9417:6:9"},"nodeType":"YulFunctionCall","src":"9417:12:9"},"nodeType":"YulExpressionStatement","src":"9417:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"9384:5:9"},{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"9405:5:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"9398:6:9"},"nodeType":"YulFunctionCall","src":"9398:13:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"9391:6:9"},"nodeType":"YulFunctionCall","src":"9391:21:9"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"9381:2:9"},"nodeType":"YulFunctionCall","src":"9381:32:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"9374:6:9"},"nodeType":"YulFunctionCall","src":"9374:40:9"},"nodeType":"YulIf","src":"9371:60:9"},{"nodeType":"YulAssignment","src":"9440:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"9450:5:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"9440:6:9"}]}]},"name":"abi_decode_tuple_t_bool","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"9221:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"9232:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"9244:6:9","type":""}],"src":"9188:273:9"},{"body":{"nodeType":"YulBlock","src":"9617:234:9","statements":[{"nodeType":"YulAssignment","src":"9627:26:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9639:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"9650:2:9","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9635:3:9"},"nodeType":"YulFunctionCall","src":"9635:18:9"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"9627:4:9"}]},{"nodeType":"YulVariableDeclaration","src":"9662:29:9","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9680:3:9","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"9685:1:9","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"9676:3:9"},"nodeType":"YulFunctionCall","src":"9676:11:9"},{"kind":"number","nodeType":"YulLiteral","src":"9689:1:9","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"9672:3:9"},"nodeType":"YulFunctionCall","src":"9672:19:9"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"9666:2:9","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9707:9:9"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"9722:6:9"},{"name":"_1","nodeType":"YulIdentifier","src":"9730:2:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"9718:3:9"},"nodeType":"YulFunctionCall","src":"9718:15:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9700:6:9"},"nodeType":"YulFunctionCall","src":"9700:34:9"},"nodeType":"YulExpressionStatement","src":"9700:34:9"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9754:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"9765:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9750:3:9"},"nodeType":"YulFunctionCall","src":"9750:18:9"},{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"9774:6:9"},{"name":"_1","nodeType":"YulIdentifier","src":"9782:2:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"9770:3:9"},"nodeType":"YulFunctionCall","src":"9770:15:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9743:6:9"},"nodeType":"YulFunctionCall","src":"9743:43:9"},"nodeType":"YulExpressionStatement","src":"9743:43:9"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9806:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"9817:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9802:3:9"},"nodeType":"YulFunctionCall","src":"9802:18:9"},{"arguments":[{"arguments":[{"name":"value2","nodeType":"YulIdentifier","src":"9836:6:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"9829:6:9"},"nodeType":"YulFunctionCall","src":"9829:14:9"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"9822:6:9"},"nodeType":"YulFunctionCall","src":"9822:22:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9795:6:9"},"nodeType":"YulFunctionCall","src":"9795:50:9"},"nodeType":"YulExpressionStatement","src":"9795:50:9"}]},"name":"abi_encode_tuple_t_address_t_address_t_bool__to_t_address_t_address_t_bool__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"9570:9:9","type":""},{"name":"value2","nodeType":"YulTypedName","src":"9581:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"9589:6:9","type":""},{"name":"value0","nodeType":"YulTypedName","src":"9597:6:9","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"9608:4:9","type":""}],"src":"9466:385:9"},{"body":{"nodeType":"YulBlock","src":"9888:95:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9905:1:9","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9912:3:9","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"9917:10:9","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"9908:3:9"},"nodeType":"YulFunctionCall","src":"9908:20:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9898:6:9"},"nodeType":"YulFunctionCall","src":"9898:31:9"},"nodeType":"YulExpressionStatement","src":"9898:31:9"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9945:1:9","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"9948:4:9","type":"","value":"0x11"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9938:6:9"},"nodeType":"YulFunctionCall","src":"9938:15:9"},"nodeType":"YulExpressionStatement","src":"9938:15:9"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9969:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"9972:4:9","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"9962:6:9"},"nodeType":"YulFunctionCall","src":"9962:15:9"},"nodeType":"YulExpressionStatement","src":"9962:15:9"}]},"name":"panic_error_0x11","nodeType":"YulFunctionDefinition","src":"9856:127:9"},{"body":{"nodeType":"YulBlock","src":"10035:88:9","statements":[{"body":{"nodeType":"YulBlock","src":"10066:22:9","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x11","nodeType":"YulIdentifier","src":"10068:16:9"},"nodeType":"YulFunctionCall","src":"10068:18:9"},"nodeType":"YulExpressionStatement","src":"10068:18:9"}]},"condition":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"10051:5:9"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10062:1:9","type":"","value":"0"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"10058:3:9"},"nodeType":"YulFunctionCall","src":"10058:6:9"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"10048:2:9"},"nodeType":"YulFunctionCall","src":"10048:17:9"},"nodeType":"YulIf","src":"10045:43:9"},{"nodeType":"YulAssignment","src":"10097:20:9","value":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"10108:5:9"},{"kind":"number","nodeType":"YulLiteral","src":"10115:1:9","type":"","value":"1"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10104:3:9"},"nodeType":"YulFunctionCall","src":"10104:13:9"},"variableNames":[{"name":"ret","nodeType":"YulIdentifier","src":"10097:3:9"}]}]},"name":"increment_t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"value","nodeType":"YulTypedName","src":"10017:5:9","type":""}],"returnVariables":[{"name":"ret","nodeType":"YulTypedName","src":"10027:3:9","type":""}],"src":"9988:135:9"},{"body":{"nodeType":"YulBlock","src":"10209:170:9","statements":[{"body":{"nodeType":"YulBlock","src":"10255:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10264:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"10267:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"10257:6:9"},"nodeType":"YulFunctionCall","src":"10257:12:9"},"nodeType":"YulExpressionStatement","src":"10257:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"10230:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"10239:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"10226:3:9"},"nodeType":"YulFunctionCall","src":"10226:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"10251:2:9","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"10222:3:9"},"nodeType":"YulFunctionCall","src":"10222:32:9"},"nodeType":"YulIf","src":"10219:52:9"},{"nodeType":"YulVariableDeclaration","src":"10280:29:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10299:9:9"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"10293:5:9"},"nodeType":"YulFunctionCall","src":"10293:16:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"10284:5:9","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"10343:5:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"10318:24:9"},"nodeType":"YulFunctionCall","src":"10318:31:9"},"nodeType":"YulExpressionStatement","src":"10318:31:9"},{"nodeType":"YulAssignment","src":"10358:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"10368:5:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"10358:6:9"}]}]},"name":"abi_decode_tuple_t_address_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"10175:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"10186:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"10198:6:9","type":""}],"src":"10128:251:9"},{"body":{"nodeType":"YulBlock","src":"10513:259:9","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10530:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"10541:2:9","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10523:6:9"},"nodeType":"YulFunctionCall","src":"10523:21:9"},"nodeType":"YulExpressionStatement","src":"10523:21:9"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10564:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"10575:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10560:3:9"},"nodeType":"YulFunctionCall","src":"10560:18:9"},{"name":"value1","nodeType":"YulIdentifier","src":"10580:6:9"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10553:6:9"},"nodeType":"YulFunctionCall","src":"10553:34:9"},"nodeType":"YulExpressionStatement","src":"10553:34:9"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10613:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"10624:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10609:3:9"},"nodeType":"YulFunctionCall","src":"10609:18:9"},{"name":"value0","nodeType":"YulIdentifier","src":"10629:6:9"},{"name":"value1","nodeType":"YulIdentifier","src":"10637:6:9"}],"functionName":{"name":"calldatacopy","nodeType":"YulIdentifier","src":"10596:12:9"},"nodeType":"YulFunctionCall","src":"10596:48:9"},"nodeType":"YulExpressionStatement","src":"10596:48:9"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10668:9:9"},{"name":"value1","nodeType":"YulIdentifier","src":"10679:6:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10664:3:9"},"nodeType":"YulFunctionCall","src":"10664:22:9"},{"kind":"number","nodeType":"YulLiteral","src":"10688:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10660:3:9"},"nodeType":"YulFunctionCall","src":"10660:31:9"},{"kind":"number","nodeType":"YulLiteral","src":"10693:1:9","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10653:6:9"},"nodeType":"YulFunctionCall","src":"10653:42:9"},"nodeType":"YulExpressionStatement","src":"10653:42:9"},{"nodeType":"YulAssignment","src":"10704:62:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10720:9:9"},{"arguments":[{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"10739:6:9"},{"kind":"number","nodeType":"YulLiteral","src":"10747:2:9","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10735:3:9"},"nodeType":"YulFunctionCall","src":"10735:15:9"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10756:2:9","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"10752:3:9"},"nodeType":"YulFunctionCall","src":"10752:7:9"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"10731:3:9"},"nodeType":"YulFunctionCall","src":"10731:29:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10716:3:9"},"nodeType":"YulFunctionCall","src":"10716:45:9"},{"kind":"number","nodeType":"YulLiteral","src":"10763:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10712:3:9"},"nodeType":"YulFunctionCall","src":"10712:54:9"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"10704:4:9"}]}]},"name":"abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"10474:9:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"10485:6:9","type":""},{"name":"value0","nodeType":"YulTypedName","src":"10493:6:9","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"10504:4:9","type":""}],"src":"10384:388:9"},{"body":{"nodeType":"YulBlock","src":"10825:77:9","statements":[{"nodeType":"YulAssignment","src":"10835:16:9","value":{"arguments":[{"name":"x","nodeType":"YulIdentifier","src":"10846:1:9"},{"name":"y","nodeType":"YulIdentifier","src":"10849:1:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10842:3:9"},"nodeType":"YulFunctionCall","src":"10842:9:9"},"variableNames":[{"name":"sum","nodeType":"YulIdentifier","src":"10835:3:9"}]},{"body":{"nodeType":"YulBlock","src":"10874:22:9","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x11","nodeType":"YulIdentifier","src":"10876:16:9"},"nodeType":"YulFunctionCall","src":"10876:18:9"},"nodeType":"YulExpressionStatement","src":"10876:18:9"}]},"condition":{"arguments":[{"name":"x","nodeType":"YulIdentifier","src":"10866:1:9"},{"name":"sum","nodeType":"YulIdentifier","src":"10869:3:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"10863:2:9"},"nodeType":"YulFunctionCall","src":"10863:10:9"},"nodeType":"YulIf","src":"10860:36:9"}]},"name":"checked_add_t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"x","nodeType":"YulTypedName","src":"10808:1:9","type":""},{"name":"y","nodeType":"YulTypedName","src":"10811:1:9","type":""}],"returnVariables":[{"name":"sum","nodeType":"YulTypedName","src":"10817:3:9","type":""}],"src":"10777:125:9"},{"body":{"nodeType":"YulBlock","src":"11030:258:9","statements":[{"body":{"nodeType":"YulBlock","src":"11076:16:9","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"11085:1:9","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"11088:1:9","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"11078:6:9"},"nodeType":"YulFunctionCall","src":"11078:12:9"},"nodeType":"YulExpressionStatement","src":"11078:12:9"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"11051:7:9"},{"name":"headStart","nodeType":"YulIdentifier","src":"11060:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"11047:3:9"},"nodeType":"YulFunctionCall","src":"11047:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"11072:2:9","type":"","value":"96"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"11043:3:9"},"nodeType":"YulFunctionCall","src":"11043:32:9"},"nodeType":"YulIf","src":"11040:52:9"},{"nodeType":"YulAssignment","src":"11101:26:9","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11117:9:9"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"11111:5:9"},"nodeType":"YulFunctionCall","src":"11111:16:9"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"11101:6:9"}]},{"nodeType":"YulVariableDeclaration","src":"11136:38:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11159:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"11170:2:9","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11155:3:9"},"nodeType":"YulFunctionCall","src":"11155:18:9"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"11149:5:9"},"nodeType":"YulFunctionCall","src":"11149:25:9"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"11140:5:9","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"11208:5:9"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"11183:24:9"},"nodeType":"YulFunctionCall","src":"11183:31:9"},"nodeType":"YulExpressionStatement","src":"11183:31:9"},{"nodeType":"YulAssignment","src":"11223:15:9","value":{"name":"value","nodeType":"YulIdentifier","src":"11233:5:9"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"11223:6:9"}]},{"nodeType":"YulAssignment","src":"11247:35:9","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"11267:9:9"},{"kind":"number","nodeType":"YulLiteral","src":"11278:2:9","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11263:3:9"},"nodeType":"YulFunctionCall","src":"11263:18:9"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"11257:5:9"},"nodeType":"YulFunctionCall","src":"11257:25:9"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"11247:6:9"}]}]},"name":"abi_decode_tuple_t_uint256t_address_payablet_uint256_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"10980:9:9","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"10991:7:9","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"11003:6:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"11011:6:9","type":""},{"name":"value2","nodeType":"YulTypedName","src":"11019:6:9","type":""}],"src":"10907:381:9"},{"body":{"nodeType":"YulBlock","src":"11440:124:9","statements":[{"expression":{"arguments":[{"name":"pos","nodeType":"YulIdentifier","src":"11463:3:9"},{"name":"value0","nodeType":"YulIdentifier","src":"11468:6:9"},{"name":"value1","nodeType":"YulIdentifier","src":"11476:6:9"}],"functionName":{"name":"calldatacopy","nodeType":"YulIdentifier","src":"11450:12:9"},"nodeType":"YulFunctionCall","src":"11450:33:9"},"nodeType":"YulExpressionStatement","src":"11450:33:9"},{"nodeType":"YulVariableDeclaration","src":"11492:26:9","value":{"arguments":[{"name":"pos","nodeType":"YulIdentifier","src":"11506:3:9"},{"name":"value1","nodeType":"YulIdentifier","src":"11511:6:9"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"11502:3:9"},"nodeType":"YulFunctionCall","src":"11502:16:9"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"11496:2:9","type":""}]},{"expression":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"11534:2:9"},{"kind":"number","nodeType":"YulLiteral","src":"11538:1:9","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"11527:6:9"},"nodeType":"YulFunctionCall","src":"11527:13:9"},"nodeType":"YulExpressionStatement","src":"11527:13:9"},{"nodeType":"YulAssignment","src":"11549:9:9","value":{"name":"_1","nodeType":"YulIdentifier","src":"11556:2:9"},"variableNames":[{"name":"end","nodeType":"YulIdentifier","src":"11549:3:9"}]}]},"name":"abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"pos","nodeType":"YulTypedName","src":"11408:3:9","type":""},{"name":"value1","nodeType":"YulTypedName","src":"11413:6:9","type":""},{"name":"value0","nodeType":"YulTypedName","src":"11421:6:9","type":""}],"returnVariables":[{"name":"end","nodeType":"YulTypedName","src":"11432:3:9","type":""}],"src":"11293:271:9"}]},"contents":"{\n { }\n function abi_decode_tuple_t_bytes4(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := calldataload(headStart)\n if iszero(eq(value, and(value, shl(224, 0xffffffff)))) { revert(0, 0) }\n value0 := value\n }\n function abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, iszero(iszero(value0)))\n }\n function abi_decode_array_address_dyn_calldata(offset, end) -> arrayPos, length\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n length := calldataload(offset)\n if gt(length, 0xffffffffffffffff) { revert(0, 0) }\n arrayPos := add(offset, 0x20)\n if gt(add(add(offset, shl(5, length)), 0x20), end) { revert(0, 0) }\n }\n function abi_decode_tuple_t_array$_t_address_$dyn_calldata_ptrt_array$_t_bool_$dyn_calldata_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n let offset := calldataload(headStart)\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n let value0_1, value1_1 := abi_decode_array_address_dyn_calldata(add(headStart, offset), dataEnd)\n value0 := value0_1\n value1 := value1_1\n let offset_1 := calldataload(add(headStart, 32))\n if gt(offset_1, _1) { revert(0, 0) }\n let value2_1, value3_1 := abi_decode_array_address_dyn_calldata(add(headStart, offset_1), dataEnd)\n value2 := value2_1\n value3 := value3_1\n }\n function validator_revert_address(value)\n {\n if iszero(eq(value, and(value, sub(shl(160, 1), 1)))) { revert(0, 0) }\n }\n function panic_error_0x41()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x41)\n revert(0, 0x24)\n }\n function allocate_memory(size) -> memPtr\n {\n memPtr := mload(64)\n let newFreePtr := add(memPtr, and(add(size, 31), not(31)))\n if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n mstore(64, newFreePtr)\n }\n function abi_decode_bytes(offset, end) -> array\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n let _1 := calldataload(offset)\n if gt(_1, 0xffffffffffffffff) { panic_error_0x41() }\n let array_1 := allocate_memory(add(and(add(_1, 0x1f), not(31)), 0x20))\n mstore(array_1, _1)\n if gt(add(add(offset, _1), 0x20), end) { revert(0, 0) }\n calldatacopy(add(array_1, 0x20), add(offset, 0x20), _1)\n mstore(add(add(array_1, _1), 0x20), 0)\n array := array_1\n }\n function abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 128) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n value2 := calldataload(add(headStart, 64))\n let offset := calldataload(add(headStart, 96))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n value3 := abi_decode_bytes(add(headStart, offset), dataEnd)\n }\n function abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, shl(224, 0xffffffff)))\n }\n function abi_decode_tuple_t_addresst_address(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n }\n function abi_encode_tuple_t_address__to_t_address__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, sub(shl(160, 1), 1)))\n }\n function abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 96) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n value1 := calldataload(add(headStart, 32))\n let offset := calldataload(add(headStart, 64))\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n let _2 := add(headStart, offset)\n if iszero(slt(add(_2, 0x1f), dataEnd)) { revert(0, 0) }\n let length := calldataload(_2)\n if gt(length, _1) { revert(0, 0) }\n if gt(add(add(_2, length), 32), dataEnd) { revert(0, 0) }\n value2 := add(_2, 32)\n value3 := length\n }\n function abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value0) -> tail\n {\n let _1 := 32\n mstore(headStart, _1)\n let length := mload(value0)\n mstore(add(headStart, _1), length)\n let i := 0\n for { } lt(i, length) { i := add(i, _1) }\n {\n mstore(add(add(headStart, i), 64), mload(add(add(value0, i), _1)))\n }\n mstore(add(add(headStart, length), 64), 0)\n tail := add(add(headStart, and(add(length, 31), not(31))), 64)\n }\n function abi_decode_array_uint256_dyn(offset, end) -> array\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n let _1 := calldataload(offset)\n let _2 := 0x20\n if gt(_1, 0xffffffffffffffff) { panic_error_0x41() }\n let _3 := shl(5, _1)\n let dst := allocate_memory(add(_3, _2))\n let dst_1 := dst\n mstore(dst, _1)\n dst := add(dst, _2)\n let srcEnd := add(add(offset, _3), _2)\n if gt(srcEnd, end) { revert(0, 0) }\n let src := add(offset, _2)\n for { } lt(src, srcEnd) { src := add(src, _2) }\n {\n mstore(dst, calldataload(src))\n dst := add(dst, _2)\n }\n array := dst_1\n }\n function abi_decode_tuple_t_addresst_addresst_array$_t_uint256_$dyn_memory_ptrt_array$_t_uint256_$dyn_memory_ptrt_bytes_memory_ptr(headStart, dataEnd) -> value0, value1, value2, value3, value4\n {\n if slt(sub(dataEnd, headStart), 160) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n let offset := calldataload(add(headStart, 64))\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n value2 := abi_decode_array_uint256_dyn(add(headStart, offset), dataEnd)\n let offset_1 := calldataload(add(headStart, 96))\n if gt(offset_1, _1) { revert(0, 0) }\n value3 := abi_decode_array_uint256_dyn(add(headStart, offset_1), dataEnd)\n let offset_2 := calldataload(add(headStart, 128))\n if gt(offset_2, _1) { revert(0, 0) }\n value4 := abi_decode_bytes(add(headStart, offset_2), dataEnd)\n }\n function abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, value0)\n }\n function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n value0 := calldataload(headStart)\n }\n function abi_decode_tuple_t_addresst_addresst_uint256t_uint256t_bytes_memory_ptr(headStart, dataEnd) -> value0, value1, value2, value3, value4\n {\n if slt(sub(dataEnd, headStart), 160) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n value2 := calldataload(add(headStart, 64))\n value3 := calldataload(add(headStart, 96))\n let offset := calldataload(add(headStart, 128))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n value4 := abi_decode_bytes(add(headStart, offset), dataEnd)\n }\n function abi_encode_tuple_t_uint256_t_address_t_uint256__to_t_uint256_t_address_t_uint256__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n tail := add(headStart, 96)\n mstore(headStart, value0)\n mstore(add(headStart, 32), and(value1, sub(shl(160, 1), 1)))\n mstore(add(headStart, 64), value2)\n }\n function abi_decode_tuple_t_address(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n }\n function panic_error_0x32()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x32)\n revert(0, 0x24)\n }\n function abi_decode_tuple_t_bool(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := calldataload(headStart)\n if iszero(eq(value, iszero(iszero(value)))) { revert(0, 0) }\n value0 := value\n }\n function abi_encode_tuple_t_address_t_address_t_bool__to_t_address_t_address_t_bool__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n tail := add(headStart, 96)\n let _1 := sub(shl(160, 1), 1)\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), and(value1, _1))\n mstore(add(headStart, 64), iszero(iszero(value2)))\n }\n function panic_error_0x11()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x11)\n revert(0, 0x24)\n }\n function increment_t_uint256(value) -> ret\n {\n if eq(value, not(0)) { panic_error_0x11() }\n ret := add(value, 1)\n }\n function abi_decode_tuple_t_address_fromMemory(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := mload(headStart)\n validator_revert_address(value)\n value0 := value\n }\n function abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value1, value0) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), value1)\n calldatacopy(add(headStart, 64), value0, value1)\n mstore(add(add(headStart, value1), 64), 0)\n tail := add(add(headStart, and(add(value1, 31), not(31))), 64)\n }\n function checked_add_t_uint256(x, y) -> sum\n {\n sum := add(x, y)\n if gt(x, sum) { panic_error_0x11() }\n }\n function abi_decode_tuple_t_uint256t_address_payablet_uint256_fromMemory(headStart, dataEnd) -> value0, value1, value2\n {\n if slt(sub(dataEnd, headStart), 96) { revert(0, 0) }\n value0 := mload(headStart)\n let value := mload(add(headStart, 32))\n validator_revert_address(value)\n value1 := value\n value2 := mload(add(headStart, 64))\n }\n function abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed(pos, value1, value0) -> end\n {\n calldatacopy(pos, value0, value1)\n let _1 := add(pos, value1)\n mstore(_1, 0)\n end := _1\n }\n}","id":9,"language":"Yul","name":"#utility.yul"}],"immutableReferences":{},"linkReferences":{},"object":"6080604052600436106100c65760003560e01c8063a4e2d6341161007f578063dd46706411610059578063dd46706414610251578063f23a6e6114610271578063fc0c546a1461029d578063fe9fbb80146102d557600080fd5b8063a4e2d634146101ea578063bc197c8114610201578063ce0617ec1461022d57600080fd5b806301ffc9a7146100d2578063039721b114610107578063150b7a02146101295780631f9838b5146101625780638da5cb5b1461019d5780639e5d4c49146101ca57600080fd5b366100cd57005b600080fd5b3480156100de57600080fd5b506100f26100ed36600461095c565b6102f5565b60405190151581526020015b60405180910390f35b34801561011357600080fd5b506101276101223660046109d9565b61035c565b005b34801561013557600080fd5b50610149610144366004610b14565b610525565b6040516001600160e01b031990911681526020016100fe565b34801561016e57600080fd5b506100f261017d366004610b80565b600160209081526000928352604080842090915290825290205460ff1681565b3480156101a957600080fd5b506101b261058d565b6040516001600160a01b0390911681526020016100fe565b6101dd6101d8366004610bb9565b610623565b6040516100fe9190610c42565b3480156101f657600080fd5b5060005442106100f2565b34801561020d57600080fd5b5061014961021c366004610d10565b63bc197c8160e01b95945050505050565b34801561023957600080fd5b5061024360005481565b6040519081526020016100fe565b34801561025d57600080fd5b5061012761026c366004610dbe565b6106c7565b34801561027d57600080fd5b5061014961028c366004610dd7565b63f23a6e6160e01b95945050505050565b3480156102a957600080fd5b506102b261078c565b604080519384526001600160a01b039092166020840152908201526060016100fe565b3480156102e157600080fd5b506100f26102f0366004610e40565b6107a4565b6000806001600160e01b031983166301ffc9a760e01b148061032757506001600160e01b03198316630271189760e51b145b8061034257506001600160e01b03198316631dfe9a6f60e31b145b905080156103535750600192915050565b50600092915050565b60005442101561037f57604051636315bfbb60e01b815260040160405180910390fd5b600061038961058d565b9050336001600160a01b038216146103b45760405163ea8e4eb560e01b815260040160405180910390fd5b838281146103d55760405163b4fa3fb360e01b815260040160405180910390fd5b60005b8181101561051c578484828181106103f2576103f2610e5d565b90506020020160208101906104079190610e73565b6001600160a01b03841660009081526001602052604081209089898581811061043257610432610e5d565b90506020020160208101906104479190610e40565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f394777a58092892d136a90c4bb7e4350c72ac50fba6a0208128677f36527dcf5838888848181106104a3576104a3610e5d565b90506020020160208101906104b89190610e40565b8787858181106104ca576104ca610e5d565b90506020020160208101906104df9190610e73565b604080516001600160a01b03948516815293909216602084015215159082015260600160405180910390a18061051481610eab565b9150506103d8565b50505050505050565b60008060008061053361088d565b925092509250468314801561055057506001600160a01b03821633145b801561055b57508581145b156105795760405163b79e3f3f60e01b815260040160405180910390fd5b50630a85bd0160e11b979650505050505050565b60008060008061059b61088d565b9250925092504683146105b2576000935050505090565b6040516331a9108f60e11b8152600481018290526001600160a01b03831690636352211e90602401602060405180830381865afa1580156105f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061b9190610ec4565b935050505090565b606061062e336107a4565b61064b5760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561066e57604051636315bfbb60e01b815260040160405180910390fd5b83856001600160a01b03167f47d99ad340f52da66535aff7e10da1ceb85a32bcbd9fa1c42314d194545e14d285856040516106aa929190610ee1565b60405180910390a36106be858585856108e0565b95945050505050565b6106cf61058d565b6001600160a01b0316336001600160a01b0316146107005760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561072357604051636315bfbb60e01b815260040160405180910390fd5b610731426301e13380610f10565b811115610751576040516301814f7d60e31b815260040160405180910390fd5b60008190556040518181527fa7b24c66dd3269a292a60b3facdbb8f3e7557d1e19e64d99e0d6ee7250be63ad9060200160405180910390a150565b600080600061079961088d565b925092509250909192565b60008060006107b161088d565b6040516331a9108f60e11b8152600481018290529194509250600091506001600160a01b03841690636352211e90602401602060405180830381865afa1580156107ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108239190610ec4565b9050806001600160a01b0316856001600160a01b03160361084957506001949350505050565b6001600160a01b0380821660009081526001602090815260408083209389168352929052205460ff161561088257506001949350505050565b506000949350505050565b604080516060808252608082019092526000918291829182919060208201818036833701905050905060ad604d60208301303c808060200190518101906108d49190610f29565b93509350935050909192565b60606000856001600160a01b03168585856040516108ff929190610f62565b60006040518083038185875af1925050503d806000811461093c576040519150601f19603f3d011682016040523d82523d6000602084013e610941565b606091505b50925090508061095357815160208301fd5b50949350505050565b60006020828403121561096e57600080fd5b81356001600160e01b03198116811461098657600080fd5b9392505050565b60008083601f84011261099f57600080fd5b50813567ffffffffffffffff8111156109b757600080fd5b6020830191508360208260051b85010111156109d257600080fd5b9250929050565b600080600080604085870312156109ef57600080fd5b843567ffffffffffffffff80821115610a0757600080fd5b610a138883890161098d565b90965094506020870135915080821115610a2c57600080fd5b50610a398782880161098d565b95989497509550505050565b6001600160a01b0381168114610a5a57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610a9c57610a9c610a5d565b604052919050565b600082601f830112610ab557600080fd5b813567ffffffffffffffff811115610acf57610acf610a5d565b610ae2601f8201601f1916602001610a73565b818152846020838601011115610af757600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215610b2a57600080fd5b8435610b3581610a45565b93506020850135610b4581610a45565b925060408501359150606085013567ffffffffffffffff811115610b6857600080fd5b610b7487828801610aa4565b91505092959194509250565b60008060408385031215610b9357600080fd5b8235610b9e81610a45565b91506020830135610bae81610a45565b809150509250929050565b60008060008060608587031215610bcf57600080fd5b8435610bda81610a45565b935060208501359250604085013567ffffffffffffffff80821115610bfe57600080fd5b818701915087601f830112610c1257600080fd5b813581811115610c2157600080fd5b886020828501011115610c3357600080fd5b95989497505060200194505050565b600060208083528351808285015260005b81811015610c6f57858101830151858201604001528201610c53565b506000604082860101526040601f19601f8301168501019250505092915050565b600082601f830112610ca157600080fd5b8135602067ffffffffffffffff821115610cbd57610cbd610a5d565b8160051b610ccc828201610a73565b9283528481018201928281019087851115610ce657600080fd5b83870192505b84831015610d0557823582529183019190830190610cec565b979650505050505050565b600080600080600060a08688031215610d2857600080fd5b8535610d3381610a45565b94506020860135610d4381610a45565b9350604086013567ffffffffffffffff80821115610d6057600080fd5b610d6c89838a01610c90565b94506060880135915080821115610d8257600080fd5b610d8e89838a01610c90565b93506080880135915080821115610da457600080fd5b50610db188828901610aa4565b9150509295509295909350565b600060208284031215610dd057600080fd5b5035919050565b600080600080600060a08688031215610def57600080fd5b8535610dfa81610a45565b94506020860135610e0a81610a45565b93506040860135925060608601359150608086013567ffffffffffffffff811115610e3457600080fd5b610db188828901610aa4565b600060208284031215610e5257600080fd5b813561098681610a45565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610e8557600080fd5b8135801515811461098657600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610ebd57610ebd610e95565b5060010190565b600060208284031215610ed657600080fd5b815161098681610a45565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b80820180821115610f2357610f23610e95565b92915050565b600080600060608486031215610f3e57600080fd5b835192506020840151610f5081610a45565b80925050604084015190509250925092565b818382376000910190815291905056fea26469706673582212208586a5aa87cff87a1d8e1dc4952c1d3b167ebfafab4c2b56ed97ed8a5ec5921664736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xC6 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0xA4E2D634 GT PUSH2 0x7F JUMPI DUP1 PUSH4 0xDD467064 GT PUSH2 0x59 JUMPI DUP1 PUSH4 0xDD467064 EQ PUSH2 0x251 JUMPI DUP1 PUSH4 0xF23A6E61 EQ PUSH2 0x271 JUMPI DUP1 PUSH4 0xFC0C546A EQ PUSH2 0x29D JUMPI DUP1 PUSH4 0xFE9FBB80 EQ PUSH2 0x2D5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0xA4E2D634 EQ PUSH2 0x1EA JUMPI DUP1 PUSH4 0xBC197C81 EQ PUSH2 0x201 JUMPI DUP1 PUSH4 0xCE0617EC EQ PUSH2 0x22D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1FFC9A7 EQ PUSH2 0xD2 JUMPI DUP1 PUSH4 0x39721B1 EQ PUSH2 0x107 JUMPI DUP1 PUSH4 0x150B7A02 EQ PUSH2 0x129 JUMPI DUP1 PUSH4 0x1F9838B5 EQ PUSH2 0x162 JUMPI DUP1 PUSH4 0x8DA5CB5B EQ PUSH2 0x19D JUMPI DUP1 PUSH4 0x9E5D4C49 EQ PUSH2 0x1CA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST CALLDATASIZE PUSH2 0xCD JUMPI STOP JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xDE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xF2 PUSH2 0xED CALLDATASIZE PUSH1 0x4 PUSH2 0x95C JUMP JUMPDEST PUSH2 0x2F5 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x113 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x127 PUSH2 0x122 CALLDATASIZE PUSH1 0x4 PUSH2 0x9D9 JUMP JUMPDEST PUSH2 0x35C JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x135 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x149 PUSH2 0x144 CALLDATASIZE PUSH1 0x4 PUSH2 0xB14 JUMP JUMPDEST PUSH2 0x525 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xFE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x16E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xF2 PUSH2 0x17D CALLDATASIZE PUSH1 0x4 PUSH2 0xB80 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x0 SWAP3 DUP4 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 SWAP1 SWAP2 MSTORE SWAP1 DUP3 MSTORE SWAP1 KECCAK256 SLOAD PUSH1 0xFF AND DUP2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1A9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1B2 PUSH2 0x58D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xFE JUMP JUMPDEST PUSH2 0x1DD PUSH2 0x1D8 CALLDATASIZE PUSH1 0x4 PUSH2 0xBB9 JUMP JUMPDEST PUSH2 0x623 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xFE SWAP2 SWAP1 PUSH2 0xC42 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1F6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x0 SLOAD TIMESTAMP LT PUSH2 0xF2 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x20D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x149 PUSH2 0x21C CALLDATASIZE PUSH1 0x4 PUSH2 0xD10 JUMP JUMPDEST PUSH4 0xBC197C81 PUSH1 0xE0 SHL SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x239 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x243 PUSH1 0x0 SLOAD DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xFE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x25D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x127 PUSH2 0x26C CALLDATASIZE PUSH1 0x4 PUSH2 0xDBE JUMP JUMPDEST PUSH2 0x6C7 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x27D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x149 PUSH2 0x28C CALLDATASIZE PUSH1 0x4 PUSH2 0xDD7 JUMP JUMPDEST PUSH4 0xF23A6E61 PUSH1 0xE0 SHL SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2A9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2B2 PUSH2 0x78C JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP4 DUP5 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE SWAP1 DUP3 ADD MSTORE PUSH1 0x60 ADD PUSH2 0xFE JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2E1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xF2 PUSH2 0x2F0 CALLDATASIZE PUSH1 0x4 PUSH2 0xE40 JUMP JUMPDEST PUSH2 0x7A4 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x1FFC9A7 PUSH1 0xE0 SHL EQ DUP1 PUSH2 0x327 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x2711897 PUSH1 0xE5 SHL EQ JUMPDEST DUP1 PUSH2 0x342 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND PUSH4 0x1DFE9A6F PUSH1 0xE3 SHL EQ JUMPDEST SWAP1 POP DUP1 ISZERO PUSH2 0x353 JUMPI POP PUSH1 0x1 SWAP3 SWAP2 POP POP JUMP JUMPDEST POP PUSH1 0x0 SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x37F JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 PUSH2 0x389 PUSH2 0x58D JUMP JUMPDEST SWAP1 POP CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND EQ PUSH2 0x3B4 JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 DUP3 DUP2 EQ PUSH2 0x3D5 JUMPI PUSH1 0x40 MLOAD PUSH4 0xB4FA3FB3 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x51C JUMPI DUP5 DUP5 DUP3 DUP2 DUP2 LT PUSH2 0x3F2 JUMPI PUSH2 0x3F2 PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x407 SWAP2 SWAP1 PUSH2 0xE73 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 SWAP1 DUP10 DUP10 DUP6 DUP2 DUP2 LT PUSH2 0x432 JUMPI PUSH2 0x432 PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x447 SWAP2 SWAP1 PUSH2 0xE40 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP2 MSTORE PUSH1 0x20 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x40 ADD PUSH1 0x0 KECCAK256 DUP1 SLOAD PUSH1 0xFF NOT AND SWAP2 ISZERO ISZERO SWAP2 SWAP1 SWAP2 OR SWAP1 SSTORE PUSH32 0x394777A58092892D136A90C4BB7E4350C72AC50FBA6A0208128677F36527DCF5 DUP4 DUP9 DUP9 DUP5 DUP2 DUP2 LT PUSH2 0x4A3 JUMPI PUSH2 0x4A3 PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x4B8 SWAP2 SWAP1 PUSH2 0xE40 JUMP JUMPDEST DUP8 DUP8 DUP6 DUP2 DUP2 LT PUSH2 0x4CA JUMPI PUSH2 0x4CA PUSH2 0xE5D JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL ADD PUSH1 0x20 DUP2 ADD SWAP1 PUSH2 0x4DF SWAP2 SWAP1 PUSH2 0xE73 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP5 DUP6 AND DUP2 MSTORE SWAP4 SWAP1 SWAP3 AND PUSH1 0x20 DUP5 ADD MSTORE ISZERO ISZERO SWAP1 DUP3 ADD MSTORE PUSH1 0x60 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 DUP1 PUSH2 0x514 DUP2 PUSH2 0xEAB JUMP JUMPDEST SWAP2 POP POP PUSH2 0x3D8 JUMP JUMPDEST POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x533 PUSH2 0x88D JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP CHAINID DUP4 EQ DUP1 ISZERO PUSH2 0x550 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND CALLER EQ JUMPDEST DUP1 ISZERO PUSH2 0x55B JUMPI POP DUP6 DUP2 EQ JUMPDEST ISZERO PUSH2 0x579 JUMPI PUSH1 0x40 MLOAD PUSH4 0xB79E3F3F PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP PUSH4 0xA85BD01 PUSH1 0xE1 SHL SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH2 0x59B PUSH2 0x88D JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP CHAINID DUP4 EQ PUSH2 0x5B2 JUMPI PUSH1 0x0 SWAP4 POP POP POP POP SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x31A9108F PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND SWAP1 PUSH4 0x6352211E SWAP1 PUSH1 0x24 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x5F7 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x61B SWAP2 SWAP1 PUSH2 0xEC4 JUMP JUMPDEST SWAP4 POP POP POP POP SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH2 0x62E CALLER PUSH2 0x7A4 JUMP JUMPDEST PUSH2 0x64B JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x66E JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP4 DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH32 0x47D99AD340F52DA66535AFF7E10DA1CEB85A32BCBD9FA1C42314D194545E14D2 DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0x6AA SWAP3 SWAP2 SWAP1 PUSH2 0xEE1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 PUSH2 0x6BE DUP6 DUP6 DUP6 DUP6 PUSH2 0x8E0 JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH2 0x6CF PUSH2 0x58D JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ PUSH2 0x700 JUMPI PUSH1 0x40 MLOAD PUSH4 0xEA8E4EB5 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 SLOAD TIMESTAMP LT ISZERO PUSH2 0x723 JUMPI PUSH1 0x40 MLOAD PUSH4 0x6315BFBB PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH2 0x731 TIMESTAMP PUSH4 0x1E13380 PUSH2 0xF10 JUMP JUMPDEST DUP2 GT ISZERO PUSH2 0x751 JUMPI PUSH1 0x40 MLOAD PUSH4 0x1814F7D PUSH1 0xE3 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 DUP2 SWAP1 SSTORE PUSH1 0x40 MLOAD DUP2 DUP2 MSTORE PUSH32 0xA7B24C66DD3269A292A60B3FACDBB8F3E7557D1E19E64D99E0D6EE7250BE63AD SWAP1 PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x799 PUSH2 0x88D JUMP JUMPDEST SWAP3 POP SWAP3 POP SWAP3 POP SWAP1 SWAP2 SWAP3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x7B1 PUSH2 0x88D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x31A9108F PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE SWAP2 SWAP5 POP SWAP3 POP PUSH1 0x0 SWAP2 POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND SWAP1 PUSH4 0x6352211E SWAP1 PUSH1 0x24 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x7FF JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x823 SWAP2 SWAP1 PUSH2 0xEC4 JUMP JUMPDEST SWAP1 POP DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SUB PUSH2 0x849 JUMPI POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP1 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x1 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP10 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD PUSH1 0xFF AND ISZERO PUSH2 0x882 JUMPI POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST POP PUSH1 0x0 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH1 0x60 DUP1 DUP3 MSTORE PUSH1 0x80 DUP3 ADD SWAP1 SWAP3 MSTORE PUSH1 0x0 SWAP2 DUP3 SWAP2 DUP3 SWAP2 DUP3 SWAP2 SWAP1 PUSH1 0x20 DUP3 ADD DUP2 DUP1 CALLDATASIZE DUP4 CALLDATACOPY ADD SWAP1 POP POP SWAP1 POP PUSH1 0xAD PUSH1 0x4D PUSH1 0x20 DUP4 ADD ADDRESS EXTCODECOPY DUP1 DUP1 PUSH1 0x20 ADD SWAP1 MLOAD DUP2 ADD SWAP1 PUSH2 0x8D4 SWAP2 SWAP1 PUSH2 0xF29 JUMP JUMPDEST SWAP4 POP SWAP4 POP SWAP4 POP POP SWAP1 SWAP2 SWAP3 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP6 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP6 DUP6 DUP6 PUSH1 0x40 MLOAD PUSH2 0x8FF SWAP3 SWAP2 SWAP1 PUSH2 0xF62 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP6 DUP8 GAS CALL SWAP3 POP POP POP RETURNDATASIZE DUP1 PUSH1 0x0 DUP2 EQ PUSH2 0x93C JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0x941 JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP SWAP3 POP SWAP1 POP DUP1 PUSH2 0x953 JUMPI DUP2 MLOAD PUSH1 0x20 DUP4 ADD REVERT JUMPDEST POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x96E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP2 AND DUP2 EQ PUSH2 0x986 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x99F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x9B7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 PUSH1 0x5 SHL DUP6 ADD ADD GT ISZERO PUSH2 0x9D2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x40 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x9EF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xA07 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xA13 DUP9 DUP4 DUP10 ADD PUSH2 0x98D JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP PUSH1 0x20 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xA2C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xA39 DUP8 DUP3 DUP9 ADD PUSH2 0x98D JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0xA5A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT AND DUP2 ADD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT DUP3 DUP3 LT OR ISZERO PUSH2 0xA9C JUMPI PUSH2 0xA9C PUSH2 0xA5D JUMP JUMPDEST PUSH1 0x40 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xAB5 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xACF JUMPI PUSH2 0xACF PUSH2 0xA5D JUMP JUMPDEST PUSH2 0xAE2 PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT AND PUSH1 0x20 ADD PUSH2 0xA73 JUMP JUMPDEST DUP2 DUP2 MSTORE DUP5 PUSH1 0x20 DUP4 DUP7 ADD ADD GT ISZERO PUSH2 0xAF7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 PUSH1 0x20 DUP6 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 SWAP2 DUP2 ADD PUSH1 0x20 ADD SWAP2 SWAP1 SWAP2 MSTORE SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xB2A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xB35 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD PUSH2 0xB45 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD SWAP2 POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xB68 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xB74 DUP8 DUP3 DUP9 ADD PUSH2 0xAA4 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xB93 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH2 0xB9E DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP2 POP PUSH1 0x20 DUP4 ADD CALLDATALOAD PUSH2 0xBAE DUP2 PUSH2 0xA45 JUMP JUMPDEST DUP1 SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x60 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xBCF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH2 0xBDA DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD CALLDATALOAD SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xBFE JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP8 ADD SWAP2 POP DUP8 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xC12 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP2 DUP2 GT ISZERO PUSH2 0xC21 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP9 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0xC33 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP POP PUSH1 0x20 ADD SWAP5 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 MSTORE DUP4 MLOAD DUP1 DUP3 DUP6 ADD MSTORE PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xC6F JUMPI DUP6 DUP2 ADD DUP4 ADD MLOAD DUP6 DUP3 ADD PUSH1 0x40 ADD MSTORE DUP3 ADD PUSH2 0xC53 JUMP JUMPDEST POP PUSH1 0x0 PUSH1 0x40 DUP3 DUP7 ADD ADD MSTORE PUSH1 0x40 PUSH1 0x1F NOT PUSH1 0x1F DUP4 ADD AND DUP6 ADD ADD SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xCA1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH1 0x20 PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0xCBD JUMPI PUSH2 0xCBD PUSH2 0xA5D JUMP JUMPDEST DUP2 PUSH1 0x5 SHL PUSH2 0xCCC DUP3 DUP3 ADD PUSH2 0xA73 JUMP JUMPDEST SWAP3 DUP4 MSTORE DUP5 DUP2 ADD DUP3 ADD SWAP3 DUP3 DUP2 ADD SWAP1 DUP8 DUP6 GT ISZERO PUSH2 0xCE6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 DUP8 ADD SWAP3 POP JUMPDEST DUP5 DUP4 LT ISZERO PUSH2 0xD05 JUMPI DUP3 CALLDATALOAD DUP3 MSTORE SWAP2 DUP4 ADD SWAP2 SWAP1 DUP4 ADD SWAP1 PUSH2 0xCEC JUMP JUMPDEST SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xD28 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xD33 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH2 0xD43 DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xD60 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD6C DUP10 DUP4 DUP11 ADD PUSH2 0xC90 JUMP JUMPDEST SWAP5 POP PUSH1 0x60 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xD82 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD8E DUP10 DUP4 DUP11 ADD PUSH2 0xC90 JUMP JUMPDEST SWAP4 POP PUSH1 0x80 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0xDA4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xDB1 DUP9 DUP3 DUP10 ADD PUSH2 0xAA4 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 SWAP1 SWAP4 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xDD0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xA0 DUP7 DUP9 SUB SLT ISZERO PUSH2 0xDEF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH2 0xDFA DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP5 POP PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH2 0xE0A DUP2 PUSH2 0xA45 JUMP JUMPDEST SWAP4 POP PUSH1 0x40 DUP7 ADD CALLDATALOAD SWAP3 POP PUSH1 0x60 DUP7 ADD CALLDATALOAD SWAP2 POP PUSH1 0x80 DUP7 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xE34 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xDB1 DUP9 DUP3 DUP10 ADD PUSH2 0xAA4 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xE52 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x986 DUP2 PUSH2 0xA45 JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x32 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xE85 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP1 ISZERO ISZERO DUP2 EQ PUSH2 0x986 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x11 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x1 DUP3 ADD PUSH2 0xEBD JUMPI PUSH2 0xEBD PUSH2 0xE95 JUMP JUMPDEST POP PUSH1 0x1 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xED6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x986 DUP2 PUSH2 0xA45 JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE DUP2 PUSH1 0x20 DUP3 ADD MSTORE DUP2 DUP4 PUSH1 0x40 DUP4 ADD CALLDATACOPY PUSH1 0x0 DUP2 DUP4 ADD PUSH1 0x40 SWAP1 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x1F SWAP1 SWAP3 ADD PUSH1 0x1F NOT AND ADD ADD SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 DUP3 ADD DUP1 DUP3 GT ISZERO PUSH2 0xF23 JUMPI PUSH2 0xF23 PUSH2 0xE95 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xF3E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 MLOAD SWAP3 POP PUSH1 0x20 DUP5 ADD MLOAD PUSH2 0xF50 DUP2 PUSH2 0xA45 JUMP JUMPDEST DUP1 SWAP3 POP POP PUSH1 0x40 DUP5 ADD MLOAD SWAP1 POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST DUP2 DUP4 DUP3 CALLDATACOPY PUSH1 0x0 SWAP2 ADD SWAP1 DUP2 MSTORE SWAP2 SWAP1 POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 DUP6 DUP7 0xA5 0xAA DUP8 0xCF 0xF8 PUSH27 0x1D8E1DC4952C1D3B167EBFAFAB4C2B56ED97ED8A5EC5921664736F PUSH13 0x63430008110033000000000000 ","sourceMap":"695:6680:6:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4889:393;;;;;;;;;;-1:-1:-1;4889:393:6;;;;;:::i;:::-;;:::i;:::-;;;470:14:9;;463:22;445:41;;433:2;418:18;4889:393:6;;;;;;;;2357:528;;;;;;;;;;-1:-1:-1;2357:528:6;;;;;:::i;:::-;;:::i;:::-;;5427:526;;;;;;;;;;-1:-1:-1;5427:526:6;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;;3559:33:9;;;3541:52;;3529:2;3514:18;5427:526:6;3397:202:9;965:63:6;;;;;;;;;;-1:-1:-1;965:63:6;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;3891:310;;;;;;;;;;;;;:::i;:::-;;;-1:-1:-1;;;;;4161:32:9;;;4143:51;;4131:2;4116:18;3891:310:6;3997:203:9;2029:265:6;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;3276:100::-;;;;;;;;;;-1:-1:-1;3317:4:6;3340:11;3354:15;-1:-1:-1;3276:100:6;;6356:244;;;;;;;;;;-1:-1:-1;6356:244:6;;;;;:::i;:::-;-1:-1:-1;;;6356:244:6;;;;;;;;871:26;;;;;;;;;;;;;;;;;;;7494:25:9;;;7482:2;7467:18;871:26:6;7348:177:9;2948:249:6;;;;;;;;;;-1:-1:-1;2948:249:6;;;;;:::i;:::-;;:::i;6043:216::-;;;;;;;;;;-1:-1:-1;6043:216:6;;;;;:::i;:::-;-1:-1:-1;;;6043:216:6;;;;;;;;3508:220;;;;;;;;;;;;;:::i;:::-;;;;8656:25:9;;;-1:-1:-1;;;;;8717:32:9;;;8712:2;8697:18;;8690:60;8766:18;;;8759:34;8644:2;8629:18;3508:220:6;8454:345:9;4272:480:6;;;;;;;;;;-1:-1:-1;4272:480:6;;;;;:::i;:::-;;:::i;4889:393::-;4999:4;;-1:-1:-1;;;;;;5041:40:6;;-1:-1:-1;;;5041:40:6;;:105;;-1:-1:-1;;;;;;;5097:49:6;;-1:-1:-1;;;5097:49:6;5041:105;:169;;;-1:-1:-1;;;;;;;5162:48:6;;-1:-1:-1;;;5162:48:6;5041:169;5019:191;;5225:14;5221:31;;;-1:-1:-1;5248:4:6;;4889:393;-1:-1:-1;;4889:393:6:o;5221:31::-;-1:-1:-1;5270:5:6;;4889:393;-1:-1:-1;;4889:393:6:o;2357:528::-;3317:4;3340:11;3354:15;-1:-1:-1;1722:38:6;;;1745:15;;-1:-1:-1;;;1745:15:6;;;;;;;;;;;1722:38;2493:14:::1;2510:7;:5;:7::i;:::-;2493:24:::0;-1:-1:-1;2531:10:6::1;-1:-1:-1::0;;;;;2531:20:6;::::1;;2527:48;;2560:15;;-1:-1:-1::0;;;2560:15:6::1;;;;;;;;;;;2527:48;2603:7:::0;2632:29;;::::1;2628:56;;2670:14;;-1:-1:-1::0;;;2670:14:6::1;;;;;;;;;;;2628:56;2700:9;2695:184;2719:6;2715:1;:10;2695:184;;;2780:12;;2793:1;2780:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;2746:19:6;::::1;;::::0;;;:11:::1;:19;::::0;;;;;2766:7;;2774:1;2766:10;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;2746:31:6::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;2746:31:6;:49;;-1:-1:-1;;2746:49:6::1;::::0;::::1;;::::0;;;::::1;::::0;;2814:54:::1;2832:6:::0;2840:7;;2848:1;2840:10;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;2852:12;;2865:1;2852:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;2814:54;::::0;;-1:-1:-1;;;;;9718:15:9;;;9700:34;;9770:15;;;;9765:2;9750:18;;9743:43;9829:14;9822:22;9802:18;;;9795:50;9650:2;9635:18;2814:54:6::1;;;;;;;2727:3:::0;::::1;::::0;::::1;:::i;:::-;;;;2695:184;;;;2483:402;;2357:528:::0;;;;:::o;5427:526::-;5578:6;5610:15;5639:21;5674:15;5702:25;:23;:25::i;:::-;5596:131;;;;;;5766:13;5755:7;:24;:67;;;;-1:-1:-1;;;;;;5795:27:6;;5812:10;5795:27;5755:67;:109;;;;;5849:15;5838:7;:26;5755:109;5738:160;;;5882:16;;-1:-1:-1;;;5882:16:6;;;;;;;;;;;5738:160;-1:-1:-1;;;;5916:30:6;5427:526;-1:-1:-1;;;;;;;5427:526:6:o;3891:310::-;3929:7;3962:15;3991:21;4026:15;4054:25;:23;:25::i;:::-;3948:131;;;;;;4105:13;4094:7;:24;4090:47;;4135:1;4120:17;;;;;3891:310;:::o;4090:47::-;4155:39;;-1:-1:-1;;;4155:39:6;;;;;7494:25:9;;;-1:-1:-1;;;;;4155:30:6;;;;;7467:18:9;;4155:39:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4148:46;;;;;3891:310;:::o;2029:265::-;2182:12;1559:24;1572:10;1559:12;:24::i;:::-;1554:53;;1592:15;;-1:-1:-1;;;1592:15:6;;;;;;;;;;;1554:53;3317:4;3340:11;3354:15;-1:-1:-1;1722:38:6::1;;;1745:15;;-1:-1:-1::0;;;1745:15:6::1;;;;;;;;;;;1722:38;2235:5:::2;2231:2;-1:-1:-1::0;;;;;2211:36:6::2;;2242:4;;2211:36;;;;;;;:::i;:::-;;;;;;;;2265:22;2271:2;2275:5;2282:4;;2265:5;:22::i;:::-;2258:29:::0;2029:265;-1:-1:-1;;;;;2029:265:6:o;2948:249::-;1387:7;:5;:7::i;:::-;-1:-1:-1;;;;;1373:21:6;:10;-1:-1:-1;;;;;1373:21:6;;1369:49;;1403:15;;-1:-1:-1;;;1403:15:6;;;;;;;;;;;1369:49;3317:4;3340:11;3354:15;-1:-1:-1;1722:38:6::1;;;1745:15;;-1:-1:-1::0;;;1745:15:6::1;;;;;;;;;;;1722:38;3045:26:::2;:15;3063:8;3045:26;:::i;:::-;3030:12;:41;3026:86;;;3092:20;;-1:-1:-1::0;;;3092:20:6::2;;;;;;;;;;;3026:86;3123:11;:26:::0;;;3165:25:::2;::::0;7494::9;;;3165::6::2;::::0;7482:2:9;7467:18;3165:25:6::2;;;;;;;2948:249:::0;:::o;3508:220::-;3585:15;3614:21;3649:15;3696:25;:23;:25::i;:::-;3689:32;;;;;;3508:220;;;:::o;4272:480::-;4331:4;4375:21;4410:15;4438:25;:23;:25::i;:::-;4490:39;;-1:-1:-1;;;4490:39:6;;;;;7494:25:9;;;4347:116:6;;-1:-1:-1;4347:116:6;-1:-1:-1;4473:14:6;;-1:-1:-1;;;;;;4490:30:6;;;;;7467:18:9;;4490:39:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4473:56;;4587:6;-1:-1:-1;;;;;4577:16:6;:6;-1:-1:-1;;;;;4577:16:6;;4573:33;;-1:-1:-1;4602:4:6;;4272:480;-1:-1:-1;;;;4272:480:6:o;4573:33::-;-1:-1:-1;;;;;4682:19:6;;;;;;;:11;:19;;;;;;;;:27;;;;;;;;;;;;4678:44;;;-1:-1:-1;4718:4:6;;4272:480;-1:-1:-1;;;;4272:480:6:o;4678:44::-;-1:-1:-1;4740:5:6;;4272:480;-1:-1:-1;;;;4272:480:6:o;90:406:8:-;263:15;;;273:4;263:15;;;;;;;;;167:7;;;;;;;;263:15;;;;;;;;;;;-1:-1:-1;263:15:8;241:37;;410:4;404;397;389:6;385:17;374:9;362:53;453:6;442:47;;;;;;;;;;;;:::i;:::-;435:54;;;;;;;90:406;;;:::o;6645:345:6:-;6756:19;6787:12;6829:2;-1:-1:-1;;;;;6829:7:6;6844:5;6851:4;;6829:27;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6809:47:6;-1:-1:-1;6809:47:6;-1:-1:-1;6809:47:6;6867:117;;6952:6;6946:13;6941:2;6933:6;6929:15;6922:38;6867:117;6777:213;6645:345;;;;;;:::o;14:286:9:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:9;;209:43;;199:71;;266:1;263;256:12;199:71;289:5;14:286;-1:-1:-1;;;14:286:9:o;497:367::-;560:8;570:6;624:3;617:4;609:6;605:17;601:27;591:55;;642:1;639;632:12;591:55;-1:-1:-1;665:20:9;;708:18;697:30;;694:50;;;740:1;737;730:12;694:50;777:4;769:6;765:17;753:29;;837:3;830:4;820:6;817:1;813:14;805:6;801:27;797:38;794:47;791:67;;;854:1;851;844:12;791:67;497:367;;;;;:::o;869:770::-;988:6;996;1004;1012;1065:2;1053:9;1044:7;1040:23;1036:32;1033:52;;;1081:1;1078;1071:12;1033:52;1121:9;1108:23;1150:18;1191:2;1183:6;1180:14;1177:34;;;1207:1;1204;1197:12;1177:34;1246:70;1308:7;1299:6;1288:9;1284:22;1246:70;:::i;:::-;1335:8;;-1:-1:-1;1220:96:9;-1:-1:-1;1423:2:9;1408:18;;1395:32;;-1:-1:-1;1439:16:9;;;1436:36;;;1468:1;1465;1458:12;1436:36;;1507:72;1571:7;1560:8;1549:9;1545:24;1507:72;:::i;:::-;869:770;;;;-1:-1:-1;1598:8:9;-1:-1:-1;;;;869:770:9:o;1644:131::-;-1:-1:-1;;;;;1719:31:9;;1709:42;;1699:70;;1765:1;1762;1755:12;1699:70;1644:131;:::o;1780:127::-;1841:10;1836:3;1832:20;1829:1;1822:31;1872:4;1869:1;1862:15;1896:4;1893:1;1886:15;1912:275;1983:2;1977:9;2048:2;2029:13;;-1:-1:-1;;2025:27:9;2013:40;;2083:18;2068:34;;2104:22;;;2065:62;2062:88;;;2130:18;;:::i;:::-;2166:2;2159:22;1912:275;;-1:-1:-1;1912:275:9:o;2192:530::-;2234:5;2287:3;2280:4;2272:6;2268:17;2264:27;2254:55;;2305:1;2302;2295:12;2254:55;2341:6;2328:20;2367:18;2363:2;2360:26;2357:52;;;2389:18;;:::i;:::-;2433:55;2476:2;2457:13;;-1:-1:-1;;2453:27:9;2482:4;2449:38;2433:55;:::i;:::-;2513:2;2504:7;2497:19;2559:3;2552:4;2547:2;2539:6;2535:15;2531:26;2528:35;2525:55;;;2576:1;2573;2566:12;2525:55;2641:2;2634:4;2626:6;2622:17;2615:4;2606:7;2602:18;2589:55;2689:1;2664:16;;;2682:4;2660:27;2653:38;;;;2668:7;2192:530;-1:-1:-1;;;2192:530:9:o;2727:665::-;2822:6;2830;2838;2846;2899:3;2887:9;2878:7;2874:23;2870:33;2867:53;;;2916:1;2913;2906:12;2867:53;2955:9;2942:23;2974:31;2999:5;2974:31;:::i;:::-;3024:5;-1:-1:-1;3081:2:9;3066:18;;3053:32;3094:33;3053:32;3094:33;:::i;:::-;3146:7;-1:-1:-1;3200:2:9;3185:18;;3172:32;;-1:-1:-1;3255:2:9;3240:18;;3227:32;3282:18;3271:30;;3268:50;;;3314:1;3311;3304:12;3268:50;3337:49;3378:7;3369:6;3358:9;3354:22;3337:49;:::i;:::-;3327:59;;;2727:665;;;;;;;:::o;3604:388::-;3672:6;3680;3733:2;3721:9;3712:7;3708:23;3704:32;3701:52;;;3749:1;3746;3739:12;3701:52;3788:9;3775:23;3807:31;3832:5;3807:31;:::i;:::-;3857:5;-1:-1:-1;3914:2:9;3899:18;;3886:32;3927:33;3886:32;3927:33;:::i;:::-;3979:7;3969:17;;;3604:388;;;;;:::o;4205:794::-;4293:6;4301;4309;4317;4370:2;4358:9;4349:7;4345:23;4341:32;4338:52;;;4386:1;4383;4376:12;4338:52;4425:9;4412:23;4444:31;4469:5;4444:31;:::i;:::-;4494:5;-1:-1:-1;4546:2:9;4531:18;;4518:32;;-1:-1:-1;4601:2:9;4586:18;;4573:32;4624:18;4654:14;;;4651:34;;;4681:1;4678;4671:12;4651:34;4719:6;4708:9;4704:22;4694:32;;4764:7;4757:4;4753:2;4749:13;4745:27;4735:55;;4786:1;4783;4776:12;4735:55;4826:2;4813:16;4852:2;4844:6;4841:14;4838:34;;;4868:1;4865;4858:12;4838:34;4913:7;4908:2;4899:6;4895:2;4891:15;4887:24;4884:37;4881:57;;;4934:1;4931;4924:12;4881:57;4205:794;;;;-1:-1:-1;;4965:2:9;4957:11;;-1:-1:-1;;;4205:794:9:o;5004:546::-;5114:4;5143:2;5172;5161:9;5154:21;5204:6;5198:13;5247:6;5242:2;5231:9;5227:18;5220:34;5272:1;5282:140;5296:6;5293:1;5290:13;5282:140;;;5391:14;;;5387:23;;5381:30;5357:17;;;5376:2;5353:26;5346:66;5311:10;;5282:140;;;5286:3;5471:1;5466:2;5457:6;5446:9;5442:22;5438:31;5431:42;5541:2;5534;5530:7;5525:2;5517:6;5513:15;5509:29;5498:9;5494:45;5490:54;5482:62;;;;5004:546;;;;:::o;5555:712::-;5609:5;5662:3;5655:4;5647:6;5643:17;5639:27;5629:55;;5680:1;5677;5670:12;5629:55;5716:6;5703:20;5742:4;5765:18;5761:2;5758:26;5755:52;;;5787:18;;:::i;:::-;5833:2;5830:1;5826:10;5856:28;5880:2;5876;5872:11;5856:28;:::i;:::-;5918:15;;;5988;;;5984:24;;;5949:12;;;;6020:15;;;6017:35;;;6048:1;6045;6038:12;6017:35;6084:2;6076:6;6072:15;6061:26;;6096:142;6112:6;6107:3;6104:15;6096:142;;;6178:17;;6166:30;;6129:12;;;;6216;;;;6096:142;;;6256:5;5555:712;-1:-1:-1;;;;;;;5555:712:9:o;6272:1071::-;6426:6;6434;6442;6450;6458;6511:3;6499:9;6490:7;6486:23;6482:33;6479:53;;;6528:1;6525;6518:12;6479:53;6567:9;6554:23;6586:31;6611:5;6586:31;:::i;:::-;6636:5;-1:-1:-1;6693:2:9;6678:18;;6665:32;6706:33;6665:32;6706:33;:::i;:::-;6758:7;-1:-1:-1;6816:2:9;6801:18;;6788:32;6839:18;6869:14;;;6866:34;;;6896:1;6893;6886:12;6866:34;6919:61;6972:7;6963:6;6952:9;6948:22;6919:61;:::i;:::-;6909:71;;7033:2;7022:9;7018:18;7005:32;6989:48;;7062:2;7052:8;7049:16;7046:36;;;7078:1;7075;7068:12;7046:36;7101:63;7156:7;7145:8;7134:9;7130:24;7101:63;:::i;:::-;7091:73;;7217:3;7206:9;7202:19;7189:33;7173:49;;7247:2;7237:8;7234:16;7231:36;;;7263:1;7260;7253:12;7231:36;;7286:51;7329:7;7318:8;7307:9;7303:24;7286:51;:::i;:::-;7276:61;;;6272:1071;;;;;;;;:::o;7530:180::-;7589:6;7642:2;7630:9;7621:7;7617:23;7613:32;7610:52;;;7658:1;7655;7648:12;7610:52;-1:-1:-1;7681:23:9;;7530:180;-1:-1:-1;7530:180:9:o;7715:734::-;7819:6;7827;7835;7843;7851;7904:3;7892:9;7883:7;7879:23;7875:33;7872:53;;;7921:1;7918;7911:12;7872:53;7960:9;7947:23;7979:31;8004:5;7979:31;:::i;:::-;8029:5;-1:-1:-1;8086:2:9;8071:18;;8058:32;8099:33;8058:32;8099:33;:::i;:::-;8151:7;-1:-1:-1;8205:2:9;8190:18;;8177:32;;-1:-1:-1;8256:2:9;8241:18;;8228:32;;-1:-1:-1;8311:3:9;8296:19;;8283:33;8339:18;8328:30;;8325:50;;;8371:1;8368;8361:12;8325:50;8394:49;8435:7;8426:6;8415:9;8411:22;8394:49;:::i;8804:247::-;8863:6;8916:2;8904:9;8895:7;8891:23;8887:32;8884:52;;;8932:1;8929;8922:12;8884:52;8971:9;8958:23;8990:31;9015:5;8990:31;:::i;9056:127::-;9117:10;9112:3;9108:20;9105:1;9098:31;9148:4;9145:1;9138:15;9172:4;9169:1;9162:15;9188:273;9244:6;9297:2;9285:9;9276:7;9272:23;9268:32;9265:52;;;9313:1;9310;9303:12;9265:52;9352:9;9339:23;9405:5;9398:13;9391:21;9384:5;9381:32;9371:60;;9427:1;9424;9417:12;9856:127;9917:10;9912:3;9908:20;9905:1;9898:31;9948:4;9945:1;9938:15;9972:4;9969:1;9962:15;9988:135;10027:3;10048:17;;;10045:43;;10068:18;;:::i;:::-;-1:-1:-1;10115:1:9;10104:13;;9988:135::o;10128:251::-;10198:6;10251:2;10239:9;10230:7;10226:23;10222:32;10219:52;;;10267:1;10264;10257:12;10219:52;10299:9;10293:16;10318:31;10343:5;10318:31;:::i;10384:388::-;10541:2;10530:9;10523:21;10580:6;10575:2;10564:9;10560:18;10553:34;10637:6;10629;10624:2;10613:9;10609:18;10596:48;10693:1;10664:22;;;10688:2;10660:31;;;10653:42;;;;10756:2;10735:15;;;-1:-1:-1;;10731:29:9;10716:45;10712:54;;10384:388;-1:-1:-1;10384:388:9:o;10777:125::-;10842:9;;;10863:10;;;10860:36;;;10876:18;;:::i;:::-;10777:125;;;;:::o;10907:381::-;11003:6;11011;11019;11072:2;11060:9;11051:7;11047:23;11043:32;11040:52;;;11088:1;11085;11078:12;11040:52;11117:9;11111:16;11101:26;;11170:2;11159:9;11155:18;11149:25;11183:31;11208:5;11183:31;:::i;:::-;11233:5;11223:15;;;11278:2;11267:9;11263:18;11257:25;11247:35;;10907:381;;;;;:::o;11293:271::-;11476:6;11468;11463:3;11450:33;11432:3;11502:16;;11527:13;;;11502:16;11293:271;-1:-1:-1;11293:271:9:o"},"gasEstimates":{"creation":{"codeDepositCost":"801600","executionCost":"838","totalCost":"802438"},"external":{"executeCall(address,uint256,bytes)":"infinite","isAuthorized(address)":"infinite","isLocked()":"2315","lock(uint256)":"infinite","lockedUntil()":"2362","onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":"infinite","onERC1155Received(address,address,uint256,uint256,bytes)":"infinite","onERC721Received(address,address,uint256,bytes)":"infinite","owner()":"infinite","permissions(address,address)":"infinite","setPermissions(address[],bool[])":"infinite","supportsInterface(bytes4)":"515","token()":"infinite"},"internal":{"_call(address,uint256,bytes calldata)":"infinite","_callStatic(address,bytes calldata)":"infinite"}},"methodIdentifiers":{"executeCall(address,uint256,bytes)":"9e5d4c49","isAuthorized(address)":"fe9fbb80","isLocked()":"a4e2d634","lock(uint256)":"dd467064","lockedUntil()":"ce0617ec","onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)":"bc197c81","onERC1155Received(address,address,uint256,uint256,bytes)":"f23a6e61","onERC721Received(address,address,uint256,bytes)":"150b7a02","owner()":"8da5cb5b","permissions(address,address)":"1f9838b5","setPermissions(address[],bool[])":"039721b1","supportsInterface(bytes4)":"01ffc9a7","token()":"fc0c546a"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"AccountLocked\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExceedsMaxLockTime\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInput\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotAuthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OwnershipCycle\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"lockedUntil\",\"type\":\"uint256\"}],\"name\":\"LockUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"OverrideUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"hasPermission\",\"type\":\"bool\"}],\"name\":\"PermissionUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"TransactionExecuted\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"executeCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"isAuthorized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isLocked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_lockedUntil\",\"type\":\"uint256\"}],\"name\":\"lock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lockedUntil\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"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\":\"receivedTokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"permissions\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"callers\",\"type\":\"address[]\"},{\"internalType\":\"bool[]\",\"name\":\"_permissions\",\"type\":\"bool[]\"}],\"name\":\"setPermissions\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"executeCall(address,uint256,bytes)\":{\"details\":\"executes a low-level call against an account if the caller is authorized to make calls\"},\"isAuthorized(address)\":{\"details\":\"Returns the authorization status for a given caller\"},\"isLocked()\":{\"details\":\"returns the current lock status of the account as a boolean\"},\"lock(uint256)\":{\"details\":\"locks the account until a certain timestamp\"},\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\":{\"details\":\"Allows ERC-1155 token batches to be received. This function can be overriden.\"},\"onERC1155Received(address,address,uint256,uint256,bytes)\":{\"details\":\"Allows ERC-1155 tokens to be received. This function can be overriden.\"},\"onERC721Received(address,address,uint256,bytes)\":{\"details\":\"Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle. This function can be overriden.\"},\"owner()\":{\"details\":\"Returns the owner of the ERC-721 token which owns this account. By default, the owner of the token has full permissions on the account.\"},\"setPermissions(address[],bool[])\":{\"details\":\"grants a given caller execution permissions\"},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if a given interfaceId is supported by this account. This method can be extended by an override.\"},\"token()\":{\"details\":\"Returns the EIP-155 chain ID, token contract address, and token ID for the token that owns this account.\"}},\"stateVariables\":{\"lockedUntil\":{\"details\":\"timestamp at which this account will be unlocked\"},\"permissions\":{\"details\":\"mapping from owner => caller => has permissions\"}},\"title\":\"A smart contract account owned by a single ERC721 token\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/MinimalisticAccount.sol\":\"MinimalisticAccount\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (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 *\\n * NOTE: 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 *\\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.\\n *\\n * NOTE: 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 *\\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\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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`.\\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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\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(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface 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 `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/MinimalisticAccount.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\nimport \\\"./interfaces/IERC6551Account.sol\\\";\\nimport \\\"./lib/ERC6551AccountLib.sol\\\";\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/interfaces/IERC1271.sol\\\";\\n\\nerror NotAuthorized();\\nerror InvalidInput();\\nerror AccountLocked();\\nerror ExceedsMaxLockTime();\\nerror UntrustedImplementation();\\nerror OwnershipCycle();\\n\\n/**\\n * @title A smart contract account owned by a single ERC721 token\\n */\\ncontract MinimalisticAccount is\\n IERC165,\\n IERC6551Account,\\n IERC721Receiver,\\n IERC1155Receiver\\n{\\n /// @dev timestamp at which this account will be unlocked\\n uint256 public lockedUntil;\\n\\n /// @dev mapping from owner => caller => has permissions\\n mapping(address => mapping(address => bool)) public permissions;\\n\\n event OverrideUpdated(\\n address owner,\\n bytes4 selector,\\n address implementation\\n );\\n\\n event PermissionUpdated(address owner, address caller, bool hasPermission);\\n\\n event LockUpdated(uint256 lockedUntil);\\n\\n /// @dev reverts if caller is not the owner of the account\\n modifier onlyOwner() {\\n if (msg.sender != owner()) revert NotAuthorized();\\n _;\\n }\\n\\n /// @dev reverts if caller is not authorized to execute on this account\\n modifier onlyAuthorized() {\\n if (!isAuthorized(msg.sender)) revert NotAuthorized();\\n _;\\n }\\n\\n /// @dev reverts if this account is currently locked\\n modifier onlyUnlocked() {\\n if (isLocked()) revert AccountLocked();\\n _;\\n }\\n\\n constructor() {}\\n\\n /// @dev allows eth transfers by default, but allows account owner to override\\n receive() external payable {\\n }\\n\\n /// @dev executes a low-level call against an account if the caller is authorized to make calls\\n function executeCall(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) external payable onlyAuthorized onlyUnlocked returns (bytes memory) {\\n emit TransactionExecuted(to, value, data);\\n\\n return _call(to, value, data);\\n }\\n\\n /// @dev grants a given caller execution permissions\\n function setPermissions(\\n address[] calldata callers,\\n bool[] calldata _permissions\\n ) external onlyUnlocked {\\n address _owner = owner();\\n if (msg.sender != _owner) revert NotAuthorized();\\n\\n uint256 length = callers.length;\\n\\n if (_permissions.length != length) revert InvalidInput();\\n\\n for (uint256 i = 0; i < length; i++) {\\n permissions[_owner][callers[i]] = _permissions[i];\\n emit PermissionUpdated(_owner, callers[i], _permissions[i]);\\n }\\n }\\n\\n /// @dev locks the account until a certain timestamp\\n function lock(uint256 _lockedUntil) external onlyOwner onlyUnlocked {\\n if (_lockedUntil > block.timestamp + 365 days)\\n revert ExceedsMaxLockTime();\\n\\n lockedUntil = _lockedUntil;\\n\\n emit LockUpdated(_lockedUntil);\\n }\\n\\n /// @dev returns the current lock status of the account as a boolean\\n function isLocked() public view returns (bool) {\\n return lockedUntil > block.timestamp;\\n }\\n\\n /// @dev Returns the EIP-155 chain ID, token contract address, and token ID for the token that\\n /// owns this account.\\n function token()\\n external\\n view\\n returns (\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n )\\n {\\n return ERC6551AccountLib.token();\\n }\\n\\n /// @dev Returns the owner of the ERC-721 token which owns this account. By default, the owner\\n /// of the token has full permissions on the account.\\n function owner() public view returns (address) {\\n (\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) = ERC6551AccountLib.token();\\n\\n if (chainId != block.chainid) return address(0);\\n\\n return IERC721(tokenContract).ownerOf(tokenId);\\n }\\n\\n /// @dev Returns the authorization status for a given caller\\n function isAuthorized(address caller) public view returns (bool) {\\n (\\n ,\\n address tokenContract,\\n uint256 tokenId\\n ) = ERC6551AccountLib.token();\\n address _owner = IERC721(tokenContract).ownerOf(tokenId);\\n\\n // authorize token owner\\n if (caller == _owner) return true;\\n\\n // authorize caller if owner has granted permissions\\n if (permissions[_owner][caller]) return true;\\n\\n return false;\\n }\\n\\n /// @dev Returns true if a given interfaceId is supported by this account. This method can be\\n /// extended by an override.\\n function supportsInterface(bytes4 interfaceId)\\n public\\n pure \\n override\\n returns (bool)\\n {\\n bool defaultSupport = interfaceId == type(IERC165).interfaceId ||\\n interfaceId == type(IERC1155Receiver).interfaceId ||\\n interfaceId == type(IERC6551Account).interfaceId;\\n\\n if (defaultSupport) return true;\\n\\n return false;\\n }\\n\\n /// @dev Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle.\\n /// This function can be overriden.\\n function onERC721Received(\\n address,\\n address,\\n uint256 receivedTokenId,\\n bytes memory\\n ) public view override returns (bytes4) {\\n (\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) = ERC6551AccountLib.token();\\n\\n if (\\n chainId == block.chainid &&\\n tokenContract == msg.sender &&\\n tokenId == receivedTokenId\\n ) revert OwnershipCycle();\\n\\n return this.onERC721Received.selector;\\n }\\n\\n /// @dev Allows ERC-1155 tokens to be received. This function can be overriden.\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes memory\\n ) public pure override returns (bytes4) {\\n return this.onERC1155Received.selector;\\n }\\n\\n /// @dev Allows ERC-1155 token batches to be received. This function can be overriden.\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] memory,\\n uint256[] memory,\\n bytes memory\\n ) public pure override returns (bytes4) {\\n return this.onERC1155BatchReceived.selector;\\n }\\n\\n /// @dev Executes a low-level call\\n function _call(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) internal returns (bytes memory result) {\\n bool success;\\n (success, result) = to.call{value: value}(data);\\n\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /// @dev Executes a low-level static call\\n function _callStatic(address to, bytes calldata data)\\n internal\\n view\\n returns (bytes memory result)\\n {\\n bool success;\\n (success, result) = to.staticcall(data);\\n\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xed537db66c8c88618b283b038ec6e1b55b56c1ad4006658a1fef0fe8e60fb528\",\"license\":\"UNLICENSED\"},\"contracts/interfaces/IERC6551Account.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\ninterface IERC6551AccountProxy {\\n function implementation() external view returns (address);\\n}\\n\\n/// @dev the ERC-165 identifier for this interface is `0xeff4d378`\\ninterface IERC6551Account {\\n event TransactionExecuted(address indexed target, uint256 indexed value, bytes data);\\n\\n receive() external payable;\\n\\n function executeCall(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) external payable returns (bytes memory);\\n\\n function token()\\n external\\n view\\n returns (uint256 chainId, address tokenContract, uint256 tokenId);\\n\\n function owner() external view returns (address);\\n}\\n\",\"keccak256\":\"0x5fe2dca745f8e753d414778980a0846c1bbcbb26a09d7cd7fb712c7db7939582\",\"license\":\"UNLICENSED\"},\"contracts/lib/ERC6551AccountLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.13;\\n\\nlibrary ERC6551AccountLib {\\n function token()\\n internal\\n view\\n returns (\\n uint256,\\n address,\\n uint256\\n )\\n {\\n bytes memory footer = new bytes(0x60);\\n\\n assembly {\\n // copy 0x60 bytes from end of footer\\n extcodecopy(address(), add(footer, 0x20), 0x4d, 0xad)\\n }\\n\\n return abi.decode(footer, (uint256, address, uint256));\\n }\\n\\n function salt() internal view returns (uint256) {\\n bytes memory footer = new bytes(0x20);\\n\\n assembly {\\n // copy 0x20 bytes from beginning of footer\\n extcodecopy(address(), add(footer, 0x20), 0x2d, 0x4d)\\n }\\n\\n return abi.decode(footer, (uint256));\\n }\\n}\\n\",\"keccak256\":\"0xf7a8eb3b4fb63068eb8ed2a1a129e4676af842541f43c1a1dc96a9f295060c45\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[{"astId":287,"contract":"contracts/MinimalisticAccount.sol:MinimalisticAccount","label":"lockedUntil","offset":0,"slot":"0","type":"t_uint256"},{"astId":294,"contract":"contracts/MinimalisticAccount.sol:MinimalisticAccount","label":"permissions","offset":0,"slot":"1","type":"t_mapping(t_address,t_mapping(t_address,t_bool))"}],"types":{"t_address":{"encoding":"inplace","label":"address","numberOfBytes":"20"},"t_bool":{"encoding":"inplace","label":"bool","numberOfBytes":"1"},"t_mapping(t_address,t_bool)":{"encoding":"mapping","key":"t_address","label":"mapping(address => bool)","numberOfBytes":"32","value":"t_bool"},"t_mapping(t_address,t_mapping(t_address,t_bool))":{"encoding":"mapping","key":"t_address","label":"mapping(address => mapping(address => bool))","numberOfBytes":"32","value":"t_mapping(t_address,t_bool)"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/interfaces/IERC6551Account.sol":{"IERC6551Account":{"abi":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":true,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"TransactionExecuted","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"executeCall","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}],"devdoc":{"details":"the ERC-165 identifier for this interface is `0xeff4d378`","kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"executeCall(address,uint256,bytes)":"9e5d4c49","owner()":"8da5cb5b","token()":"fc0c546a"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"TransactionExecuted\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"executeCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"the ERC-165 identifier for this interface is `0xeff4d378`\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/interfaces/IERC6551Account.sol\":\"IERC6551Account\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interfaces/IERC6551Account.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\ninterface IERC6551AccountProxy {\\n function implementation() external view returns (address);\\n}\\n\\n/// @dev the ERC-165 identifier for this interface is `0xeff4d378`\\ninterface IERC6551Account {\\n event TransactionExecuted(address indexed target, uint256 indexed value, bytes data);\\n\\n receive() external payable;\\n\\n function executeCall(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) external payable returns (bytes memory);\\n\\n function token()\\n external\\n view\\n returns (uint256 chainId, address tokenContract, uint256 tokenId);\\n\\n function owner() external view returns (address);\\n}\\n\",\"keccak256\":\"0x5fe2dca745f8e753d414778980a0846c1bbcbb26a09d7cd7fb712c7db7939582\",\"license\":\"UNLICENSED\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}},"IERC6551AccountProxy":{"abi":[{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"implementation()":"5c60da1b"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/interfaces/IERC6551Account.sol\":\"IERC6551AccountProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interfaces/IERC6551Account.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\ninterface IERC6551AccountProxy {\\n function implementation() external view returns (address);\\n}\\n\\n/// @dev the ERC-165 identifier for this interface is `0xeff4d378`\\ninterface IERC6551Account {\\n event TransactionExecuted(address indexed target, uint256 indexed value, bytes data);\\n\\n receive() external payable;\\n\\n function executeCall(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) external payable returns (bytes memory);\\n\\n function token()\\n external\\n view\\n returns (uint256 chainId, address tokenContract, uint256 tokenId);\\n\\n function owner() external view returns (address);\\n}\\n\",\"keccak256\":\"0x5fe2dca745f8e753d414778980a0846c1bbcbb26a09d7cd7fb712c7db7939582\",\"license\":\"UNLICENSED\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/lib/ERC6551AccountLib.sol":{"ERC6551AccountLib":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220507d1af45fff54535180cd2db9c0244503eb6a3f2538827633938e9a22f0be7564736f6c63430008110033","opcodes":"PUSH1 0x56 PUSH1 0x37 PUSH1 0xB DUP3 DUP3 DUP3 CODECOPY DUP1 MLOAD PUSH1 0x0 BYTE PUSH1 0x73 EQ PUSH1 0x2A JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x0 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST ADDRESS PUSH1 0x0 MSTORE PUSH1 0x73 DUP2 MSTORE8 DUP3 DUP2 RETURN INVALID PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 POP PUSH30 0x1AF45FFF54535180CD2DB9C0244503EB6A3F2538827633938E9A22F0BE75 PUSH5 0x736F6C6343 STOP ADDMOD GT STOP CALLER ","sourceMap":"58:747:8:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;58:747:8;;;;;;;;;;;;;;;;;"},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220507d1af45fff54535180cd2db9c0244503eb6a3f2538827633938e9a22f0be7564736f6c63430008110033","opcodes":"PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 POP PUSH30 0x1AF45FFF54535180CD2DB9C0244503EB6A3F2538827633938E9A22F0BE75 PUSH5 0x736F6C6343 STOP ADDMOD GT STOP CALLER ","sourceMap":"58:747:8:-:0;;;;;;;;"},"gasEstimates":{"creation":{"codeDepositCost":"17200","executionCost":"103","totalCost":"17303"},"internal":{"salt()":"infinite","token()":"infinite"}},"methodIdentifiers":{}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/lib/ERC6551AccountLib.sol\":\"ERC6551AccountLib\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/lib/ERC6551AccountLib.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.13;\\n\\nlibrary ERC6551AccountLib {\\n function token()\\n internal\\n view\\n returns (\\n uint256,\\n address,\\n uint256\\n )\\n {\\n bytes memory footer = new bytes(0x60);\\n\\n assembly {\\n // copy 0x60 bytes from end of footer\\n extcodecopy(address(), add(footer, 0x20), 0x4d, 0xad)\\n }\\n\\n return abi.decode(footer, (uint256, address, uint256));\\n }\\n\\n function salt() internal view returns (uint256) {\\n bytes memory footer = new bytes(0x20);\\n\\n assembly {\\n // copy 0x20 bytes from beginning of footer\\n extcodecopy(address(), add(footer, 0x20), 0x2d, 0x4d)\\n }\\n\\n return abi.decode(footer, (uint256));\\n }\\n}\\n\",\"keccak256\":\"0xf7a8eb3b4fb63068eb8ed2a1a129e4676af842541f43c1a1dc96a9f295060c45\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}}}}} \ No newline at end of file diff --git a/build/contracts/build-info/621b40ccb08e9f77631297486483360b.json b/build/contracts/build-info/621b40ccb08e9f77631297486483360b.json deleted file mode 100644 index bb513d4..0000000 --- a/build/contracts/build-info/621b40ccb08e9f77631297486483360b.json +++ /dev/null @@ -1 +0,0 @@ -{"id":"621b40ccb08e9f77631297486483360b","_format":"hh-sol-build-info-1","solcVersion":"0.8.17","solcLongVersion":"0.8.17+commit.8df45f5f","input":{"language":"Solidity","sources":{"@openzeppelin/contracts/token/ERC721/ERC721.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (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: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = 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 token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or 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(address from, address to, uint256 tokenId, bytes memory data) 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 the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\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 _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) 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, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\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, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\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(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try 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 /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n"},"@openzeppelin/contracts/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/token/ERC721/IERC721.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (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`.\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(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\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(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"},"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface 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 `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"},"@openzeppelin/contracts/utils/Address.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\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 * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, \"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(address target, bytes memory data, uint256 value) 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 (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or 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 _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n"},"@openzeppelin/contracts/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/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/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/utils/math/Math.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (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 enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\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 == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10 ** 64) {\n value /= 10 ** 64;\n result += 64;\n }\n if (value >= 10 ** 32) {\n value /= 10 ** 32;\n result += 32;\n }\n if (value >= 10 ** 16) {\n value /= 10 ** 16;\n result += 16;\n }\n if (value >= 10 ** 8) {\n value /= 10 ** 8;\n result += 8;\n }\n if (value >= 10 ** 4) {\n value /= 10 ** 4;\n result += 4;\n }\n if (value >= 10 ** 2) {\n value /= 10 ** 2;\n result += 2;\n }\n if (value >= 10 ** 1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n"},"@openzeppelin/contracts/utils/math/SignedMath.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n"},"@openzeppelin/contracts/utils/Strings.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\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 unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\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] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n"},"contracts/AccountRegistryBridge.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.13;\n\nimport \"./interfaces/IRegistry.sol\";\ncontract AccountRegistryBridge {\n address public constant REGISTRY = \t0x02101dfB77FDE026414827Fdc604ddAF224F0921;\n address public constant IMPLMENTATION = 0x2D25602551487C3f3354dD80D76D54383A243358;\n\n function createAccount(address contractAddress, uint256 tokenId)\n external\n returns (address)\n {\n return IRegistry(REGISTRY).createAccount(\n IMPLMENTATION,\n block.chainid,\n contractAddress,\n tokenId,\n 0,\n ''\n );\n }\n\n function account(address contractAddress, uint256 tokenId)\n external\n view\n returns (address)\n {\n return IRegistry(REGISTRY).account(\n IMPLMENTATION,\n block.chainid,\n contractAddress,\n tokenId,\n 0\n );\n }\n}"},"contracts/ChargedParticles.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.13;\n\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./AccountRegistryBridge.sol\";\n\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\ncontract ChargedParticles is AccountRegistryBridge {\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n ) external returns (uint256 yieldTokensAmount) {\n \n }\n\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount) {\n\n }\n\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount) {\n\n }\n\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 receiverAmount) {\n\n }\n\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount) {\n\n }\n\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount) {\n\n }\n\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success) {\n address tokenBoundAccount = this.account(contractAddress, tokenId); \n IERC721(nftTokenAddress).safeTransferFrom(msg.sender, tokenBoundAccount, nftTokenId);\n }\n\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success) {\n\n }\n\n}\n"},"contracts/interfaces/IAccount.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\ninterface IAccount {\n function owner() external view returns (address);\n\n function token()\n external\n view\n returns (address tokenContract, uint256 tokenId);\n\n function executeCall(\n address to,\n uint256 value,\n bytes calldata data\n ) external payable returns (bytes memory);\n}\n"},"contracts/interfaces/IChargedParticles.sol":{"content":"// SPDX-License-Identifier: MIT\n\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Charged Particles\n */\ninterface IChargedParticles {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getStateAddress() external view returns (address stateAddress);\n function getSettingsAddress() external view returns (address settingsAddress);\n function getManagersAddress() external view returns (address managersAddress);\n\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\n\n /***********************************|\n | Particle Mechanics |\n |__________________________________*/\n\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n ) external returns (uint256 yieldTokensAmount);\n\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 receiverAmount);\n\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositFeeSet(uint256 depositFee);\n event ProtocolFeesCollected(address indexed assetToken, uint256 depositAmount, uint256 feesCollected);\n}\n"},"contracts/interfaces/IRegistry.sol":{"content":"// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\ninterface IRegistry {\n function createAccount(\n address implementation,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId,\n uint256 salt,\n bytes calldata initData\n ) external returns (address);\n\n function account(\n address implementation,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId,\n uint256 salt\n ) external view returns (address);\n}\n"},"contracts/mock/NFTMock.sol":{"content":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.8;\n\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\n\ncontract NFTMock is ERC721 {\n // solhint-disable-next-line no-empty-blocks\n constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {\n }\n\n function mint(address to, uint256 tokenId) external {\n _mint(to, tokenId);\n }\n}"}},"settings":{"optimizer":{"enabled":true,"runs":200},"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata","devdoc","userdoc","storageLayout","evm.gasEstimates"],"":["ast"]}},"metadata":{"useLiteralContent":true}}},"output":{"errors":[{"component":"general","errorCode":"5667","formattedMessage":"Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.\n --> contracts/ChargedParticles.sol:77:9:\n |\n77 | string calldata basketManagerId,\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n","message":"Unused function parameter. Remove or comment out the variable name to silence this warning.","severity":"warning","sourceLocation":{"end":2067,"file":"contracts/ChargedParticles.sol","start":2036},"type":"Warning"},{"component":"general","errorCode":"5667","formattedMessage":"Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.\n --> contracts/ChargedParticles.sol:80:9:\n |\n80 | uint256 nftTokenAmount\n | ^^^^^^^^^^^^^^^^^^^^^^\n\n","message":"Unused function parameter. Remove or comment out the variable name to silence this warning.","severity":"warning","sourceLocation":{"end":2160,"file":"contracts/ChargedParticles.sol","start":2138},"type":"Warning"},{"component":"general","errorCode":"5667","formattedMessage":"Warning: Unused function parameter. Remove or comment out the variable name to silence this warning.\n --> contracts/ChargedParticles.sol:81:25:\n |\n81 | ) external returns (bool success) {\n | ^^^^^^^^^^^^\n\n","message":"Unused function parameter. Remove or comment out the variable name to silence this warning.","severity":"warning","sourceLocation":{"end":2197,"file":"contracts/ChargedParticles.sol","start":2185},"type":"Warning"}],"sources":{"@openzeppelin/contracts/token/ERC721/ERC721.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/token/ERC721/ERC721.sol","exportedSymbols":{"Address":[1417],"Context":[1439],"ERC165":[1692],"ERC721":[926],"IERC165":[1704],"IERC721":[1042],"IERC721Metadata":[1087],"IERC721Receiver":[1060],"Math":[2570],"SignedMath":[2675],"Strings":[1668]},"id":927,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":1,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"107:23:0"},{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721.sol","file":"./IERC721.sol","id":2,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":927,"sourceUnit":1043,"src":"132:23:0","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol","file":"./IERC721Receiver.sol","id":3,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":927,"sourceUnit":1061,"src":"156:31:0","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol","file":"./extensions/IERC721Metadata.sol","id":4,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":927,"sourceUnit":1088,"src":"188:42:0","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/utils/Address.sol","file":"../../utils/Address.sol","id":5,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":927,"sourceUnit":1418,"src":"231:33:0","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/utils/Context.sol","file":"../../utils/Context.sol","id":6,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":927,"sourceUnit":1440,"src":"265:33:0","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/utils/Strings.sol","file":"../../utils/Strings.sol","id":7,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":927,"sourceUnit":1669,"src":"299:33:0","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/utils/introspection/ERC165.sol","file":"../../utils/introspection/ERC165.sol","id":8,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":927,"sourceUnit":1693,"src":"333:46:0","symbolAliases":[],"unitAlias":""},{"abstract":false,"baseContracts":[{"baseName":{"id":10,"name":"Context","nameLocations":["647:7:0"],"nodeType":"IdentifierPath","referencedDeclaration":1439,"src":"647:7:0"},"id":11,"nodeType":"InheritanceSpecifier","src":"647:7:0"},{"baseName":{"id":12,"name":"ERC165","nameLocations":["656:6:0"],"nodeType":"IdentifierPath","referencedDeclaration":1692,"src":"656:6:0"},"id":13,"nodeType":"InheritanceSpecifier","src":"656:6:0"},{"baseName":{"id":14,"name":"IERC721","nameLocations":["664:7:0"],"nodeType":"IdentifierPath","referencedDeclaration":1042,"src":"664:7:0"},"id":15,"nodeType":"InheritanceSpecifier","src":"664:7:0"},{"baseName":{"id":16,"name":"IERC721Metadata","nameLocations":["673:15:0"],"nodeType":"IdentifierPath","referencedDeclaration":1087,"src":"673:15:0"},"id":17,"nodeType":"InheritanceSpecifier","src":"673:15:0"}],"canonicalName":"ERC721","contractDependencies":[],"contractKind":"contract","documentation":{"id":9,"nodeType":"StructuredDocumentation","src":"381:246:0","text":" @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}."},"fullyImplemented":true,"id":926,"linearizedBaseContracts":[926,1087,1042,1692,1704,1439],"name":"ERC721","nameLocation":"637:6:0","nodeType":"ContractDefinition","nodes":[{"global":false,"id":20,"libraryName":{"id":18,"name":"Address","nameLocations":["701:7:0"],"nodeType":"IdentifierPath","referencedDeclaration":1417,"src":"701:7:0"},"nodeType":"UsingForDirective","src":"695:26:0","typeName":{"id":19,"name":"address","nodeType":"ElementaryTypeName","src":"713:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}},{"global":false,"id":23,"libraryName":{"id":21,"name":"Strings","nameLocations":["732:7:0"],"nodeType":"IdentifierPath","referencedDeclaration":1668,"src":"732:7:0"},"nodeType":"UsingForDirective","src":"726:26:0","typeName":{"id":22,"name":"uint256","nodeType":"ElementaryTypeName","src":"744:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}},{"constant":false,"id":25,"mutability":"mutable","name":"_name","nameLocation":"791:5:0","nodeType":"VariableDeclaration","scope":926,"src":"776:20:0","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_string_storage","typeString":"string"},"typeName":{"id":24,"name":"string","nodeType":"ElementaryTypeName","src":"776:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"private"},{"constant":false,"id":27,"mutability":"mutable","name":"_symbol","nameLocation":"838:7:0","nodeType":"VariableDeclaration","scope":926,"src":"823:22:0","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_string_storage","typeString":"string"},"typeName":{"id":26,"name":"string","nodeType":"ElementaryTypeName","src":"823:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"private"},{"constant":false,"id":31,"mutability":"mutable","name":"_owners","nameLocation":"934:7:0","nodeType":"VariableDeclaration","scope":926,"src":"898:43:0","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_mapping$_t_uint256_$_t_address_$","typeString":"mapping(uint256 => address)"},"typeName":{"id":30,"keyType":{"id":28,"name":"uint256","nodeType":"ElementaryTypeName","src":"906:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Mapping","src":"898:27:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_uint256_$_t_address_$","typeString":"mapping(uint256 => address)"},"valueType":{"id":29,"name":"address","nodeType":"ElementaryTypeName","src":"917:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}},"visibility":"private"},{"constant":false,"id":35,"mutability":"mutable","name":"_balances","nameLocation":"1028:9:0","nodeType":"VariableDeclaration","scope":926,"src":"992:45:0","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_uint256_$","typeString":"mapping(address => uint256)"},"typeName":{"id":34,"keyType":{"id":32,"name":"address","nodeType":"ElementaryTypeName","src":"1000:7:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"Mapping","src":"992:27:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_uint256_$","typeString":"mapping(address => uint256)"},"valueType":{"id":33,"name":"uint256","nodeType":"ElementaryTypeName","src":"1011:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}},"visibility":"private"},{"constant":false,"id":39,"mutability":"mutable","name":"_tokenApprovals","nameLocation":"1129:15:0","nodeType":"VariableDeclaration","scope":926,"src":"1093:51:0","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_mapping$_t_uint256_$_t_address_$","typeString":"mapping(uint256 => address)"},"typeName":{"id":38,"keyType":{"id":36,"name":"uint256","nodeType":"ElementaryTypeName","src":"1101:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Mapping","src":"1093:27:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_uint256_$_t_address_$","typeString":"mapping(uint256 => address)"},"valueType":{"id":37,"name":"address","nodeType":"ElementaryTypeName","src":"1112:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}},"visibility":"private"},{"constant":false,"id":45,"mutability":"mutable","name":"_operatorApprovals","nameLocation":"1252:18:0","nodeType":"VariableDeclaration","scope":926,"src":"1199:71:0","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_mapping$_t_address_$_t_bool_$_$","typeString":"mapping(address => mapping(address => bool))"},"typeName":{"id":44,"keyType":{"id":40,"name":"address","nodeType":"ElementaryTypeName","src":"1207:7:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"Mapping","src":"1199:44:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_mapping$_t_address_$_t_bool_$_$","typeString":"mapping(address => mapping(address => bool))"},"valueType":{"id":43,"keyType":{"id":41,"name":"address","nodeType":"ElementaryTypeName","src":"1226:7:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"Mapping","src":"1218:24:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_bool_$","typeString":"mapping(address => bool)"},"valueType":{"id":42,"name":"bool","nodeType":"ElementaryTypeName","src":"1237:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}}},"visibility":"private"},{"body":{"id":61,"nodeType":"Block","src":"1446:57:0","statements":[{"expression":{"id":55,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":53,"name":"_name","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":25,"src":"1456:5:0","typeDescriptions":{"typeIdentifier":"t_string_storage","typeString":"string storage ref"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":54,"name":"name_","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":48,"src":"1464:5:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},"src":"1456:13:0","typeDescriptions":{"typeIdentifier":"t_string_storage","typeString":"string storage ref"}},"id":56,"nodeType":"ExpressionStatement","src":"1456:13:0"},{"expression":{"id":59,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":57,"name":"_symbol","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":27,"src":"1479:7:0","typeDescriptions":{"typeIdentifier":"t_string_storage","typeString":"string storage ref"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":58,"name":"symbol_","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":50,"src":"1489:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},"src":"1479:17:0","typeDescriptions":{"typeIdentifier":"t_string_storage","typeString":"string storage ref"}},"id":60,"nodeType":"ExpressionStatement","src":"1479:17:0"}]},"documentation":{"id":46,"nodeType":"StructuredDocumentation","src":"1277:108:0","text":" @dev Initializes the contract by setting a `name` and a `symbol` to the token collection."},"id":62,"implemented":true,"kind":"constructor","modifiers":[],"name":"","nameLocation":"-1:-1:-1","nodeType":"FunctionDefinition","parameters":{"id":51,"nodeType":"ParameterList","parameters":[{"constant":false,"id":48,"mutability":"mutable","name":"name_","nameLocation":"1416:5:0","nodeType":"VariableDeclaration","scope":62,"src":"1402:19:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":47,"name":"string","nodeType":"ElementaryTypeName","src":"1402:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":50,"mutability":"mutable","name":"symbol_","nameLocation":"1437:7:0","nodeType":"VariableDeclaration","scope":62,"src":"1423:21:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":49,"name":"string","nodeType":"ElementaryTypeName","src":"1423:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1401:44:0"},"returnParameters":{"id":52,"nodeType":"ParameterList","parameters":[],"src":"1446:0:0"},"scope":926,"src":"1390:113:0","stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"baseFunctions":[1691,1703],"body":{"id":92,"nodeType":"Block","src":"1678:192:0","statements":[{"expression":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":90,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":85,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"id":78,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":73,"name":"interfaceId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":65,"src":"1707:11:0","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"arguments":[{"id":75,"name":"IERC721","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1042,"src":"1727:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC721_$1042_$","typeString":"type(contract IERC721)"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_type$_t_contract$_IERC721_$1042_$","typeString":"type(contract IERC721)"}],"id":74,"name":"type","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-27,"src":"1722:4:0","typeDescriptions":{"typeIdentifier":"t_function_metatype_pure$__$returns$__$","typeString":"function () pure"}},"id":76,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1722:13:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_magic_meta_type_t_contract$_IERC721_$1042","typeString":"type(contract IERC721)"}},"id":77,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"1736:11:0","memberName":"interfaceId","nodeType":"MemberAccess","src":"1722:25:0","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"src":"1707:40:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"||","rightExpression":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"id":84,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":79,"name":"interfaceId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":65,"src":"1763:11:0","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"arguments":[{"id":81,"name":"IERC721Metadata","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1087,"src":"1783:15:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC721Metadata_$1087_$","typeString":"type(contract IERC721Metadata)"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_type$_t_contract$_IERC721Metadata_$1087_$","typeString":"type(contract IERC721Metadata)"}],"id":80,"name":"type","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-27,"src":"1778:4:0","typeDescriptions":{"typeIdentifier":"t_function_metatype_pure$__$returns$__$","typeString":"function () pure"}},"id":82,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1778:21:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_magic_meta_type_t_contract$_IERC721Metadata_$1087","typeString":"type(contract IERC721Metadata)"}},"id":83,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"1800:11:0","memberName":"interfaceId","nodeType":"MemberAccess","src":"1778:33:0","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"src":"1763:48:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"1707:104:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"||","rightExpression":{"arguments":[{"id":88,"name":"interfaceId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":65,"src":"1851:11:0","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes4","typeString":"bytes4"}],"expression":{"id":86,"name":"super","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-25,"src":"1827:5:0","typeDescriptions":{"typeIdentifier":"t_type$_t_super$_ERC721_$926_$","typeString":"type(contract super ERC721)"}},"id":87,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"1833:17:0","memberName":"supportsInterface","nodeType":"MemberAccess","referencedDeclaration":1691,"src":"1827:23:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_bytes4_$returns$_t_bool_$","typeString":"function (bytes4) view returns (bool)"}},"id":89,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1827:36:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"1707:156:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"functionReturnParameters":72,"id":91,"nodeType":"Return","src":"1688:175:0"}]},"documentation":{"id":63,"nodeType":"StructuredDocumentation","src":"1509:56:0","text":" @dev See {IERC165-supportsInterface}."},"functionSelector":"01ffc9a7","id":93,"implemented":true,"kind":"function","modifiers":[],"name":"supportsInterface","nameLocation":"1579:17:0","nodeType":"FunctionDefinition","overrides":{"id":69,"nodeType":"OverrideSpecifier","overrides":[{"id":67,"name":"ERC165","nameLocations":["1646:6:0"],"nodeType":"IdentifierPath","referencedDeclaration":1692,"src":"1646:6:0"},{"id":68,"name":"IERC165","nameLocations":["1654:7:0"],"nodeType":"IdentifierPath","referencedDeclaration":1704,"src":"1654:7:0"}],"src":"1637:25:0"},"parameters":{"id":66,"nodeType":"ParameterList","parameters":[{"constant":false,"id":65,"mutability":"mutable","name":"interfaceId","nameLocation":"1604:11:0","nodeType":"VariableDeclaration","scope":93,"src":"1597:18:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":64,"name":"bytes4","nodeType":"ElementaryTypeName","src":"1597:6:0","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"1596:20:0"},"returnParameters":{"id":72,"nodeType":"ParameterList","parameters":[{"constant":false,"id":71,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":93,"src":"1672:4:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":70,"name":"bool","nodeType":"ElementaryTypeName","src":"1672:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1671:6:0"},"scope":926,"src":"1570:300:0","stateMutability":"view","virtual":true,"visibility":"public"},{"baseFunctions":[967],"body":{"id":116,"nodeType":"Block","src":"2010:123:0","statements":[{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":108,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":103,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":96,"src":"2028:5:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"!=","rightExpression":{"arguments":[{"hexValue":"30","id":106,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"2045:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"id":105,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2037:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":104,"name":"address","nodeType":"ElementaryTypeName","src":"2037:7:0","typeDescriptions":{}}},"id":107,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2037:10:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"2028:19:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"4552433732313a2061646472657373207a65726f206973206e6f7420612076616c6964206f776e6572","id":109,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2049:43:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_6d05c90094f31cfeb8f0eb86f0a513af3f7f8992991fbde41b08aa7960677159","typeString":"literal_string \"ERC721: address zero is not a valid owner\""},"value":"ERC721: address zero is not a valid owner"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_6d05c90094f31cfeb8f0eb86f0a513af3f7f8992991fbde41b08aa7960677159","typeString":"literal_string \"ERC721: address zero is not a valid owner\""}],"id":102,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"2020:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":110,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2020:73:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":111,"nodeType":"ExpressionStatement","src":"2020:73:0"},{"expression":{"baseExpression":{"id":112,"name":"_balances","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":35,"src":"2110:9:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_uint256_$","typeString":"mapping(address => uint256)"}},"id":114,"indexExpression":{"id":113,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":96,"src":"2120:5:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"2110:16:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"functionReturnParameters":101,"id":115,"nodeType":"Return","src":"2103:23:0"}]},"documentation":{"id":94,"nodeType":"StructuredDocumentation","src":"1876:48:0","text":" @dev See {IERC721-balanceOf}."},"functionSelector":"70a08231","id":117,"implemented":true,"kind":"function","modifiers":[],"name":"balanceOf","nameLocation":"1938:9:0","nodeType":"FunctionDefinition","overrides":{"id":98,"nodeType":"OverrideSpecifier","overrides":[],"src":"1983:8:0"},"parameters":{"id":97,"nodeType":"ParameterList","parameters":[{"constant":false,"id":96,"mutability":"mutable","name":"owner","nameLocation":"1956:5:0","nodeType":"VariableDeclaration","scope":117,"src":"1948:13:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":95,"name":"address","nodeType":"ElementaryTypeName","src":"1948:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1947:15:0"},"returnParameters":{"id":101,"nodeType":"ParameterList","parameters":[{"constant":false,"id":100,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":117,"src":"2001:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":99,"name":"uint256","nodeType":"ElementaryTypeName","src":"2001:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2000:9:0"},"scope":926,"src":"1929:204:0","stateMutability":"view","virtual":true,"visibility":"public"},{"baseFunctions":[975],"body":{"id":144,"nodeType":"Block","src":"2271:138:0","statements":[{"assignments":[127],"declarations":[{"constant":false,"id":127,"mutability":"mutable","name":"owner","nameLocation":"2289:5:0","nodeType":"VariableDeclaration","scope":144,"src":"2281:13:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":126,"name":"address","nodeType":"ElementaryTypeName","src":"2281:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":131,"initialValue":{"arguments":[{"id":129,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":120,"src":"2306:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":128,"name":"_ownerOf","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":427,"src":"2297:8:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_uint256_$returns$_t_address_$","typeString":"function (uint256) view returns (address)"}},"id":130,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2297:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"2281:33:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":138,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":133,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":127,"src":"2332:5:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"!=","rightExpression":{"arguments":[{"hexValue":"30","id":136,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"2349:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"id":135,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2341:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":134,"name":"address","nodeType":"ElementaryTypeName","src":"2341:7:0","typeDescriptions":{}}},"id":137,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2341:10:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"2332:19:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"4552433732313a20696e76616c696420746f6b656e204944","id":139,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2353:26:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b08d2b0fec7cc108ab049809a8beb42779d969a49299d0c317c907d9db22974f","typeString":"literal_string \"ERC721: invalid token ID\""},"value":"ERC721: invalid token ID"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_b08d2b0fec7cc108ab049809a8beb42779d969a49299d0c317c907d9db22974f","typeString":"literal_string \"ERC721: invalid token ID\""}],"id":132,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"2324:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":140,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2324:56:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":141,"nodeType":"ExpressionStatement","src":"2324:56:0"},{"expression":{"id":142,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":127,"src":"2397:5:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"functionReturnParameters":125,"id":143,"nodeType":"Return","src":"2390:12:0"}]},"documentation":{"id":118,"nodeType":"StructuredDocumentation","src":"2139:46:0","text":" @dev See {IERC721-ownerOf}."},"functionSelector":"6352211e","id":145,"implemented":true,"kind":"function","modifiers":[],"name":"ownerOf","nameLocation":"2199:7:0","nodeType":"FunctionDefinition","overrides":{"id":122,"nodeType":"OverrideSpecifier","overrides":[],"src":"2244:8:0"},"parameters":{"id":121,"nodeType":"ParameterList","parameters":[{"constant":false,"id":120,"mutability":"mutable","name":"tokenId","nameLocation":"2215:7:0","nodeType":"VariableDeclaration","scope":145,"src":"2207:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":119,"name":"uint256","nodeType":"ElementaryTypeName","src":"2207:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2206:17:0"},"returnParameters":{"id":125,"nodeType":"ParameterList","parameters":[{"constant":false,"id":124,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":145,"src":"2262:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":123,"name":"address","nodeType":"ElementaryTypeName","src":"2262:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"2261:9:0"},"scope":926,"src":"2190:219:0","stateMutability":"view","virtual":true,"visibility":"public"},{"baseFunctions":[1072],"body":{"id":154,"nodeType":"Block","src":"2540:29:0","statements":[{"expression":{"id":152,"name":"_name","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":25,"src":"2557:5:0","typeDescriptions":{"typeIdentifier":"t_string_storage","typeString":"string storage ref"}},"functionReturnParameters":151,"id":153,"nodeType":"Return","src":"2550:12:0"}]},"documentation":{"id":146,"nodeType":"StructuredDocumentation","src":"2415:51:0","text":" @dev See {IERC721Metadata-name}."},"functionSelector":"06fdde03","id":155,"implemented":true,"kind":"function","modifiers":[],"name":"name","nameLocation":"2480:4:0","nodeType":"FunctionDefinition","overrides":{"id":148,"nodeType":"OverrideSpecifier","overrides":[],"src":"2507:8:0"},"parameters":{"id":147,"nodeType":"ParameterList","parameters":[],"src":"2484:2:0"},"returnParameters":{"id":151,"nodeType":"ParameterList","parameters":[{"constant":false,"id":150,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":155,"src":"2525:13:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":149,"name":"string","nodeType":"ElementaryTypeName","src":"2525:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2524:15:0"},"scope":926,"src":"2471:98:0","stateMutability":"view","virtual":true,"visibility":"public"},{"baseFunctions":[1078],"body":{"id":164,"nodeType":"Block","src":"2704:31:0","statements":[{"expression":{"id":162,"name":"_symbol","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":27,"src":"2721:7:0","typeDescriptions":{"typeIdentifier":"t_string_storage","typeString":"string storage ref"}},"functionReturnParameters":161,"id":163,"nodeType":"Return","src":"2714:14:0"}]},"documentation":{"id":156,"nodeType":"StructuredDocumentation","src":"2575:53:0","text":" @dev See {IERC721Metadata-symbol}."},"functionSelector":"95d89b41","id":165,"implemented":true,"kind":"function","modifiers":[],"name":"symbol","nameLocation":"2642:6:0","nodeType":"FunctionDefinition","overrides":{"id":158,"nodeType":"OverrideSpecifier","overrides":[],"src":"2671:8:0"},"parameters":{"id":157,"nodeType":"ParameterList","parameters":[],"src":"2648:2:0"},"returnParameters":{"id":161,"nodeType":"ParameterList","parameters":[{"constant":false,"id":160,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":165,"src":"2689:13:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":159,"name":"string","nodeType":"ElementaryTypeName","src":"2689:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2688:15:0"},"scope":926,"src":"2633:102:0","stateMutability":"view","virtual":true,"visibility":"public"},{"baseFunctions":[1086],"body":{"id":203,"nodeType":"Block","src":"2889:188:0","statements":[{"expression":{"arguments":[{"id":175,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":168,"src":"2914:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":174,"name":"_requireMinted","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":822,"src":"2899:14:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_uint256_$returns$__$","typeString":"function (uint256) view"}},"id":176,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2899:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":177,"nodeType":"ExpressionStatement","src":"2899:23:0"},{"assignments":[179],"declarations":[{"constant":false,"id":179,"mutability":"mutable","name":"baseURI","nameLocation":"2947:7:0","nodeType":"VariableDeclaration","scope":203,"src":"2933:21:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":178,"name":"string","nodeType":"ElementaryTypeName","src":"2933:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":182,"initialValue":{"arguments":[],"expression":{"argumentTypes":[],"id":180,"name":"_baseURI","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":213,"src":"2957:8:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_string_memory_ptr_$","typeString":"function () view returns (string memory)"}},"id":181,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2957:10:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},"nodeType":"VariableDeclarationStatement","src":"2933:34:0"},{"expression":{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":189,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"expression":{"arguments":[{"id":185,"name":"baseURI","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":179,"src":"2990:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"id":184,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2984:5:0","typeDescriptions":{"typeIdentifier":"t_type$_t_bytes_storage_ptr_$","typeString":"type(bytes storage pointer)"},"typeName":{"id":183,"name":"bytes","nodeType":"ElementaryTypeName","src":"2984:5:0","typeDescriptions":{}}},"id":186,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2984:14:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":187,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"2999:6:0","memberName":"length","nodeType":"MemberAccess","src":"2984:21:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"hexValue":"30","id":188,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3008:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"2984:25:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"falseExpression":{"hexValue":"","id":200,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3068:2:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","typeString":"literal_string \"\""},"value":""},"id":201,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"Conditional","src":"2984:86:0","trueExpression":{"arguments":[{"arguments":[{"id":194,"name":"baseURI","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":179,"src":"3036:7:0","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":195,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":168,"src":"3045:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":196,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"3053:8:0","memberName":"toString","nodeType":"MemberAccess","referencedDeclaration":1498,"src":"3045:16:0","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_uint256_$returns$_t_string_memory_ptr_$bound_to$_t_uint256_$","typeString":"function (uint256) pure returns (string memory)"}},"id":197,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3045:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":192,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"3019:3:0","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":193,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"3023:12:0","memberName":"encodePacked","nodeType":"MemberAccess","src":"3019:16:0","typeDescriptions":{"typeIdentifier":"t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$","typeString":"function () pure returns (bytes memory)"}},"id":198,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3019:45:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":191,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"3012:6:0","typeDescriptions":{"typeIdentifier":"t_type$_t_string_storage_ptr_$","typeString":"type(string storage pointer)"},"typeName":{"id":190,"name":"string","nodeType":"ElementaryTypeName","src":"3012:6:0","typeDescriptions":{}}},"id":199,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3012:53:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},"typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},"functionReturnParameters":173,"id":202,"nodeType":"Return","src":"2977:93:0"}]},"documentation":{"id":166,"nodeType":"StructuredDocumentation","src":"2741:55:0","text":" @dev See {IERC721Metadata-tokenURI}."},"functionSelector":"c87b56dd","id":204,"implemented":true,"kind":"function","modifiers":[],"name":"tokenURI","nameLocation":"2810:8:0","nodeType":"FunctionDefinition","overrides":{"id":170,"nodeType":"OverrideSpecifier","overrides":[],"src":"2856:8:0"},"parameters":{"id":169,"nodeType":"ParameterList","parameters":[{"constant":false,"id":168,"mutability":"mutable","name":"tokenId","nameLocation":"2827:7:0","nodeType":"VariableDeclaration","scope":204,"src":"2819:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":167,"name":"uint256","nodeType":"ElementaryTypeName","src":"2819:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2818:17:0"},"returnParameters":{"id":173,"nodeType":"ParameterList","parameters":[{"constant":false,"id":172,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":204,"src":"2874:13:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":171,"name":"string","nodeType":"ElementaryTypeName","src":"2874:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2873:15:0"},"scope":926,"src":"2801:276:0","stateMutability":"view","virtual":true,"visibility":"public"},{"body":{"id":212,"nodeType":"Block","src":"3385:26:0","statements":[{"expression":{"hexValue":"","id":210,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3402:2:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","typeString":"literal_string \"\""},"value":""},"functionReturnParameters":209,"id":211,"nodeType":"Return","src":"3395:9:0"}]},"documentation":{"id":205,"nodeType":"StructuredDocumentation","src":"3083:231:0","text":" @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n by default, can be overridden in child contracts."},"id":213,"implemented":true,"kind":"function","modifiers":[],"name":"_baseURI","nameLocation":"3328:8:0","nodeType":"FunctionDefinition","parameters":{"id":206,"nodeType":"ParameterList","parameters":[],"src":"3336:2:0"},"returnParameters":{"id":209,"nodeType":"ParameterList","parameters":[{"constant":false,"id":208,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":213,"src":"3370:13:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":207,"name":"string","nodeType":"ElementaryTypeName","src":"3370:6:0","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"3369:15:0"},"scope":926,"src":"3319:92:0","stateMutability":"view","virtual":true,"visibility":"internal"},{"baseFunctions":[1015],"body":{"id":255,"nodeType":"Block","src":"3538:336:0","statements":[{"assignments":[223],"declarations":[{"constant":false,"id":223,"mutability":"mutable","name":"owner","nameLocation":"3556:5:0","nodeType":"VariableDeclaration","scope":255,"src":"3548:13:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":222,"name":"address","nodeType":"ElementaryTypeName","src":"3548:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":228,"initialValue":{"arguments":[{"id":226,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":218,"src":"3579:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":224,"name":"ERC721","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":926,"src":"3564:6:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_ERC721_$926_$","typeString":"type(contract ERC721)"}},"id":225,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"3571:7:0","memberName":"ownerOf","nodeType":"MemberAccess","referencedDeclaration":145,"src":"3564:14:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_uint256_$returns$_t_address_$","typeString":"function (uint256) view returns (address)"}},"id":227,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3564:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"3548:39:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":232,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":230,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":216,"src":"3605:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"!=","rightExpression":{"id":231,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":223,"src":"3611:5:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"3605:11:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"4552433732313a20617070726f76616c20746f2063757272656e74206f776e6572","id":233,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3618:35:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b51b4875eede07862961e8f9365c6749f5fe55c6ee5d7a9e42b6912ad0b15942","typeString":"literal_string \"ERC721: approval to current owner\""},"value":"ERC721: approval to current owner"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_b51b4875eede07862961e8f9365c6749f5fe55c6ee5d7a9e42b6912ad0b15942","typeString":"literal_string \"ERC721: approval to current owner\""}],"id":229,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"3597:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":234,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3597:57:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":235,"nodeType":"ExpressionStatement","src":"3597:57:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":246,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":240,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[],"expression":{"argumentTypes":[],"id":237,"name":"_msgSender","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1429,"src":"3686:10:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_address_$","typeString":"function () view returns (address)"}},"id":238,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3686:12:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"id":239,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":223,"src":"3702:5:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"3686:21:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"||","rightExpression":{"arguments":[{"id":242,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":223,"src":"3728:5:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"arguments":[],"expression":{"argumentTypes":[],"id":243,"name":"_msgSender","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1429,"src":"3735:10:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_address_$","typeString":"function () view returns (address)"}},"id":244,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3735:12:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"}],"id":241,"name":"isApprovedForAll","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":309,"src":"3711:16:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_address_$_t_address_$returns$_t_bool_$","typeString":"function (address,address) view returns (bool)"}},"id":245,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3711:37:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"3686:62:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c","id":247,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3762:63:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c6e14a63ffb144eeef7cce6988e5dce07c60a7e0a7b1ef25dbe18c61483e0a83","typeString":"literal_string \"ERC721: approve caller is not token owner or approved for all\""},"value":"ERC721: approve caller is not token owner or approved for all"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_c6e14a63ffb144eeef7cce6988e5dce07c60a7e0a7b1ef25dbe18c61483e0a83","typeString":"literal_string \"ERC721: approve caller is not token owner or approved for all\""}],"id":236,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"3665:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":248,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3665:170:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":249,"nodeType":"ExpressionStatement","src":"3665:170:0"},{"expression":{"arguments":[{"id":251,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":216,"src":"3855:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":252,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":218,"src":"3859:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":250,"name":"_approve","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":776,"src":"3846:8:0","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_uint256_$returns$__$","typeString":"function (address,uint256)"}},"id":253,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3846:21:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":254,"nodeType":"ExpressionStatement","src":"3846:21:0"}]},"documentation":{"id":214,"nodeType":"StructuredDocumentation","src":"3417:46:0","text":" @dev See {IERC721-approve}."},"functionSelector":"095ea7b3","id":256,"implemented":true,"kind":"function","modifiers":[],"name":"approve","nameLocation":"3477:7:0","nodeType":"FunctionDefinition","overrides":{"id":220,"nodeType":"OverrideSpecifier","overrides":[],"src":"3529:8:0"},"parameters":{"id":219,"nodeType":"ParameterList","parameters":[{"constant":false,"id":216,"mutability":"mutable","name":"to","nameLocation":"3493:2:0","nodeType":"VariableDeclaration","scope":256,"src":"3485:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":215,"name":"address","nodeType":"ElementaryTypeName","src":"3485:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":218,"mutability":"mutable","name":"tokenId","nameLocation":"3505:7:0","nodeType":"VariableDeclaration","scope":256,"src":"3497:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":217,"name":"uint256","nodeType":"ElementaryTypeName","src":"3497:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3484:29:0"},"returnParameters":{"id":221,"nodeType":"ParameterList","parameters":[],"src":"3538:0:0"},"scope":926,"src":"3468:406:0","stateMutability":"nonpayable","virtual":true,"visibility":"public"},{"baseFunctions":[1031],"body":{"id":273,"nodeType":"Block","src":"4020:82:0","statements":[{"expression":{"arguments":[{"id":266,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":259,"src":"4045:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":265,"name":"_requireMinted","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":822,"src":"4030:14:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_uint256_$returns$__$","typeString":"function (uint256) view"}},"id":267,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4030:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":268,"nodeType":"ExpressionStatement","src":"4030:23:0"},{"expression":{"baseExpression":{"id":269,"name":"_tokenApprovals","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":39,"src":"4071:15:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_uint256_$_t_address_$","typeString":"mapping(uint256 => address)"}},"id":271,"indexExpression":{"id":270,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":259,"src":"4087:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"4071:24:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"functionReturnParameters":264,"id":272,"nodeType":"Return","src":"4064:31:0"}]},"documentation":{"id":257,"nodeType":"StructuredDocumentation","src":"3880:50:0","text":" @dev See {IERC721-getApproved}."},"functionSelector":"081812fc","id":274,"implemented":true,"kind":"function","modifiers":[],"name":"getApproved","nameLocation":"3944:11:0","nodeType":"FunctionDefinition","overrides":{"id":261,"nodeType":"OverrideSpecifier","overrides":[],"src":"3993:8:0"},"parameters":{"id":260,"nodeType":"ParameterList","parameters":[{"constant":false,"id":259,"mutability":"mutable","name":"tokenId","nameLocation":"3964:7:0","nodeType":"VariableDeclaration","scope":274,"src":"3956:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":258,"name":"uint256","nodeType":"ElementaryTypeName","src":"3956:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3955:17:0"},"returnParameters":{"id":264,"nodeType":"ParameterList","parameters":[{"constant":false,"id":263,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":274,"src":"4011:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":262,"name":"address","nodeType":"ElementaryTypeName","src":"4011:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"4010:9:0"},"scope":926,"src":"3935:167:0","stateMutability":"view","virtual":true,"visibility":"public"},{"baseFunctions":[1023],"body":{"id":290,"nodeType":"Block","src":"4253:69:0","statements":[{"expression":{"arguments":[{"arguments":[],"expression":{"argumentTypes":[],"id":284,"name":"_msgSender","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1429,"src":"4282:10:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_address_$","typeString":"function () view returns (address)"}},"id":285,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4282:12:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":286,"name":"operator","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":277,"src":"4296:8:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":287,"name":"approved","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":279,"src":"4306:8:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_bool","typeString":"bool"}],"id":283,"name":"_setApprovalForAll","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":808,"src":"4263:18:0","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_address_$_t_bool_$returns$__$","typeString":"function (address,address,bool)"}},"id":288,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4263:52:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":289,"nodeType":"ExpressionStatement","src":"4263:52:0"}]},"documentation":{"id":275,"nodeType":"StructuredDocumentation","src":"4108:56:0","text":" @dev See {IERC721-setApprovalForAll}."},"functionSelector":"a22cb465","id":291,"implemented":true,"kind":"function","modifiers":[],"name":"setApprovalForAll","nameLocation":"4178:17:0","nodeType":"FunctionDefinition","overrides":{"id":281,"nodeType":"OverrideSpecifier","overrides":[],"src":"4244:8:0"},"parameters":{"id":280,"nodeType":"ParameterList","parameters":[{"constant":false,"id":277,"mutability":"mutable","name":"operator","nameLocation":"4204:8:0","nodeType":"VariableDeclaration","scope":291,"src":"4196:16:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":276,"name":"address","nodeType":"ElementaryTypeName","src":"4196:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":279,"mutability":"mutable","name":"approved","nameLocation":"4219:8:0","nodeType":"VariableDeclaration","scope":291,"src":"4214:13:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":278,"name":"bool","nodeType":"ElementaryTypeName","src":"4214:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"4195:33:0"},"returnParameters":{"id":282,"nodeType":"ParameterList","parameters":[],"src":"4253:0:0"},"scope":926,"src":"4169:153:0","stateMutability":"nonpayable","virtual":true,"visibility":"public"},{"baseFunctions":[1041],"body":{"id":308,"nodeType":"Block","src":"4491:59:0","statements":[{"expression":{"baseExpression":{"baseExpression":{"id":302,"name":"_operatorApprovals","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":45,"src":"4508:18:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_mapping$_t_address_$_t_bool_$_$","typeString":"mapping(address => mapping(address => bool))"}},"id":304,"indexExpression":{"id":303,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":294,"src":"4527:5:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"4508:25:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_bool_$","typeString":"mapping(address => bool)"}},"id":306,"indexExpression":{"id":305,"name":"operator","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":296,"src":"4534:8:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"4508:35:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"functionReturnParameters":301,"id":307,"nodeType":"Return","src":"4501:42:0"}]},"documentation":{"id":292,"nodeType":"StructuredDocumentation","src":"4328:55:0","text":" @dev See {IERC721-isApprovedForAll}."},"functionSelector":"e985e9c5","id":309,"implemented":true,"kind":"function","modifiers":[],"name":"isApprovedForAll","nameLocation":"4397:16:0","nodeType":"FunctionDefinition","overrides":{"id":298,"nodeType":"OverrideSpecifier","overrides":[],"src":"4467:8:0"},"parameters":{"id":297,"nodeType":"ParameterList","parameters":[{"constant":false,"id":294,"mutability":"mutable","name":"owner","nameLocation":"4422:5:0","nodeType":"VariableDeclaration","scope":309,"src":"4414:13:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":293,"name":"address","nodeType":"ElementaryTypeName","src":"4414:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":296,"mutability":"mutable","name":"operator","nameLocation":"4437:8:0","nodeType":"VariableDeclaration","scope":309,"src":"4429:16:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":295,"name":"address","nodeType":"ElementaryTypeName","src":"4429:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"4413:33:0"},"returnParameters":{"id":301,"nodeType":"ParameterList","parameters":[{"constant":false,"id":300,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":309,"src":"4485:4:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":299,"name":"bool","nodeType":"ElementaryTypeName","src":"4485:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"4484:6:0"},"scope":926,"src":"4388:162:0","stateMutability":"view","virtual":true,"visibility":"public"},{"baseFunctions":[1007],"body":{"id":335,"nodeType":"Block","src":"4701:207:0","statements":[{"expression":{"arguments":[{"arguments":[{"arguments":[],"expression":{"argumentTypes":[],"id":322,"name":"_msgSender","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1429,"src":"4790:10:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_address_$","typeString":"function () view returns (address)"}},"id":323,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4790:12:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":324,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":316,"src":"4804:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":321,"name":"_isApprovedOrOwner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":479,"src":"4771:18:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_address_$_t_uint256_$returns$_t_bool_$","typeString":"function (address,uint256) view returns (bool)"}},"id":325,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4771:41:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6572206f7220617070726f766564","id":326,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4814:47:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_12a8e5623d251e191fe4a291d9a59bcc01a4db7a1f5c20fc8de44358c18308af","typeString":"literal_string \"ERC721: caller is not token owner or approved\""},"value":"ERC721: caller is not token owner or approved"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_12a8e5623d251e191fe4a291d9a59bcc01a4db7a1f5c20fc8de44358c18308af","typeString":"literal_string \"ERC721: caller is not token owner or approved\""}],"id":320,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"4763:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":327,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4763:99:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":328,"nodeType":"ExpressionStatement","src":"4763:99:0"},{"expression":{"arguments":[{"id":330,"name":"from","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":312,"src":"4883:4:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":331,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":314,"src":"4889:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":332,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":316,"src":"4893:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":329,"name":"_transfer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":752,"src":"4873:9:0","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$","typeString":"function (address,address,uint256)"}},"id":333,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4873:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":334,"nodeType":"ExpressionStatement","src":"4873:28:0"}]},"documentation":{"id":310,"nodeType":"StructuredDocumentation","src":"4556:51:0","text":" @dev See {IERC721-transferFrom}."},"functionSelector":"23b872dd","id":336,"implemented":true,"kind":"function","modifiers":[],"name":"transferFrom","nameLocation":"4621:12:0","nodeType":"FunctionDefinition","overrides":{"id":318,"nodeType":"OverrideSpecifier","overrides":[],"src":"4692:8:0"},"parameters":{"id":317,"nodeType":"ParameterList","parameters":[{"constant":false,"id":312,"mutability":"mutable","name":"from","nameLocation":"4642:4:0","nodeType":"VariableDeclaration","scope":336,"src":"4634:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":311,"name":"address","nodeType":"ElementaryTypeName","src":"4634:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":314,"mutability":"mutable","name":"to","nameLocation":"4656:2:0","nodeType":"VariableDeclaration","scope":336,"src":"4648:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":313,"name":"address","nodeType":"ElementaryTypeName","src":"4648:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":316,"mutability":"mutable","name":"tokenId","nameLocation":"4668:7:0","nodeType":"VariableDeclaration","scope":336,"src":"4660:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":315,"name":"uint256","nodeType":"ElementaryTypeName","src":"4660:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"4633:43:0"},"returnParameters":{"id":319,"nodeType":"ParameterList","parameters":[],"src":"4701:0:0"},"scope":926,"src":"4612:296:0","stateMutability":"nonpayable","virtual":true,"visibility":"public"},{"baseFunctions":[997],"body":{"id":354,"nodeType":"Block","src":"5067:56:0","statements":[{"expression":{"arguments":[{"id":348,"name":"from","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":339,"src":"5094:4:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":349,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":341,"src":"5100:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":350,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":343,"src":"5104:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"hexValue":"","id":351,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"5113:2:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","typeString":"literal_string \"\""},"value":""}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","typeString":"literal_string \"\""}],"id":347,"name":"safeTransferFrom","nodeType":"Identifier","overloadedDeclarations":[355,385],"referencedDeclaration":385,"src":"5077:16:0","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$_t_bytes_memory_ptr_$returns$__$","typeString":"function (address,address,uint256,bytes memory)"}},"id":352,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5077:39:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":353,"nodeType":"ExpressionStatement","src":"5077:39:0"}]},"documentation":{"id":337,"nodeType":"StructuredDocumentation","src":"4914:55:0","text":" @dev See {IERC721-safeTransferFrom}."},"functionSelector":"42842e0e","id":355,"implemented":true,"kind":"function","modifiers":[],"name":"safeTransferFrom","nameLocation":"4983:16:0","nodeType":"FunctionDefinition","overrides":{"id":345,"nodeType":"OverrideSpecifier","overrides":[],"src":"5058:8:0"},"parameters":{"id":344,"nodeType":"ParameterList","parameters":[{"constant":false,"id":339,"mutability":"mutable","name":"from","nameLocation":"5008:4:0","nodeType":"VariableDeclaration","scope":355,"src":"5000:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":338,"name":"address","nodeType":"ElementaryTypeName","src":"5000:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":341,"mutability":"mutable","name":"to","nameLocation":"5022:2:0","nodeType":"VariableDeclaration","scope":355,"src":"5014:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":340,"name":"address","nodeType":"ElementaryTypeName","src":"5014:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":343,"mutability":"mutable","name":"tokenId","nameLocation":"5034:7:0","nodeType":"VariableDeclaration","scope":355,"src":"5026:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":342,"name":"uint256","nodeType":"ElementaryTypeName","src":"5026:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"4999:43:0"},"returnParameters":{"id":346,"nodeType":"ParameterList","parameters":[],"src":"5067:0:0"},"scope":926,"src":"4974:149:0","stateMutability":"nonpayable","virtual":true,"visibility":"public"},{"baseFunctions":[987],"body":{"id":384,"nodeType":"Block","src":"5301:164:0","statements":[{"expression":{"arguments":[{"arguments":[{"arguments":[],"expression":{"argumentTypes":[],"id":370,"name":"_msgSender","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1429,"src":"5338:10:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_address_$","typeString":"function () view returns (address)"}},"id":371,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5338:12:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":372,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":362,"src":"5352:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":369,"name":"_isApprovedOrOwner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":479,"src":"5319:18:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_address_$_t_uint256_$returns$_t_bool_$","typeString":"function (address,uint256) view returns (bool)"}},"id":373,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5319:41:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6572206f7220617070726f766564","id":374,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"5362:47:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_12a8e5623d251e191fe4a291d9a59bcc01a4db7a1f5c20fc8de44358c18308af","typeString":"literal_string \"ERC721: caller is not token owner or approved\""},"value":"ERC721: caller is not token owner or approved"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_12a8e5623d251e191fe4a291d9a59bcc01a4db7a1f5c20fc8de44358c18308af","typeString":"literal_string \"ERC721: caller is not token owner or approved\""}],"id":368,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"5311:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":375,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5311:99:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":376,"nodeType":"ExpressionStatement","src":"5311:99:0"},{"expression":{"arguments":[{"id":378,"name":"from","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":358,"src":"5434:4:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":379,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":360,"src":"5440:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":380,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":362,"src":"5444:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":381,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":364,"src":"5453:4:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":377,"name":"_safeTransfer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":414,"src":"5420:13:0","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$_t_bytes_memory_ptr_$returns$__$","typeString":"function (address,address,uint256,bytes memory)"}},"id":382,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5420:38:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":383,"nodeType":"ExpressionStatement","src":"5420:38:0"}]},"documentation":{"id":356,"nodeType":"StructuredDocumentation","src":"5129:55:0","text":" @dev See {IERC721-safeTransferFrom}."},"functionSelector":"b88d4fde","id":385,"implemented":true,"kind":"function","modifiers":[],"name":"safeTransferFrom","nameLocation":"5198:16:0","nodeType":"FunctionDefinition","overrides":{"id":366,"nodeType":"OverrideSpecifier","overrides":[],"src":"5292:8:0"},"parameters":{"id":365,"nodeType":"ParameterList","parameters":[{"constant":false,"id":358,"mutability":"mutable","name":"from","nameLocation":"5223:4:0","nodeType":"VariableDeclaration","scope":385,"src":"5215:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":357,"name":"address","nodeType":"ElementaryTypeName","src":"5215:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":360,"mutability":"mutable","name":"to","nameLocation":"5237:2:0","nodeType":"VariableDeclaration","scope":385,"src":"5229:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":359,"name":"address","nodeType":"ElementaryTypeName","src":"5229:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":362,"mutability":"mutable","name":"tokenId","nameLocation":"5249:7:0","nodeType":"VariableDeclaration","scope":385,"src":"5241:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":361,"name":"uint256","nodeType":"ElementaryTypeName","src":"5241:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":364,"mutability":"mutable","name":"data","nameLocation":"5271:4:0","nodeType":"VariableDeclaration","scope":385,"src":"5258:17:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":363,"name":"bytes","nodeType":"ElementaryTypeName","src":"5258:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"5214:62:0"},"returnParameters":{"id":367,"nodeType":"ParameterList","parameters":[],"src":"5301:0:0"},"scope":926,"src":"5189:276:0","stateMutability":"nonpayable","virtual":true,"visibility":"public"},{"body":{"id":413,"nodeType":"Block","src":"6428:165:0","statements":[{"expression":{"arguments":[{"id":398,"name":"from","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":388,"src":"6448:4:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":399,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":390,"src":"6454:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":400,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":392,"src":"6458:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":397,"name":"_transfer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":752,"src":"6438:9:0","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$","typeString":"function (address,address,uint256)"}},"id":401,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"6438:28:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":402,"nodeType":"ExpressionStatement","src":"6438:28:0"},{"expression":{"arguments":[{"arguments":[{"id":405,"name":"from","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":388,"src":"6507:4:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":406,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":390,"src":"6513:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":407,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":392,"src":"6517:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":408,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":394,"src":"6526:4:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":404,"name":"_checkOnERC721Received","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":884,"src":"6484:22:0","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$_t_bytes_memory_ptr_$returns$_t_bool_$","typeString":"function (address,address,uint256,bytes memory) returns (bool)"}},"id":409,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"6484:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e746572","id":410,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"6533:52:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1e766a06da43a53d0f4c380e06e5a342e14d5af1bf8501996c844905530ca84e","typeString":"literal_string \"ERC721: transfer to non ERC721Receiver implementer\""},"value":"ERC721: transfer to non ERC721Receiver implementer"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_1e766a06da43a53d0f4c380e06e5a342e14d5af1bf8501996c844905530ca84e","typeString":"literal_string \"ERC721: transfer to non ERC721Receiver implementer\""}],"id":403,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"6476:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":411,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"6476:110:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":412,"nodeType":"ExpressionStatement","src":"6476:110:0"}]},"documentation":{"id":386,"nodeType":"StructuredDocumentation","src":"5471:850:0","text":" @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 `data` is additional data, it has no specified format and it is sent in call to `to`.\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 Requirements:\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 Emits a {Transfer} event."},"id":414,"implemented":true,"kind":"function","modifiers":[],"name":"_safeTransfer","nameLocation":"6335:13:0","nodeType":"FunctionDefinition","parameters":{"id":395,"nodeType":"ParameterList","parameters":[{"constant":false,"id":388,"mutability":"mutable","name":"from","nameLocation":"6357:4:0","nodeType":"VariableDeclaration","scope":414,"src":"6349:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":387,"name":"address","nodeType":"ElementaryTypeName","src":"6349:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":390,"mutability":"mutable","name":"to","nameLocation":"6371:2:0","nodeType":"VariableDeclaration","scope":414,"src":"6363:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":389,"name":"address","nodeType":"ElementaryTypeName","src":"6363:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":392,"mutability":"mutable","name":"tokenId","nameLocation":"6383:7:0","nodeType":"VariableDeclaration","scope":414,"src":"6375:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":391,"name":"uint256","nodeType":"ElementaryTypeName","src":"6375:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":394,"mutability":"mutable","name":"data","nameLocation":"6405:4:0","nodeType":"VariableDeclaration","scope":414,"src":"6392:17:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":393,"name":"bytes","nodeType":"ElementaryTypeName","src":"6392:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"6348:62:0"},"returnParameters":{"id":396,"nodeType":"ParameterList","parameters":[],"src":"6428:0:0"},"scope":926,"src":"6326:267:0","stateMutability":"nonpayable","virtual":true,"visibility":"internal"},{"body":{"id":426,"nodeType":"Block","src":"6777:40:0","statements":[{"expression":{"baseExpression":{"id":422,"name":"_owners","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":31,"src":"6794:7:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_uint256_$_t_address_$","typeString":"mapping(uint256 => address)"}},"id":424,"indexExpression":{"id":423,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":417,"src":"6802:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"6794:16:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"functionReturnParameters":421,"id":425,"nodeType":"Return","src":"6787:23:0"}]},"documentation":{"id":415,"nodeType":"StructuredDocumentation","src":"6599:98:0","text":" @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist"},"id":427,"implemented":true,"kind":"function","modifiers":[],"name":"_ownerOf","nameLocation":"6711:8:0","nodeType":"FunctionDefinition","parameters":{"id":418,"nodeType":"ParameterList","parameters":[{"constant":false,"id":417,"mutability":"mutable","name":"tokenId","nameLocation":"6728:7:0","nodeType":"VariableDeclaration","scope":427,"src":"6720:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":416,"name":"uint256","nodeType":"ElementaryTypeName","src":"6720:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"6719:17:0"},"returnParameters":{"id":421,"nodeType":"ParameterList","parameters":[{"constant":false,"id":420,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":427,"src":"6768:7:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":419,"name":"address","nodeType":"ElementaryTypeName","src":"6768:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"6767:9:0"},"scope":926,"src":"6702:115:0","stateMutability":"view","virtual":true,"visibility":"internal"},{"body":{"id":444,"nodeType":"Block","src":"7191:55:0","statements":[{"expression":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":442,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[{"id":436,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":430,"src":"7217:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":435,"name":"_ownerOf","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":427,"src":"7208:8:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_uint256_$returns$_t_address_$","typeString":"function (uint256) view returns (address)"}},"id":437,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"7208:17:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"!=","rightExpression":{"arguments":[{"hexValue":"30","id":440,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"7237:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"id":439,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"7229:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":438,"name":"address","nodeType":"ElementaryTypeName","src":"7229:7:0","typeDescriptions":{}}},"id":441,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"7229:10:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"7208:31:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"functionReturnParameters":434,"id":443,"nodeType":"Return","src":"7201:38:0"}]},"documentation":{"id":428,"nodeType":"StructuredDocumentation","src":"6823:292:0","text":" @dev Returns whether `tokenId` exists.\n Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n Tokens start existing when they are minted (`_mint`),\n and stop existing when they are burned (`_burn`)."},"id":445,"implemented":true,"kind":"function","modifiers":[],"name":"_exists","nameLocation":"7129:7:0","nodeType":"FunctionDefinition","parameters":{"id":431,"nodeType":"ParameterList","parameters":[{"constant":false,"id":430,"mutability":"mutable","name":"tokenId","nameLocation":"7145:7:0","nodeType":"VariableDeclaration","scope":445,"src":"7137:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":429,"name":"uint256","nodeType":"ElementaryTypeName","src":"7137:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"7136:17:0"},"returnParameters":{"id":434,"nodeType":"ParameterList","parameters":[{"constant":false,"id":433,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":445,"src":"7185:4:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":432,"name":"bool","nodeType":"ElementaryTypeName","src":"7185:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"7184:6:0"},"scope":926,"src":"7120:126:0","stateMutability":"view","virtual":true,"visibility":"internal"},{"body":{"id":478,"nodeType":"Block","src":"7503:162:0","statements":[{"assignments":[456],"declarations":[{"constant":false,"id":456,"mutability":"mutable","name":"owner","nameLocation":"7521:5:0","nodeType":"VariableDeclaration","scope":478,"src":"7513:13:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":455,"name":"address","nodeType":"ElementaryTypeName","src":"7513:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":461,"initialValue":{"arguments":[{"id":459,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":450,"src":"7544:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":457,"name":"ERC721","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":926,"src":"7529:6:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_ERC721_$926_$","typeString":"type(contract ERC721)"}},"id":458,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"7536:7:0","memberName":"ownerOf","nodeType":"MemberAccess","referencedDeclaration":145,"src":"7529:14:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_uint256_$returns$_t_address_$","typeString":"function (uint256) view returns (address)"}},"id":460,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"7529:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"7513:39:0"},{"expression":{"components":[{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":475,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":469,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":464,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":462,"name":"spender","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":448,"src":"7570:7:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"id":463,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":456,"src":"7581:5:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"7570:16:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"||","rightExpression":{"arguments":[{"id":466,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":456,"src":"7607:5:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":467,"name":"spender","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":448,"src":"7614:7:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"}],"id":465,"name":"isApprovedForAll","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":309,"src":"7590:16:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_address_$_t_address_$returns$_t_bool_$","typeString":"function (address,address) view returns (bool)"}},"id":468,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"7590:32:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"7570:52:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"||","rightExpression":{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":474,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[{"id":471,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":450,"src":"7638:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":470,"name":"getApproved","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":274,"src":"7626:11:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_uint256_$returns$_t_address_$","typeString":"function (uint256) view returns (address)"}},"id":472,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"7626:20:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"id":473,"name":"spender","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":448,"src":"7650:7:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"7626:31:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"7570:87:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"id":476,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"7569:89:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"functionReturnParameters":454,"id":477,"nodeType":"Return","src":"7562:96:0"}]},"documentation":{"id":446,"nodeType":"StructuredDocumentation","src":"7252:147:0","text":" @dev Returns whether `spender` is allowed to manage `tokenId`.\n Requirements:\n - `tokenId` must exist."},"id":479,"implemented":true,"kind":"function","modifiers":[],"name":"_isApprovedOrOwner","nameLocation":"7413:18:0","nodeType":"FunctionDefinition","parameters":{"id":451,"nodeType":"ParameterList","parameters":[{"constant":false,"id":448,"mutability":"mutable","name":"spender","nameLocation":"7440:7:0","nodeType":"VariableDeclaration","scope":479,"src":"7432:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":447,"name":"address","nodeType":"ElementaryTypeName","src":"7432:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":450,"mutability":"mutable","name":"tokenId","nameLocation":"7457:7:0","nodeType":"VariableDeclaration","scope":479,"src":"7449:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":449,"name":"uint256","nodeType":"ElementaryTypeName","src":"7449:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"7431:34:0"},"returnParameters":{"id":454,"nodeType":"ParameterList","parameters":[{"constant":false,"id":453,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":479,"src":"7497:4:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":452,"name":"bool","nodeType":"ElementaryTypeName","src":"7497:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"7496:6:0"},"scope":926,"src":"7404:261:0","stateMutability":"view","virtual":true,"visibility":"internal"},{"body":{"id":493,"nodeType":"Block","src":"8060:43:0","statements":[{"expression":{"arguments":[{"id":488,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":482,"src":"8080:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":489,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":484,"src":"8084:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"hexValue":"","id":490,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"8093:2:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","typeString":"literal_string \"\""},"value":""}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","typeString":"literal_string \"\""}],"id":487,"name":"_safeMint","nodeType":"Identifier","overloadedDeclarations":[494,523],"referencedDeclaration":523,"src":"8070:9:0","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_uint256_$_t_bytes_memory_ptr_$returns$__$","typeString":"function (address,uint256,bytes memory)"}},"id":491,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"8070:26:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":492,"nodeType":"ExpressionStatement","src":"8070:26:0"}]},"documentation":{"id":480,"nodeType":"StructuredDocumentation","src":"7671:319:0","text":" @dev Safely mints `tokenId` and transfers it to `to`.\n Requirements:\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 Emits a {Transfer} event."},"id":494,"implemented":true,"kind":"function","modifiers":[],"name":"_safeMint","nameLocation":"8004:9:0","nodeType":"FunctionDefinition","parameters":{"id":485,"nodeType":"ParameterList","parameters":[{"constant":false,"id":482,"mutability":"mutable","name":"to","nameLocation":"8022:2:0","nodeType":"VariableDeclaration","scope":494,"src":"8014:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":481,"name":"address","nodeType":"ElementaryTypeName","src":"8014:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":484,"mutability":"mutable","name":"tokenId","nameLocation":"8034:7:0","nodeType":"VariableDeclaration","scope":494,"src":"8026:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":483,"name":"uint256","nodeType":"ElementaryTypeName","src":"8026:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"8013:29:0"},"returnParameters":{"id":486,"nodeType":"ParameterList","parameters":[],"src":"8060:0:0"},"scope":926,"src":"7995:108:0","stateMutability":"nonpayable","virtual":true,"visibility":"internal"},{"body":{"id":522,"nodeType":"Block","src":"8408:195:0","statements":[{"expression":{"arguments":[{"id":505,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":497,"src":"8424:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":506,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":499,"src":"8428:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":504,"name":"_mint","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":600,"src":"8418:5:0","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_uint256_$returns$__$","typeString":"function (address,uint256)"}},"id":507,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"8418:18:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":508,"nodeType":"ExpressionStatement","src":"8418:18:0"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"hexValue":"30","id":513,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"8498:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"id":512,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"8490:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":511,"name":"address","nodeType":"ElementaryTypeName","src":"8490:7:0","typeDescriptions":{}}},"id":514,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"8490:10:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":515,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":497,"src":"8502:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":516,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":499,"src":"8506:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":517,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":501,"src":"8515:4:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":510,"name":"_checkOnERC721Received","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":884,"src":"8467:22:0","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$_t_bytes_memory_ptr_$returns$_t_bool_$","typeString":"function (address,address,uint256,bytes memory) returns (bool)"}},"id":518,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"8467:53:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e746572","id":519,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"8534:52:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1e766a06da43a53d0f4c380e06e5a342e14d5af1bf8501996c844905530ca84e","typeString":"literal_string \"ERC721: transfer to non ERC721Receiver implementer\""},"value":"ERC721: transfer to non ERC721Receiver implementer"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_1e766a06da43a53d0f4c380e06e5a342e14d5af1bf8501996c844905530ca84e","typeString":"literal_string \"ERC721: transfer to non ERC721Receiver implementer\""}],"id":509,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"8446:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":520,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"8446:150:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":521,"nodeType":"ExpressionStatement","src":"8446:150:0"}]},"documentation":{"id":495,"nodeType":"StructuredDocumentation","src":"8109:210:0","text":" @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n forwarded in {IERC721Receiver-onERC721Received} to contract recipients."},"id":523,"implemented":true,"kind":"function","modifiers":[],"name":"_safeMint","nameLocation":"8333:9:0","nodeType":"FunctionDefinition","parameters":{"id":502,"nodeType":"ParameterList","parameters":[{"constant":false,"id":497,"mutability":"mutable","name":"to","nameLocation":"8351:2:0","nodeType":"VariableDeclaration","scope":523,"src":"8343:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":496,"name":"address","nodeType":"ElementaryTypeName","src":"8343:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":499,"mutability":"mutable","name":"tokenId","nameLocation":"8363:7:0","nodeType":"VariableDeclaration","scope":523,"src":"8355:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":498,"name":"uint256","nodeType":"ElementaryTypeName","src":"8355:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":501,"mutability":"mutable","name":"data","nameLocation":"8385:4:0","nodeType":"VariableDeclaration","scope":523,"src":"8372:17:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":500,"name":"bytes","nodeType":"ElementaryTypeName","src":"8372:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"8342:48:0"},"returnParameters":{"id":503,"nodeType":"ParameterList","parameters":[],"src":"8408:0:0"},"scope":926,"src":"8324:279:0","stateMutability":"nonpayable","virtual":true,"visibility":"internal"},{"body":{"id":599,"nodeType":"Block","src":"8986:859:0","statements":[{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":537,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":532,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":526,"src":"9004:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"!=","rightExpression":{"arguments":[{"hexValue":"30","id":535,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9018:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"id":534,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"9010:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":533,"name":"address","nodeType":"ElementaryTypeName","src":"9010:7:0","typeDescriptions":{}}},"id":536,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"9010:10:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"9004:16:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"4552433732313a206d696e7420746f20746865207a65726f2061646472657373","id":538,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"9022:34:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_8a66f4bb6512ffbfcc3db9b42318eb65f26ac15163eaa9a1e5cfa7bee9d1c7c6","typeString":"literal_string \"ERC721: mint to the zero address\""},"value":"ERC721: mint to the zero address"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_8a66f4bb6512ffbfcc3db9b42318eb65f26ac15163eaa9a1e5cfa7bee9d1c7c6","typeString":"literal_string \"ERC721: mint to the zero address\""}],"id":531,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"8996:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":539,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"8996:61:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":540,"nodeType":"ExpressionStatement","src":"8996:61:0"},{"expression":{"arguments":[{"id":545,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"!","prefix":true,"src":"9075:17:0","subExpression":{"arguments":[{"id":543,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":528,"src":"9084:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":542,"name":"_exists","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":445,"src":"9076:7:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_uint256_$returns$_t_bool_$","typeString":"function (uint256) view returns (bool)"}},"id":544,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"9076:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"4552433732313a20746f6b656e20616c7265616479206d696e746564","id":546,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"9094:30:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2a63ce106ef95058ed21fd07c42a10f11dc5c32ac13a4e847923f7759f635d57","typeString":"literal_string \"ERC721: token already minted\""},"value":"ERC721: token already minted"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_2a63ce106ef95058ed21fd07c42a10f11dc5c32ac13a4e847923f7759f635d57","typeString":"literal_string \"ERC721: token already minted\""}],"id":541,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"9067:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":547,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"9067:58:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":548,"nodeType":"ExpressionStatement","src":"9067:58:0"},{"expression":{"arguments":[{"arguments":[{"hexValue":"30","id":552,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9165:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"id":551,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"9157:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":550,"name":"address","nodeType":"ElementaryTypeName","src":"9157:7:0","typeDescriptions":{}}},"id":553,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"9157:10:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":554,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":526,"src":"9169:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":555,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":528,"src":"9173:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"hexValue":"31","id":556,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9182:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"}],"id":549,"name":"_beforeTokenTransfer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":897,"src":"9136:20:0","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$_t_uint256_$returns$__$","typeString":"function (address,address,uint256,uint256)"}},"id":557,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"9136:48:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":558,"nodeType":"ExpressionStatement","src":"9136:48:0"},{"expression":{"arguments":[{"id":563,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"!","prefix":true,"src":"9279:17:0","subExpression":{"arguments":[{"id":561,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":528,"src":"9288:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":560,"name":"_exists","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":445,"src":"9280:7:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_uint256_$returns$_t_bool_$","typeString":"function (uint256) view returns (bool)"}},"id":562,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"9280:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"4552433732313a20746f6b656e20616c7265616479206d696e746564","id":564,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"9298:30:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_2a63ce106ef95058ed21fd07c42a10f11dc5c32ac13a4e847923f7759f635d57","typeString":"literal_string \"ERC721: token already minted\""},"value":"ERC721: token already minted"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_2a63ce106ef95058ed21fd07c42a10f11dc5c32ac13a4e847923f7759f635d57","typeString":"literal_string \"ERC721: token already minted\""}],"id":559,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"9271:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":565,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"9271:58:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":566,"nodeType":"ExpressionStatement","src":"9271:58:0"},{"id":573,"nodeType":"UncheckedBlock","src":"9340:360:0","statements":[{"expression":{"id":571,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"baseExpression":{"id":567,"name":"_balances","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":35,"src":"9671:9:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_uint256_$","typeString":"mapping(address => uint256)"}},"id":569,"indexExpression":{"id":568,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":526,"src":"9681:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"IndexAccess","src":"9671:13:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"31","id":570,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9688:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"9671:18:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":572,"nodeType":"ExpressionStatement","src":"9671:18:0"}]},{"expression":{"id":578,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"baseExpression":{"id":574,"name":"_owners","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":31,"src":"9710:7:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_uint256_$_t_address_$","typeString":"mapping(uint256 => address)"}},"id":576,"indexExpression":{"id":575,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":528,"src":"9718:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"IndexAccess","src":"9710:16:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":577,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":526,"src":"9729:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"9710:21:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":579,"nodeType":"ExpressionStatement","src":"9710:21:0"},{"eventCall":{"arguments":[{"arguments":[{"hexValue":"30","id":583,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9764:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"id":582,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"9756:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":581,"name":"address","nodeType":"ElementaryTypeName","src":"9756:7:0","typeDescriptions":{}}},"id":584,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"9756:10:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":585,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":526,"src":"9768:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":586,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":528,"src":"9772:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":580,"name":"Transfer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":941,"src":"9747:8:0","typeDescriptions":{"typeIdentifier":"t_function_event_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$","typeString":"function (address,address,uint256)"}},"id":587,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"9747:33:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":588,"nodeType":"EmitStatement","src":"9742:38:0"},{"expression":{"arguments":[{"arguments":[{"hexValue":"30","id":592,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9819:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"id":591,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"9811:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":590,"name":"address","nodeType":"ElementaryTypeName","src":"9811:7:0","typeDescriptions":{}}},"id":593,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"9811:10:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":594,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":526,"src":"9823:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":595,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":528,"src":"9827:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"hexValue":"31","id":596,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9836:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"}],"id":589,"name":"_afterTokenTransfer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":910,"src":"9791:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$_t_uint256_$returns$__$","typeString":"function (address,address,uint256,uint256)"}},"id":597,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"9791:47:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":598,"nodeType":"ExpressionStatement","src":"9791:47:0"}]},"documentation":{"id":524,"nodeType":"StructuredDocumentation","src":"8609:311:0","text":" @dev Mints `tokenId` and transfers it to `to`.\n WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n Requirements:\n - `tokenId` must not exist.\n - `to` cannot be the zero address.\n Emits a {Transfer} event."},"id":600,"implemented":true,"kind":"function","modifiers":[],"name":"_mint","nameLocation":"8934:5:0","nodeType":"FunctionDefinition","parameters":{"id":529,"nodeType":"ParameterList","parameters":[{"constant":false,"id":526,"mutability":"mutable","name":"to","nameLocation":"8948:2:0","nodeType":"VariableDeclaration","scope":600,"src":"8940:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":525,"name":"address","nodeType":"ElementaryTypeName","src":"8940:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":528,"mutability":"mutable","name":"tokenId","nameLocation":"8960:7:0","nodeType":"VariableDeclaration","scope":600,"src":"8952:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":527,"name":"uint256","nodeType":"ElementaryTypeName","src":"8952:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"8939:29:0"},"returnParameters":{"id":530,"nodeType":"ParameterList","parameters":[],"src":"8986:0:0"},"scope":926,"src":"8925:920:0","stateMutability":"nonpayable","virtual":true,"visibility":"internal"},{"body":{"id":666,"nodeType":"Block","src":"10220:713:0","statements":[{"assignments":[607],"declarations":[{"constant":false,"id":607,"mutability":"mutable","name":"owner","nameLocation":"10238:5:0","nodeType":"VariableDeclaration","scope":666,"src":"10230:13:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":606,"name":"address","nodeType":"ElementaryTypeName","src":"10230:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":612,"initialValue":{"arguments":[{"id":610,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":603,"src":"10261:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":608,"name":"ERC721","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":926,"src":"10246:6:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_ERC721_$926_$","typeString":"type(contract ERC721)"}},"id":609,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"10253:7:0","memberName":"ownerOf","nodeType":"MemberAccess","referencedDeclaration":145,"src":"10246:14:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_uint256_$returns$_t_address_$","typeString":"function (uint256) view returns (address)"}},"id":611,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"10246:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"10230:39:0"},{"expression":{"arguments":[{"id":614,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":607,"src":"10301:5:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"arguments":[{"hexValue":"30","id":617,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10316:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"id":616,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"10308:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":615,"name":"address","nodeType":"ElementaryTypeName","src":"10308:7:0","typeDescriptions":{}}},"id":618,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"10308:10:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":619,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":603,"src":"10320:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"hexValue":"31","id":620,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10329:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"}],"id":613,"name":"_beforeTokenTransfer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":897,"src":"10280:20:0","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$_t_uint256_$returns$__$","typeString":"function (address,address,uint256,uint256)"}},"id":621,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"10280:51:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":622,"nodeType":"ExpressionStatement","src":"10280:51:0"},{"expression":{"id":628,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":623,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":607,"src":"10433:5:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"arguments":[{"id":626,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":603,"src":"10456:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":624,"name":"ERC721","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":926,"src":"10441:6:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_ERC721_$926_$","typeString":"type(contract ERC721)"}},"id":625,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"10448:7:0","memberName":"ownerOf","nodeType":"MemberAccess","referencedDeclaration":145,"src":"10441:14:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_uint256_$returns$_t_address_$","typeString":"function (uint256) view returns (address)"}},"id":627,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"10441:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"10433:31:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":629,"nodeType":"ExpressionStatement","src":"10433:31:0"},{"expression":{"id":633,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"delete","prefix":true,"src":"10502:31:0","subExpression":{"baseExpression":{"id":630,"name":"_tokenApprovals","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":39,"src":"10509:15:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_uint256_$_t_address_$","typeString":"mapping(uint256 => address)"}},"id":632,"indexExpression":{"id":631,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":603,"src":"10525:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"IndexAccess","src":"10509:24:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":634,"nodeType":"ExpressionStatement","src":"10502:31:0"},{"id":641,"nodeType":"UncheckedBlock","src":"10544:237:0","statements":[{"expression":{"id":639,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"baseExpression":{"id":635,"name":"_balances","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":35,"src":"10749:9:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_uint256_$","typeString":"mapping(address => uint256)"}},"id":637,"indexExpression":{"id":636,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":607,"src":"10759:5:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"IndexAccess","src":"10749:16:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"-=","rightHandSide":{"hexValue":"31","id":638,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10769:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"10749:21:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":640,"nodeType":"ExpressionStatement","src":"10749:21:0"}]},{"expression":{"id":645,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"delete","prefix":true,"src":"10790:23:0","subExpression":{"baseExpression":{"id":642,"name":"_owners","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":31,"src":"10797:7:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_uint256_$_t_address_$","typeString":"mapping(uint256 => address)"}},"id":644,"indexExpression":{"id":643,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":603,"src":"10805:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"IndexAccess","src":"10797:16:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":646,"nodeType":"ExpressionStatement","src":"10790:23:0"},{"eventCall":{"arguments":[{"id":648,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":607,"src":"10838:5:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"arguments":[{"hexValue":"30","id":651,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10853:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"id":650,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"10845:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":649,"name":"address","nodeType":"ElementaryTypeName","src":"10845:7:0","typeDescriptions":{}}},"id":652,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"10845:10:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":653,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":603,"src":"10857:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":647,"name":"Transfer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":941,"src":"10829:8:0","typeDescriptions":{"typeIdentifier":"t_function_event_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$","typeString":"function (address,address,uint256)"}},"id":654,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"10829:36:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":655,"nodeType":"EmitStatement","src":"10824:41:0"},{"expression":{"arguments":[{"id":657,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":607,"src":"10896:5:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"arguments":[{"hexValue":"30","id":660,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10911:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"id":659,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"10903:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":658,"name":"address","nodeType":"ElementaryTypeName","src":"10903:7:0","typeDescriptions":{}}},"id":661,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"10903:10:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":662,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":603,"src":"10915:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"hexValue":"31","id":663,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10924:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"}],"id":656,"name":"_afterTokenTransfer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":910,"src":"10876:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$_t_uint256_$returns$__$","typeString":"function (address,address,uint256,uint256)"}},"id":664,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"10876:50:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":665,"nodeType":"ExpressionStatement","src":"10876:50:0"}]},"documentation":{"id":601,"nodeType":"StructuredDocumentation","src":"9851:315:0","text":" @dev Destroys `tokenId`.\n The approval is cleared when the token is burned.\n This is an internal function that does not check if the sender is authorized to operate on the token.\n Requirements:\n - `tokenId` must exist.\n Emits a {Transfer} event."},"id":667,"implemented":true,"kind":"function","modifiers":[],"name":"_burn","nameLocation":"10180:5:0","nodeType":"FunctionDefinition","parameters":{"id":604,"nodeType":"ParameterList","parameters":[{"constant":false,"id":603,"mutability":"mutable","name":"tokenId","nameLocation":"10194:7:0","nodeType":"VariableDeclaration","scope":667,"src":"10186:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":602,"name":"uint256","nodeType":"ElementaryTypeName","src":"10186:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"10185:17:0"},"returnParameters":{"id":605,"nodeType":"ParameterList","parameters":[],"src":"10220:0:0"},"scope":926,"src":"10171:762:0","stateMutability":"nonpayable","virtual":true,"visibility":"internal"},{"body":{"id":751,"nodeType":"Block","src":"11336:1124:0","statements":[{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":683,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[{"id":680,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":674,"src":"11369:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":678,"name":"ERC721","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":926,"src":"11354:6:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_ERC721_$926_$","typeString":"type(contract ERC721)"}},"id":679,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"11361:7:0","memberName":"ownerOf","nodeType":"MemberAccess","referencedDeclaration":145,"src":"11354:14:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_uint256_$returns$_t_address_$","typeString":"function (uint256) view returns (address)"}},"id":681,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"11354:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"id":682,"name":"from","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":670,"src":"11381:4:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"11354:31:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"4552433732313a207472616e736665722066726f6d20696e636f7272656374206f776e6572","id":684,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"11387:39:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_277f8ee9d5b4fc3c4149386f24de0fc1bbc63a8210e2197bfd1c0376a2ac5f48","typeString":"literal_string \"ERC721: transfer from incorrect owner\""},"value":"ERC721: transfer from incorrect owner"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_277f8ee9d5b4fc3c4149386f24de0fc1bbc63a8210e2197bfd1c0376a2ac5f48","typeString":"literal_string \"ERC721: transfer from incorrect owner\""}],"id":677,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"11346:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":685,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"11346:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":686,"nodeType":"ExpressionStatement","src":"11346:81:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":693,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":688,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":672,"src":"11445:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"!=","rightExpression":{"arguments":[{"hexValue":"30","id":691,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"11459:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"id":690,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"11451:7:0","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":689,"name":"address","nodeType":"ElementaryTypeName","src":"11451:7:0","typeDescriptions":{}}},"id":692,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"11451:10:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"11445:16:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"4552433732313a207472616e7366657220746f20746865207a65726f2061646472657373","id":694,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"11463:38:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_455fea98ea03c32d7dd1a6f1426917d80529bf47b3ccbde74e7206e889e709f4","typeString":"literal_string \"ERC721: transfer to the zero address\""},"value":"ERC721: transfer to the zero address"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_455fea98ea03c32d7dd1a6f1426917d80529bf47b3ccbde74e7206e889e709f4","typeString":"literal_string \"ERC721: transfer to the zero address\""}],"id":687,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"11437:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":695,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"11437:65:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":696,"nodeType":"ExpressionStatement","src":"11437:65:0"},{"expression":{"arguments":[{"id":698,"name":"from","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":670,"src":"11534:4:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":699,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":672,"src":"11540:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":700,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":674,"src":"11544:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"hexValue":"31","id":701,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"11553:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"}],"id":697,"name":"_beforeTokenTransfer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":897,"src":"11513:20:0","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$_t_uint256_$returns$__$","typeString":"function (address,address,uint256,uint256)"}},"id":702,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"11513:42:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":703,"nodeType":"ExpressionStatement","src":"11513:42:0"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":710,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[{"id":707,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":674,"src":"11670:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":705,"name":"ERC721","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":926,"src":"11655:6:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_ERC721_$926_$","typeString":"type(contract ERC721)"}},"id":706,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"11662:7:0","memberName":"ownerOf","nodeType":"MemberAccess","referencedDeclaration":145,"src":"11655:14:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_uint256_$returns$_t_address_$","typeString":"function (uint256) view returns (address)"}},"id":708,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"11655:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"id":709,"name":"from","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":670,"src":"11682:4:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"11655:31:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"4552433732313a207472616e736665722066726f6d20696e636f7272656374206f776e6572","id":711,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"11688:39:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_277f8ee9d5b4fc3c4149386f24de0fc1bbc63a8210e2197bfd1c0376a2ac5f48","typeString":"literal_string \"ERC721: transfer from incorrect owner\""},"value":"ERC721: transfer from incorrect owner"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_277f8ee9d5b4fc3c4149386f24de0fc1bbc63a8210e2197bfd1c0376a2ac5f48","typeString":"literal_string \"ERC721: transfer from incorrect owner\""}],"id":704,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"11647:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":712,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"11647:81:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":713,"nodeType":"ExpressionStatement","src":"11647:81:0"},{"expression":{"id":717,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"delete","prefix":true,"src":"11790:31:0","subExpression":{"baseExpression":{"id":714,"name":"_tokenApprovals","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":39,"src":"11797:15:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_uint256_$_t_address_$","typeString":"mapping(uint256 => address)"}},"id":716,"indexExpression":{"id":715,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":674,"src":"11813:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"IndexAccess","src":"11797:24:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":718,"nodeType":"ExpressionStatement","src":"11790:31:0"},{"id":731,"nodeType":"UncheckedBlock","src":"11832:496:0","statements":[{"expression":{"id":723,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"baseExpression":{"id":719,"name":"_balances","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":35,"src":"12265:9:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_uint256_$","typeString":"mapping(address => uint256)"}},"id":721,"indexExpression":{"id":720,"name":"from","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":670,"src":"12275:4:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"IndexAccess","src":"12265:15:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"-=","rightHandSide":{"hexValue":"31","id":722,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"12284:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"12265:20:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":724,"nodeType":"ExpressionStatement","src":"12265:20:0"},{"expression":{"id":729,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"baseExpression":{"id":725,"name":"_balances","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":35,"src":"12299:9:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_uint256_$","typeString":"mapping(address => uint256)"}},"id":727,"indexExpression":{"id":726,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":672,"src":"12309:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"IndexAccess","src":"12299:13:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"31","id":728,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"12316:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"12299:18:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":730,"nodeType":"ExpressionStatement","src":"12299:18:0"}]},{"expression":{"id":736,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"baseExpression":{"id":732,"name":"_owners","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":31,"src":"12337:7:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_uint256_$_t_address_$","typeString":"mapping(uint256 => address)"}},"id":734,"indexExpression":{"id":733,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":674,"src":"12345:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"IndexAccess","src":"12337:16:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":735,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":672,"src":"12356:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"12337:21:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":737,"nodeType":"ExpressionStatement","src":"12337:21:0"},{"eventCall":{"arguments":[{"id":739,"name":"from","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":670,"src":"12383:4:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":740,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":672,"src":"12389:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":741,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":674,"src":"12393:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":738,"name":"Transfer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":941,"src":"12374:8:0","typeDescriptions":{"typeIdentifier":"t_function_event_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$","typeString":"function (address,address,uint256)"}},"id":742,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"12374:27:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":743,"nodeType":"EmitStatement","src":"12369:32:0"},{"expression":{"arguments":[{"id":745,"name":"from","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":670,"src":"12432:4:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":746,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":672,"src":"12438:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":747,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":674,"src":"12442:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"hexValue":"31","id":748,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"12451:1:0","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"}],"id":744,"name":"_afterTokenTransfer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":910,"src":"12412:19:0","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_address_$_t_uint256_$_t_uint256_$returns$__$","typeString":"function (address,address,uint256,uint256)"}},"id":749,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"12412:41:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":750,"nodeType":"ExpressionStatement","src":"12412:41:0"}]},"documentation":{"id":668,"nodeType":"StructuredDocumentation","src":"10939:313:0","text":" @dev Transfers `tokenId` from `from` to `to`.\n As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n Requirements:\n - `to` cannot be the zero address.\n - `tokenId` token must be owned by `from`.\n Emits a {Transfer} event."},"id":752,"implemented":true,"kind":"function","modifiers":[],"name":"_transfer","nameLocation":"11266:9:0","nodeType":"FunctionDefinition","parameters":{"id":675,"nodeType":"ParameterList","parameters":[{"constant":false,"id":670,"mutability":"mutable","name":"from","nameLocation":"11284:4:0","nodeType":"VariableDeclaration","scope":752,"src":"11276:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":669,"name":"address","nodeType":"ElementaryTypeName","src":"11276:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":672,"mutability":"mutable","name":"to","nameLocation":"11298:2:0","nodeType":"VariableDeclaration","scope":752,"src":"11290:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":671,"name":"address","nodeType":"ElementaryTypeName","src":"11290:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":674,"mutability":"mutable","name":"tokenId","nameLocation":"11310:7:0","nodeType":"VariableDeclaration","scope":752,"src":"11302:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":673,"name":"uint256","nodeType":"ElementaryTypeName","src":"11302:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"11275:43:0"},"returnParameters":{"id":676,"nodeType":"ParameterList","parameters":[],"src":"11336:0:0"},"scope":926,"src":"11257:1203:0","stateMutability":"nonpayable","virtual":true,"visibility":"internal"},{"body":{"id":775,"nodeType":"Block","src":"12636:107:0","statements":[{"expression":{"id":764,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"baseExpression":{"id":760,"name":"_tokenApprovals","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":39,"src":"12646:15:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_uint256_$_t_address_$","typeString":"mapping(uint256 => address)"}},"id":762,"indexExpression":{"id":761,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":757,"src":"12662:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"IndexAccess","src":"12646:24:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":763,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":755,"src":"12673:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"12646:29:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":765,"nodeType":"ExpressionStatement","src":"12646:29:0"},{"eventCall":{"arguments":[{"arguments":[{"id":769,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":757,"src":"12714:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":767,"name":"ERC721","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":926,"src":"12699:6:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_ERC721_$926_$","typeString":"type(contract ERC721)"}},"id":768,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"12706:7:0","memberName":"ownerOf","nodeType":"MemberAccess","referencedDeclaration":145,"src":"12699:14:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_uint256_$returns$_t_address_$","typeString":"function (uint256) view returns (address)"}},"id":770,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"12699:23:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":771,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":755,"src":"12724:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":772,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":757,"src":"12728:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":766,"name":"Approval","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":950,"src":"12690:8:0","typeDescriptions":{"typeIdentifier":"t_function_event_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$","typeString":"function (address,address,uint256)"}},"id":773,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"12690:46:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":774,"nodeType":"EmitStatement","src":"12685:51:0"}]},"documentation":{"id":753,"nodeType":"StructuredDocumentation","src":"12466:101:0","text":" @dev Approve `to` to operate on `tokenId`\n Emits an {Approval} event."},"id":776,"implemented":true,"kind":"function","modifiers":[],"name":"_approve","nameLocation":"12581:8:0","nodeType":"FunctionDefinition","parameters":{"id":758,"nodeType":"ParameterList","parameters":[{"constant":false,"id":755,"mutability":"mutable","name":"to","nameLocation":"12598:2:0","nodeType":"VariableDeclaration","scope":776,"src":"12590:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":754,"name":"address","nodeType":"ElementaryTypeName","src":"12590:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":757,"mutability":"mutable","name":"tokenId","nameLocation":"12610:7:0","nodeType":"VariableDeclaration","scope":776,"src":"12602:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":756,"name":"uint256","nodeType":"ElementaryTypeName","src":"12602:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"12589:29:0"},"returnParameters":{"id":759,"nodeType":"ParameterList","parameters":[],"src":"12636:0:0"},"scope":926,"src":"12572:171:0","stateMutability":"nonpayable","virtual":true,"visibility":"internal"},{"body":{"id":807,"nodeType":"Block","src":"12972:184:0","statements":[{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_address","typeString":"address"},"id":789,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":787,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":779,"src":"12990:5:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"BinaryOperation","operator":"!=","rightExpression":{"id":788,"name":"operator","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":781,"src":"12999:8:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"src":"12990:17:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"4552433732313a20617070726f766520746f2063616c6c6572","id":790,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"13009:27:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_45fe4329685be5ecd250fd0e6a25aea0ea4d0e30fb6a73c118b95749e6d70d05","typeString":"literal_string \"ERC721: approve to caller\""},"value":"ERC721: approve to caller"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_45fe4329685be5ecd250fd0e6a25aea0ea4d0e30fb6a73c118b95749e6d70d05","typeString":"literal_string \"ERC721: approve to caller\""}],"id":786,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"12982:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":791,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"12982:55:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":792,"nodeType":"ExpressionStatement","src":"12982:55:0"},{"expression":{"id":799,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"baseExpression":{"baseExpression":{"id":793,"name":"_operatorApprovals","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":45,"src":"13047:18:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_mapping$_t_address_$_t_bool_$_$","typeString":"mapping(address => mapping(address => bool))"}},"id":796,"indexExpression":{"id":794,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":779,"src":"13066:5:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"13047:25:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_bool_$","typeString":"mapping(address => bool)"}},"id":797,"indexExpression":{"id":795,"name":"operator","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":781,"src":"13073:8:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"IndexAccess","src":"13047:35:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"id":798,"name":"approved","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":783,"src":"13085:8:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"13047:46:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":800,"nodeType":"ExpressionStatement","src":"13047:46:0"},{"eventCall":{"arguments":[{"id":802,"name":"owner","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":779,"src":"13123:5:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":803,"name":"operator","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":781,"src":"13130:8:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":804,"name":"approved","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":783,"src":"13140:8:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_bool","typeString":"bool"}],"id":801,"name":"ApprovalForAll","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":959,"src":"13108:14:0","typeDescriptions":{"typeIdentifier":"t_function_event_nonpayable$_t_address_$_t_address_$_t_bool_$returns$__$","typeString":"function (address,address,bool)"}},"id":805,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"13108:41:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":806,"nodeType":"EmitStatement","src":"13103:46:0"}]},"documentation":{"id":777,"nodeType":"StructuredDocumentation","src":"12749:125:0","text":" @dev Approve `operator` to operate on all of `owner` tokens\n Emits an {ApprovalForAll} event."},"id":808,"implemented":true,"kind":"function","modifiers":[],"name":"_setApprovalForAll","nameLocation":"12888:18:0","nodeType":"FunctionDefinition","parameters":{"id":784,"nodeType":"ParameterList","parameters":[{"constant":false,"id":779,"mutability":"mutable","name":"owner","nameLocation":"12915:5:0","nodeType":"VariableDeclaration","scope":808,"src":"12907:13:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":778,"name":"address","nodeType":"ElementaryTypeName","src":"12907:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":781,"mutability":"mutable","name":"operator","nameLocation":"12930:8:0","nodeType":"VariableDeclaration","scope":808,"src":"12922:16:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":780,"name":"address","nodeType":"ElementaryTypeName","src":"12922:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":783,"mutability":"mutable","name":"approved","nameLocation":"12945:8:0","nodeType":"VariableDeclaration","scope":808,"src":"12940:13:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":782,"name":"bool","nodeType":"ElementaryTypeName","src":"12940:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"12906:48:0"},"returnParameters":{"id":785,"nodeType":"ParameterList","parameters":[],"src":"12972:0:0"},"scope":926,"src":"12879:277:0","stateMutability":"nonpayable","virtual":true,"visibility":"internal"},{"body":{"id":821,"nodeType":"Block","src":"13303:70:0","statements":[{"expression":{"arguments":[{"arguments":[{"id":816,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":811,"src":"13329:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":815,"name":"_exists","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":445,"src":"13321:7:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_uint256_$returns$_t_bool_$","typeString":"function (uint256) view returns (bool)"}},"id":817,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"13321:16:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"4552433732313a20696e76616c696420746f6b656e204944","id":818,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"13339:26:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_b08d2b0fec7cc108ab049809a8beb42779d969a49299d0c317c907d9db22974f","typeString":"literal_string \"ERC721: invalid token ID\""},"value":"ERC721: invalid token ID"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_b08d2b0fec7cc108ab049809a8beb42779d969a49299d0c317c907d9db22974f","typeString":"literal_string \"ERC721: invalid token ID\""}],"id":814,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"13313:7:0","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":819,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"13313:53:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":820,"nodeType":"ExpressionStatement","src":"13313:53:0"}]},"documentation":{"id":809,"nodeType":"StructuredDocumentation","src":"13162:73:0","text":" @dev Reverts if the `tokenId` has not been minted yet."},"id":822,"implemented":true,"kind":"function","modifiers":[],"name":"_requireMinted","nameLocation":"13249:14:0","nodeType":"FunctionDefinition","parameters":{"id":812,"nodeType":"ParameterList","parameters":[{"constant":false,"id":811,"mutability":"mutable","name":"tokenId","nameLocation":"13272:7:0","nodeType":"VariableDeclaration","scope":822,"src":"13264:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":810,"name":"uint256","nodeType":"ElementaryTypeName","src":"13264:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"13263:17:0"},"returnParameters":{"id":813,"nodeType":"ParameterList","parameters":[],"src":"13303:0:0"},"scope":926,"src":"13240:133:0","stateMutability":"view","virtual":true,"visibility":"internal"},{"body":{"id":883,"nodeType":"Block","src":"14080:676:0","statements":[{"condition":{"arguments":[],"expression":{"argumentTypes":[],"expression":{"id":836,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":827,"src":"14094:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":837,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"14097:10:0","memberName":"isContract","nodeType":"MemberAccess","referencedDeclaration":1105,"src":"14094:13:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_address_$returns$_t_bool_$bound_to$_t_address_$","typeString":"function (address) view returns (bool)"}},"id":838,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"14094:15:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"falseBody":{"id":881,"nodeType":"Block","src":"14714:36:0","statements":[{"expression":{"hexValue":"74727565","id":879,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"14735:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"true"},"functionReturnParameters":835,"id":880,"nodeType":"Return","src":"14728:11:0"}]},"id":882,"nodeType":"IfStatement","src":"14090:660:0","trueBody":{"id":878,"nodeType":"Block","src":"14111:597:0","statements":[{"clauses":[{"block":{"id":858,"nodeType":"Block","src":"14225:91:0","statements":[{"expression":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"id":856,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":852,"name":"retval","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":850,"src":"14250:6:0","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"expression":{"id":853,"name":"IERC721Receiver","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1060,"src":"14260:15:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC721Receiver_$1060_$","typeString":"type(contract IERC721Receiver)"}},"id":854,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"14276:16:0","memberName":"onERC721Received","nodeType":"MemberAccess","referencedDeclaration":1059,"src":"14260:32:0","typeDescriptions":{"typeIdentifier":"t_function_declaration_nonpayable$_t_address_$_t_address_$_t_uint256_$_t_bytes_calldata_ptr_$returns$_t_bytes4_$","typeString":"function IERC721Receiver.onERC721Received(address,address,uint256,bytes calldata) returns (bytes4)"}},"id":855,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"14293:8:0","memberName":"selector","nodeType":"MemberAccess","src":"14260:41:0","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"src":"14250:51:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"functionReturnParameters":835,"id":857,"nodeType":"Return","src":"14243:58:0"}]},"errorName":"","id":859,"nodeType":"TryCatchClause","parameters":{"id":851,"nodeType":"ParameterList","parameters":[{"constant":false,"id":850,"mutability":"mutable","name":"retval","nameLocation":"14217:6:0","nodeType":"VariableDeclaration","scope":859,"src":"14210:13:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":849,"name":"bytes4","nodeType":"ElementaryTypeName","src":"14210:6:0","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"14209:15:0"},"src":"14201:115:0"},{"block":{"id":875,"nodeType":"Block","src":"14345:353:0","statements":[{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":866,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"expression":{"id":863,"name":"reason","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":861,"src":"14367:6:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":864,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"14374:6:0","memberName":"length","nodeType":"MemberAccess","src":"14367:13:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"30","id":865,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"14384:1:0","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"14367:18:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"falseBody":{"id":873,"nodeType":"Block","src":"14494:190:0","statements":[{"AST":{"nodeType":"YulBlock","src":"14580:86:0","statements":[{"expression":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"14617:2:0","type":"","value":"32"},{"name":"reason","nodeType":"YulIdentifier","src":"14621:6:0"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"14613:3:0"},"nodeType":"YulFunctionCall","src":"14613:15:0"},{"arguments":[{"name":"reason","nodeType":"YulIdentifier","src":"14636:6:0"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"14630:5:0"},"nodeType":"YulFunctionCall","src":"14630:13:0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"14606:6:0"},"nodeType":"YulFunctionCall","src":"14606:38:0"},"nodeType":"YulExpressionStatement","src":"14606:38:0"}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":861,"isOffset":false,"isSlot":false,"src":"14621:6:0","valueSize":1},{"declaration":861,"isOffset":false,"isSlot":false,"src":"14636:6:0","valueSize":1}],"id":872,"nodeType":"InlineAssembly","src":"14571:95:0"}]},"id":874,"nodeType":"IfStatement","src":"14363:321:0","trueBody":{"id":871,"nodeType":"Block","src":"14387:101:0","statements":[{"expression":{"arguments":[{"hexValue":"4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e746572","id":868,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"14416:52:0","typeDescriptions":{"typeIdentifier":"t_stringliteral_1e766a06da43a53d0f4c380e06e5a342e14d5af1bf8501996c844905530ca84e","typeString":"literal_string \"ERC721: transfer to non ERC721Receiver implementer\""},"value":"ERC721: transfer to non ERC721Receiver implementer"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_1e766a06da43a53d0f4c380e06e5a342e14d5af1bf8501996c844905530ca84e","typeString":"literal_string \"ERC721: transfer to non ERC721Receiver implementer\""}],"id":867,"name":"revert","nodeType":"Identifier","overloadedDeclarations":[-19,-19],"referencedDeclaration":-19,"src":"14409:6:0","typeDescriptions":{"typeIdentifier":"t_function_revert_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":869,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"14409:60:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":870,"nodeType":"ExpressionStatement","src":"14409:60:0"}]}}]},"errorName":"","id":876,"nodeType":"TryCatchClause","parameters":{"id":862,"nodeType":"ParameterList","parameters":[{"constant":false,"id":861,"mutability":"mutable","name":"reason","nameLocation":"14337:6:0","nodeType":"VariableDeclaration","scope":876,"src":"14324:19:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":860,"name":"bytes","nodeType":"ElementaryTypeName","src":"14324:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"14323:21:0"},"src":"14317:381:0"}],"externalCall":{"arguments":[{"arguments":[],"expression":{"argumentTypes":[],"id":843,"name":"_msgSender","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1429,"src":"14166:10:0","typeDescriptions":{"typeIdentifier":"t_function_internal_view$__$returns$_t_address_$","typeString":"function () view returns (address)"}},"id":844,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"14166:12:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":845,"name":"from","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":825,"src":"14180:4:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":846,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":829,"src":"14186:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":847,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":831,"src":"14195:4:0","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"expression":{"arguments":[{"id":840,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":827,"src":"14145:2:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":839,"name":"IERC721Receiver","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1060,"src":"14129:15:0","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC721Receiver_$1060_$","typeString":"type(contract IERC721Receiver)"}},"id":841,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"14129:19:0","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_IERC721Receiver_$1060","typeString":"contract IERC721Receiver"}},"id":842,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"14149:16:0","memberName":"onERC721Received","nodeType":"MemberAccess","referencedDeclaration":1059,"src":"14129:36:0","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$_t_address_$_t_uint256_$_t_bytes_memory_ptr_$returns$_t_bytes4_$","typeString":"function (address,address,uint256,bytes memory) external returns (bytes4)"}},"id":848,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"14129:71:0","tryCall":true,"typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"id":877,"nodeType":"TryStatement","src":"14125:573:0"}]}}]},"documentation":{"id":823,"nodeType":"StructuredDocumentation","src":"13379:541:0","text":" @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 @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"},"id":884,"implemented":true,"kind":"function","modifiers":[],"name":"_checkOnERC721Received","nameLocation":"13934:22:0","nodeType":"FunctionDefinition","parameters":{"id":832,"nodeType":"ParameterList","parameters":[{"constant":false,"id":825,"mutability":"mutable","name":"from","nameLocation":"13974:4:0","nodeType":"VariableDeclaration","scope":884,"src":"13966:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":824,"name":"address","nodeType":"ElementaryTypeName","src":"13966:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":827,"mutability":"mutable","name":"to","nameLocation":"13996:2:0","nodeType":"VariableDeclaration","scope":884,"src":"13988:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":826,"name":"address","nodeType":"ElementaryTypeName","src":"13988:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":829,"mutability":"mutable","name":"tokenId","nameLocation":"14016:7:0","nodeType":"VariableDeclaration","scope":884,"src":"14008:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":828,"name":"uint256","nodeType":"ElementaryTypeName","src":"14008:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":831,"mutability":"mutable","name":"data","nameLocation":"14046:4:0","nodeType":"VariableDeclaration","scope":884,"src":"14033:17:0","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":830,"name":"bytes","nodeType":"ElementaryTypeName","src":"14033:5:0","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"13956:100:0"},"returnParameters":{"id":835,"nodeType":"ParameterList","parameters":[{"constant":false,"id":834,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":884,"src":"14074:4:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":833,"name":"bool","nodeType":"ElementaryTypeName","src":"14074:4:0","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"14073:6:0"},"scope":926,"src":"13925:831:0","stateMutability":"nonpayable","virtual":false,"visibility":"private"},{"body":{"id":896,"nodeType":"Block","src":"15586:2:0","statements":[]},"documentation":{"id":885,"nodeType":"StructuredDocumentation","src":"14762:705:0","text":" @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n Calling conditions:\n - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n - When `from` is zero, the tokens will be minted for `to`.\n - When `to` is zero, ``from``'s tokens will be burned.\n - `from` and `to` are never both zero.\n - `batchSize` is non-zero.\n To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]."},"id":897,"implemented":true,"kind":"function","modifiers":[],"name":"_beforeTokenTransfer","nameLocation":"15481:20:0","nodeType":"FunctionDefinition","parameters":{"id":894,"nodeType":"ParameterList","parameters":[{"constant":false,"id":887,"mutability":"mutable","name":"from","nameLocation":"15510:4:0","nodeType":"VariableDeclaration","scope":897,"src":"15502:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":886,"name":"address","nodeType":"ElementaryTypeName","src":"15502:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":889,"mutability":"mutable","name":"to","nameLocation":"15524:2:0","nodeType":"VariableDeclaration","scope":897,"src":"15516:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":888,"name":"address","nodeType":"ElementaryTypeName","src":"15516:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":891,"mutability":"mutable","name":"firstTokenId","nameLocation":"15536:12:0","nodeType":"VariableDeclaration","scope":897,"src":"15528:20:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":890,"name":"uint256","nodeType":"ElementaryTypeName","src":"15528:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":893,"mutability":"mutable","name":"batchSize","nameLocation":"15558:9:0","nodeType":"VariableDeclaration","scope":897,"src":"15550:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":892,"name":"uint256","nodeType":"ElementaryTypeName","src":"15550:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"15501:67:0"},"returnParameters":{"id":895,"nodeType":"ParameterList","parameters":[],"src":"15586:0:0"},"scope":926,"src":"15472:116:0","stateMutability":"nonpayable","virtual":true,"visibility":"internal"},{"body":{"id":909,"nodeType":"Block","src":"16407:2:0","statements":[]},"documentation":{"id":898,"nodeType":"StructuredDocumentation","src":"15594:695:0","text":" @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n Calling conditions:\n - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n - When `from` is zero, the tokens were minted for `to`.\n - When `to` is zero, ``from``'s tokens were burned.\n - `from` and `to` are never both zero.\n - `batchSize` is non-zero.\n To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]."},"id":910,"implemented":true,"kind":"function","modifiers":[],"name":"_afterTokenTransfer","nameLocation":"16303:19:0","nodeType":"FunctionDefinition","parameters":{"id":907,"nodeType":"ParameterList","parameters":[{"constant":false,"id":900,"mutability":"mutable","name":"from","nameLocation":"16331:4:0","nodeType":"VariableDeclaration","scope":910,"src":"16323:12:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":899,"name":"address","nodeType":"ElementaryTypeName","src":"16323:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":902,"mutability":"mutable","name":"to","nameLocation":"16345:2:0","nodeType":"VariableDeclaration","scope":910,"src":"16337:10:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":901,"name":"address","nodeType":"ElementaryTypeName","src":"16337:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":904,"mutability":"mutable","name":"firstTokenId","nameLocation":"16357:12:0","nodeType":"VariableDeclaration","scope":910,"src":"16349:20:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":903,"name":"uint256","nodeType":"ElementaryTypeName","src":"16349:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":906,"mutability":"mutable","name":"batchSize","nameLocation":"16379:9:0","nodeType":"VariableDeclaration","scope":910,"src":"16371:17:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":905,"name":"uint256","nodeType":"ElementaryTypeName","src":"16371:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"16322:67:0"},"returnParameters":{"id":908,"nodeType":"ParameterList","parameters":[],"src":"16407:0:0"},"scope":926,"src":"16294:115:0","stateMutability":"nonpayable","virtual":true,"visibility":"internal"},{"body":{"id":924,"nodeType":"Block","src":"16958:45:0","statements":[{"expression":{"id":922,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"baseExpression":{"id":918,"name":"_balances","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":35,"src":"16968:9:0","typeDescriptions":{"typeIdentifier":"t_mapping$_t_address_$_t_uint256_$","typeString":"mapping(address => uint256)"}},"id":920,"indexExpression":{"id":919,"name":"account","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":913,"src":"16978:7:0","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"IndexAccess","src":"16968:18:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"id":921,"name":"amount","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":915,"src":"16990:6:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"16968:28:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":923,"nodeType":"ExpressionStatement","src":"16968:28:0"}]},"documentation":{"id":911,"nodeType":"StructuredDocumentation","src":"16415:409:0","text":" @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n that `ownerOf(tokenId)` is `a`."},"id":925,"implemented":true,"kind":"function","modifiers":[],"name":"__unsafe_increaseBalance","nameLocation":"16891:24:0","nodeType":"FunctionDefinition","parameters":{"id":916,"nodeType":"ParameterList","parameters":[{"constant":false,"id":913,"mutability":"mutable","name":"account","nameLocation":"16924:7:0","nodeType":"VariableDeclaration","scope":925,"src":"16916:15:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":912,"name":"address","nodeType":"ElementaryTypeName","src":"16916:7:0","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":915,"mutability":"mutable","name":"amount","nameLocation":"16941:6:0","nodeType":"VariableDeclaration","scope":925,"src":"16933:14:0","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":914,"name":"uint256","nodeType":"ElementaryTypeName","src":"16933:7:0","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"16915:33:0"},"returnParameters":{"id":917,"nodeType":"ParameterList","parameters":[],"src":"16958:0:0"},"scope":926,"src":"16882:121:0","stateMutability":"nonpayable","virtual":false,"visibility":"internal"}],"scope":927,"src":"628:16377:0","usedErrors":[]}],"src":"107:16899:0"},"id":0},"@openzeppelin/contracts/token/ERC721/IERC721.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721.sol","exportedSymbols":{"IERC165":[1704],"IERC721":[1042]},"id":1043,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":928,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"108:23:1"},{"absolutePath":"@openzeppelin/contracts/utils/introspection/IERC165.sol","file":"../../utils/introspection/IERC165.sol","id":929,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":1043,"sourceUnit":1705,"src":"133:47:1","symbolAliases":[],"unitAlias":""},{"abstract":false,"baseContracts":[{"baseName":{"id":931,"name":"IERC165","nameLocations":["271:7:1"],"nodeType":"IdentifierPath","referencedDeclaration":1704,"src":"271:7:1"},"id":932,"nodeType":"InheritanceSpecifier","src":"271:7:1"}],"canonicalName":"IERC721","contractDependencies":[],"contractKind":"interface","documentation":{"id":930,"nodeType":"StructuredDocumentation","src":"182:67:1","text":" @dev Required interface of an ERC721 compliant contract."},"fullyImplemented":false,"id":1042,"linearizedBaseContracts":[1042,1704],"name":"IERC721","nameLocation":"260:7:1","nodeType":"ContractDefinition","nodes":[{"anonymous":false,"documentation":{"id":933,"nodeType":"StructuredDocumentation","src":"285:88:1","text":" @dev Emitted when `tokenId` token is transferred from `from` to `to`."},"eventSelector":"ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","id":941,"name":"Transfer","nameLocation":"384:8:1","nodeType":"EventDefinition","parameters":{"id":940,"nodeType":"ParameterList","parameters":[{"constant":false,"id":935,"indexed":true,"mutability":"mutable","name":"from","nameLocation":"409:4:1","nodeType":"VariableDeclaration","scope":941,"src":"393:20:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":934,"name":"address","nodeType":"ElementaryTypeName","src":"393:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":937,"indexed":true,"mutability":"mutable","name":"to","nameLocation":"431:2:1","nodeType":"VariableDeclaration","scope":941,"src":"415:18:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":936,"name":"address","nodeType":"ElementaryTypeName","src":"415:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":939,"indexed":true,"mutability":"mutable","name":"tokenId","nameLocation":"451:7:1","nodeType":"VariableDeclaration","scope":941,"src":"435:23:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":938,"name":"uint256","nodeType":"ElementaryTypeName","src":"435:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"392:67:1"},"src":"378:82:1"},{"anonymous":false,"documentation":{"id":942,"nodeType":"StructuredDocumentation","src":"466:94:1","text":" @dev Emitted when `owner` enables `approved` to manage the `tokenId` token."},"eventSelector":"8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925","id":950,"name":"Approval","nameLocation":"571:8:1","nodeType":"EventDefinition","parameters":{"id":949,"nodeType":"ParameterList","parameters":[{"constant":false,"id":944,"indexed":true,"mutability":"mutable","name":"owner","nameLocation":"596:5:1","nodeType":"VariableDeclaration","scope":950,"src":"580:21:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":943,"name":"address","nodeType":"ElementaryTypeName","src":"580:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":946,"indexed":true,"mutability":"mutable","name":"approved","nameLocation":"619:8:1","nodeType":"VariableDeclaration","scope":950,"src":"603:24:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":945,"name":"address","nodeType":"ElementaryTypeName","src":"603:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":948,"indexed":true,"mutability":"mutable","name":"tokenId","nameLocation":"645:7:1","nodeType":"VariableDeclaration","scope":950,"src":"629:23:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":947,"name":"uint256","nodeType":"ElementaryTypeName","src":"629:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"579:74:1"},"src":"565:89:1"},{"anonymous":false,"documentation":{"id":951,"nodeType":"StructuredDocumentation","src":"660:117:1","text":" @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets."},"eventSelector":"17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31","id":959,"name":"ApprovalForAll","nameLocation":"788:14:1","nodeType":"EventDefinition","parameters":{"id":958,"nodeType":"ParameterList","parameters":[{"constant":false,"id":953,"indexed":true,"mutability":"mutable","name":"owner","nameLocation":"819:5:1","nodeType":"VariableDeclaration","scope":959,"src":"803:21:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":952,"name":"address","nodeType":"ElementaryTypeName","src":"803:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":955,"indexed":true,"mutability":"mutable","name":"operator","nameLocation":"842:8:1","nodeType":"VariableDeclaration","scope":959,"src":"826:24:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":954,"name":"address","nodeType":"ElementaryTypeName","src":"826:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":957,"indexed":false,"mutability":"mutable","name":"approved","nameLocation":"857:8:1","nodeType":"VariableDeclaration","scope":959,"src":"852:13:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":956,"name":"bool","nodeType":"ElementaryTypeName","src":"852:4:1","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"802:64:1"},"src":"782:85:1"},{"documentation":{"id":960,"nodeType":"StructuredDocumentation","src":"873:76:1","text":" @dev Returns the number of tokens in ``owner``'s account."},"functionSelector":"70a08231","id":967,"implemented":false,"kind":"function","modifiers":[],"name":"balanceOf","nameLocation":"963:9:1","nodeType":"FunctionDefinition","parameters":{"id":963,"nodeType":"ParameterList","parameters":[{"constant":false,"id":962,"mutability":"mutable","name":"owner","nameLocation":"981:5:1","nodeType":"VariableDeclaration","scope":967,"src":"973:13:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":961,"name":"address","nodeType":"ElementaryTypeName","src":"973:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"972:15:1"},"returnParameters":{"id":966,"nodeType":"ParameterList","parameters":[{"constant":false,"id":965,"mutability":"mutable","name":"balance","nameLocation":"1019:7:1","nodeType":"VariableDeclaration","scope":967,"src":"1011:15:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":964,"name":"uint256","nodeType":"ElementaryTypeName","src":"1011:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1010:17:1"},"scope":1042,"src":"954:74:1","stateMutability":"view","virtual":false,"visibility":"external"},{"documentation":{"id":968,"nodeType":"StructuredDocumentation","src":"1034:131:1","text":" @dev Returns the owner of the `tokenId` token.\n Requirements:\n - `tokenId` must exist."},"functionSelector":"6352211e","id":975,"implemented":false,"kind":"function","modifiers":[],"name":"ownerOf","nameLocation":"1179:7:1","nodeType":"FunctionDefinition","parameters":{"id":971,"nodeType":"ParameterList","parameters":[{"constant":false,"id":970,"mutability":"mutable","name":"tokenId","nameLocation":"1195:7:1","nodeType":"VariableDeclaration","scope":975,"src":"1187:15:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":969,"name":"uint256","nodeType":"ElementaryTypeName","src":"1187:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1186:17:1"},"returnParameters":{"id":974,"nodeType":"ParameterList","parameters":[{"constant":false,"id":973,"mutability":"mutable","name":"owner","nameLocation":"1235:5:1","nodeType":"VariableDeclaration","scope":975,"src":"1227:13:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":972,"name":"address","nodeType":"ElementaryTypeName","src":"1227:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1226:15:1"},"scope":1042,"src":"1170:72:1","stateMutability":"view","virtual":false,"visibility":"external"},{"documentation":{"id":976,"nodeType":"StructuredDocumentation","src":"1248:556:1","text":" @dev Safely transfers `tokenId` token from `from` to `to`.\n Requirements:\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 Emits a {Transfer} event."},"functionSelector":"b88d4fde","id":987,"implemented":false,"kind":"function","modifiers":[],"name":"safeTransferFrom","nameLocation":"1818:16:1","nodeType":"FunctionDefinition","parameters":{"id":985,"nodeType":"ParameterList","parameters":[{"constant":false,"id":978,"mutability":"mutable","name":"from","nameLocation":"1843:4:1","nodeType":"VariableDeclaration","scope":987,"src":"1835:12:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":977,"name":"address","nodeType":"ElementaryTypeName","src":"1835:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":980,"mutability":"mutable","name":"to","nameLocation":"1857:2:1","nodeType":"VariableDeclaration","scope":987,"src":"1849:10:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":979,"name":"address","nodeType":"ElementaryTypeName","src":"1849:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":982,"mutability":"mutable","name":"tokenId","nameLocation":"1869:7:1","nodeType":"VariableDeclaration","scope":987,"src":"1861:15:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":981,"name":"uint256","nodeType":"ElementaryTypeName","src":"1861:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":984,"mutability":"mutable","name":"data","nameLocation":"1893:4:1","nodeType":"VariableDeclaration","scope":987,"src":"1878:19:1","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":983,"name":"bytes","nodeType":"ElementaryTypeName","src":"1878:5:1","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"1834:64:1"},"returnParameters":{"id":986,"nodeType":"ParameterList","parameters":[],"src":"1907:0:1"},"scope":1042,"src":"1809:99:1","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":988,"nodeType":"StructuredDocumentation","src":"1914:687:1","text":" @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 Requirements:\n - `from` cannot be the zero address.\n - `to` cannot be the zero address.\n - `tokenId` token must exist and be owned by `from`.\n - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n Emits a {Transfer} event."},"functionSelector":"42842e0e","id":997,"implemented":false,"kind":"function","modifiers":[],"name":"safeTransferFrom","nameLocation":"2615:16:1","nodeType":"FunctionDefinition","parameters":{"id":995,"nodeType":"ParameterList","parameters":[{"constant":false,"id":990,"mutability":"mutable","name":"from","nameLocation":"2640:4:1","nodeType":"VariableDeclaration","scope":997,"src":"2632:12:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":989,"name":"address","nodeType":"ElementaryTypeName","src":"2632:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":992,"mutability":"mutable","name":"to","nameLocation":"2654:2:1","nodeType":"VariableDeclaration","scope":997,"src":"2646:10:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":991,"name":"address","nodeType":"ElementaryTypeName","src":"2646:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":994,"mutability":"mutable","name":"tokenId","nameLocation":"2666:7:1","nodeType":"VariableDeclaration","scope":997,"src":"2658:15:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":993,"name":"uint256","nodeType":"ElementaryTypeName","src":"2658:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2631:43:1"},"returnParameters":{"id":996,"nodeType":"ParameterList","parameters":[],"src":"2683:0:1"},"scope":1042,"src":"2606:78:1","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":998,"nodeType":"StructuredDocumentation","src":"2690:732:1","text":" @dev Transfers `tokenId` token from `from` to `to`.\n WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n understand this adds an external call which potentially creates a reentrancy vulnerability.\n Requirements:\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 Emits a {Transfer} event."},"functionSelector":"23b872dd","id":1007,"implemented":false,"kind":"function","modifiers":[],"name":"transferFrom","nameLocation":"3436:12:1","nodeType":"FunctionDefinition","parameters":{"id":1005,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1000,"mutability":"mutable","name":"from","nameLocation":"3457:4:1","nodeType":"VariableDeclaration","scope":1007,"src":"3449:12:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":999,"name":"address","nodeType":"ElementaryTypeName","src":"3449:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1002,"mutability":"mutable","name":"to","nameLocation":"3471:2:1","nodeType":"VariableDeclaration","scope":1007,"src":"3463:10:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1001,"name":"address","nodeType":"ElementaryTypeName","src":"3463:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1004,"mutability":"mutable","name":"tokenId","nameLocation":"3483:7:1","nodeType":"VariableDeclaration","scope":1007,"src":"3475:15:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1003,"name":"uint256","nodeType":"ElementaryTypeName","src":"3475:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3448:43:1"},"returnParameters":{"id":1006,"nodeType":"ParameterList","parameters":[],"src":"3500:0:1"},"scope":1042,"src":"3427:74:1","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":1008,"nodeType":"StructuredDocumentation","src":"3507:452:1","text":" @dev Gives permission to `to` to transfer `tokenId` token to another account.\n The approval is cleared when the token is transferred.\n Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n Requirements:\n - The caller must own the token or be an approved operator.\n - `tokenId` must exist.\n Emits an {Approval} event."},"functionSelector":"095ea7b3","id":1015,"implemented":false,"kind":"function","modifiers":[],"name":"approve","nameLocation":"3973:7:1","nodeType":"FunctionDefinition","parameters":{"id":1013,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1010,"mutability":"mutable","name":"to","nameLocation":"3989:2:1","nodeType":"VariableDeclaration","scope":1015,"src":"3981:10:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1009,"name":"address","nodeType":"ElementaryTypeName","src":"3981:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1012,"mutability":"mutable","name":"tokenId","nameLocation":"4001:7:1","nodeType":"VariableDeclaration","scope":1015,"src":"3993:15:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1011,"name":"uint256","nodeType":"ElementaryTypeName","src":"3993:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3980:29:1"},"returnParameters":{"id":1014,"nodeType":"ParameterList","parameters":[],"src":"4018:0:1"},"scope":1042,"src":"3964:55:1","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":1016,"nodeType":"StructuredDocumentation","src":"4025:309:1","text":" @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 Requirements:\n - The `operator` cannot be the caller.\n Emits an {ApprovalForAll} event."},"functionSelector":"a22cb465","id":1023,"implemented":false,"kind":"function","modifiers":[],"name":"setApprovalForAll","nameLocation":"4348:17:1","nodeType":"FunctionDefinition","parameters":{"id":1021,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1018,"mutability":"mutable","name":"operator","nameLocation":"4374:8:1","nodeType":"VariableDeclaration","scope":1023,"src":"4366:16:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1017,"name":"address","nodeType":"ElementaryTypeName","src":"4366:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1020,"mutability":"mutable","name":"approved","nameLocation":"4389:8:1","nodeType":"VariableDeclaration","scope":1023,"src":"4384:13:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":1019,"name":"bool","nodeType":"ElementaryTypeName","src":"4384:4:1","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"4365:33:1"},"returnParameters":{"id":1022,"nodeType":"ParameterList","parameters":[],"src":"4407:0:1"},"scope":1042,"src":"4339:69:1","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"documentation":{"id":1024,"nodeType":"StructuredDocumentation","src":"4414:139:1","text":" @dev Returns the account approved for `tokenId` token.\n Requirements:\n - `tokenId` must exist."},"functionSelector":"081812fc","id":1031,"implemented":false,"kind":"function","modifiers":[],"name":"getApproved","nameLocation":"4567:11:1","nodeType":"FunctionDefinition","parameters":{"id":1027,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1026,"mutability":"mutable","name":"tokenId","nameLocation":"4587:7:1","nodeType":"VariableDeclaration","scope":1031,"src":"4579:15:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1025,"name":"uint256","nodeType":"ElementaryTypeName","src":"4579:7:1","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"4578:17:1"},"returnParameters":{"id":1030,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1029,"mutability":"mutable","name":"operator","nameLocation":"4627:8:1","nodeType":"VariableDeclaration","scope":1031,"src":"4619:16:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1028,"name":"address","nodeType":"ElementaryTypeName","src":"4619:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"4618:18:1"},"scope":1042,"src":"4558:79:1","stateMutability":"view","virtual":false,"visibility":"external"},{"documentation":{"id":1032,"nodeType":"StructuredDocumentation","src":"4643:138:1","text":" @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n See {setApprovalForAll}"},"functionSelector":"e985e9c5","id":1041,"implemented":false,"kind":"function","modifiers":[],"name":"isApprovedForAll","nameLocation":"4795:16:1","nodeType":"FunctionDefinition","parameters":{"id":1037,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1034,"mutability":"mutable","name":"owner","nameLocation":"4820:5:1","nodeType":"VariableDeclaration","scope":1041,"src":"4812:13:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1033,"name":"address","nodeType":"ElementaryTypeName","src":"4812:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1036,"mutability":"mutable","name":"operator","nameLocation":"4835:8:1","nodeType":"VariableDeclaration","scope":1041,"src":"4827:16:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1035,"name":"address","nodeType":"ElementaryTypeName","src":"4827:7:1","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"4811:33:1"},"returnParameters":{"id":1040,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1039,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1041,"src":"4868:4:1","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":1038,"name":"bool","nodeType":"ElementaryTypeName","src":"4868:4:1","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"4867:6:1"},"scope":1042,"src":"4786:88:1","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":1043,"src":"250:4626:1","usedErrors":[]}],"src":"108:4769:1"},"id":1},"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol","exportedSymbols":{"IERC721Receiver":[1060]},"id":1061,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":1044,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"116:23:2"},{"abstract":false,"baseContracts":[],"canonicalName":"IERC721Receiver","contractDependencies":[],"contractKind":"interface","documentation":{"id":1045,"nodeType":"StructuredDocumentation","src":"141:152:2","text":" @title ERC721 token receiver interface\n @dev Interface for any contract that wants to support safeTransfers\n from ERC721 asset contracts."},"fullyImplemented":false,"id":1060,"linearizedBaseContracts":[1060],"name":"IERC721Receiver","nameLocation":"304:15:2","nodeType":"ContractDefinition","nodes":[{"documentation":{"id":1046,"nodeType":"StructuredDocumentation","src":"326:493:2","text":" @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n by `operator` from `from`, this function is called.\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 The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`."},"functionSelector":"150b7a02","id":1059,"implemented":false,"kind":"function","modifiers":[],"name":"onERC721Received","nameLocation":"833:16:2","nodeType":"FunctionDefinition","parameters":{"id":1055,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1048,"mutability":"mutable","name":"operator","nameLocation":"867:8:2","nodeType":"VariableDeclaration","scope":1059,"src":"859:16:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1047,"name":"address","nodeType":"ElementaryTypeName","src":"859:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1050,"mutability":"mutable","name":"from","nameLocation":"893:4:2","nodeType":"VariableDeclaration","scope":1059,"src":"885:12:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1049,"name":"address","nodeType":"ElementaryTypeName","src":"885:7:2","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1052,"mutability":"mutable","name":"tokenId","nameLocation":"915:7:2","nodeType":"VariableDeclaration","scope":1059,"src":"907:15:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1051,"name":"uint256","nodeType":"ElementaryTypeName","src":"907:7:2","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1054,"mutability":"mutable","name":"data","nameLocation":"947:4:2","nodeType":"VariableDeclaration","scope":1059,"src":"932:19:2","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":1053,"name":"bytes","nodeType":"ElementaryTypeName","src":"932:5:2","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"849:108:2"},"returnParameters":{"id":1058,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1057,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1059,"src":"976:6:2","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":1056,"name":"bytes4","nodeType":"ElementaryTypeName","src":"976:6:2","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"975:8:2"},"scope":1060,"src":"824:160:2","stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"scope":1061,"src":"294:692:2","usedErrors":[]}],"src":"116:871:2"},"id":2},"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol","exportedSymbols":{"IERC165":[1704],"IERC721":[1042],"IERC721Metadata":[1087]},"id":1088,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":1062,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"112:23:3"},{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721.sol","file":"../IERC721.sol","id":1063,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":1088,"sourceUnit":1043,"src":"137:24:3","symbolAliases":[],"unitAlias":""},{"abstract":false,"baseContracts":[{"baseName":{"id":1065,"name":"IERC721","nameLocations":["326:7:3"],"nodeType":"IdentifierPath","referencedDeclaration":1042,"src":"326:7:3"},"id":1066,"nodeType":"InheritanceSpecifier","src":"326:7:3"}],"canonicalName":"IERC721Metadata","contractDependencies":[],"contractKind":"interface","documentation":{"id":1064,"nodeType":"StructuredDocumentation","src":"163:133:3","text":" @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n @dev See https://eips.ethereum.org/EIPS/eip-721"},"fullyImplemented":false,"id":1087,"linearizedBaseContracts":[1087,1042,1704],"name":"IERC721Metadata","nameLocation":"307:15:3","nodeType":"ContractDefinition","nodes":[{"documentation":{"id":1067,"nodeType":"StructuredDocumentation","src":"340:58:3","text":" @dev Returns the token collection name."},"functionSelector":"06fdde03","id":1072,"implemented":false,"kind":"function","modifiers":[],"name":"name","nameLocation":"412:4:3","nodeType":"FunctionDefinition","parameters":{"id":1068,"nodeType":"ParameterList","parameters":[],"src":"416:2:3"},"returnParameters":{"id":1071,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1070,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1072,"src":"442:13:3","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":1069,"name":"string","nodeType":"ElementaryTypeName","src":"442:6:3","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"441:15:3"},"scope":1087,"src":"403:54:3","stateMutability":"view","virtual":false,"visibility":"external"},{"documentation":{"id":1073,"nodeType":"StructuredDocumentation","src":"463:60:3","text":" @dev Returns the token collection symbol."},"functionSelector":"95d89b41","id":1078,"implemented":false,"kind":"function","modifiers":[],"name":"symbol","nameLocation":"537:6:3","nodeType":"FunctionDefinition","parameters":{"id":1074,"nodeType":"ParameterList","parameters":[],"src":"543:2:3"},"returnParameters":{"id":1077,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1076,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1078,"src":"569:13:3","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":1075,"name":"string","nodeType":"ElementaryTypeName","src":"569:6:3","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"568:15:3"},"scope":1087,"src":"528:56:3","stateMutability":"view","virtual":false,"visibility":"external"},{"documentation":{"id":1079,"nodeType":"StructuredDocumentation","src":"590:90:3","text":" @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token."},"functionSelector":"c87b56dd","id":1086,"implemented":false,"kind":"function","modifiers":[],"name":"tokenURI","nameLocation":"694:8:3","nodeType":"FunctionDefinition","parameters":{"id":1082,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1081,"mutability":"mutable","name":"tokenId","nameLocation":"711:7:3","nodeType":"VariableDeclaration","scope":1086,"src":"703:15:3","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1080,"name":"uint256","nodeType":"ElementaryTypeName","src":"703:7:3","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"702:17:3"},"returnParameters":{"id":1085,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1084,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1086,"src":"743:13:3","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":1083,"name":"string","nodeType":"ElementaryTypeName","src":"743:6:3","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"742:15:3"},"scope":1087,"src":"685:73:3","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":1088,"src":"297:463:3","usedErrors":[]}],"src":"112:649:3"},"id":3},"@openzeppelin/contracts/utils/Address.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/utils/Address.sol","exportedSymbols":{"Address":[1417]},"id":1418,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":1089,"literals":["solidity","^","0.8",".1"],"nodeType":"PragmaDirective","src":"101:23:4"},{"abstract":false,"baseContracts":[],"canonicalName":"Address","contractDependencies":[],"contractKind":"library","documentation":{"id":1090,"nodeType":"StructuredDocumentation","src":"126:67:4","text":" @dev Collection of functions related to the address type"},"fullyImplemented":true,"id":1417,"linearizedBaseContracts":[1417],"name":"Address","nameLocation":"202:7:4","nodeType":"ContractDefinition","nodes":[{"body":{"id":1104,"nodeType":"Block","src":"1478:254:4","statements":[{"expression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1102,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"expression":{"expression":{"id":1098,"name":"account","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1093,"src":"1702:7:4","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":1099,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"1710:4:4","memberName":"code","nodeType":"MemberAccess","src":"1702:12:4","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":1100,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"1715:6:4","memberName":"length","nodeType":"MemberAccess","src":"1702:19:4","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"hexValue":"30","id":1101,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"1724:1:4","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"1702:23:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"functionReturnParameters":1097,"id":1103,"nodeType":"Return","src":"1695:30:4"}]},"documentation":{"id":1091,"nodeType":"StructuredDocumentation","src":"216:1191:4","text":" @dev Returns true if `account` is a contract.\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 Among others, `isContract` will return false for the following\n types of addresses:\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 Furthermore, `isContract` will also return true if the target contract within\n the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n which only has an effect at the end of a transaction.\n ====\n [IMPORTANT]\n ====\n You shouldn't rely on `isContract` to protect against flash loan attacks!\n Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n constructor.\n ===="},"id":1105,"implemented":true,"kind":"function","modifiers":[],"name":"isContract","nameLocation":"1421:10:4","nodeType":"FunctionDefinition","parameters":{"id":1094,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1093,"mutability":"mutable","name":"account","nameLocation":"1440:7:4","nodeType":"VariableDeclaration","scope":1105,"src":"1432:15:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1092,"name":"address","nodeType":"ElementaryTypeName","src":"1432:7:4","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1431:17:4"},"returnParameters":{"id":1097,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1096,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1105,"src":"1472:4:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":1095,"name":"bool","nodeType":"ElementaryTypeName","src":"1472:4:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"1471:6:4"},"scope":1417,"src":"1412:320:4","stateMutability":"view","virtual":false,"visibility":"internal"},{"body":{"id":1138,"nodeType":"Block","src":"2718:241:4","statements":[{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1120,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"expression":{"arguments":[{"id":1116,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"2744:4:4","typeDescriptions":{"typeIdentifier":"t_contract$_Address_$1417","typeString":"library Address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_Address_$1417","typeString":"library Address"}],"id":1115,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2736:7:4","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":1114,"name":"address","nodeType":"ElementaryTypeName","src":"2736:7:4","typeDescriptions":{}}},"id":1117,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2736:13:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":1118,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"2750:7:4","memberName":"balance","nodeType":"MemberAccess","src":"2736:21:4","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">=","rightExpression":{"id":1119,"name":"amount","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1110,"src":"2761:6:4","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"2736:31:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"416464726573733a20696e73756666696369656e742062616c616e6365","id":1121,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2769:31:4","typeDescriptions":{"typeIdentifier":"t_stringliteral_5597a22abd0ef5332f8053862eb236db7590f17e2b93a53f63a103becfb561f9","typeString":"literal_string \"Address: insufficient balance\""},"value":"Address: insufficient balance"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_5597a22abd0ef5332f8053862eb236db7590f17e2b93a53f63a103becfb561f9","typeString":"literal_string \"Address: insufficient balance\""}],"id":1113,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"2728:7:4","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":1122,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2728:73:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":1123,"nodeType":"ExpressionStatement","src":"2728:73:4"},{"assignments":[1125,null],"declarations":[{"constant":false,"id":1125,"mutability":"mutable","name":"success","nameLocation":"2818:7:4","nodeType":"VariableDeclaration","scope":1138,"src":"2813:12:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":1124,"name":"bool","nodeType":"ElementaryTypeName","src":"2813:4:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"},null],"id":1132,"initialValue":{"arguments":[{"hexValue":"","id":1130,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2861:2:4","typeDescriptions":{"typeIdentifier":"t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","typeString":"literal_string \"\""},"value":""}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","typeString":"literal_string \"\""}],"expression":{"argumentTypes":[{"typeIdentifier":"t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","typeString":"literal_string \"\""}],"expression":{"id":1126,"name":"recipient","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1108,"src":"2831:9:4","typeDescriptions":{"typeIdentifier":"t_address_payable","typeString":"address payable"}},"id":1127,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"2841:4:4","memberName":"call","nodeType":"MemberAccess","src":"2831:14:4","typeDescriptions":{"typeIdentifier":"t_function_barecall_payable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$","typeString":"function (bytes memory) payable returns (bool,bytes memory)"}},"id":1129,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"names":["value"],"nodeType":"FunctionCallOptions","options":[{"id":1128,"name":"amount","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1110,"src":"2853:6:4","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"src":"2831:29:4","typeDescriptions":{"typeIdentifier":"t_function_barecall_payable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$value","typeString":"function (bytes memory) payable returns (bool,bytes memory)"}},"id":1131,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2831:33:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_bool_$_t_bytes_memory_ptr_$","typeString":"tuple(bool,bytes memory)"}},"nodeType":"VariableDeclarationStatement","src":"2812:52:4"},{"expression":{"arguments":[{"id":1134,"name":"success","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1125,"src":"2882:7:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"416464726573733a20756e61626c6520746f2073656e642076616c75652c20726563697069656e74206d61792068617665207265766572746564","id":1135,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2891:60:4","typeDescriptions":{"typeIdentifier":"t_stringliteral_51ddaa38748c0a1144620fb5bfe8edab31ea437571ad591a7734bbfd0429aeae","typeString":"literal_string \"Address: unable to send value, recipient may have reverted\""},"value":"Address: unable to send value, recipient may have reverted"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_51ddaa38748c0a1144620fb5bfe8edab31ea437571ad591a7734bbfd0429aeae","typeString":"literal_string \"Address: unable to send value, recipient may have reverted\""}],"id":1133,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"2874:7:4","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":1136,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2874:78:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":1137,"nodeType":"ExpressionStatement","src":"2874:78:4"}]},"documentation":{"id":1106,"nodeType":"StructuredDocumentation","src":"1738:904:4","text":" @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n `recipient`, forwarding all available gas and reverting on errors.\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 https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\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.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]."},"id":1139,"implemented":true,"kind":"function","modifiers":[],"name":"sendValue","nameLocation":"2656:9:4","nodeType":"FunctionDefinition","parameters":{"id":1111,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1108,"mutability":"mutable","name":"recipient","nameLocation":"2682:9:4","nodeType":"VariableDeclaration","scope":1139,"src":"2666:25:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address_payable","typeString":"address payable"},"typeName":{"id":1107,"name":"address","nodeType":"ElementaryTypeName","src":"2666:15:4","stateMutability":"payable","typeDescriptions":{"typeIdentifier":"t_address_payable","typeString":"address payable"}},"visibility":"internal"},{"constant":false,"id":1110,"mutability":"mutable","name":"amount","nameLocation":"2701:6:4","nodeType":"VariableDeclaration","scope":1139,"src":"2693:14:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1109,"name":"uint256","nodeType":"ElementaryTypeName","src":"2693:7:4","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2665:43:4"},"returnParameters":{"id":1112,"nodeType":"ParameterList","parameters":[],"src":"2718:0:4"},"scope":1417,"src":"2647:312:4","stateMutability":"nonpayable","virtual":false,"visibility":"internal"},{"body":{"id":1156,"nodeType":"Block","src":"3790:96:4","statements":[{"expression":{"arguments":[{"id":1150,"name":"target","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1142,"src":"3829:6:4","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":1151,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1144,"src":"3837:4:4","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},{"hexValue":"30","id":1152,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3843:1:4","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},{"hexValue":"416464726573733a206c6f772d6c6576656c2063616c6c206661696c6564","id":1153,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"3846:32:4","typeDescriptions":{"typeIdentifier":"t_stringliteral_24d7ab5d382116e64324f19950ca9340b8af1ddeb09a8d026e0a3c6a01dcc9df","typeString":"literal_string \"Address: low-level call failed\""},"value":"Address: low-level call failed"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"},{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},{"typeIdentifier":"t_stringliteral_24d7ab5d382116e64324f19950ca9340b8af1ddeb09a8d026e0a3c6a01dcc9df","typeString":"literal_string \"Address: low-level call failed\""}],"id":1149,"name":"functionCallWithValue","nodeType":"Identifier","overloadedDeclarations":[1197,1241],"referencedDeclaration":1241,"src":"3807:21:4","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_bytes_memory_ptr_$_t_uint256_$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (address,bytes memory,uint256,string memory) returns (bytes memory)"}},"id":1154,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"3807:72:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"functionReturnParameters":1148,"id":1155,"nodeType":"Return","src":"3800:79:4"}]},"documentation":{"id":1140,"nodeType":"StructuredDocumentation","src":"2965:731:4","text":" @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 If `target` reverts with a revert reason, it is bubbled up by this\n function (like regular Solidity function calls).\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 Requirements:\n - `target` must be a contract.\n - calling `target` with `data` must not revert.\n _Available since v3.1._"},"id":1157,"implemented":true,"kind":"function","modifiers":[],"name":"functionCall","nameLocation":"3710:12:4","nodeType":"FunctionDefinition","parameters":{"id":1145,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1142,"mutability":"mutable","name":"target","nameLocation":"3731:6:4","nodeType":"VariableDeclaration","scope":1157,"src":"3723:14:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1141,"name":"address","nodeType":"ElementaryTypeName","src":"3723:7:4","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1144,"mutability":"mutable","name":"data","nameLocation":"3752:4:4","nodeType":"VariableDeclaration","scope":1157,"src":"3739:17:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1143,"name":"bytes","nodeType":"ElementaryTypeName","src":"3739:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"3722:35:4"},"returnParameters":{"id":1148,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1147,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1157,"src":"3776:12:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1146,"name":"bytes","nodeType":"ElementaryTypeName","src":"3776:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"3775:14:4"},"scope":1417,"src":"3701:185:4","stateMutability":"nonpayable","virtual":false,"visibility":"internal"},{"body":{"id":1176,"nodeType":"Block","src":"4255:76:4","statements":[{"expression":{"arguments":[{"id":1170,"name":"target","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1160,"src":"4294:6:4","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":1171,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1162,"src":"4302:4:4","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},{"hexValue":"30","id":1172,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4308:1:4","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},{"id":1173,"name":"errorMessage","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1164,"src":"4311:12:4","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"},{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"id":1169,"name":"functionCallWithValue","nodeType":"Identifier","overloadedDeclarations":[1197,1241],"referencedDeclaration":1241,"src":"4272:21:4","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_bytes_memory_ptr_$_t_uint256_$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (address,bytes memory,uint256,string memory) returns (bytes memory)"}},"id":1174,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4272:52:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"functionReturnParameters":1168,"id":1175,"nodeType":"Return","src":"4265:59:4"}]},"documentation":{"id":1158,"nodeType":"StructuredDocumentation","src":"3892:211:4","text":" @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n `errorMessage` as a fallback revert reason when `target` reverts.\n _Available since v3.1._"},"id":1177,"implemented":true,"kind":"function","modifiers":[],"name":"functionCall","nameLocation":"4117:12:4","nodeType":"FunctionDefinition","parameters":{"id":1165,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1160,"mutability":"mutable","name":"target","nameLocation":"4147:6:4","nodeType":"VariableDeclaration","scope":1177,"src":"4139:14:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1159,"name":"address","nodeType":"ElementaryTypeName","src":"4139:7:4","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1162,"mutability":"mutable","name":"data","nameLocation":"4176:4:4","nodeType":"VariableDeclaration","scope":1177,"src":"4163:17:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1161,"name":"bytes","nodeType":"ElementaryTypeName","src":"4163:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"},{"constant":false,"id":1164,"mutability":"mutable","name":"errorMessage","nameLocation":"4204:12:4","nodeType":"VariableDeclaration","scope":1177,"src":"4190:26:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":1163,"name":"string","nodeType":"ElementaryTypeName","src":"4190:6:4","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4129:93:4"},"returnParameters":{"id":1168,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1167,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1177,"src":"4241:12:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1166,"name":"bytes","nodeType":"ElementaryTypeName","src":"4241:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"4240:14:4"},"scope":1417,"src":"4108:223:4","stateMutability":"nonpayable","virtual":false,"visibility":"internal"},{"body":{"id":1196,"nodeType":"Block","src":"4806:111:4","statements":[{"expression":{"arguments":[{"id":1190,"name":"target","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1180,"src":"4845:6:4","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":1191,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1182,"src":"4853:4:4","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},{"id":1192,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1184,"src":"4859:5:4","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"hexValue":"416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564","id":1193,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"4866:43:4","typeDescriptions":{"typeIdentifier":"t_stringliteral_88a4a0b5e975840320a0475d4027005235904fdb5ece94df156f3d717cb2dbfc","typeString":"literal_string \"Address: low-level call with value failed\""},"value":"Address: low-level call with value failed"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_stringliteral_88a4a0b5e975840320a0475d4027005235904fdb5ece94df156f3d717cb2dbfc","typeString":"literal_string \"Address: low-level call with value failed\""}],"id":1189,"name":"functionCallWithValue","nodeType":"Identifier","overloadedDeclarations":[1197,1241],"referencedDeclaration":1241,"src":"4823:21:4","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_bytes_memory_ptr_$_t_uint256_$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (address,bytes memory,uint256,string memory) returns (bytes memory)"}},"id":1194,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"4823:87:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"functionReturnParameters":1188,"id":1195,"nodeType":"Return","src":"4816:94:4"}]},"documentation":{"id":1178,"nodeType":"StructuredDocumentation","src":"4337:351:4","text":" @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n but also transferring `value` wei to `target`.\n Requirements:\n - the calling contract must have an ETH balance of at least `value`.\n - the called Solidity function must be `payable`.\n _Available since v3.1._"},"id":1197,"implemented":true,"kind":"function","modifiers":[],"name":"functionCallWithValue","nameLocation":"4702:21:4","nodeType":"FunctionDefinition","parameters":{"id":1185,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1180,"mutability":"mutable","name":"target","nameLocation":"4732:6:4","nodeType":"VariableDeclaration","scope":1197,"src":"4724:14:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1179,"name":"address","nodeType":"ElementaryTypeName","src":"4724:7:4","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1182,"mutability":"mutable","name":"data","nameLocation":"4753:4:4","nodeType":"VariableDeclaration","scope":1197,"src":"4740:17:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1181,"name":"bytes","nodeType":"ElementaryTypeName","src":"4740:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"},{"constant":false,"id":1184,"mutability":"mutable","name":"value","nameLocation":"4767:5:4","nodeType":"VariableDeclaration","scope":1197,"src":"4759:13:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1183,"name":"uint256","nodeType":"ElementaryTypeName","src":"4759:7:4","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"4723:50:4"},"returnParameters":{"id":1188,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1187,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1197,"src":"4792:12:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1186,"name":"bytes","nodeType":"ElementaryTypeName","src":"4792:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"4791:14:4"},"scope":1417,"src":"4693:224:4","stateMutability":"nonpayable","virtual":false,"visibility":"internal"},{"body":{"id":1240,"nodeType":"Block","src":"5344:267:4","statements":[{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1218,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"expression":{"arguments":[{"id":1214,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"5370:4:4","typeDescriptions":{"typeIdentifier":"t_contract$_Address_$1417","typeString":"library Address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_contract$_Address_$1417","typeString":"library Address"}],"id":1213,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"5362:7:4","typeDescriptions":{"typeIdentifier":"t_type$_t_address_$","typeString":"type(address)"},"typeName":{"id":1212,"name":"address","nodeType":"ElementaryTypeName","src":"5362:7:4","typeDescriptions":{}}},"id":1215,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5362:13:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":1216,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"5376:7:4","memberName":"balance","nodeType":"MemberAccess","src":"5362:21:4","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">=","rightExpression":{"id":1217,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1204,"src":"5387:5:4","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5362:30:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c","id":1219,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"5394:40:4","typeDescriptions":{"typeIdentifier":"t_stringliteral_565f1a77334fc4792800921178c71e4521acffab18ff9e7885b49377ee80ab4c","typeString":"literal_string \"Address: insufficient balance for call\""},"value":"Address: insufficient balance for call"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_565f1a77334fc4792800921178c71e4521acffab18ff9e7885b49377ee80ab4c","typeString":"literal_string \"Address: insufficient balance for call\""}],"id":1211,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"5354:7:4","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":1220,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5354:81:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":1221,"nodeType":"ExpressionStatement","src":"5354:81:4"},{"assignments":[1223,1225],"declarations":[{"constant":false,"id":1223,"mutability":"mutable","name":"success","nameLocation":"5451:7:4","nodeType":"VariableDeclaration","scope":1240,"src":"5446:12:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":1222,"name":"bool","nodeType":"ElementaryTypeName","src":"5446:4:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"},{"constant":false,"id":1225,"mutability":"mutable","name":"returndata","nameLocation":"5473:10:4","nodeType":"VariableDeclaration","scope":1240,"src":"5460:23:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1224,"name":"bytes","nodeType":"ElementaryTypeName","src":"5460:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"id":1232,"initialValue":{"arguments":[{"id":1230,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1202,"src":"5513:4:4","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"expression":{"id":1226,"name":"target","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1200,"src":"5487:6:4","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":1227,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"5494:4:4","memberName":"call","nodeType":"MemberAccess","src":"5487:11:4","typeDescriptions":{"typeIdentifier":"t_function_barecall_payable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$","typeString":"function (bytes memory) payable returns (bool,bytes memory)"}},"id":1229,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"names":["value"],"nodeType":"FunctionCallOptions","options":[{"id":1228,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1204,"src":"5506:5:4","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"src":"5487:25:4","typeDescriptions":{"typeIdentifier":"t_function_barecall_payable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$value","typeString":"function (bytes memory) payable returns (bool,bytes memory)"}},"id":1231,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5487:31:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_bool_$_t_bytes_memory_ptr_$","typeString":"tuple(bool,bytes memory)"}},"nodeType":"VariableDeclarationStatement","src":"5445:73:4"},{"expression":{"arguments":[{"id":1234,"name":"target","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1200,"src":"5562:6:4","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":1235,"name":"success","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1223,"src":"5570:7:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"id":1236,"name":"returndata","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1225,"src":"5579:10:4","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},{"id":1237,"name":"errorMessage","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1206,"src":"5591:12:4","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"id":1233,"name":"verifyCallResultFromTarget","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1372,"src":"5535:26:4","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_address_$_t_bool_$_t_bytes_memory_ptr_$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (address,bool,bytes memory,string memory) view returns (bytes memory)"}},"id":1238,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5535:69:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"functionReturnParameters":1210,"id":1239,"nodeType":"Return","src":"5528:76:4"}]},"documentation":{"id":1198,"nodeType":"StructuredDocumentation","src":"4923:237:4","text":" @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n with `errorMessage` as a fallback revert reason when `target` reverts.\n _Available since v3.1._"},"id":1241,"implemented":true,"kind":"function","modifiers":[],"name":"functionCallWithValue","nameLocation":"5174:21:4","nodeType":"FunctionDefinition","parameters":{"id":1207,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1200,"mutability":"mutable","name":"target","nameLocation":"5213:6:4","nodeType":"VariableDeclaration","scope":1241,"src":"5205:14:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1199,"name":"address","nodeType":"ElementaryTypeName","src":"5205:7:4","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1202,"mutability":"mutable","name":"data","nameLocation":"5242:4:4","nodeType":"VariableDeclaration","scope":1241,"src":"5229:17:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1201,"name":"bytes","nodeType":"ElementaryTypeName","src":"5229:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"},{"constant":false,"id":1204,"mutability":"mutable","name":"value","nameLocation":"5264:5:4","nodeType":"VariableDeclaration","scope":1241,"src":"5256:13:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1203,"name":"uint256","nodeType":"ElementaryTypeName","src":"5256:7:4","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1206,"mutability":"mutable","name":"errorMessage","nameLocation":"5293:12:4","nodeType":"VariableDeclaration","scope":1241,"src":"5279:26:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":1205,"name":"string","nodeType":"ElementaryTypeName","src":"5279:6:4","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"5195:116:4"},"returnParameters":{"id":1210,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1209,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1241,"src":"5330:12:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1208,"name":"bytes","nodeType":"ElementaryTypeName","src":"5330:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"5329:14:4"},"scope":1417,"src":"5165:446:4","stateMutability":"nonpayable","virtual":false,"visibility":"internal"},{"body":{"id":1257,"nodeType":"Block","src":"5888:97:4","statements":[{"expression":{"arguments":[{"id":1252,"name":"target","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1244,"src":"5924:6:4","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":1253,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1246,"src":"5932:4:4","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},{"hexValue":"416464726573733a206c6f772d6c6576656c207374617469632063616c6c206661696c6564","id":1254,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"5938:39:4","typeDescriptions":{"typeIdentifier":"t_stringliteral_90ec82aa826a536a4cbfae44ecfa384680faa9a4b77344bce96aa761ad904df0","typeString":"literal_string \"Address: low-level static call failed\""},"value":"Address: low-level static call failed"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"},{"typeIdentifier":"t_stringliteral_90ec82aa826a536a4cbfae44ecfa384680faa9a4b77344bce96aa761ad904df0","typeString":"literal_string \"Address: low-level static call failed\""}],"id":1251,"name":"functionStaticCall","nodeType":"Identifier","overloadedDeclarations":[1258,1287],"referencedDeclaration":1287,"src":"5905:18:4","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_address_$_t_bytes_memory_ptr_$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (address,bytes memory,string memory) view returns (bytes memory)"}},"id":1255,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"5905:73:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"functionReturnParameters":1250,"id":1256,"nodeType":"Return","src":"5898:80:4"}]},"documentation":{"id":1242,"nodeType":"StructuredDocumentation","src":"5617:166:4","text":" @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n but performing a static call.\n _Available since v3.3._"},"id":1258,"implemented":true,"kind":"function","modifiers":[],"name":"functionStaticCall","nameLocation":"5797:18:4","nodeType":"FunctionDefinition","parameters":{"id":1247,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1244,"mutability":"mutable","name":"target","nameLocation":"5824:6:4","nodeType":"VariableDeclaration","scope":1258,"src":"5816:14:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1243,"name":"address","nodeType":"ElementaryTypeName","src":"5816:7:4","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1246,"mutability":"mutable","name":"data","nameLocation":"5845:4:4","nodeType":"VariableDeclaration","scope":1258,"src":"5832:17:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1245,"name":"bytes","nodeType":"ElementaryTypeName","src":"5832:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"5815:35:4"},"returnParameters":{"id":1250,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1249,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1258,"src":"5874:12:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1248,"name":"bytes","nodeType":"ElementaryTypeName","src":"5874:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"5873:14:4"},"scope":1417,"src":"5788:197:4","stateMutability":"view","virtual":false,"visibility":"internal"},{"body":{"id":1286,"nodeType":"Block","src":"6327:168:4","statements":[{"assignments":[1271,1273],"declarations":[{"constant":false,"id":1271,"mutability":"mutable","name":"success","nameLocation":"6343:7:4","nodeType":"VariableDeclaration","scope":1286,"src":"6338:12:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":1270,"name":"bool","nodeType":"ElementaryTypeName","src":"6338:4:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"},{"constant":false,"id":1273,"mutability":"mutable","name":"returndata","nameLocation":"6365:10:4","nodeType":"VariableDeclaration","scope":1286,"src":"6352:23:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1272,"name":"bytes","nodeType":"ElementaryTypeName","src":"6352:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"id":1278,"initialValue":{"arguments":[{"id":1276,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1263,"src":"6397:4:4","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"expression":{"id":1274,"name":"target","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1261,"src":"6379:6:4","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":1275,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"6386:10:4","memberName":"staticcall","nodeType":"MemberAccess","src":"6379:17:4","typeDescriptions":{"typeIdentifier":"t_function_barestaticcall_view$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$","typeString":"function (bytes memory) view returns (bool,bytes memory)"}},"id":1277,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"6379:23:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_bool_$_t_bytes_memory_ptr_$","typeString":"tuple(bool,bytes memory)"}},"nodeType":"VariableDeclarationStatement","src":"6337:65:4"},{"expression":{"arguments":[{"id":1280,"name":"target","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1261,"src":"6446:6:4","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":1281,"name":"success","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1271,"src":"6454:7:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"id":1282,"name":"returndata","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1273,"src":"6463:10:4","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},{"id":1283,"name":"errorMessage","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1265,"src":"6475:12:4","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"id":1279,"name":"verifyCallResultFromTarget","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1372,"src":"6419:26:4","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_address_$_t_bool_$_t_bytes_memory_ptr_$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (address,bool,bytes memory,string memory) view returns (bytes memory)"}},"id":1284,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"6419:69:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"functionReturnParameters":1269,"id":1285,"nodeType":"Return","src":"6412:76:4"}]},"documentation":{"id":1259,"nodeType":"StructuredDocumentation","src":"5991:173:4","text":" @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n but performing a static call.\n _Available since v3.3._"},"id":1287,"implemented":true,"kind":"function","modifiers":[],"name":"functionStaticCall","nameLocation":"6178:18:4","nodeType":"FunctionDefinition","parameters":{"id":1266,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1261,"mutability":"mutable","name":"target","nameLocation":"6214:6:4","nodeType":"VariableDeclaration","scope":1287,"src":"6206:14:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1260,"name":"address","nodeType":"ElementaryTypeName","src":"6206:7:4","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1263,"mutability":"mutable","name":"data","nameLocation":"6243:4:4","nodeType":"VariableDeclaration","scope":1287,"src":"6230:17:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1262,"name":"bytes","nodeType":"ElementaryTypeName","src":"6230:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"},{"constant":false,"id":1265,"mutability":"mutable","name":"errorMessage","nameLocation":"6271:12:4","nodeType":"VariableDeclaration","scope":1287,"src":"6257:26:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":1264,"name":"string","nodeType":"ElementaryTypeName","src":"6257:6:4","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"6196:93:4"},"returnParameters":{"id":1269,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1268,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1287,"src":"6313:12:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1267,"name":"bytes","nodeType":"ElementaryTypeName","src":"6313:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"6312:14:4"},"scope":1417,"src":"6169:326:4","stateMutability":"view","virtual":false,"visibility":"internal"},{"body":{"id":1303,"nodeType":"Block","src":"6771:101:4","statements":[{"expression":{"arguments":[{"id":1298,"name":"target","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1290,"src":"6809:6:4","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":1299,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1292,"src":"6817:4:4","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},{"hexValue":"416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564","id":1300,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"6823:41:4","typeDescriptions":{"typeIdentifier":"t_stringliteral_9fdcd12e4b726339b32a442b0a448365d5d85c96b2d2cff917b4f66c63110398","typeString":"literal_string \"Address: low-level delegate call failed\""},"value":"Address: low-level delegate call failed"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"},{"typeIdentifier":"t_stringliteral_9fdcd12e4b726339b32a442b0a448365d5d85c96b2d2cff917b4f66c63110398","typeString":"literal_string \"Address: low-level delegate call failed\""}],"id":1297,"name":"functionDelegateCall","nodeType":"Identifier","overloadedDeclarations":[1304,1333],"referencedDeclaration":1333,"src":"6788:20:4","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_bytes_memory_ptr_$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (address,bytes memory,string memory) returns (bytes memory)"}},"id":1301,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"6788:77:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"functionReturnParameters":1296,"id":1302,"nodeType":"Return","src":"6781:84:4"}]},"documentation":{"id":1288,"nodeType":"StructuredDocumentation","src":"6501:168:4","text":" @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n but performing a delegate call.\n _Available since v3.4._"},"id":1304,"implemented":true,"kind":"function","modifiers":[],"name":"functionDelegateCall","nameLocation":"6683:20:4","nodeType":"FunctionDefinition","parameters":{"id":1293,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1290,"mutability":"mutable","name":"target","nameLocation":"6712:6:4","nodeType":"VariableDeclaration","scope":1304,"src":"6704:14:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1289,"name":"address","nodeType":"ElementaryTypeName","src":"6704:7:4","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1292,"mutability":"mutable","name":"data","nameLocation":"6733:4:4","nodeType":"VariableDeclaration","scope":1304,"src":"6720:17:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1291,"name":"bytes","nodeType":"ElementaryTypeName","src":"6720:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"6703:35:4"},"returnParameters":{"id":1296,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1295,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1304,"src":"6757:12:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1294,"name":"bytes","nodeType":"ElementaryTypeName","src":"6757:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"6756:14:4"},"scope":1417,"src":"6674:198:4","stateMutability":"nonpayable","virtual":false,"visibility":"internal"},{"body":{"id":1332,"nodeType":"Block","src":"7213:170:4","statements":[{"assignments":[1317,1319],"declarations":[{"constant":false,"id":1317,"mutability":"mutable","name":"success","nameLocation":"7229:7:4","nodeType":"VariableDeclaration","scope":1332,"src":"7224:12:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":1316,"name":"bool","nodeType":"ElementaryTypeName","src":"7224:4:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"},{"constant":false,"id":1319,"mutability":"mutable","name":"returndata","nameLocation":"7251:10:4","nodeType":"VariableDeclaration","scope":1332,"src":"7238:23:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1318,"name":"bytes","nodeType":"ElementaryTypeName","src":"7238:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"id":1324,"initialValue":{"arguments":[{"id":1322,"name":"data","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1309,"src":"7285:4:4","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"expression":{"id":1320,"name":"target","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1307,"src":"7265:6:4","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"id":1321,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"7272:12:4","memberName":"delegatecall","nodeType":"MemberAccess","src":"7265:19:4","typeDescriptions":{"typeIdentifier":"t_function_baredelegatecall_nonpayable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$","typeString":"function (bytes memory) returns (bool,bytes memory)"}},"id":1323,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"7265:25:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$_t_bool_$_t_bytes_memory_ptr_$","typeString":"tuple(bool,bytes memory)"}},"nodeType":"VariableDeclarationStatement","src":"7223:67:4"},{"expression":{"arguments":[{"id":1326,"name":"target","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1307,"src":"7334:6:4","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":1327,"name":"success","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1317,"src":"7342:7:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"id":1328,"name":"returndata","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1319,"src":"7351:10:4","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},{"id":1329,"name":"errorMessage","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1311,"src":"7363:12:4","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"id":1325,"name":"verifyCallResultFromTarget","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1372,"src":"7307:26:4","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_address_$_t_bool_$_t_bytes_memory_ptr_$_t_string_memory_ptr_$returns$_t_bytes_memory_ptr_$","typeString":"function (address,bool,bytes memory,string memory) view returns (bytes memory)"}},"id":1330,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"7307:69:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"functionReturnParameters":1315,"id":1331,"nodeType":"Return","src":"7300:76:4"}]},"documentation":{"id":1305,"nodeType":"StructuredDocumentation","src":"6878:175:4","text":" @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n but performing a delegate call.\n _Available since v3.4._"},"id":1333,"implemented":true,"kind":"function","modifiers":[],"name":"functionDelegateCall","nameLocation":"7067:20:4","nodeType":"FunctionDefinition","parameters":{"id":1312,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1307,"mutability":"mutable","name":"target","nameLocation":"7105:6:4","nodeType":"VariableDeclaration","scope":1333,"src":"7097:14:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1306,"name":"address","nodeType":"ElementaryTypeName","src":"7097:7:4","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1309,"mutability":"mutable","name":"data","nameLocation":"7134:4:4","nodeType":"VariableDeclaration","scope":1333,"src":"7121:17:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1308,"name":"bytes","nodeType":"ElementaryTypeName","src":"7121:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"},{"constant":false,"id":1311,"mutability":"mutable","name":"errorMessage","nameLocation":"7162:12:4","nodeType":"VariableDeclaration","scope":1333,"src":"7148:26:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":1310,"name":"string","nodeType":"ElementaryTypeName","src":"7148:6:4","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"7087:93:4"},"returnParameters":{"id":1315,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1314,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1333,"src":"7199:12:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1313,"name":"bytes","nodeType":"ElementaryTypeName","src":"7199:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"7198:14:4"},"scope":1417,"src":"7058:325:4","stateMutability":"nonpayable","virtual":false,"visibility":"internal"},{"body":{"id":1371,"nodeType":"Block","src":"7865:434:4","statements":[{"condition":{"id":1347,"name":"success","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1338,"src":"7879:7:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"falseBody":{"id":1369,"nodeType":"Block","src":"8235:58:4","statements":[{"expression":{"arguments":[{"id":1365,"name":"returndata","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1340,"src":"8257:10:4","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},{"id":1366,"name":"errorMessage","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1342,"src":"8269:12:4","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"id":1364,"name":"_revert","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1416,"src":"8249:7:4","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (bytes memory,string memory) pure"}},"id":1367,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"8249:33:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":1368,"nodeType":"ExpressionStatement","src":"8249:33:4"}]},"id":1370,"nodeType":"IfStatement","src":"7875:418:4","trueBody":{"id":1363,"nodeType":"Block","src":"7888:341:4","statements":[{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1351,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"expression":{"id":1348,"name":"returndata","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1340,"src":"7906:10:4","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":1349,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"7917:6:4","memberName":"length","nodeType":"MemberAccess","src":"7906:17:4","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"30","id":1350,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"7927:1:4","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"7906:22:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":1360,"nodeType":"IfStatement","src":"7902:286:4","trueBody":{"id":1359,"nodeType":"Block","src":"7930:258:4","statements":[{"expression":{"arguments":[{"arguments":[{"id":1354,"name":"target","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1336,"src":"8132:6:4","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":1353,"name":"isContract","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1105,"src":"8121:10:4","typeDescriptions":{"typeIdentifier":"t_function_internal_view$_t_address_$returns$_t_bool_$","typeString":"function (address) view returns (bool)"}},"id":1355,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"8121:18:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374","id":1356,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"8141:31:4","typeDescriptions":{"typeIdentifier":"t_stringliteral_cc2e4e38850b7c0a3e942cfed89b71c77302df25bcb2ec297a0c4ff9ff6b90ad","typeString":"literal_string \"Address: call to non-contract\""},"value":"Address: call to non-contract"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_cc2e4e38850b7c0a3e942cfed89b71c77302df25bcb2ec297a0c4ff9ff6b90ad","typeString":"literal_string \"Address: call to non-contract\""}],"id":1352,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"8113:7:4","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":1357,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"8113:60:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":1358,"nodeType":"ExpressionStatement","src":"8113:60:4"}]}},{"expression":{"id":1361,"name":"returndata","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1340,"src":"8208:10:4","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"functionReturnParameters":1346,"id":1362,"nodeType":"Return","src":"8201:17:4"}]}}]},"documentation":{"id":1334,"nodeType":"StructuredDocumentation","src":"7389:277:4","text":" @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n _Available since v4.8._"},"id":1372,"implemented":true,"kind":"function","modifiers":[],"name":"verifyCallResultFromTarget","nameLocation":"7680:26:4","nodeType":"FunctionDefinition","parameters":{"id":1343,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1336,"mutability":"mutable","name":"target","nameLocation":"7724:6:4","nodeType":"VariableDeclaration","scope":1372,"src":"7716:14:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1335,"name":"address","nodeType":"ElementaryTypeName","src":"7716:7:4","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":1338,"mutability":"mutable","name":"success","nameLocation":"7745:7:4","nodeType":"VariableDeclaration","scope":1372,"src":"7740:12:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":1337,"name":"bool","nodeType":"ElementaryTypeName","src":"7740:4:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"},{"constant":false,"id":1340,"mutability":"mutable","name":"returndata","nameLocation":"7775:10:4","nodeType":"VariableDeclaration","scope":1372,"src":"7762:23:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1339,"name":"bytes","nodeType":"ElementaryTypeName","src":"7762:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"},{"constant":false,"id":1342,"mutability":"mutable","name":"errorMessage","nameLocation":"7809:12:4","nodeType":"VariableDeclaration","scope":1372,"src":"7795:26:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":1341,"name":"string","nodeType":"ElementaryTypeName","src":"7795:6:4","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"7706:121:4"},"returnParameters":{"id":1346,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1345,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1372,"src":"7851:12:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1344,"name":"bytes","nodeType":"ElementaryTypeName","src":"7851:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"7850:14:4"},"scope":1417,"src":"7671:628:4","stateMutability":"view","virtual":false,"visibility":"internal"},{"body":{"id":1395,"nodeType":"Block","src":"8680:135:4","statements":[{"condition":{"id":1384,"name":"success","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1375,"src":"8694:7:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"falseBody":{"id":1393,"nodeType":"Block","src":"8751:58:4","statements":[{"expression":{"arguments":[{"id":1389,"name":"returndata","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1377,"src":"8773:10:4","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},{"id":1390,"name":"errorMessage","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1379,"src":"8785:12:4","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"id":1388,"name":"_revert","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1416,"src":"8765:7:4","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_bytes_memory_ptr_$_t_string_memory_ptr_$returns$__$","typeString":"function (bytes memory,string memory) pure"}},"id":1391,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"8765:33:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":1392,"nodeType":"ExpressionStatement","src":"8765:33:4"}]},"id":1394,"nodeType":"IfStatement","src":"8690:119:4","trueBody":{"id":1387,"nodeType":"Block","src":"8703:42:4","statements":[{"expression":{"id":1385,"name":"returndata","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1377,"src":"8724:10:4","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"functionReturnParameters":1383,"id":1386,"nodeType":"Return","src":"8717:17:4"}]}}]},"documentation":{"id":1373,"nodeType":"StructuredDocumentation","src":"8305:210:4","text":" @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n revert reason or using the provided one.\n _Available since v4.3._"},"id":1396,"implemented":true,"kind":"function","modifiers":[],"name":"verifyCallResult","nameLocation":"8529:16:4","nodeType":"FunctionDefinition","parameters":{"id":1380,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1375,"mutability":"mutable","name":"success","nameLocation":"8560:7:4","nodeType":"VariableDeclaration","scope":1396,"src":"8555:12:4","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":1374,"name":"bool","nodeType":"ElementaryTypeName","src":"8555:4:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"},{"constant":false,"id":1377,"mutability":"mutable","name":"returndata","nameLocation":"8590:10:4","nodeType":"VariableDeclaration","scope":1396,"src":"8577:23:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1376,"name":"bytes","nodeType":"ElementaryTypeName","src":"8577:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"},{"constant":false,"id":1379,"mutability":"mutable","name":"errorMessage","nameLocation":"8624:12:4","nodeType":"VariableDeclaration","scope":1396,"src":"8610:26:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":1378,"name":"string","nodeType":"ElementaryTypeName","src":"8610:6:4","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"8545:97:4"},"returnParameters":{"id":1383,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1382,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1396,"src":"8666:12:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1381,"name":"bytes","nodeType":"ElementaryTypeName","src":"8666:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"8665:14:4"},"scope":1417,"src":"8520:295:4","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":1415,"nodeType":"Block","src":"8904:457:4","statements":[{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1406,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"expression":{"id":1403,"name":"returndata","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1398,"src":"8980:10:4","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":1404,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"8991:6:4","memberName":"length","nodeType":"MemberAccess","src":"8980:17:4","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"hexValue":"30","id":1405,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9000:1:4","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"8980:21:4","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"falseBody":{"id":1413,"nodeType":"Block","src":"9310:45:4","statements":[{"expression":{"arguments":[{"id":1410,"name":"errorMessage","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1400,"src":"9331:12:4","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"id":1409,"name":"revert","nodeType":"Identifier","overloadedDeclarations":[-19,-19],"referencedDeclaration":-19,"src":"9324:6:4","typeDescriptions":{"typeIdentifier":"t_function_revert_pure$_t_string_memory_ptr_$returns$__$","typeString":"function (string memory) pure"}},"id":1411,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"9324:20:4","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":1412,"nodeType":"ExpressionStatement","src":"9324:20:4"}]},"id":1414,"nodeType":"IfStatement","src":"8976:379:4","trueBody":{"id":1408,"nodeType":"Block","src":"9003:301:4","statements":[{"AST":{"nodeType":"YulBlock","src":"9161:133:4","statements":[{"nodeType":"YulVariableDeclaration","src":"9179:40:4","value":{"arguments":[{"name":"returndata","nodeType":"YulIdentifier","src":"9208:10:4"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"9202:5:4"},"nodeType":"YulFunctionCall","src":"9202:17:4"},"variables":[{"name":"returndata_size","nodeType":"YulTypedName","src":"9183:15:4","type":""}]},{"expression":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9247:2:4","type":"","value":"32"},{"name":"returndata","nodeType":"YulIdentifier","src":"9251:10:4"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9243:3:4"},"nodeType":"YulFunctionCall","src":"9243:19:4"},{"name":"returndata_size","nodeType":"YulIdentifier","src":"9264:15:4"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"9236:6:4"},"nodeType":"YulFunctionCall","src":"9236:44:4"},"nodeType":"YulExpressionStatement","src":"9236:44:4"}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":1398,"isOffset":false,"isSlot":false,"src":"9208:10:4","valueSize":1},{"declaration":1398,"isOffset":false,"isSlot":false,"src":"9251:10:4","valueSize":1}],"id":1407,"nodeType":"InlineAssembly","src":"9152:142:4"}]}}]},"id":1416,"implemented":true,"kind":"function","modifiers":[],"name":"_revert","nameLocation":"8830:7:4","nodeType":"FunctionDefinition","parameters":{"id":1401,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1398,"mutability":"mutable","name":"returndata","nameLocation":"8851:10:4","nodeType":"VariableDeclaration","scope":1416,"src":"8838:23:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1397,"name":"bytes","nodeType":"ElementaryTypeName","src":"8838:5:4","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"},{"constant":false,"id":1400,"mutability":"mutable","name":"errorMessage","nameLocation":"8877:12:4","nodeType":"VariableDeclaration","scope":1416,"src":"8863:26:4","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":1399,"name":"string","nodeType":"ElementaryTypeName","src":"8863:6:4","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"8837:53:4"},"returnParameters":{"id":1402,"nodeType":"ParameterList","parameters":[],"src":"8904:0:4"},"scope":1417,"src":"8821:540:4","stateMutability":"pure","virtual":false,"visibility":"private"}],"scope":1418,"src":"194:9169:4","usedErrors":[]}],"src":"101:9263:4"},"id":4},"@openzeppelin/contracts/utils/Context.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/utils/Context.sol","exportedSymbols":{"Context":[1439]},"id":1440,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":1419,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"86:23:5"},{"abstract":true,"baseContracts":[],"canonicalName":"Context","contractDependencies":[],"contractKind":"contract","documentation":{"id":1420,"nodeType":"StructuredDocumentation","src":"111:496:5","text":" @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 This contract is only required for intermediate, library-like contracts."},"fullyImplemented":true,"id":1439,"linearizedBaseContracts":[1439],"name":"Context","nameLocation":"626:7:5","nodeType":"ContractDefinition","nodes":[{"body":{"id":1428,"nodeType":"Block","src":"702:34:5","statements":[{"expression":{"expression":{"id":1425,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"719:3:5","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":1426,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"723:6:5","memberName":"sender","nodeType":"MemberAccess","src":"719:10:5","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"functionReturnParameters":1424,"id":1427,"nodeType":"Return","src":"712:17:5"}]},"id":1429,"implemented":true,"kind":"function","modifiers":[],"name":"_msgSender","nameLocation":"649:10:5","nodeType":"FunctionDefinition","parameters":{"id":1421,"nodeType":"ParameterList","parameters":[],"src":"659:2:5"},"returnParameters":{"id":1424,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1423,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1429,"src":"693:7:5","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1422,"name":"address","nodeType":"ElementaryTypeName","src":"693:7:5","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"692:9:5"},"scope":1439,"src":"640:96:5","stateMutability":"view","virtual":true,"visibility":"internal"},{"body":{"id":1437,"nodeType":"Block","src":"809:32:5","statements":[{"expression":{"expression":{"id":1434,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"826:3:5","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":1435,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"830:4:5","memberName":"data","nodeType":"MemberAccess","src":"826:8:5","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes calldata"}},"functionReturnParameters":1433,"id":1436,"nodeType":"Return","src":"819:15:5"}]},"id":1438,"implemented":true,"kind":"function","modifiers":[],"name":"_msgData","nameLocation":"751:8:5","nodeType":"FunctionDefinition","parameters":{"id":1430,"nodeType":"ParameterList","parameters":[],"src":"759:2:5"},"returnParameters":{"id":1433,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1432,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1438,"src":"793:14:5","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":1431,"name":"bytes","nodeType":"ElementaryTypeName","src":"793:5:5","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"792:16:5"},"scope":1439,"src":"742:99:5","stateMutability":"view","virtual":true,"visibility":"internal"}],"scope":1440,"src":"608:235:5","usedErrors":[]}],"src":"86:758:5"},"id":5},"@openzeppelin/contracts/utils/Strings.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/utils/Strings.sol","exportedSymbols":{"Math":[2570],"SignedMath":[2675],"Strings":[1668]},"id":1669,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":1441,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"101:23:6"},{"absolutePath":"@openzeppelin/contracts/utils/math/Math.sol","file":"./math/Math.sol","id":1442,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":1669,"sourceUnit":2571,"src":"126:25:6","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/utils/math/SignedMath.sol","file":"./math/SignedMath.sol","id":1443,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":1669,"sourceUnit":2676,"src":"152:31:6","symbolAliases":[],"unitAlias":""},{"abstract":false,"baseContracts":[],"canonicalName":"Strings","contractDependencies":[],"contractKind":"library","documentation":{"id":1444,"nodeType":"StructuredDocumentation","src":"185:34:6","text":" @dev String operations."},"fullyImplemented":true,"id":1668,"linearizedBaseContracts":[1668],"name":"Strings","nameLocation":"228:7:6","nodeType":"ContractDefinition","nodes":[{"constant":true,"id":1447,"mutability":"constant","name":"_SYMBOLS","nameLocation":"267:8:6","nodeType":"VariableDeclaration","scope":1668,"src":"242:54:6","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes16","typeString":"bytes16"},"typeName":{"id":1445,"name":"bytes16","nodeType":"ElementaryTypeName","src":"242:7:6","typeDescriptions":{"typeIdentifier":"t_bytes16","typeString":"bytes16"}},"value":{"hexValue":"30313233343536373839616263646566","id":1446,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"278:18:6","typeDescriptions":{"typeIdentifier":"t_stringliteral_cb29997ed99ead0db59ce4d12b7d3723198c827273e5796737c926d78019c39f","typeString":"literal_string \"0123456789abcdef\""},"value":"0123456789abcdef"},"visibility":"private"},{"constant":true,"id":1450,"mutability":"constant","name":"_ADDRESS_LENGTH","nameLocation":"325:15:6","nodeType":"VariableDeclaration","scope":1668,"src":"302:43:6","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"},"typeName":{"id":1448,"name":"uint8","nodeType":"ElementaryTypeName","src":"302:5:6","typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"}},"value":{"hexValue":"3230","id":1449,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"343:2:6","typeDescriptions":{"typeIdentifier":"t_rational_20_by_1","typeString":"int_const 20"},"value":"20"},"visibility":"private"},{"body":{"id":1497,"nodeType":"Block","src":"518:625:6","statements":[{"id":1496,"nodeType":"UncheckedBlock","src":"528:609:6","statements":[{"assignments":[1459],"declarations":[{"constant":false,"id":1459,"mutability":"mutable","name":"length","nameLocation":"560:6:6","nodeType":"VariableDeclaration","scope":1496,"src":"552:14:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1458,"name":"uint256","nodeType":"ElementaryTypeName","src":"552:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":1466,"initialValue":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1465,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[{"id":1462,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1453,"src":"580:5:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":1460,"name":"Math","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2570,"src":"569:4:6","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Math_$2570_$","typeString":"type(library Math)"}},"id":1461,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"574:5:6","memberName":"log10","nodeType":"MemberAccess","referencedDeclaration":2407,"src":"569:10:6","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_uint256_$returns$_t_uint256_$","typeString":"function (uint256) pure returns (uint256)"}},"id":1463,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"569:17:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"hexValue":"31","id":1464,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"589:1:6","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"569:21:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"552:38:6"},{"assignments":[1468],"declarations":[{"constant":false,"id":1468,"mutability":"mutable","name":"buffer","nameLocation":"618:6:6","nodeType":"VariableDeclaration","scope":1496,"src":"604:20:6","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":1467,"name":"string","nodeType":"ElementaryTypeName","src":"604:6:6","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"id":1473,"initialValue":{"arguments":[{"id":1471,"name":"length","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1459,"src":"638:6:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":1470,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"NewExpression","src":"627:10:6","typeDescriptions":{"typeIdentifier":"t_function_objectcreation_pure$_t_uint256_$returns$_t_string_memory_ptr_$","typeString":"function (uint256) pure returns (string memory)"},"typeName":{"id":1469,"name":"string","nodeType":"ElementaryTypeName","src":"631:6:6","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}}},"id":1472,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"627:18:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},"nodeType":"VariableDeclarationStatement","src":"604:41:6"},{"assignments":[1475],"declarations":[{"constant":false,"id":1475,"mutability":"mutable","name":"ptr","nameLocation":"667:3:6","nodeType":"VariableDeclaration","scope":1496,"src":"659:11:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1474,"name":"uint256","nodeType":"ElementaryTypeName","src":"659:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":1476,"nodeType":"VariableDeclarationStatement","src":"659:11:6"},{"AST":{"nodeType":"YulBlock","src":"740:67:6","statements":[{"nodeType":"YulAssignment","src":"758:35:6","value":{"arguments":[{"name":"buffer","nodeType":"YulIdentifier","src":"769:6:6"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"781:2:6","type":"","value":"32"},{"name":"length","nodeType":"YulIdentifier","src":"785:6:6"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"777:3:6"},"nodeType":"YulFunctionCall","src":"777:15:6"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"765:3:6"},"nodeType":"YulFunctionCall","src":"765:28:6"},"variableNames":[{"name":"ptr","nodeType":"YulIdentifier","src":"758:3:6"}]}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":1468,"isOffset":false,"isSlot":false,"src":"769:6:6","valueSize":1},{"declaration":1459,"isOffset":false,"isSlot":false,"src":"785:6:6","valueSize":1},{"declaration":1475,"isOffset":false,"isSlot":false,"src":"758:3:6","valueSize":1}],"id":1477,"nodeType":"InlineAssembly","src":"731:76:6"},{"body":{"id":1492,"nodeType":"Block","src":"833:267:6","statements":[{"expression":{"id":1480,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"--","prefix":false,"src":"851:5:6","subExpression":{"id":1479,"name":"ptr","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1475,"src":"851:3:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":1481,"nodeType":"ExpressionStatement","src":"851:5:6"},{"AST":{"nodeType":"YulBlock","src":"934:84:6","statements":[{"expression":{"arguments":[{"name":"ptr","nodeType":"YulIdentifier","src":"964:3:6"},{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"978:5:6"},{"kind":"number","nodeType":"YulLiteral","src":"985:2:6","type":"","value":"10"}],"functionName":{"name":"mod","nodeType":"YulIdentifier","src":"974:3:6"},"nodeType":"YulFunctionCall","src":"974:14:6"},{"name":"_SYMBOLS","nodeType":"YulIdentifier","src":"990:8:6"}],"functionName":{"name":"byte","nodeType":"YulIdentifier","src":"969:4:6"},"nodeType":"YulFunctionCall","src":"969:30:6"}],"functionName":{"name":"mstore8","nodeType":"YulIdentifier","src":"956:7:6"},"nodeType":"YulFunctionCall","src":"956:44:6"},"nodeType":"YulExpressionStatement","src":"956:44:6"}]},"documentation":"@solidity memory-safe-assembly","evmVersion":"london","externalReferences":[{"declaration":1447,"isOffset":false,"isSlot":false,"src":"990:8:6","valueSize":1},{"declaration":1475,"isOffset":false,"isSlot":false,"src":"964:3:6","valueSize":1},{"declaration":1453,"isOffset":false,"isSlot":false,"src":"978:5:6","valueSize":1}],"id":1482,"nodeType":"InlineAssembly","src":"925:93:6"},{"expression":{"id":1485,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":1483,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1453,"src":"1035:5:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"/=","rightHandSide":{"hexValue":"3130","id":1484,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"1044:2:6","typeDescriptions":{"typeIdentifier":"t_rational_10_by_1","typeString":"int_const 10"},"value":"10"},"src":"1035:11:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":1486,"nodeType":"ExpressionStatement","src":"1035:11:6"},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1489,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1487,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1453,"src":"1068:5:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"30","id":1488,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"1077:1:6","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"1068:10:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":1491,"nodeType":"IfStatement","src":"1064:21:6","trueBody":{"id":1490,"nodeType":"Break","src":"1080:5:6"}}]},"condition":{"hexValue":"74727565","id":1478,"isConstant":false,"isLValue":false,"isPure":true,"kind":"bool","lValueRequested":false,"nodeType":"Literal","src":"827:4:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"value":"true"},"id":1493,"nodeType":"WhileStatement","src":"820:280:6"},{"expression":{"id":1494,"name":"buffer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1468,"src":"1120:6:6","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},"functionReturnParameters":1457,"id":1495,"nodeType":"Return","src":"1113:13:6"}]}]},"documentation":{"id":1451,"nodeType":"StructuredDocumentation","src":"352:90:6","text":" @dev Converts a `uint256` to its ASCII `string` decimal representation."},"id":1498,"implemented":true,"kind":"function","modifiers":[],"name":"toString","nameLocation":"456:8:6","nodeType":"FunctionDefinition","parameters":{"id":1454,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1453,"mutability":"mutable","name":"value","nameLocation":"473:5:6","nodeType":"VariableDeclaration","scope":1498,"src":"465:13:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1452,"name":"uint256","nodeType":"ElementaryTypeName","src":"465:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"464:15:6"},"returnParameters":{"id":1457,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1456,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1498,"src":"503:13:6","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":1455,"name":"string","nodeType":"ElementaryTypeName","src":"503:6:6","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"502:15:6"},"scope":1668,"src":"447:696:6","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":1525,"nodeType":"Block","src":"1313:103:6","statements":[{"expression":{"arguments":[{"arguments":[{"condition":{"commonType":{"typeIdentifier":"t_int256","typeString":"int256"},"id":1512,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1510,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1501,"src":"1354:5:6","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"nodeType":"BinaryOperation","operator":"<","rightExpression":{"hexValue":"30","id":1511,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"1362:1:6","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"1354:9:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"falseExpression":{"hexValue":"","id":1514,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1372:2:6","typeDescriptions":{"typeIdentifier":"t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","typeString":"literal_string \"\""},"value":""},"id":1515,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"Conditional","src":"1354:20:6","trueExpression":{"hexValue":"2d","id":1513,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1366:3:6","typeDescriptions":{"typeIdentifier":"t_stringliteral_d3b8281179950f98149eefdb158d0e1acb56f56e8e343aa9fefafa7e36959561","typeString":"literal_string \"-\""},"value":"-"},"typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"arguments":[{"arguments":[{"id":1519,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1501,"src":"1400:5:6","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_int256","typeString":"int256"}],"expression":{"id":1517,"name":"SignedMath","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2675,"src":"1385:10:6","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_SignedMath_$2675_$","typeString":"type(library SignedMath)"}},"id":1518,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"1396:3:6","memberName":"abs","nodeType":"MemberAccess","referencedDeclaration":2674,"src":"1385:14:6","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_int256_$returns$_t_uint256_$","typeString":"function (int256) pure returns (uint256)"}},"id":1520,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1385:21:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":1516,"name":"toString","nodeType":"Identifier","overloadedDeclarations":[1498,1526],"referencedDeclaration":1498,"src":"1376:8:6","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_uint256_$returns$_t_string_memory_ptr_$","typeString":"function (uint256) pure returns (string memory)"}},"id":1521,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1376:31:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"},{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"expression":{"id":1508,"name":"abi","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-1,"src":"1337:3:6","typeDescriptions":{"typeIdentifier":"t_magic_abi","typeString":"abi"}},"id":1509,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"1341:12:6","memberName":"encodePacked","nodeType":"MemberAccess","src":"1337:16:6","typeDescriptions":{"typeIdentifier":"t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$","typeString":"function () pure returns (bytes memory)"}},"id":1522,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1337:71:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":1507,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"1330:6:6","typeDescriptions":{"typeIdentifier":"t_type$_t_string_storage_ptr_$","typeString":"type(string storage pointer)"},"typeName":{"id":1506,"name":"string","nodeType":"ElementaryTypeName","src":"1330:6:6","typeDescriptions":{}}},"id":1523,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1330:79:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},"functionReturnParameters":1505,"id":1524,"nodeType":"Return","src":"1323:86:6"}]},"documentation":{"id":1499,"nodeType":"StructuredDocumentation","src":"1149:89:6","text":" @dev Converts a `int256` to its ASCII `string` decimal representation."},"id":1526,"implemented":true,"kind":"function","modifiers":[],"name":"toString","nameLocation":"1252:8:6","nodeType":"FunctionDefinition","parameters":{"id":1502,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1501,"mutability":"mutable","name":"value","nameLocation":"1268:5:6","nodeType":"VariableDeclaration","scope":1526,"src":"1261:12:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"},"typeName":{"id":1500,"name":"int256","nodeType":"ElementaryTypeName","src":"1261:6:6","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"visibility":"internal"}],"src":"1260:14:6"},"returnParameters":{"id":1505,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1504,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1526,"src":"1298:13:6","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":1503,"name":"string","nodeType":"ElementaryTypeName","src":"1298:6:6","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1297:15:6"},"scope":1668,"src":"1243:173:6","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":1545,"nodeType":"Block","src":"1595:100:6","statements":[{"id":1544,"nodeType":"UncheckedBlock","src":"1605:84:6","statements":[{"expression":{"arguments":[{"id":1535,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1529,"src":"1648:5:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1541,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[{"id":1538,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1529,"src":"1667:5:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":1536,"name":"Math","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2570,"src":"1655:4:6","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_Math_$2570_$","typeString":"type(library Math)"}},"id":1537,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"1660:6:6","memberName":"log256","nodeType":"MemberAccess","referencedDeclaration":2530,"src":"1655:11:6","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_uint256_$returns$_t_uint256_$","typeString":"function (uint256) pure returns (uint256)"}},"id":1539,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1655:18:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"hexValue":"31","id":1540,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"1676:1:6","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"1655:22:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":1534,"name":"toHexString","nodeType":"Identifier","overloadedDeclarations":[1546,1622,1642],"referencedDeclaration":1622,"src":"1636:11:6","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_string_memory_ptr_$","typeString":"function (uint256,uint256) pure returns (string memory)"}},"id":1542,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1636:42:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},"functionReturnParameters":1533,"id":1543,"nodeType":"Return","src":"1629:49:6"}]}]},"documentation":{"id":1527,"nodeType":"StructuredDocumentation","src":"1422:94:6","text":" @dev Converts a `uint256` to its ASCII `string` hexadecimal representation."},"id":1546,"implemented":true,"kind":"function","modifiers":[],"name":"toHexString","nameLocation":"1530:11:6","nodeType":"FunctionDefinition","parameters":{"id":1530,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1529,"mutability":"mutable","name":"value","nameLocation":"1550:5:6","nodeType":"VariableDeclaration","scope":1546,"src":"1542:13:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1528,"name":"uint256","nodeType":"ElementaryTypeName","src":"1542:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1541:15:6"},"returnParameters":{"id":1533,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1532,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1546,"src":"1580:13:6","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":1531,"name":"string","nodeType":"ElementaryTypeName","src":"1580:6:6","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1579:15:6"},"scope":1668,"src":"1521:174:6","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":1621,"nodeType":"Block","src":"1908:347:6","statements":[{"assignments":[1557],"declarations":[{"constant":false,"id":1557,"mutability":"mutable","name":"buffer","nameLocation":"1931:6:6","nodeType":"VariableDeclaration","scope":1621,"src":"1918:19:6","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":1556,"name":"bytes","nodeType":"ElementaryTypeName","src":"1918:5:6","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"id":1566,"initialValue":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1564,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1562,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"hexValue":"32","id":1560,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"1950:1:6","typeDescriptions":{"typeIdentifier":"t_rational_2_by_1","typeString":"int_const 2"},"value":"2"},"nodeType":"BinaryOperation","operator":"*","rightExpression":{"id":1561,"name":"length","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1551,"src":"1954:6:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"1950:10:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"hexValue":"32","id":1563,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"1963:1:6","typeDescriptions":{"typeIdentifier":"t_rational_2_by_1","typeString":"int_const 2"},"value":"2"},"src":"1950:14:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":1559,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"NewExpression","src":"1940:9:6","typeDescriptions":{"typeIdentifier":"t_function_objectcreation_pure$_t_uint256_$returns$_t_bytes_memory_ptr_$","typeString":"function (uint256) pure returns (bytes memory)"},"typeName":{"id":1558,"name":"bytes","nodeType":"ElementaryTypeName","src":"1944:5:6","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}}},"id":1565,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1940:25:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"nodeType":"VariableDeclarationStatement","src":"1918:47:6"},{"expression":{"id":1571,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"baseExpression":{"id":1567,"name":"buffer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1557,"src":"1975:6:6","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":1569,"indexExpression":{"hexValue":"30","id":1568,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"1982:1:6","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"IndexAccess","src":"1975:9:6","typeDescriptions":{"typeIdentifier":"t_bytes1","typeString":"bytes1"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"hexValue":"30","id":1570,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"1987:3:6","typeDescriptions":{"typeIdentifier":"t_stringliteral_044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d","typeString":"literal_string \"0\""},"value":"0"},"src":"1975:15:6","typeDescriptions":{"typeIdentifier":"t_bytes1","typeString":"bytes1"}},"id":1572,"nodeType":"ExpressionStatement","src":"1975:15:6"},{"expression":{"id":1577,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"baseExpression":{"id":1573,"name":"buffer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1557,"src":"2000:6:6","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":1575,"indexExpression":{"hexValue":"31","id":1574,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"2007:1:6","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"IndexAccess","src":"2000:9:6","typeDescriptions":{"typeIdentifier":"t_bytes1","typeString":"bytes1"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"hexValue":"78","id":1576,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2012:3:6","typeDescriptions":{"typeIdentifier":"t_stringliteral_7521d1cadbcfa91eec65aa16715b94ffc1c9654ba57ea2ef1a2127bca1127a83","typeString":"literal_string \"x\""},"value":"x"},"src":"2000:15:6","typeDescriptions":{"typeIdentifier":"t_bytes1","typeString":"bytes1"}},"id":1578,"nodeType":"ExpressionStatement","src":"2000:15:6"},{"body":{"id":1607,"nodeType":"Block","src":"2070:83:6","statements":[{"expression":{"id":1601,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"baseExpression":{"id":1593,"name":"buffer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1557,"src":"2084:6:6","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}},"id":1595,"indexExpression":{"id":1594,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1580,"src":"2091:1:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":true,"isPure":false,"lValueRequested":true,"nodeType":"IndexAccess","src":"2084:9:6","typeDescriptions":{"typeIdentifier":"t_bytes1","typeString":"bytes1"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"baseExpression":{"id":1596,"name":"_SYMBOLS","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1447,"src":"2096:8:6","typeDescriptions":{"typeIdentifier":"t_bytes16","typeString":"bytes16"}},"id":1600,"indexExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1599,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1597,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1549,"src":"2105:5:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"&","rightExpression":{"hexValue":"307866","id":1598,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"2113:3:6","typeDescriptions":{"typeIdentifier":"t_rational_15_by_1","typeString":"int_const 15"},"value":"0xf"},"src":"2105:11:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"IndexAccess","src":"2096:21:6","typeDescriptions":{"typeIdentifier":"t_bytes1","typeString":"bytes1"}},"src":"2084:33:6","typeDescriptions":{"typeIdentifier":"t_bytes1","typeString":"bytes1"}},"id":1602,"nodeType":"ExpressionStatement","src":"2084:33:6"},{"expression":{"id":1605,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":1603,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1549,"src":"2131:5:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":">>=","rightHandSide":{"hexValue":"34","id":1604,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"2141:1:6","typeDescriptions":{"typeIdentifier":"t_rational_4_by_1","typeString":"int_const 4"},"value":"4"},"src":"2131:11:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":1606,"nodeType":"ExpressionStatement","src":"2131:11:6"}]},"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1589,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1587,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1580,"src":"2058:1:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"hexValue":"31","id":1588,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"2062:1:6","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"2058:5:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":1608,"initializationExpression":{"assignments":[1580],"declarations":[{"constant":false,"id":1580,"mutability":"mutable","name":"i","nameLocation":"2038:1:6","nodeType":"VariableDeclaration","scope":1608,"src":"2030:9:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1579,"name":"uint256","nodeType":"ElementaryTypeName","src":"2030:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":1586,"initialValue":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1585,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1583,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"hexValue":"32","id":1581,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"2042:1:6","typeDescriptions":{"typeIdentifier":"t_rational_2_by_1","typeString":"int_const 2"},"value":"2"},"nodeType":"BinaryOperation","operator":"*","rightExpression":{"id":1582,"name":"length","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1551,"src":"2046:6:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"2042:10:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"hexValue":"31","id":1584,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"2055:1:6","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"2042:14:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"2030:26:6"},"loopExpression":{"expression":{"id":1591,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"--","prefix":true,"src":"2065:3:6","subExpression":{"id":1590,"name":"i","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1580,"src":"2067:1:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":1592,"nodeType":"ExpressionStatement","src":"2065:3:6"},"nodeType":"ForStatement","src":"2025:128:6"},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1612,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1610,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1549,"src":"2170:5:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"30","id":1611,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"2179:1:6","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"2170:10:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"537472696e67733a20686578206c656e67746820696e73756666696369656e74","id":1613,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2182:34:6","typeDescriptions":{"typeIdentifier":"t_stringliteral_04fc88320d7c9f639317c75102c103ff0044d3075a5c627e24e76e5bbb2733c2","typeString":"literal_string \"Strings: hex length insufficient\""},"value":"Strings: hex length insufficient"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_04fc88320d7c9f639317c75102c103ff0044d3075a5c627e24e76e5bbb2733c2","typeString":"literal_string \"Strings: hex length insufficient\""}],"id":1609,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"2162:7:6","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":1614,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2162:55:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":1615,"nodeType":"ExpressionStatement","src":"2162:55:6"},{"expression":{"arguments":[{"id":1618,"name":"buffer","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1557,"src":"2241:6:6","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":1617,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2234:6:6","typeDescriptions":{"typeIdentifier":"t_type$_t_string_storage_ptr_$","typeString":"type(string storage pointer)"},"typeName":{"id":1616,"name":"string","nodeType":"ElementaryTypeName","src":"2234:6:6","typeDescriptions":{}}},"id":1619,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2234:14:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},"functionReturnParameters":1555,"id":1620,"nodeType":"Return","src":"2227:21:6"}]},"documentation":{"id":1547,"nodeType":"StructuredDocumentation","src":"1701:112:6","text":" @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length."},"id":1622,"implemented":true,"kind":"function","modifiers":[],"name":"toHexString","nameLocation":"1827:11:6","nodeType":"FunctionDefinition","parameters":{"id":1552,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1549,"mutability":"mutable","name":"value","nameLocation":"1847:5:6","nodeType":"VariableDeclaration","scope":1622,"src":"1839:13:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1548,"name":"uint256","nodeType":"ElementaryTypeName","src":"1839:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1551,"mutability":"mutable","name":"length","nameLocation":"1862:6:6","nodeType":"VariableDeclaration","scope":1622,"src":"1854:14:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1550,"name":"uint256","nodeType":"ElementaryTypeName","src":"1854:7:6","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1838:31:6"},"returnParameters":{"id":1555,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1554,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1622,"src":"1893:13:6","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":1553,"name":"string","nodeType":"ElementaryTypeName","src":"1893:6:6","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"1892:15:6"},"scope":1668,"src":"1818:437:6","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":1641,"nodeType":"Block","src":"2480:76:6","statements":[{"expression":{"arguments":[{"arguments":[{"arguments":[{"id":1635,"name":"addr","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1625,"src":"2525:4:6","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":1634,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2517:7:6","typeDescriptions":{"typeIdentifier":"t_type$_t_uint160_$","typeString":"type(uint160)"},"typeName":{"id":1633,"name":"uint160","nodeType":"ElementaryTypeName","src":"2517:7:6","typeDescriptions":{}}},"id":1636,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2517:13:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint160","typeString":"uint160"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint160","typeString":"uint160"}],"id":1632,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2509:7:6","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":1631,"name":"uint256","nodeType":"ElementaryTypeName","src":"2509:7:6","typeDescriptions":{}}},"id":1637,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2509:22:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":1638,"name":"_ADDRESS_LENGTH","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1450,"src":"2533:15:6","typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_uint8","typeString":"uint8"}],"id":1630,"name":"toHexString","nodeType":"Identifier","overloadedDeclarations":[1546,1622,1642],"referencedDeclaration":1622,"src":"2497:11:6","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_string_memory_ptr_$","typeString":"function (uint256,uint256) pure returns (string memory)"}},"id":1639,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2497:52:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},"functionReturnParameters":1629,"id":1640,"nodeType":"Return","src":"2490:59:6"}]},"documentation":{"id":1623,"nodeType":"StructuredDocumentation","src":"2261:141:6","text":" @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation."},"id":1642,"implemented":true,"kind":"function","modifiers":[],"name":"toHexString","nameLocation":"2416:11:6","nodeType":"FunctionDefinition","parameters":{"id":1626,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1625,"mutability":"mutable","name":"addr","nameLocation":"2436:4:6","nodeType":"VariableDeclaration","scope":1642,"src":"2428:12:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":1624,"name":"address","nodeType":"ElementaryTypeName","src":"2428:7:6","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"2427:14:6"},"returnParameters":{"id":1629,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1628,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1642,"src":"2465:13:6","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":1627,"name":"string","nodeType":"ElementaryTypeName","src":"2465:6:6","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2464:15:6"},"scope":1668,"src":"2407:149:6","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":1666,"nodeType":"Block","src":"2711:66:6","statements":[{"expression":{"commonType":{"typeIdentifier":"t_bytes32","typeString":"bytes32"},"id":1664,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[{"arguments":[{"id":1655,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1645,"src":"2744:1:6","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"id":1654,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2738:5:6","typeDescriptions":{"typeIdentifier":"t_type$_t_bytes_storage_ptr_$","typeString":"type(bytes storage pointer)"},"typeName":{"id":1653,"name":"bytes","nodeType":"ElementaryTypeName","src":"2738:5:6","typeDescriptions":{}}},"id":1656,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2738:8:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":1652,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2728:9:6","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":1657,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2728:19:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"arguments":[{"arguments":[{"id":1661,"name":"b","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1647,"src":"2767:1:6","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}],"id":1660,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"2761:5:6","typeDescriptions":{"typeIdentifier":"t_type$_t_bytes_storage_ptr_$","typeString":"type(bytes storage pointer)"},"typeName":{"id":1659,"name":"bytes","nodeType":"ElementaryTypeName","src":"2761:5:6","typeDescriptions":{}}},"id":1662,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2761:8:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes memory"}],"id":1658,"name":"keccak256","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-8,"src":"2751:9:6","typeDescriptions":{"typeIdentifier":"t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$","typeString":"function (bytes memory) pure returns (bytes32)"}},"id":1663,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2751:19:6","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_bytes32","typeString":"bytes32"}},"src":"2728:42:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"functionReturnParameters":1651,"id":1665,"nodeType":"Return","src":"2721:49:6"}]},"documentation":{"id":1643,"nodeType":"StructuredDocumentation","src":"2562:66:6","text":" @dev Returns true if the two strings are equal."},"id":1667,"implemented":true,"kind":"function","modifiers":[],"name":"equal","nameLocation":"2642:5:6","nodeType":"FunctionDefinition","parameters":{"id":1648,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1645,"mutability":"mutable","name":"a","nameLocation":"2662:1:6","nodeType":"VariableDeclaration","scope":1667,"src":"2648:15:6","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":1644,"name":"string","nodeType":"ElementaryTypeName","src":"2648:6:6","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":1647,"mutability":"mutable","name":"b","nameLocation":"2679:1:6","nodeType":"VariableDeclaration","scope":1667,"src":"2665:15:6","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":1646,"name":"string","nodeType":"ElementaryTypeName","src":"2665:6:6","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2647:34:6"},"returnParameters":{"id":1651,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1650,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1667,"src":"2705:4:6","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":1649,"name":"bool","nodeType":"ElementaryTypeName","src":"2705:4:6","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"2704:6:6"},"scope":1668,"src":"2633:144:6","stateMutability":"pure","virtual":false,"visibility":"internal"}],"scope":1669,"src":"220:2559:6","usedErrors":[]}],"src":"101:2679:6"},"id":6},"@openzeppelin/contracts/utils/introspection/ERC165.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/utils/introspection/ERC165.sol","exportedSymbols":{"ERC165":[1692],"IERC165":[1704]},"id":1693,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":1670,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"99:23:7"},{"absolutePath":"@openzeppelin/contracts/utils/introspection/IERC165.sol","file":"./IERC165.sol","id":1671,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":1693,"sourceUnit":1705,"src":"124:23:7","symbolAliases":[],"unitAlias":""},{"abstract":true,"baseContracts":[{"baseName":{"id":1673,"name":"IERC165","nameLocations":["754:7:7"],"nodeType":"IdentifierPath","referencedDeclaration":1704,"src":"754:7:7"},"id":1674,"nodeType":"InheritanceSpecifier","src":"754:7:7"}],"canonicalName":"ERC165","contractDependencies":[],"contractKind":"contract","documentation":{"id":1672,"nodeType":"StructuredDocumentation","src":"149:576:7","text":" @dev Implementation of the {IERC165} interface.\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 ```solidity\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n }\n ```\n Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation."},"fullyImplemented":true,"id":1692,"linearizedBaseContracts":[1692,1704],"name":"ERC165","nameLocation":"744:6:7","nodeType":"ContractDefinition","nodes":[{"baseFunctions":[1703],"body":{"id":1690,"nodeType":"Block","src":"920:64:7","statements":[{"expression":{"commonType":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"id":1688,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1683,"name":"interfaceId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1677,"src":"937:11:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"arguments":[{"id":1685,"name":"IERC165","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1704,"src":"957:7:7","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC165_$1704_$","typeString":"type(contract IERC165)"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_type$_t_contract$_IERC165_$1704_$","typeString":"type(contract IERC165)"}],"id":1684,"name":"type","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-27,"src":"952:4:7","typeDescriptions":{"typeIdentifier":"t_function_metatype_pure$__$returns$__$","typeString":"function () pure"}},"id":1686,"isConstant":false,"isLValue":false,"isPure":true,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"952:13:7","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_magic_meta_type_t_contract$_IERC165_$1704","typeString":"type(contract IERC165)"}},"id":1687,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"966:11:7","memberName":"interfaceId","nodeType":"MemberAccess","src":"952:25:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"src":"937:40:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"functionReturnParameters":1682,"id":1689,"nodeType":"Return","src":"930:47:7"}]},"documentation":{"id":1675,"nodeType":"StructuredDocumentation","src":"768:56:7","text":" @dev See {IERC165-supportsInterface}."},"functionSelector":"01ffc9a7","id":1691,"implemented":true,"kind":"function","modifiers":[],"name":"supportsInterface","nameLocation":"838:17:7","nodeType":"FunctionDefinition","overrides":{"id":1679,"nodeType":"OverrideSpecifier","overrides":[],"src":"896:8:7"},"parameters":{"id":1678,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1677,"mutability":"mutable","name":"interfaceId","nameLocation":"863:11:7","nodeType":"VariableDeclaration","scope":1691,"src":"856:18:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":1676,"name":"bytes4","nodeType":"ElementaryTypeName","src":"856:6:7","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"855:20:7"},"returnParameters":{"id":1682,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1681,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1691,"src":"914:4:7","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":1680,"name":"bool","nodeType":"ElementaryTypeName","src":"914:4:7","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"913:6:7"},"scope":1692,"src":"829:155:7","stateMutability":"view","virtual":true,"visibility":"public"}],"scope":1693,"src":"726:260:7","usedErrors":[]}],"src":"99:888:7"},"id":7},"@openzeppelin/contracts/utils/introspection/IERC165.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/utils/introspection/IERC165.sol","exportedSymbols":{"IERC165":[1704]},"id":1705,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":1694,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"100:23:8"},{"abstract":false,"baseContracts":[],"canonicalName":"IERC165","contractDependencies":[],"contractKind":"interface","documentation":{"id":1695,"nodeType":"StructuredDocumentation","src":"125:279:8","text":" @dev Interface of the ERC165 standard, as defined in the\n https://eips.ethereum.org/EIPS/eip-165[EIP].\n Implementers can declare support of contract interfaces, which can then be\n queried by others ({ERC165Checker}).\n For an implementation, see {ERC165}."},"fullyImplemented":false,"id":1704,"linearizedBaseContracts":[1704],"name":"IERC165","nameLocation":"415:7:8","nodeType":"ContractDefinition","nodes":[{"documentation":{"id":1696,"nodeType":"StructuredDocumentation","src":"429:340:8","text":" @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 This function call must use less than 30 000 gas."},"functionSelector":"01ffc9a7","id":1703,"implemented":false,"kind":"function","modifiers":[],"name":"supportsInterface","nameLocation":"783:17:8","nodeType":"FunctionDefinition","parameters":{"id":1699,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1698,"mutability":"mutable","name":"interfaceId","nameLocation":"808:11:8","nodeType":"VariableDeclaration","scope":1703,"src":"801:18:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"},"typeName":{"id":1697,"name":"bytes4","nodeType":"ElementaryTypeName","src":"801:6:8","typeDescriptions":{"typeIdentifier":"t_bytes4","typeString":"bytes4"}},"visibility":"internal"}],"src":"800:20:8"},"returnParameters":{"id":1702,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1701,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1703,"src":"844:4:8","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":1700,"name":"bool","nodeType":"ElementaryTypeName","src":"844:4:8","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"843:6:8"},"scope":1704,"src":"774:76:8","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":1705,"src":"405:447:8","usedErrors":[]}],"src":"100:753:8"},"id":8},"@openzeppelin/contracts/utils/math/Math.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/utils/math/Math.sol","exportedSymbols":{"Math":[2570]},"id":2571,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":1706,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"103:23:9"},{"abstract":false,"baseContracts":[],"canonicalName":"Math","contractDependencies":[],"contractKind":"library","documentation":{"id":1707,"nodeType":"StructuredDocumentation","src":"128:73:9","text":" @dev Standard math utilities missing in the Solidity language."},"fullyImplemented":true,"id":2570,"linearizedBaseContracts":[2570],"name":"Math","nameLocation":"210:4:9","nodeType":"ContractDefinition","nodes":[{"canonicalName":"Math.Rounding","id":1711,"members":[{"id":1708,"name":"Down","nameLocation":"245:4:9","nodeType":"EnumValue","src":"245:4:9"},{"id":1709,"name":"Up","nameLocation":"287:2:9","nodeType":"EnumValue","src":"287:2:9"},{"id":1710,"name":"Zero","nameLocation":"318:4:9","nodeType":"EnumValue","src":"318:4:9"}],"name":"Rounding","nameLocation":"226:8:9","nodeType":"EnumDefinition","src":"221:122:9"},{"body":{"id":1728,"nodeType":"Block","src":"480:37:9","statements":[{"expression":{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1723,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1721,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1714,"src":"497:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"id":1722,"name":"b","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1716,"src":"501:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"497:5:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"falseExpression":{"id":1725,"name":"b","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1716,"src":"509:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":1726,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"Conditional","src":"497:13:9","trueExpression":{"id":1724,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1714,"src":"505:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"functionReturnParameters":1720,"id":1727,"nodeType":"Return","src":"490:20:9"}]},"documentation":{"id":1712,"nodeType":"StructuredDocumentation","src":"349:59:9","text":" @dev Returns the largest of two numbers."},"id":1729,"implemented":true,"kind":"function","modifiers":[],"name":"max","nameLocation":"422:3:9","nodeType":"FunctionDefinition","parameters":{"id":1717,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1714,"mutability":"mutable","name":"a","nameLocation":"434:1:9","nodeType":"VariableDeclaration","scope":1729,"src":"426:9:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1713,"name":"uint256","nodeType":"ElementaryTypeName","src":"426:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1716,"mutability":"mutable","name":"b","nameLocation":"445:1:9","nodeType":"VariableDeclaration","scope":1729,"src":"437:9:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1715,"name":"uint256","nodeType":"ElementaryTypeName","src":"437:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"425:22:9"},"returnParameters":{"id":1720,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1719,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1729,"src":"471:7:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1718,"name":"uint256","nodeType":"ElementaryTypeName","src":"471:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"470:9:9"},"scope":2570,"src":"413:104:9","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":1746,"nodeType":"Block","src":"655:37:9","statements":[{"expression":{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1741,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1739,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1732,"src":"672:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"<","rightExpression":{"id":1740,"name":"b","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1734,"src":"676:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"672:5:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"falseExpression":{"id":1743,"name":"b","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1734,"src":"684:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":1744,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"Conditional","src":"672:13:9","trueExpression":{"id":1742,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1732,"src":"680:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"functionReturnParameters":1738,"id":1745,"nodeType":"Return","src":"665:20:9"}]},"documentation":{"id":1730,"nodeType":"StructuredDocumentation","src":"523:60:9","text":" @dev Returns the smallest of two numbers."},"id":1747,"implemented":true,"kind":"function","modifiers":[],"name":"min","nameLocation":"597:3:9","nodeType":"FunctionDefinition","parameters":{"id":1735,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1732,"mutability":"mutable","name":"a","nameLocation":"609:1:9","nodeType":"VariableDeclaration","scope":1747,"src":"601:9:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1731,"name":"uint256","nodeType":"ElementaryTypeName","src":"601:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1734,"mutability":"mutable","name":"b","nameLocation":"620:1:9","nodeType":"VariableDeclaration","scope":1747,"src":"612:9:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1733,"name":"uint256","nodeType":"ElementaryTypeName","src":"612:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"600:22:9"},"returnParameters":{"id":1738,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1737,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1747,"src":"646:7:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1736,"name":"uint256","nodeType":"ElementaryTypeName","src":"646:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"645:9:9"},"scope":2570,"src":"588:104:9","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":1769,"nodeType":"Block","src":"876:82:9","statements":[{"expression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1767,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"components":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1759,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1757,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1750,"src":"931:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"&","rightExpression":{"id":1758,"name":"b","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1752,"src":"935:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"931:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"id":1760,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"930:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1766,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"components":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1763,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1761,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1750,"src":"941:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"^","rightExpression":{"id":1762,"name":"b","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1752,"src":"945:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"941:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"id":1764,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"940:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"/","rightExpression":{"hexValue":"32","id":1765,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"950:1:9","typeDescriptions":{"typeIdentifier":"t_rational_2_by_1","typeString":"int_const 2"},"value":"2"},"src":"940:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"930:21:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"functionReturnParameters":1756,"id":1768,"nodeType":"Return","src":"923:28:9"}]},"documentation":{"id":1748,"nodeType":"StructuredDocumentation","src":"698:102:9","text":" @dev Returns the average of two numbers. The result is rounded towards\n zero."},"id":1770,"implemented":true,"kind":"function","modifiers":[],"name":"average","nameLocation":"814:7:9","nodeType":"FunctionDefinition","parameters":{"id":1753,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1750,"mutability":"mutable","name":"a","nameLocation":"830:1:9","nodeType":"VariableDeclaration","scope":1770,"src":"822:9:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1749,"name":"uint256","nodeType":"ElementaryTypeName","src":"822:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1752,"mutability":"mutable","name":"b","nameLocation":"841:1:9","nodeType":"VariableDeclaration","scope":1770,"src":"833:9:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1751,"name":"uint256","nodeType":"ElementaryTypeName","src":"833:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"821:22:9"},"returnParameters":{"id":1756,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1755,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1770,"src":"867:7:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1754,"name":"uint256","nodeType":"ElementaryTypeName","src":"867:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"866:9:9"},"scope":2570,"src":"805:153:9","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":1794,"nodeType":"Block","src":"1228:123:9","statements":[{"expression":{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1782,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1780,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1773,"src":"1316:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"30","id":1781,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"1321:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"1316:6:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"falseExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1791,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1789,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"components":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1786,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1784,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1773,"src":"1330:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"-","rightExpression":{"hexValue":"31","id":1785,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"1334:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"1330:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"id":1787,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"1329:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"/","rightExpression":{"id":1788,"name":"b","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1775,"src":"1339:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"1329:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"hexValue":"31","id":1790,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"1343:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"1329:15:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":1792,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"Conditional","src":"1316:28:9","trueExpression":{"hexValue":"30","id":1783,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"1325:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"functionReturnParameters":1779,"id":1793,"nodeType":"Return","src":"1309:35:9"}]},"documentation":{"id":1771,"nodeType":"StructuredDocumentation","src":"964:188:9","text":" @dev Returns the ceiling of the division of two numbers.\n This differs from standard division with `/` in that it rounds up instead\n of rounding down."},"id":1795,"implemented":true,"kind":"function","modifiers":[],"name":"ceilDiv","nameLocation":"1166:7:9","nodeType":"FunctionDefinition","parameters":{"id":1776,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1773,"mutability":"mutable","name":"a","nameLocation":"1182:1:9","nodeType":"VariableDeclaration","scope":1795,"src":"1174:9:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1772,"name":"uint256","nodeType":"ElementaryTypeName","src":"1174:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1775,"mutability":"mutable","name":"b","nameLocation":"1193:1:9","nodeType":"VariableDeclaration","scope":1795,"src":"1185:9:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1774,"name":"uint256","nodeType":"ElementaryTypeName","src":"1185:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1173:22:9"},"returnParameters":{"id":1779,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1778,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1795,"src":"1219:7:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1777,"name":"uint256","nodeType":"ElementaryTypeName","src":"1219:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1218:9:9"},"scope":2570,"src":"1157:194:9","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":1917,"nodeType":"Block","src":"1765:4115:9","statements":[{"id":1916,"nodeType":"UncheckedBlock","src":"1775:4099:9","statements":[{"assignments":[1808],"declarations":[{"constant":false,"id":1808,"mutability":"mutable","name":"prod0","nameLocation":"2104:5:9","nodeType":"VariableDeclaration","scope":1916,"src":"2096:13:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1807,"name":"uint256","nodeType":"ElementaryTypeName","src":"2096:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":1809,"nodeType":"VariableDeclarationStatement","src":"2096:13:9"},{"assignments":[1811],"declarations":[{"constant":false,"id":1811,"mutability":"mutable","name":"prod1","nameLocation":"2176:5:9","nodeType":"VariableDeclaration","scope":1916,"src":"2168:13:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1810,"name":"uint256","nodeType":"ElementaryTypeName","src":"2168:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":1812,"nodeType":"VariableDeclarationStatement","src":"2168:13:9"},{"AST":{"nodeType":"YulBlock","src":"2248:157:9","statements":[{"nodeType":"YulVariableDeclaration","src":"2266:30:9","value":{"arguments":[{"name":"x","nodeType":"YulIdentifier","src":"2283:1:9"},{"name":"y","nodeType":"YulIdentifier","src":"2286:1:9"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2293:1:9","type":"","value":"0"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"2289:3:9"},"nodeType":"YulFunctionCall","src":"2289:6:9"}],"functionName":{"name":"mulmod","nodeType":"YulIdentifier","src":"2276:6:9"},"nodeType":"YulFunctionCall","src":"2276:20:9"},"variables":[{"name":"mm","nodeType":"YulTypedName","src":"2270:2:9","type":""}]},{"nodeType":"YulAssignment","src":"2313:18:9","value":{"arguments":[{"name":"x","nodeType":"YulIdentifier","src":"2326:1:9"},{"name":"y","nodeType":"YulIdentifier","src":"2329:1:9"}],"functionName":{"name":"mul","nodeType":"YulIdentifier","src":"2322:3:9"},"nodeType":"YulFunctionCall","src":"2322:9:9"},"variableNames":[{"name":"prod0","nodeType":"YulIdentifier","src":"2313:5:9"}]},{"nodeType":"YulAssignment","src":"2348:43:9","value":{"arguments":[{"arguments":[{"name":"mm","nodeType":"YulIdentifier","src":"2365:2:9"},{"name":"prod0","nodeType":"YulIdentifier","src":"2369:5:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"2361:3:9"},"nodeType":"YulFunctionCall","src":"2361:14:9"},{"arguments":[{"name":"mm","nodeType":"YulIdentifier","src":"2380:2:9"},{"name":"prod0","nodeType":"YulIdentifier","src":"2384:5:9"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"2377:2:9"},"nodeType":"YulFunctionCall","src":"2377:13:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"2357:3:9"},"nodeType":"YulFunctionCall","src":"2357:34:9"},"variableNames":[{"name":"prod1","nodeType":"YulIdentifier","src":"2348:5:9"}]}]},"evmVersion":"london","externalReferences":[{"declaration":1808,"isOffset":false,"isSlot":false,"src":"2313:5:9","valueSize":1},{"declaration":1808,"isOffset":false,"isSlot":false,"src":"2369:5:9","valueSize":1},{"declaration":1808,"isOffset":false,"isSlot":false,"src":"2384:5:9","valueSize":1},{"declaration":1811,"isOffset":false,"isSlot":false,"src":"2348:5:9","valueSize":1},{"declaration":1798,"isOffset":false,"isSlot":false,"src":"2283:1:9","valueSize":1},{"declaration":1798,"isOffset":false,"isSlot":false,"src":"2326:1:9","valueSize":1},{"declaration":1800,"isOffset":false,"isSlot":false,"src":"2286:1:9","valueSize":1},{"declaration":1800,"isOffset":false,"isSlot":false,"src":"2329:1:9","valueSize":1}],"id":1813,"nodeType":"InlineAssembly","src":"2239:166:9"},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1816,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1814,"name":"prod1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1811,"src":"2486:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"30","id":1815,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"2495:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"2486:10:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":1822,"nodeType":"IfStatement","src":"2482:368:9","trueBody":{"id":1821,"nodeType":"Block","src":"2498:352:9","statements":[{"expression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1819,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1817,"name":"prod0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1808,"src":"2816:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"/","rightExpression":{"id":1818,"name":"denominator","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1802,"src":"2824:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"2816:19:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"functionReturnParameters":1806,"id":1820,"nodeType":"Return","src":"2809:26:9"}]}},{"expression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1826,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1824,"name":"denominator","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1802,"src":"2960:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"id":1825,"name":"prod1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1811,"src":"2974:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"2960:19:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},{"hexValue":"4d6174683a206d756c446976206f766572666c6f77","id":1827,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"2981:23:9","typeDescriptions":{"typeIdentifier":"t_stringliteral_d87093691d63b122ac2c14d1b11554b287e2431cf2b03550b3be7cffb0f86851","typeString":"literal_string \"Math: mulDiv overflow\""},"value":"Math: mulDiv overflow"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_bool","typeString":"bool"},{"typeIdentifier":"t_stringliteral_d87093691d63b122ac2c14d1b11554b287e2431cf2b03550b3be7cffb0f86851","typeString":"literal_string \"Math: mulDiv overflow\""}],"id":1823,"name":"require","nodeType":"Identifier","overloadedDeclarations":[-18,-18],"referencedDeclaration":-18,"src":"2952:7:9","typeDescriptions":{"typeIdentifier":"t_function_require_pure$_t_bool_$_t_string_memory_ptr_$returns$__$","typeString":"function (bool,string memory) pure"}},"id":1828,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2952:53:9","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":1829,"nodeType":"ExpressionStatement","src":"2952:53:9"},{"assignments":[1831],"declarations":[{"constant":false,"id":1831,"mutability":"mutable","name":"remainder","nameLocation":"3269:9:9","nodeType":"VariableDeclaration","scope":1916,"src":"3261:17:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1830,"name":"uint256","nodeType":"ElementaryTypeName","src":"3261:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":1832,"nodeType":"VariableDeclarationStatement","src":"3261:17:9"},{"AST":{"nodeType":"YulBlock","src":"3301:291:9","statements":[{"nodeType":"YulAssignment","src":"3370:38:9","value":{"arguments":[{"name":"x","nodeType":"YulIdentifier","src":"3390:1:9"},{"name":"y","nodeType":"YulIdentifier","src":"3393:1:9"},{"name":"denominator","nodeType":"YulIdentifier","src":"3396:11:9"}],"functionName":{"name":"mulmod","nodeType":"YulIdentifier","src":"3383:6:9"},"nodeType":"YulFunctionCall","src":"3383:25:9"},"variableNames":[{"name":"remainder","nodeType":"YulIdentifier","src":"3370:9:9"}]},{"nodeType":"YulAssignment","src":"3490:41:9","value":{"arguments":[{"name":"prod1","nodeType":"YulIdentifier","src":"3503:5:9"},{"arguments":[{"name":"remainder","nodeType":"YulIdentifier","src":"3513:9:9"},{"name":"prod0","nodeType":"YulIdentifier","src":"3524:5:9"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"3510:2:9"},"nodeType":"YulFunctionCall","src":"3510:20:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"3499:3:9"},"nodeType":"YulFunctionCall","src":"3499:32:9"},"variableNames":[{"name":"prod1","nodeType":"YulIdentifier","src":"3490:5:9"}]},{"nodeType":"YulAssignment","src":"3548:30:9","value":{"arguments":[{"name":"prod0","nodeType":"YulIdentifier","src":"3561:5:9"},{"name":"remainder","nodeType":"YulIdentifier","src":"3568:9:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"3557:3:9"},"nodeType":"YulFunctionCall","src":"3557:21:9"},"variableNames":[{"name":"prod0","nodeType":"YulIdentifier","src":"3548:5:9"}]}]},"evmVersion":"london","externalReferences":[{"declaration":1802,"isOffset":false,"isSlot":false,"src":"3396:11:9","valueSize":1},{"declaration":1808,"isOffset":false,"isSlot":false,"src":"3524:5:9","valueSize":1},{"declaration":1808,"isOffset":false,"isSlot":false,"src":"3548:5:9","valueSize":1},{"declaration":1808,"isOffset":false,"isSlot":false,"src":"3561:5:9","valueSize":1},{"declaration":1811,"isOffset":false,"isSlot":false,"src":"3490:5:9","valueSize":1},{"declaration":1811,"isOffset":false,"isSlot":false,"src":"3503:5:9","valueSize":1},{"declaration":1831,"isOffset":false,"isSlot":false,"src":"3370:9:9","valueSize":1},{"declaration":1831,"isOffset":false,"isSlot":false,"src":"3513:9:9","valueSize":1},{"declaration":1831,"isOffset":false,"isSlot":false,"src":"3568:9:9","valueSize":1},{"declaration":1798,"isOffset":false,"isSlot":false,"src":"3390:1:9","valueSize":1},{"declaration":1800,"isOffset":false,"isSlot":false,"src":"3393:1:9","valueSize":1}],"id":1833,"nodeType":"InlineAssembly","src":"3292:300:9"},{"assignments":[1835],"declarations":[{"constant":false,"id":1835,"mutability":"mutable","name":"twos","nameLocation":"3907:4:9","nodeType":"VariableDeclaration","scope":1916,"src":"3899:12:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1834,"name":"uint256","nodeType":"ElementaryTypeName","src":"3899:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":1843,"initialValue":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1842,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1836,"name":"denominator","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1802,"src":"3914:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"&","rightExpression":{"components":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1840,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1838,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"~","prefix":true,"src":"3929:12:9","subExpression":{"id":1837,"name":"denominator","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1802,"src":"3930:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"hexValue":"31","id":1839,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"3944:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"3929:16:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"id":1841,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"3928:18:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"3914:32:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"3899:47:9"},{"AST":{"nodeType":"YulBlock","src":"3969:362:9","statements":[{"nodeType":"YulAssignment","src":"4034:37:9","value":{"arguments":[{"name":"denominator","nodeType":"YulIdentifier","src":"4053:11:9"},{"name":"twos","nodeType":"YulIdentifier","src":"4066:4:9"}],"functionName":{"name":"div","nodeType":"YulIdentifier","src":"4049:3:9"},"nodeType":"YulFunctionCall","src":"4049:22:9"},"variableNames":[{"name":"denominator","nodeType":"YulIdentifier","src":"4034:11:9"}]},{"nodeType":"YulAssignment","src":"4138:25:9","value":{"arguments":[{"name":"prod0","nodeType":"YulIdentifier","src":"4151:5:9"},{"name":"twos","nodeType":"YulIdentifier","src":"4158:4:9"}],"functionName":{"name":"div","nodeType":"YulIdentifier","src":"4147:3:9"},"nodeType":"YulFunctionCall","src":"4147:16:9"},"variableNames":[{"name":"prod0","nodeType":"YulIdentifier","src":"4138:5:9"}]},{"nodeType":"YulAssignment","src":"4278:39:9","value":{"arguments":[{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4298:1:9","type":"","value":"0"},{"name":"twos","nodeType":"YulIdentifier","src":"4301:4:9"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"4294:3:9"},"nodeType":"YulFunctionCall","src":"4294:12:9"},{"name":"twos","nodeType":"YulIdentifier","src":"4308:4:9"}],"functionName":{"name":"div","nodeType":"YulIdentifier","src":"4290:3:9"},"nodeType":"YulFunctionCall","src":"4290:23:9"},{"kind":"number","nodeType":"YulLiteral","src":"4315:1:9","type":"","value":"1"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4286:3:9"},"nodeType":"YulFunctionCall","src":"4286:31:9"},"variableNames":[{"name":"twos","nodeType":"YulIdentifier","src":"4278:4:9"}]}]},"evmVersion":"london","externalReferences":[{"declaration":1802,"isOffset":false,"isSlot":false,"src":"4034:11:9","valueSize":1},{"declaration":1802,"isOffset":false,"isSlot":false,"src":"4053:11:9","valueSize":1},{"declaration":1808,"isOffset":false,"isSlot":false,"src":"4138:5:9","valueSize":1},{"declaration":1808,"isOffset":false,"isSlot":false,"src":"4151:5:9","valueSize":1},{"declaration":1835,"isOffset":false,"isSlot":false,"src":"4066:4:9","valueSize":1},{"declaration":1835,"isOffset":false,"isSlot":false,"src":"4158:4:9","valueSize":1},{"declaration":1835,"isOffset":false,"isSlot":false,"src":"4278:4:9","valueSize":1},{"declaration":1835,"isOffset":false,"isSlot":false,"src":"4301:4:9","valueSize":1},{"declaration":1835,"isOffset":false,"isSlot":false,"src":"4308:4:9","valueSize":1}],"id":1844,"nodeType":"InlineAssembly","src":"3960:371:9"},{"expression":{"id":1849,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":1845,"name":"prod0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1808,"src":"4397:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"|=","rightHandSide":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1848,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1846,"name":"prod1","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1811,"src":"4406:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"*","rightExpression":{"id":1847,"name":"twos","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1835,"src":"4414:4:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"4406:12:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"4397:21:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":1850,"nodeType":"ExpressionStatement","src":"4397:21:9"},{"assignments":[1852],"declarations":[{"constant":false,"id":1852,"mutability":"mutable","name":"inverse","nameLocation":"4744:7:9","nodeType":"VariableDeclaration","scope":1916,"src":"4736:15:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1851,"name":"uint256","nodeType":"ElementaryTypeName","src":"4736:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":1859,"initialValue":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1858,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"components":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1855,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"hexValue":"33","id":1853,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4755:1:9","typeDescriptions":{"typeIdentifier":"t_rational_3_by_1","typeString":"int_const 3"},"value":"3"},"nodeType":"BinaryOperation","operator":"*","rightExpression":{"id":1854,"name":"denominator","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1802,"src":"4759:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"4755:15:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"id":1856,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"4754:17:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"^","rightExpression":{"hexValue":"32","id":1857,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"4774:1:9","typeDescriptions":{"typeIdentifier":"t_rational_2_by_1","typeString":"int_const 2"},"value":"2"},"src":"4754:21:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"4736:39:9"},{"expression":{"id":1866,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":1860,"name":"inverse","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1852,"src":"4992:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"*=","rightHandSide":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1865,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"hexValue":"32","id":1861,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"5003:1:9","typeDescriptions":{"typeIdentifier":"t_rational_2_by_1","typeString":"int_const 2"},"value":"2"},"nodeType":"BinaryOperation","operator":"-","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1864,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1862,"name":"denominator","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1802,"src":"5007:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"*","rightExpression":{"id":1863,"name":"inverse","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1852,"src":"5021:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5007:21:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5003:25:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"4992:36:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":1867,"nodeType":"ExpressionStatement","src":"4992:36:9"},{"expression":{"id":1874,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":1868,"name":"inverse","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1852,"src":"5061:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"*=","rightHandSide":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1873,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"hexValue":"32","id":1869,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"5072:1:9","typeDescriptions":{"typeIdentifier":"t_rational_2_by_1","typeString":"int_const 2"},"value":"2"},"nodeType":"BinaryOperation","operator":"-","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1872,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1870,"name":"denominator","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1802,"src":"5076:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"*","rightExpression":{"id":1871,"name":"inverse","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1852,"src":"5090:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5076:21:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5072:25:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5061:36:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":1875,"nodeType":"ExpressionStatement","src":"5061:36:9"},{"expression":{"id":1882,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":1876,"name":"inverse","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1852,"src":"5131:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"*=","rightHandSide":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1881,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"hexValue":"32","id":1877,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"5142:1:9","typeDescriptions":{"typeIdentifier":"t_rational_2_by_1","typeString":"int_const 2"},"value":"2"},"nodeType":"BinaryOperation","operator":"-","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1880,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1878,"name":"denominator","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1802,"src":"5146:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"*","rightExpression":{"id":1879,"name":"inverse","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1852,"src":"5160:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5146:21:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5142:25:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5131:36:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":1883,"nodeType":"ExpressionStatement","src":"5131:36:9"},{"expression":{"id":1890,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":1884,"name":"inverse","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1852,"src":"5201:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"*=","rightHandSide":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1889,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"hexValue":"32","id":1885,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"5212:1:9","typeDescriptions":{"typeIdentifier":"t_rational_2_by_1","typeString":"int_const 2"},"value":"2"},"nodeType":"BinaryOperation","operator":"-","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1888,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1886,"name":"denominator","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1802,"src":"5216:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"*","rightExpression":{"id":1887,"name":"inverse","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1852,"src":"5230:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5216:21:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5212:25:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5201:36:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":1891,"nodeType":"ExpressionStatement","src":"5201:36:9"},{"expression":{"id":1898,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":1892,"name":"inverse","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1852,"src":"5271:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"*=","rightHandSide":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1897,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"hexValue":"32","id":1893,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"5282:1:9","typeDescriptions":{"typeIdentifier":"t_rational_2_by_1","typeString":"int_const 2"},"value":"2"},"nodeType":"BinaryOperation","operator":"-","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1896,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1894,"name":"denominator","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1802,"src":"5286:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"*","rightExpression":{"id":1895,"name":"inverse","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1852,"src":"5300:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5286:21:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5282:25:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5271:36:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":1899,"nodeType":"ExpressionStatement","src":"5271:36:9"},{"expression":{"id":1906,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":1900,"name":"inverse","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1852,"src":"5342:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"*=","rightHandSide":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1905,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"hexValue":"32","id":1901,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"5353:1:9","typeDescriptions":{"typeIdentifier":"t_rational_2_by_1","typeString":"int_const 2"},"value":"2"},"nodeType":"BinaryOperation","operator":"-","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1904,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1902,"name":"denominator","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1802,"src":"5357:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"*","rightExpression":{"id":1903,"name":"inverse","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1852,"src":"5371:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5357:21:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5353:25:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5342:36:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":1907,"nodeType":"ExpressionStatement","src":"5342:36:9"},{"expression":{"id":1912,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":1908,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1805,"src":"5812:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1911,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1909,"name":"prod0","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1808,"src":"5821:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"*","rightExpression":{"id":1910,"name":"inverse","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1852,"src":"5829:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5821:15:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"5812:24:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":1913,"nodeType":"ExpressionStatement","src":"5812:24:9"},{"expression":{"id":1914,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1805,"src":"5857:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"functionReturnParameters":1806,"id":1915,"nodeType":"Return","src":"5850:13:9"}]}]},"documentation":{"id":1796,"nodeType":"StructuredDocumentation","src":"1357:305:9","text":" @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n with further edits by Uniswap Labs also under MIT license."},"id":1918,"implemented":true,"kind":"function","modifiers":[],"name":"mulDiv","nameLocation":"1676:6:9","nodeType":"FunctionDefinition","parameters":{"id":1803,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1798,"mutability":"mutable","name":"x","nameLocation":"1691:1:9","nodeType":"VariableDeclaration","scope":1918,"src":"1683:9:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1797,"name":"uint256","nodeType":"ElementaryTypeName","src":"1683:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1800,"mutability":"mutable","name":"y","nameLocation":"1702:1:9","nodeType":"VariableDeclaration","scope":1918,"src":"1694:9:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1799,"name":"uint256","nodeType":"ElementaryTypeName","src":"1694:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1802,"mutability":"mutable","name":"denominator","nameLocation":"1713:11:9","nodeType":"VariableDeclaration","scope":1918,"src":"1705:19:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1801,"name":"uint256","nodeType":"ElementaryTypeName","src":"1705:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1682:43:9"},"returnParameters":{"id":1806,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1805,"mutability":"mutable","name":"result","nameLocation":"1757:6:9","nodeType":"VariableDeclaration","scope":1918,"src":"1749:14:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1804,"name":"uint256","nodeType":"ElementaryTypeName","src":"1749:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1748:16:9"},"scope":2570,"src":"1667:4213:9","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":1961,"nodeType":"Block","src":"6122:189:9","statements":[{"assignments":[1934],"declarations":[{"constant":false,"id":1934,"mutability":"mutable","name":"result","nameLocation":"6140:6:9","nodeType":"VariableDeclaration","scope":1961,"src":"6132:14:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1933,"name":"uint256","nodeType":"ElementaryTypeName","src":"6132:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":1940,"initialValue":{"arguments":[{"id":1936,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1921,"src":"6156:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":1937,"name":"y","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1923,"src":"6159:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":1938,"name":"denominator","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1925,"src":"6162:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":1935,"name":"mulDiv","nodeType":"Identifier","overloadedDeclarations":[1918,1962],"referencedDeclaration":1918,"src":"6149:6:9","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$","typeString":"function (uint256,uint256,uint256) pure returns (uint256)"}},"id":1939,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"6149:25:9","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"6132:42:9"},{"condition":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":1952,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"},"id":1944,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1941,"name":"rounding","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1928,"src":"6188:8:9","typeDescriptions":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"id":1942,"name":"Rounding","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1711,"src":"6200:8:9","typeDescriptions":{"typeIdentifier":"t_type$_t_enum$_Rounding_$1711_$","typeString":"type(enum Math.Rounding)"}},"id":1943,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"6209:2:9","memberName":"Up","nodeType":"MemberAccess","referencedDeclaration":1709,"src":"6200:11:9","typeDescriptions":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"}},"src":"6188:23:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"&&","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1951,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[{"id":1946,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1921,"src":"6222:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":1947,"name":"y","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1923,"src":"6225:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":1948,"name":"denominator","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1925,"src":"6228:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":1945,"name":"mulmod","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-16,"src":"6215:6:9","typeDescriptions":{"typeIdentifier":"t_function_mulmod_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$_t_uint256_$","typeString":"function (uint256,uint256,uint256) pure returns (uint256)"}},"id":1949,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"6215:25:9","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"hexValue":"30","id":1950,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"6243:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"6215:29:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"6188:56:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":1958,"nodeType":"IfStatement","src":"6184:98:9","trueBody":{"id":1957,"nodeType":"Block","src":"6246:36:9","statements":[{"expression":{"id":1955,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":1953,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1934,"src":"6260:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"31","id":1954,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"6270:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"6260:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":1956,"nodeType":"ExpressionStatement","src":"6260:11:9"}]}},{"expression":{"id":1959,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1934,"src":"6298:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"functionReturnParameters":1932,"id":1960,"nodeType":"Return","src":"6291:13:9"}]},"documentation":{"id":1919,"nodeType":"StructuredDocumentation","src":"5886:121:9","text":" @notice Calculates x * y / denominator with full precision, following the selected rounding direction."},"id":1962,"implemented":true,"kind":"function","modifiers":[],"name":"mulDiv","nameLocation":"6021:6:9","nodeType":"FunctionDefinition","parameters":{"id":1929,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1921,"mutability":"mutable","name":"x","nameLocation":"6036:1:9","nodeType":"VariableDeclaration","scope":1962,"src":"6028:9:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1920,"name":"uint256","nodeType":"ElementaryTypeName","src":"6028:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1923,"mutability":"mutable","name":"y","nameLocation":"6047:1:9","nodeType":"VariableDeclaration","scope":1962,"src":"6039:9:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1922,"name":"uint256","nodeType":"ElementaryTypeName","src":"6039:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1925,"mutability":"mutable","name":"denominator","nameLocation":"6058:11:9","nodeType":"VariableDeclaration","scope":1962,"src":"6050:19:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1924,"name":"uint256","nodeType":"ElementaryTypeName","src":"6050:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":1928,"mutability":"mutable","name":"rounding","nameLocation":"6080:8:9","nodeType":"VariableDeclaration","scope":1962,"src":"6071:17:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"},"typeName":{"id":1927,"nodeType":"UserDefinedTypeName","pathNode":{"id":1926,"name":"Rounding","nameLocations":["6071:8:9"],"nodeType":"IdentifierPath","referencedDeclaration":1711,"src":"6071:8:9"},"referencedDeclaration":1711,"src":"6071:8:9","typeDescriptions":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"}},"visibility":"internal"}],"src":"6027:62:9"},"returnParameters":{"id":1932,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1931,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":1962,"src":"6113:7:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1930,"name":"uint256","nodeType":"ElementaryTypeName","src":"6113:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"6112:9:9"},"scope":2570,"src":"6012:299:9","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":2073,"nodeType":"Block","src":"6587:1585:9","statements":[{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1972,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1970,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1965,"src":"6601:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"hexValue":"30","id":1971,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"6606:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"6601:6:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":1976,"nodeType":"IfStatement","src":"6597:45:9","trueBody":{"id":1975,"nodeType":"Block","src":"6609:33:9","statements":[{"expression":{"hexValue":"30","id":1973,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"6630:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"functionReturnParameters":1969,"id":1974,"nodeType":"Return","src":"6623:8:9"}]}},{"assignments":[1978],"declarations":[{"constant":false,"id":1978,"mutability":"mutable","name":"result","nameLocation":"7329:6:9","nodeType":"VariableDeclaration","scope":2073,"src":"7321:14:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1977,"name":"uint256","nodeType":"ElementaryTypeName","src":"7321:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":1987,"initialValue":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1986,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"hexValue":"31","id":1979,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"7338:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"nodeType":"BinaryOperation","operator":"<<","rightExpression":{"components":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1984,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[{"id":1981,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1965,"src":"7349:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":1980,"name":"log2","nodeType":"Identifier","overloadedDeclarations":[2242,2278],"referencedDeclaration":2242,"src":"7344:4:9","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_uint256_$returns$_t_uint256_$","typeString":"function (uint256) pure returns (uint256)"}},"id":1982,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"7344:7:9","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"31","id":1983,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"7355:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"7344:12:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"id":1985,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"7343:14:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"7338:19:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"7321:36:9"},{"id":2072,"nodeType":"UncheckedBlock","src":"7758:408:9","statements":[{"expression":{"id":1997,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":1988,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"7782:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1996,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"components":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1993,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1989,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"7792:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":1992,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":1990,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1965,"src":"7801:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"/","rightExpression":{"id":1991,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"7805:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"7801:10:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"7792:19:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"id":1994,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"7791:21:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"31","id":1995,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"7816:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"7791:26:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"7782:35:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":1998,"nodeType":"ExpressionStatement","src":"7782:35:9"},{"expression":{"id":2008,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":1999,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"7831:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2007,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"components":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2004,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2000,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"7841:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2003,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2001,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1965,"src":"7850:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"/","rightExpression":{"id":2002,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"7854:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"7850:10:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"7841:19:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"id":2005,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"7840:21:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"31","id":2006,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"7865:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"7840:26:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"7831:35:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2009,"nodeType":"ExpressionStatement","src":"7831:35:9"},{"expression":{"id":2019,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2010,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"7880:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2018,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"components":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2015,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2011,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"7890:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2014,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2012,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1965,"src":"7899:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"/","rightExpression":{"id":2013,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"7903:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"7899:10:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"7890:19:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"id":2016,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"7889:21:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"31","id":2017,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"7914:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"7889:26:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"7880:35:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2020,"nodeType":"ExpressionStatement","src":"7880:35:9"},{"expression":{"id":2030,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2021,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"7929:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2029,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"components":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2026,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2022,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"7939:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2025,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2023,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1965,"src":"7948:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"/","rightExpression":{"id":2024,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"7952:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"7948:10:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"7939:19:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"id":2027,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"7938:21:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"31","id":2028,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"7963:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"7938:26:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"7929:35:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2031,"nodeType":"ExpressionStatement","src":"7929:35:9"},{"expression":{"id":2041,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2032,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"7978:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2040,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"components":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2037,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2033,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"7988:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2036,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2034,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1965,"src":"7997:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"/","rightExpression":{"id":2035,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"8001:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"7997:10:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"7988:19:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"id":2038,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"7987:21:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"31","id":2039,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"8012:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"7987:26:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"7978:35:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2042,"nodeType":"ExpressionStatement","src":"7978:35:9"},{"expression":{"id":2052,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2043,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"8027:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2051,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"components":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2048,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2044,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"8037:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2047,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2045,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1965,"src":"8046:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"/","rightExpression":{"id":2046,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"8050:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"8046:10:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"8037:19:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"id":2049,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"8036:21:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"31","id":2050,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"8061:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"8036:26:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"8027:35:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2053,"nodeType":"ExpressionStatement","src":"8027:35:9"},{"expression":{"id":2063,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2054,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"8076:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"=","rightHandSide":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2062,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"components":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2059,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2055,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"8086:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2058,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2056,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1965,"src":"8095:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"/","rightExpression":{"id":2057,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"8099:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"8095:10:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"8086:19:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"id":2060,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"8085:21:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"31","id":2061,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"8110:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"8085:26:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"8076:35:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2064,"nodeType":"ExpressionStatement","src":"8076:35:9"},{"expression":{"arguments":[{"id":2066,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"8136:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2069,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2067,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1965,"src":"8144:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"/","rightExpression":{"id":2068,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1978,"src":"8148:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"8144:10:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":2065,"name":"min","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1747,"src":"8132:3:9","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_uint256_$_t_uint256_$returns$_t_uint256_$","typeString":"function (uint256,uint256) pure returns (uint256)"}},"id":2070,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"8132:23:9","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"functionReturnParameters":1969,"id":2071,"nodeType":"Return","src":"8125:30:9"}]}]},"documentation":{"id":1963,"nodeType":"StructuredDocumentation","src":"6317:208:9","text":" @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11)."},"id":2074,"implemented":true,"kind":"function","modifiers":[],"name":"sqrt","nameLocation":"6539:4:9","nodeType":"FunctionDefinition","parameters":{"id":1966,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1965,"mutability":"mutable","name":"a","nameLocation":"6552:1:9","nodeType":"VariableDeclaration","scope":2074,"src":"6544:9:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1964,"name":"uint256","nodeType":"ElementaryTypeName","src":"6544:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"6543:11:9"},"returnParameters":{"id":1969,"nodeType":"ParameterList","parameters":[{"constant":false,"id":1968,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":2074,"src":"6578:7:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":1967,"name":"uint256","nodeType":"ElementaryTypeName","src":"6578:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"6577:9:9"},"scope":2570,"src":"6530:1642:9","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":2109,"nodeType":"Block","src":"8348:161:9","statements":[{"id":2108,"nodeType":"UncheckedBlock","src":"8358:145:9","statements":[{"assignments":[2086],"declarations":[{"constant":false,"id":2086,"mutability":"mutable","name":"result","nameLocation":"8390:6:9","nodeType":"VariableDeclaration","scope":2108,"src":"8382:14:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2085,"name":"uint256","nodeType":"ElementaryTypeName","src":"8382:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":2090,"initialValue":{"arguments":[{"id":2088,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2077,"src":"8404:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":2087,"name":"sqrt","nodeType":"Identifier","overloadedDeclarations":[2074,2110],"referencedDeclaration":2074,"src":"8399:4:9","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_uint256_$returns$_t_uint256_$","typeString":"function (uint256) pure returns (uint256)"}},"id":2089,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"8399:7:9","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"8382:24:9"},{"expression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2106,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2091,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2086,"src":"8427:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"components":[{"condition":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":2101,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"},"id":2095,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2092,"name":"rounding","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2080,"src":"8437:8:9","typeDescriptions":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"id":2093,"name":"Rounding","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1711,"src":"8449:8:9","typeDescriptions":{"typeIdentifier":"t_type$_t_enum$_Rounding_$1711_$","typeString":"type(enum Math.Rounding)"}},"id":2094,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"8458:2:9","memberName":"Up","nodeType":"MemberAccess","referencedDeclaration":1709,"src":"8449:11:9","typeDescriptions":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"}},"src":"8437:23:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"&&","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2100,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2098,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2096,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2086,"src":"8464:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"*","rightExpression":{"id":2097,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2086,"src":"8473:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"8464:15:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"<","rightExpression":{"id":2099,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2077,"src":"8482:1:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"8464:19:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"8437:46:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"falseExpression":{"hexValue":"30","id":2103,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"8490:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"id":2104,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"Conditional","src":"8437:54:9","trueExpression":{"hexValue":"31","id":2102,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"8486:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"}}],"id":2105,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"8436:56:9","typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"}},"src":"8427:65:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"functionReturnParameters":2084,"id":2107,"nodeType":"Return","src":"8420:72:9"}]}]},"documentation":{"id":2075,"nodeType":"StructuredDocumentation","src":"8178:89:9","text":" @notice Calculates sqrt(a), following the selected rounding direction."},"id":2110,"implemented":true,"kind":"function","modifiers":[],"name":"sqrt","nameLocation":"8281:4:9","nodeType":"FunctionDefinition","parameters":{"id":2081,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2077,"mutability":"mutable","name":"a","nameLocation":"8294:1:9","nodeType":"VariableDeclaration","scope":2110,"src":"8286:9:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2076,"name":"uint256","nodeType":"ElementaryTypeName","src":"8286:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2080,"mutability":"mutable","name":"rounding","nameLocation":"8306:8:9","nodeType":"VariableDeclaration","scope":2110,"src":"8297:17:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"},"typeName":{"id":2079,"nodeType":"UserDefinedTypeName","pathNode":{"id":2078,"name":"Rounding","nameLocations":["8297:8:9"],"nodeType":"IdentifierPath","referencedDeclaration":1711,"src":"8297:8:9"},"referencedDeclaration":1711,"src":"8297:8:9","typeDescriptions":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"}},"visibility":"internal"}],"src":"8285:30:9"},"returnParameters":{"id":2084,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2083,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":2110,"src":"8339:7:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2082,"name":"uint256","nodeType":"ElementaryTypeName","src":"8339:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"8338:9:9"},"scope":2570,"src":"8272:237:9","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":2241,"nodeType":"Block","src":"8694:922:9","statements":[{"assignments":[2119],"declarations":[{"constant":false,"id":2119,"mutability":"mutable","name":"result","nameLocation":"8712:6:9","nodeType":"VariableDeclaration","scope":2241,"src":"8704:14:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2118,"name":"uint256","nodeType":"ElementaryTypeName","src":"8704:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":2121,"initialValue":{"hexValue":"30","id":2120,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"8721:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"nodeType":"VariableDeclarationStatement","src":"8704:18:9"},{"id":2238,"nodeType":"UncheckedBlock","src":"8732:855:9","statements":[{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2126,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2124,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2122,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2113,"src":"8760:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"313238","id":2123,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"8769:3:9","typeDescriptions":{"typeIdentifier":"t_rational_128_by_1","typeString":"int_const 128"},"value":"128"},"src":"8760:12:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"hexValue":"30","id":2125,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"8775:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"8760:16:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":2136,"nodeType":"IfStatement","src":"8756:99:9","trueBody":{"id":2135,"nodeType":"Block","src":"8778:77:9","statements":[{"expression":{"id":2129,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2127,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2113,"src":"8796:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":">>=","rightHandSide":{"hexValue":"313238","id":2128,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"8806:3:9","typeDescriptions":{"typeIdentifier":"t_rational_128_by_1","typeString":"int_const 128"},"value":"128"},"src":"8796:13:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2130,"nodeType":"ExpressionStatement","src":"8796:13:9"},{"expression":{"id":2133,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2131,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2119,"src":"8827:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"313238","id":2132,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"8837:3:9","typeDescriptions":{"typeIdentifier":"t_rational_128_by_1","typeString":"int_const 128"},"value":"128"},"src":"8827:13:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2134,"nodeType":"ExpressionStatement","src":"8827:13:9"}]}},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2141,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2139,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2137,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2113,"src":"8872:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"3634","id":2138,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"8881:2:9","typeDescriptions":{"typeIdentifier":"t_rational_64_by_1","typeString":"int_const 64"},"value":"64"},"src":"8872:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"hexValue":"30","id":2140,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"8886:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"8872:15:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":2151,"nodeType":"IfStatement","src":"8868:96:9","trueBody":{"id":2150,"nodeType":"Block","src":"8889:75:9","statements":[{"expression":{"id":2144,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2142,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2113,"src":"8907:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":">>=","rightHandSide":{"hexValue":"3634","id":2143,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"8917:2:9","typeDescriptions":{"typeIdentifier":"t_rational_64_by_1","typeString":"int_const 64"},"value":"64"},"src":"8907:12:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2145,"nodeType":"ExpressionStatement","src":"8907:12:9"},{"expression":{"id":2148,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2146,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2119,"src":"8937:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"3634","id":2147,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"8947:2:9","typeDescriptions":{"typeIdentifier":"t_rational_64_by_1","typeString":"int_const 64"},"value":"64"},"src":"8937:12:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2149,"nodeType":"ExpressionStatement","src":"8937:12:9"}]}},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2156,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2154,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2152,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2113,"src":"8981:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"3332","id":2153,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"8990:2:9","typeDescriptions":{"typeIdentifier":"t_rational_32_by_1","typeString":"int_const 32"},"value":"32"},"src":"8981:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"hexValue":"30","id":2155,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"8995:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"8981:15:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":2166,"nodeType":"IfStatement","src":"8977:96:9","trueBody":{"id":2165,"nodeType":"Block","src":"8998:75:9","statements":[{"expression":{"id":2159,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2157,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2113,"src":"9016:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":">>=","rightHandSide":{"hexValue":"3332","id":2158,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9026:2:9","typeDescriptions":{"typeIdentifier":"t_rational_32_by_1","typeString":"int_const 32"},"value":"32"},"src":"9016:12:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2160,"nodeType":"ExpressionStatement","src":"9016:12:9"},{"expression":{"id":2163,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2161,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2119,"src":"9046:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"3332","id":2162,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9056:2:9","typeDescriptions":{"typeIdentifier":"t_rational_32_by_1","typeString":"int_const 32"},"value":"32"},"src":"9046:12:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2164,"nodeType":"ExpressionStatement","src":"9046:12:9"}]}},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2171,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2169,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2167,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2113,"src":"9090:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"3136","id":2168,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9099:2:9","typeDescriptions":{"typeIdentifier":"t_rational_16_by_1","typeString":"int_const 16"},"value":"16"},"src":"9090:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"hexValue":"30","id":2170,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9104:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"9090:15:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":2181,"nodeType":"IfStatement","src":"9086:96:9","trueBody":{"id":2180,"nodeType":"Block","src":"9107:75:9","statements":[{"expression":{"id":2174,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2172,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2113,"src":"9125:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":">>=","rightHandSide":{"hexValue":"3136","id":2173,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9135:2:9","typeDescriptions":{"typeIdentifier":"t_rational_16_by_1","typeString":"int_const 16"},"value":"16"},"src":"9125:12:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2175,"nodeType":"ExpressionStatement","src":"9125:12:9"},{"expression":{"id":2178,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2176,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2119,"src":"9155:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"3136","id":2177,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9165:2:9","typeDescriptions":{"typeIdentifier":"t_rational_16_by_1","typeString":"int_const 16"},"value":"16"},"src":"9155:12:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2179,"nodeType":"ExpressionStatement","src":"9155:12:9"}]}},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2186,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2184,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2182,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2113,"src":"9199:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"38","id":2183,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9208:1:9","typeDescriptions":{"typeIdentifier":"t_rational_8_by_1","typeString":"int_const 8"},"value":"8"},"src":"9199:10:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"hexValue":"30","id":2185,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9212:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"9199:14:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":2196,"nodeType":"IfStatement","src":"9195:93:9","trueBody":{"id":2195,"nodeType":"Block","src":"9215:73:9","statements":[{"expression":{"id":2189,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2187,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2113,"src":"9233:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":">>=","rightHandSide":{"hexValue":"38","id":2188,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9243:1:9","typeDescriptions":{"typeIdentifier":"t_rational_8_by_1","typeString":"int_const 8"},"value":"8"},"src":"9233:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2190,"nodeType":"ExpressionStatement","src":"9233:11:9"},{"expression":{"id":2193,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2191,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2119,"src":"9262:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"38","id":2192,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9272:1:9","typeDescriptions":{"typeIdentifier":"t_rational_8_by_1","typeString":"int_const 8"},"value":"8"},"src":"9262:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2194,"nodeType":"ExpressionStatement","src":"9262:11:9"}]}},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2201,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2199,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2197,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2113,"src":"9305:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"34","id":2198,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9314:1:9","typeDescriptions":{"typeIdentifier":"t_rational_4_by_1","typeString":"int_const 4"},"value":"4"},"src":"9305:10:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"hexValue":"30","id":2200,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9318:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"9305:14:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":2211,"nodeType":"IfStatement","src":"9301:93:9","trueBody":{"id":2210,"nodeType":"Block","src":"9321:73:9","statements":[{"expression":{"id":2204,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2202,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2113,"src":"9339:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":">>=","rightHandSide":{"hexValue":"34","id":2203,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9349:1:9","typeDescriptions":{"typeIdentifier":"t_rational_4_by_1","typeString":"int_const 4"},"value":"4"},"src":"9339:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2205,"nodeType":"ExpressionStatement","src":"9339:11:9"},{"expression":{"id":2208,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2206,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2119,"src":"9368:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"34","id":2207,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9378:1:9","typeDescriptions":{"typeIdentifier":"t_rational_4_by_1","typeString":"int_const 4"},"value":"4"},"src":"9368:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2209,"nodeType":"ExpressionStatement","src":"9368:11:9"}]}},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2216,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2214,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2212,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2113,"src":"9411:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"32","id":2213,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9420:1:9","typeDescriptions":{"typeIdentifier":"t_rational_2_by_1","typeString":"int_const 2"},"value":"2"},"src":"9411:10:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"hexValue":"30","id":2215,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9424:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"9411:14:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":2226,"nodeType":"IfStatement","src":"9407:93:9","trueBody":{"id":2225,"nodeType":"Block","src":"9427:73:9","statements":[{"expression":{"id":2219,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2217,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2113,"src":"9445:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":">>=","rightHandSide":{"hexValue":"32","id":2218,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9455:1:9","typeDescriptions":{"typeIdentifier":"t_rational_2_by_1","typeString":"int_const 2"},"value":"2"},"src":"9445:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2220,"nodeType":"ExpressionStatement","src":"9445:11:9"},{"expression":{"id":2223,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2221,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2119,"src":"9474:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"32","id":2222,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9484:1:9","typeDescriptions":{"typeIdentifier":"t_rational_2_by_1","typeString":"int_const 2"},"value":"2"},"src":"9474:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2224,"nodeType":"ExpressionStatement","src":"9474:11:9"}]}},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2231,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2229,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2227,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2113,"src":"9517:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"31","id":2228,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9526:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"9517:10:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"hexValue":"30","id":2230,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9530:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"9517:14:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":2237,"nodeType":"IfStatement","src":"9513:64:9","trueBody":{"id":2236,"nodeType":"Block","src":"9533:44:9","statements":[{"expression":{"id":2234,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2232,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2119,"src":"9551:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"31","id":2233,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9561:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"9551:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2235,"nodeType":"ExpressionStatement","src":"9551:11:9"}]}}]},{"expression":{"id":2239,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2119,"src":"9603:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"functionReturnParameters":2117,"id":2240,"nodeType":"Return","src":"9596:13:9"}]},"documentation":{"id":2111,"nodeType":"StructuredDocumentation","src":"8515:113:9","text":" @dev Return the log in base 2, rounded down, of a positive value.\n Returns 0 if given 0."},"id":2242,"implemented":true,"kind":"function","modifiers":[],"name":"log2","nameLocation":"8642:4:9","nodeType":"FunctionDefinition","parameters":{"id":2114,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2113,"mutability":"mutable","name":"value","nameLocation":"8655:5:9","nodeType":"VariableDeclaration","scope":2242,"src":"8647:13:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2112,"name":"uint256","nodeType":"ElementaryTypeName","src":"8647:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"8646:15:9"},"returnParameters":{"id":2117,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2116,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":2242,"src":"8685:7:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2115,"name":"uint256","nodeType":"ElementaryTypeName","src":"8685:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"8684:9:9"},"scope":2570,"src":"8633:983:9","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":2277,"nodeType":"Block","src":"9849:165:9","statements":[{"id":2276,"nodeType":"UncheckedBlock","src":"9859:149:9","statements":[{"assignments":[2254],"declarations":[{"constant":false,"id":2254,"mutability":"mutable","name":"result","nameLocation":"9891:6:9","nodeType":"VariableDeclaration","scope":2276,"src":"9883:14:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2253,"name":"uint256","nodeType":"ElementaryTypeName","src":"9883:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":2258,"initialValue":{"arguments":[{"id":2256,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2245,"src":"9905:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":2255,"name":"log2","nodeType":"Identifier","overloadedDeclarations":[2242,2278],"referencedDeclaration":2242,"src":"9900:4:9","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_uint256_$returns$_t_uint256_$","typeString":"function (uint256) pure returns (uint256)"}},"id":2257,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"9900:11:9","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"9883:28:9"},{"expression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2274,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2259,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2254,"src":"9932:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"components":[{"condition":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":2269,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"},"id":2263,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2260,"name":"rounding","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2248,"src":"9942:8:9","typeDescriptions":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"id":2261,"name":"Rounding","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1711,"src":"9954:8:9","typeDescriptions":{"typeIdentifier":"t_type$_t_enum$_Rounding_$1711_$","typeString":"type(enum Math.Rounding)"}},"id":2262,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"9963:2:9","memberName":"Up","nodeType":"MemberAccess","referencedDeclaration":1709,"src":"9954:11:9","typeDescriptions":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"}},"src":"9942:23:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"&&","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2268,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2266,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"hexValue":"31","id":2264,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9969:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"nodeType":"BinaryOperation","operator":"<<","rightExpression":{"id":2265,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2254,"src":"9974:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"9969:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"<","rightExpression":{"id":2267,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2245,"src":"9983:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"9969:19:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"9942:46:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"falseExpression":{"hexValue":"30","id":2271,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9995:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"id":2272,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"Conditional","src":"9942:54:9","trueExpression":{"hexValue":"31","id":2270,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"9991:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"}}],"id":2273,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"9941:56:9","typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"}},"src":"9932:65:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"functionReturnParameters":2252,"id":2275,"nodeType":"Return","src":"9925:72:9"}]}]},"documentation":{"id":2243,"nodeType":"StructuredDocumentation","src":"9622:142:9","text":" @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n Returns 0 if given 0."},"id":2278,"implemented":true,"kind":"function","modifiers":[],"name":"log2","nameLocation":"9778:4:9","nodeType":"FunctionDefinition","parameters":{"id":2249,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2245,"mutability":"mutable","name":"value","nameLocation":"9791:5:9","nodeType":"VariableDeclaration","scope":2278,"src":"9783:13:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2244,"name":"uint256","nodeType":"ElementaryTypeName","src":"9783:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2248,"mutability":"mutable","name":"rounding","nameLocation":"9807:8:9","nodeType":"VariableDeclaration","scope":2278,"src":"9798:17:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"},"typeName":{"id":2247,"nodeType":"UserDefinedTypeName","pathNode":{"id":2246,"name":"Rounding","nameLocations":["9798:8:9"],"nodeType":"IdentifierPath","referencedDeclaration":1711,"src":"9798:8:9"},"referencedDeclaration":1711,"src":"9798:8:9","typeDescriptions":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"}},"visibility":"internal"}],"src":"9782:34:9"},"returnParameters":{"id":2252,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2251,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":2278,"src":"9840:7:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2250,"name":"uint256","nodeType":"ElementaryTypeName","src":"9840:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"9839:9:9"},"scope":2570,"src":"9769:245:9","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":2406,"nodeType":"Block","src":"10201:854:9","statements":[{"assignments":[2287],"declarations":[{"constant":false,"id":2287,"mutability":"mutable","name":"result","nameLocation":"10219:6:9","nodeType":"VariableDeclaration","scope":2406,"src":"10211:14:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2286,"name":"uint256","nodeType":"ElementaryTypeName","src":"10211:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":2289,"initialValue":{"hexValue":"30","id":2288,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10228:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"nodeType":"VariableDeclarationStatement","src":"10211:18:9"},{"id":2403,"nodeType":"UncheckedBlock","src":"10239:787:9","statements":[{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2294,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2290,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2281,"src":"10267:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">=","rightExpression":{"commonType":{"typeIdentifier":"t_rational_10000000000000000000000000000000000000000000000000000000000000000_by_1","typeString":"int_const 1000...(57 digits omitted)...0000"},"id":2293,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"leftExpression":{"hexValue":"3130","id":2291,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10276:2:9","typeDescriptions":{"typeIdentifier":"t_rational_10_by_1","typeString":"int_const 10"},"value":"10"},"nodeType":"BinaryOperation","operator":"**","rightExpression":{"hexValue":"3634","id":2292,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10282:2:9","typeDescriptions":{"typeIdentifier":"t_rational_64_by_1","typeString":"int_const 64"},"value":"64"},"src":"10276:8:9","typeDescriptions":{"typeIdentifier":"t_rational_10000000000000000000000000000000000000000000000000000000000000000_by_1","typeString":"int_const 1000...(57 digits omitted)...0000"}},"src":"10267:17:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":2306,"nodeType":"IfStatement","src":"10263:103:9","trueBody":{"id":2305,"nodeType":"Block","src":"10286:80:9","statements":[{"expression":{"id":2299,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2295,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2281,"src":"10304:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"/=","rightHandSide":{"commonType":{"typeIdentifier":"t_rational_10000000000000000000000000000000000000000000000000000000000000000_by_1","typeString":"int_const 1000...(57 digits omitted)...0000"},"id":2298,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"leftExpression":{"hexValue":"3130","id":2296,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10313:2:9","typeDescriptions":{"typeIdentifier":"t_rational_10_by_1","typeString":"int_const 10"},"value":"10"},"nodeType":"BinaryOperation","operator":"**","rightExpression":{"hexValue":"3634","id":2297,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10319:2:9","typeDescriptions":{"typeIdentifier":"t_rational_64_by_1","typeString":"int_const 64"},"value":"64"},"src":"10313:8:9","typeDescriptions":{"typeIdentifier":"t_rational_10000000000000000000000000000000000000000000000000000000000000000_by_1","typeString":"int_const 1000...(57 digits omitted)...0000"}},"src":"10304:17:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2300,"nodeType":"ExpressionStatement","src":"10304:17:9"},{"expression":{"id":2303,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2301,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2287,"src":"10339:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"3634","id":2302,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10349:2:9","typeDescriptions":{"typeIdentifier":"t_rational_64_by_1","typeString":"int_const 64"},"value":"64"},"src":"10339:12:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2304,"nodeType":"ExpressionStatement","src":"10339:12:9"}]}},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2311,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2307,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2281,"src":"10383:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">=","rightExpression":{"commonType":{"typeIdentifier":"t_rational_100000000000000000000000000000000_by_1","typeString":"int_const 1000...(25 digits omitted)...0000"},"id":2310,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"leftExpression":{"hexValue":"3130","id":2308,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10392:2:9","typeDescriptions":{"typeIdentifier":"t_rational_10_by_1","typeString":"int_const 10"},"value":"10"},"nodeType":"BinaryOperation","operator":"**","rightExpression":{"hexValue":"3332","id":2309,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10398:2:9","typeDescriptions":{"typeIdentifier":"t_rational_32_by_1","typeString":"int_const 32"},"value":"32"},"src":"10392:8:9","typeDescriptions":{"typeIdentifier":"t_rational_100000000000000000000000000000000_by_1","typeString":"int_const 1000...(25 digits omitted)...0000"}},"src":"10383:17:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":2323,"nodeType":"IfStatement","src":"10379:103:9","trueBody":{"id":2322,"nodeType":"Block","src":"10402:80:9","statements":[{"expression":{"id":2316,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2312,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2281,"src":"10420:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"/=","rightHandSide":{"commonType":{"typeIdentifier":"t_rational_100000000000000000000000000000000_by_1","typeString":"int_const 1000...(25 digits omitted)...0000"},"id":2315,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"leftExpression":{"hexValue":"3130","id":2313,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10429:2:9","typeDescriptions":{"typeIdentifier":"t_rational_10_by_1","typeString":"int_const 10"},"value":"10"},"nodeType":"BinaryOperation","operator":"**","rightExpression":{"hexValue":"3332","id":2314,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10435:2:9","typeDescriptions":{"typeIdentifier":"t_rational_32_by_1","typeString":"int_const 32"},"value":"32"},"src":"10429:8:9","typeDescriptions":{"typeIdentifier":"t_rational_100000000000000000000000000000000_by_1","typeString":"int_const 1000...(25 digits omitted)...0000"}},"src":"10420:17:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2317,"nodeType":"ExpressionStatement","src":"10420:17:9"},{"expression":{"id":2320,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2318,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2287,"src":"10455:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"3332","id":2319,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10465:2:9","typeDescriptions":{"typeIdentifier":"t_rational_32_by_1","typeString":"int_const 32"},"value":"32"},"src":"10455:12:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2321,"nodeType":"ExpressionStatement","src":"10455:12:9"}]}},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2328,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2324,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2281,"src":"10499:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">=","rightExpression":{"commonType":{"typeIdentifier":"t_rational_10000000000000000_by_1","typeString":"int_const 10000000000000000"},"id":2327,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"leftExpression":{"hexValue":"3130","id":2325,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10508:2:9","typeDescriptions":{"typeIdentifier":"t_rational_10_by_1","typeString":"int_const 10"},"value":"10"},"nodeType":"BinaryOperation","operator":"**","rightExpression":{"hexValue":"3136","id":2326,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10514:2:9","typeDescriptions":{"typeIdentifier":"t_rational_16_by_1","typeString":"int_const 16"},"value":"16"},"src":"10508:8:9","typeDescriptions":{"typeIdentifier":"t_rational_10000000000000000_by_1","typeString":"int_const 10000000000000000"}},"src":"10499:17:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":2340,"nodeType":"IfStatement","src":"10495:103:9","trueBody":{"id":2339,"nodeType":"Block","src":"10518:80:9","statements":[{"expression":{"id":2333,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2329,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2281,"src":"10536:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"/=","rightHandSide":{"commonType":{"typeIdentifier":"t_rational_10000000000000000_by_1","typeString":"int_const 10000000000000000"},"id":2332,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"leftExpression":{"hexValue":"3130","id":2330,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10545:2:9","typeDescriptions":{"typeIdentifier":"t_rational_10_by_1","typeString":"int_const 10"},"value":"10"},"nodeType":"BinaryOperation","operator":"**","rightExpression":{"hexValue":"3136","id":2331,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10551:2:9","typeDescriptions":{"typeIdentifier":"t_rational_16_by_1","typeString":"int_const 16"},"value":"16"},"src":"10545:8:9","typeDescriptions":{"typeIdentifier":"t_rational_10000000000000000_by_1","typeString":"int_const 10000000000000000"}},"src":"10536:17:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2334,"nodeType":"ExpressionStatement","src":"10536:17:9"},{"expression":{"id":2337,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2335,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2287,"src":"10571:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"3136","id":2336,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10581:2:9","typeDescriptions":{"typeIdentifier":"t_rational_16_by_1","typeString":"int_const 16"},"value":"16"},"src":"10571:12:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2338,"nodeType":"ExpressionStatement","src":"10571:12:9"}]}},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2345,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2341,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2281,"src":"10615:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">=","rightExpression":{"commonType":{"typeIdentifier":"t_rational_100000000_by_1","typeString":"int_const 100000000"},"id":2344,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"leftExpression":{"hexValue":"3130","id":2342,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10624:2:9","typeDescriptions":{"typeIdentifier":"t_rational_10_by_1","typeString":"int_const 10"},"value":"10"},"nodeType":"BinaryOperation","operator":"**","rightExpression":{"hexValue":"38","id":2343,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10630:1:9","typeDescriptions":{"typeIdentifier":"t_rational_8_by_1","typeString":"int_const 8"},"value":"8"},"src":"10624:7:9","typeDescriptions":{"typeIdentifier":"t_rational_100000000_by_1","typeString":"int_const 100000000"}},"src":"10615:16:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":2357,"nodeType":"IfStatement","src":"10611:100:9","trueBody":{"id":2356,"nodeType":"Block","src":"10633:78:9","statements":[{"expression":{"id":2350,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2346,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2281,"src":"10651:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"/=","rightHandSide":{"commonType":{"typeIdentifier":"t_rational_100000000_by_1","typeString":"int_const 100000000"},"id":2349,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"leftExpression":{"hexValue":"3130","id":2347,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10660:2:9","typeDescriptions":{"typeIdentifier":"t_rational_10_by_1","typeString":"int_const 10"},"value":"10"},"nodeType":"BinaryOperation","operator":"**","rightExpression":{"hexValue":"38","id":2348,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10666:1:9","typeDescriptions":{"typeIdentifier":"t_rational_8_by_1","typeString":"int_const 8"},"value":"8"},"src":"10660:7:9","typeDescriptions":{"typeIdentifier":"t_rational_100000000_by_1","typeString":"int_const 100000000"}},"src":"10651:16:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2351,"nodeType":"ExpressionStatement","src":"10651:16:9"},{"expression":{"id":2354,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2352,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2287,"src":"10685:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"38","id":2353,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10695:1:9","typeDescriptions":{"typeIdentifier":"t_rational_8_by_1","typeString":"int_const 8"},"value":"8"},"src":"10685:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2355,"nodeType":"ExpressionStatement","src":"10685:11:9"}]}},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2362,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2358,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2281,"src":"10728:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">=","rightExpression":{"commonType":{"typeIdentifier":"t_rational_10000_by_1","typeString":"int_const 10000"},"id":2361,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"leftExpression":{"hexValue":"3130","id":2359,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10737:2:9","typeDescriptions":{"typeIdentifier":"t_rational_10_by_1","typeString":"int_const 10"},"value":"10"},"nodeType":"BinaryOperation","operator":"**","rightExpression":{"hexValue":"34","id":2360,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10743:1:9","typeDescriptions":{"typeIdentifier":"t_rational_4_by_1","typeString":"int_const 4"},"value":"4"},"src":"10737:7:9","typeDescriptions":{"typeIdentifier":"t_rational_10000_by_1","typeString":"int_const 10000"}},"src":"10728:16:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":2374,"nodeType":"IfStatement","src":"10724:100:9","trueBody":{"id":2373,"nodeType":"Block","src":"10746:78:9","statements":[{"expression":{"id":2367,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2363,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2281,"src":"10764:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"/=","rightHandSide":{"commonType":{"typeIdentifier":"t_rational_10000_by_1","typeString":"int_const 10000"},"id":2366,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"leftExpression":{"hexValue":"3130","id":2364,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10773:2:9","typeDescriptions":{"typeIdentifier":"t_rational_10_by_1","typeString":"int_const 10"},"value":"10"},"nodeType":"BinaryOperation","operator":"**","rightExpression":{"hexValue":"34","id":2365,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10779:1:9","typeDescriptions":{"typeIdentifier":"t_rational_4_by_1","typeString":"int_const 4"},"value":"4"},"src":"10773:7:9","typeDescriptions":{"typeIdentifier":"t_rational_10000_by_1","typeString":"int_const 10000"}},"src":"10764:16:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2368,"nodeType":"ExpressionStatement","src":"10764:16:9"},{"expression":{"id":2371,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2369,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2287,"src":"10798:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"34","id":2370,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10808:1:9","typeDescriptions":{"typeIdentifier":"t_rational_4_by_1","typeString":"int_const 4"},"value":"4"},"src":"10798:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2372,"nodeType":"ExpressionStatement","src":"10798:11:9"}]}},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2379,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2375,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2281,"src":"10841:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">=","rightExpression":{"commonType":{"typeIdentifier":"t_rational_100_by_1","typeString":"int_const 100"},"id":2378,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"leftExpression":{"hexValue":"3130","id":2376,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10850:2:9","typeDescriptions":{"typeIdentifier":"t_rational_10_by_1","typeString":"int_const 10"},"value":"10"},"nodeType":"BinaryOperation","operator":"**","rightExpression":{"hexValue":"32","id":2377,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10856:1:9","typeDescriptions":{"typeIdentifier":"t_rational_2_by_1","typeString":"int_const 2"},"value":"2"},"src":"10850:7:9","typeDescriptions":{"typeIdentifier":"t_rational_100_by_1","typeString":"int_const 100"}},"src":"10841:16:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":2391,"nodeType":"IfStatement","src":"10837:100:9","trueBody":{"id":2390,"nodeType":"Block","src":"10859:78:9","statements":[{"expression":{"id":2384,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2380,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2281,"src":"10877:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"/=","rightHandSide":{"commonType":{"typeIdentifier":"t_rational_100_by_1","typeString":"int_const 100"},"id":2383,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"leftExpression":{"hexValue":"3130","id":2381,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10886:2:9","typeDescriptions":{"typeIdentifier":"t_rational_10_by_1","typeString":"int_const 10"},"value":"10"},"nodeType":"BinaryOperation","operator":"**","rightExpression":{"hexValue":"32","id":2382,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10892:1:9","typeDescriptions":{"typeIdentifier":"t_rational_2_by_1","typeString":"int_const 2"},"value":"2"},"src":"10886:7:9","typeDescriptions":{"typeIdentifier":"t_rational_100_by_1","typeString":"int_const 100"}},"src":"10877:16:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2385,"nodeType":"ExpressionStatement","src":"10877:16:9"},{"expression":{"id":2388,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2386,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2287,"src":"10911:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"32","id":2387,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10921:1:9","typeDescriptions":{"typeIdentifier":"t_rational_2_by_1","typeString":"int_const 2"},"value":"2"},"src":"10911:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2389,"nodeType":"ExpressionStatement","src":"10911:11:9"}]}},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2396,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2392,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2281,"src":"10954:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">=","rightExpression":{"commonType":{"typeIdentifier":"t_rational_10_by_1","typeString":"int_const 10"},"id":2395,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"leftExpression":{"hexValue":"3130","id":2393,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10963:2:9","typeDescriptions":{"typeIdentifier":"t_rational_10_by_1","typeString":"int_const 10"},"value":"10"},"nodeType":"BinaryOperation","operator":"**","rightExpression":{"hexValue":"31","id":2394,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"10969:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"10963:7:9","typeDescriptions":{"typeIdentifier":"t_rational_10_by_1","typeString":"int_const 10"}},"src":"10954:16:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":2402,"nodeType":"IfStatement","src":"10950:66:9","trueBody":{"id":2401,"nodeType":"Block","src":"10972:44:9","statements":[{"expression":{"id":2399,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2397,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2287,"src":"10990:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"31","id":2398,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"11000:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"10990:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2400,"nodeType":"ExpressionStatement","src":"10990:11:9"}]}}]},{"expression":{"id":2404,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2287,"src":"11042:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"functionReturnParameters":2285,"id":2405,"nodeType":"Return","src":"11035:13:9"}]},"documentation":{"id":2279,"nodeType":"StructuredDocumentation","src":"10020:114:9","text":" @dev Return the log in base 10, rounded down, of a positive value.\n Returns 0 if given 0."},"id":2407,"implemented":true,"kind":"function","modifiers":[],"name":"log10","nameLocation":"10148:5:9","nodeType":"FunctionDefinition","parameters":{"id":2282,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2281,"mutability":"mutable","name":"value","nameLocation":"10162:5:9","nodeType":"VariableDeclaration","scope":2407,"src":"10154:13:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2280,"name":"uint256","nodeType":"ElementaryTypeName","src":"10154:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"10153:15:9"},"returnParameters":{"id":2285,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2284,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":2407,"src":"10192:7:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2283,"name":"uint256","nodeType":"ElementaryTypeName","src":"10192:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"10191:9:9"},"scope":2570,"src":"10139:916:9","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":2442,"nodeType":"Block","src":"11290:167:9","statements":[{"id":2441,"nodeType":"UncheckedBlock","src":"11300:151:9","statements":[{"assignments":[2419],"declarations":[{"constant":false,"id":2419,"mutability":"mutable","name":"result","nameLocation":"11332:6:9","nodeType":"VariableDeclaration","scope":2441,"src":"11324:14:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2418,"name":"uint256","nodeType":"ElementaryTypeName","src":"11324:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":2423,"initialValue":{"arguments":[{"id":2421,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2410,"src":"11347:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":2420,"name":"log10","nodeType":"Identifier","overloadedDeclarations":[2407,2443],"referencedDeclaration":2407,"src":"11341:5:9","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_uint256_$returns$_t_uint256_$","typeString":"function (uint256) pure returns (uint256)"}},"id":2422,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"11341:12:9","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"11324:29:9"},{"expression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2439,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2424,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2419,"src":"11374:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"components":[{"condition":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":2434,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"},"id":2428,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2425,"name":"rounding","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2413,"src":"11384:8:9","typeDescriptions":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"id":2426,"name":"Rounding","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1711,"src":"11396:8:9","typeDescriptions":{"typeIdentifier":"t_type$_t_enum$_Rounding_$1711_$","typeString":"type(enum Math.Rounding)"}},"id":2427,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"11405:2:9","memberName":"Up","nodeType":"MemberAccess","referencedDeclaration":1709,"src":"11396:11:9","typeDescriptions":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"}},"src":"11384:23:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"&&","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2433,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2431,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"hexValue":"3130","id":2429,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"11411:2:9","typeDescriptions":{"typeIdentifier":"t_rational_10_by_1","typeString":"int_const 10"},"value":"10"},"nodeType":"BinaryOperation","operator":"**","rightExpression":{"id":2430,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2419,"src":"11417:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"11411:12:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"<","rightExpression":{"id":2432,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2410,"src":"11426:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"11411:20:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"11384:47:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"falseExpression":{"hexValue":"30","id":2436,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"11438:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"id":2437,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"Conditional","src":"11384:55:9","trueExpression":{"hexValue":"31","id":2435,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"11434:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"}}],"id":2438,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"11383:57:9","typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"}},"src":"11374:66:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"functionReturnParameters":2417,"id":2440,"nodeType":"Return","src":"11367:73:9"}]}]},"documentation":{"id":2408,"nodeType":"StructuredDocumentation","src":"11061:143:9","text":" @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n Returns 0 if given 0."},"id":2443,"implemented":true,"kind":"function","modifiers":[],"name":"log10","nameLocation":"11218:5:9","nodeType":"FunctionDefinition","parameters":{"id":2414,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2410,"mutability":"mutable","name":"value","nameLocation":"11232:5:9","nodeType":"VariableDeclaration","scope":2443,"src":"11224:13:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2409,"name":"uint256","nodeType":"ElementaryTypeName","src":"11224:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2413,"mutability":"mutable","name":"rounding","nameLocation":"11248:8:9","nodeType":"VariableDeclaration","scope":2443,"src":"11239:17:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"},"typeName":{"id":2412,"nodeType":"UserDefinedTypeName","pathNode":{"id":2411,"name":"Rounding","nameLocations":["11239:8:9"],"nodeType":"IdentifierPath","referencedDeclaration":1711,"src":"11239:8:9"},"referencedDeclaration":1711,"src":"11239:8:9","typeDescriptions":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"}},"visibility":"internal"}],"src":"11223:34:9"},"returnParameters":{"id":2417,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2416,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":2443,"src":"11281:7:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2415,"name":"uint256","nodeType":"ElementaryTypeName","src":"11281:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"11280:9:9"},"scope":2570,"src":"11209:248:9","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":2529,"nodeType":"Block","src":"11771:600:9","statements":[{"assignments":[2452],"declarations":[{"constant":false,"id":2452,"mutability":"mutable","name":"result","nameLocation":"11789:6:9","nodeType":"VariableDeclaration","scope":2529,"src":"11781:14:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2451,"name":"uint256","nodeType":"ElementaryTypeName","src":"11781:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":2454,"initialValue":{"hexValue":"30","id":2453,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"11798:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"nodeType":"VariableDeclarationStatement","src":"11781:18:9"},{"id":2526,"nodeType":"UncheckedBlock","src":"11809:533:9","statements":[{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2459,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2457,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2455,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2446,"src":"11837:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"313238","id":2456,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"11846:3:9","typeDescriptions":{"typeIdentifier":"t_rational_128_by_1","typeString":"int_const 128"},"value":"128"},"src":"11837:12:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"hexValue":"30","id":2458,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"11852:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"11837:16:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":2469,"nodeType":"IfStatement","src":"11833:98:9","trueBody":{"id":2468,"nodeType":"Block","src":"11855:76:9","statements":[{"expression":{"id":2462,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2460,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2446,"src":"11873:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":">>=","rightHandSide":{"hexValue":"313238","id":2461,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"11883:3:9","typeDescriptions":{"typeIdentifier":"t_rational_128_by_1","typeString":"int_const 128"},"value":"128"},"src":"11873:13:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2463,"nodeType":"ExpressionStatement","src":"11873:13:9"},{"expression":{"id":2466,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2464,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2452,"src":"11904:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"3136","id":2465,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"11914:2:9","typeDescriptions":{"typeIdentifier":"t_rational_16_by_1","typeString":"int_const 16"},"value":"16"},"src":"11904:12:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2467,"nodeType":"ExpressionStatement","src":"11904:12:9"}]}},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2474,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2472,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2470,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2446,"src":"11948:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"3634","id":2471,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"11957:2:9","typeDescriptions":{"typeIdentifier":"t_rational_64_by_1","typeString":"int_const 64"},"value":"64"},"src":"11948:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"hexValue":"30","id":2473,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"11962:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"11948:15:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":2484,"nodeType":"IfStatement","src":"11944:95:9","trueBody":{"id":2483,"nodeType":"Block","src":"11965:74:9","statements":[{"expression":{"id":2477,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2475,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2446,"src":"11983:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":">>=","rightHandSide":{"hexValue":"3634","id":2476,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"11993:2:9","typeDescriptions":{"typeIdentifier":"t_rational_64_by_1","typeString":"int_const 64"},"value":"64"},"src":"11983:12:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2478,"nodeType":"ExpressionStatement","src":"11983:12:9"},{"expression":{"id":2481,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2479,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2452,"src":"12013:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"38","id":2480,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"12023:1:9","typeDescriptions":{"typeIdentifier":"t_rational_8_by_1","typeString":"int_const 8"},"value":"8"},"src":"12013:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2482,"nodeType":"ExpressionStatement","src":"12013:11:9"}]}},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2489,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2487,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2485,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2446,"src":"12056:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"3332","id":2486,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"12065:2:9","typeDescriptions":{"typeIdentifier":"t_rational_32_by_1","typeString":"int_const 32"},"value":"32"},"src":"12056:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"hexValue":"30","id":2488,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"12070:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"12056:15:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":2499,"nodeType":"IfStatement","src":"12052:95:9","trueBody":{"id":2498,"nodeType":"Block","src":"12073:74:9","statements":[{"expression":{"id":2492,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2490,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2446,"src":"12091:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":">>=","rightHandSide":{"hexValue":"3332","id":2491,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"12101:2:9","typeDescriptions":{"typeIdentifier":"t_rational_32_by_1","typeString":"int_const 32"},"value":"32"},"src":"12091:12:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2493,"nodeType":"ExpressionStatement","src":"12091:12:9"},{"expression":{"id":2496,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2494,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2452,"src":"12121:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"34","id":2495,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"12131:1:9","typeDescriptions":{"typeIdentifier":"t_rational_4_by_1","typeString":"int_const 4"},"value":"4"},"src":"12121:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2497,"nodeType":"ExpressionStatement","src":"12121:11:9"}]}},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2504,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2502,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2500,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2446,"src":"12164:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"3136","id":2501,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"12173:2:9","typeDescriptions":{"typeIdentifier":"t_rational_16_by_1","typeString":"int_const 16"},"value":"16"},"src":"12164:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"hexValue":"30","id":2503,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"12178:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"12164:15:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":2514,"nodeType":"IfStatement","src":"12160:95:9","trueBody":{"id":2513,"nodeType":"Block","src":"12181:74:9","statements":[{"expression":{"id":2507,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2505,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2446,"src":"12199:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":">>=","rightHandSide":{"hexValue":"3136","id":2506,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"12209:2:9","typeDescriptions":{"typeIdentifier":"t_rational_16_by_1","typeString":"int_const 16"},"value":"16"},"src":"12199:12:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2508,"nodeType":"ExpressionStatement","src":"12199:12:9"},{"expression":{"id":2511,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2509,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2452,"src":"12229:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"32","id":2510,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"12239:1:9","typeDescriptions":{"typeIdentifier":"t_rational_2_by_1","typeString":"int_const 2"},"value":"2"},"src":"12229:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2512,"nodeType":"ExpressionStatement","src":"12229:11:9"}]}},{"condition":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2519,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2517,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2515,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2446,"src":"12272:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"38","id":2516,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"12281:1:9","typeDescriptions":{"typeIdentifier":"t_rational_8_by_1","typeString":"int_const 8"},"value":"8"},"src":"12272:10:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"hexValue":"30","id":2518,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"12285:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"12272:14:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"id":2525,"nodeType":"IfStatement","src":"12268:64:9","trueBody":{"id":2524,"nodeType":"Block","src":"12288:44:9","statements":[{"expression":{"id":2522,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftHandSide":{"id":2520,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2452,"src":"12306:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"Assignment","operator":"+=","rightHandSide":{"hexValue":"31","id":2521,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"12316:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"12306:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"id":2523,"nodeType":"ExpressionStatement","src":"12306:11:9"}]}}]},{"expression":{"id":2527,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2452,"src":"12358:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"functionReturnParameters":2450,"id":2528,"nodeType":"Return","src":"12351:13:9"}]},"documentation":{"id":2444,"nodeType":"StructuredDocumentation","src":"11463:240:9","text":" @dev Return the log in base 256, rounded down, of a positive value.\n Returns 0 if given 0.\n Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string."},"id":2530,"implemented":true,"kind":"function","modifiers":[],"name":"log256","nameLocation":"11717:6:9","nodeType":"FunctionDefinition","parameters":{"id":2447,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2446,"mutability":"mutable","name":"value","nameLocation":"11732:5:9","nodeType":"VariableDeclaration","scope":2530,"src":"11724:13:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2445,"name":"uint256","nodeType":"ElementaryTypeName","src":"11724:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"11723:15:9"},"returnParameters":{"id":2450,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2449,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":2530,"src":"11762:7:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2448,"name":"uint256","nodeType":"ElementaryTypeName","src":"11762:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"11761:9:9"},"scope":2570,"src":"11708:663:9","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":2568,"nodeType":"Block","src":"12608:174:9","statements":[{"id":2567,"nodeType":"UncheckedBlock","src":"12618:158:9","statements":[{"assignments":[2542],"declarations":[{"constant":false,"id":2542,"mutability":"mutable","name":"result","nameLocation":"12650:6:9","nodeType":"VariableDeclaration","scope":2567,"src":"12642:14:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2541,"name":"uint256","nodeType":"ElementaryTypeName","src":"12642:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"id":2546,"initialValue":{"arguments":[{"id":2544,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2533,"src":"12666:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":2543,"name":"log256","nodeType":"Identifier","overloadedDeclarations":[2530,2569],"referencedDeclaration":2530,"src":"12659:6:9","typeDescriptions":{"typeIdentifier":"t_function_internal_pure$_t_uint256_$returns$_t_uint256_$","typeString":"function (uint256) pure returns (uint256)"}},"id":2545,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"12659:13:9","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"VariableDeclarationStatement","src":"12642:30:9"},{"expression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2565,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2547,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2542,"src":"12693:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"components":[{"condition":{"commonType":{"typeIdentifier":"t_bool","typeString":"bool"},"id":2560,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"},"id":2551,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2548,"name":"rounding","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2536,"src":"12703:8:9","typeDescriptions":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"}},"nodeType":"BinaryOperation","operator":"==","rightExpression":{"expression":{"id":2549,"name":"Rounding","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1711,"src":"12715:8:9","typeDescriptions":{"typeIdentifier":"t_type$_t_enum$_Rounding_$1711_$","typeString":"type(enum Math.Rounding)"}},"id":2550,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"memberLocation":"12724:2:9","memberName":"Up","nodeType":"MemberAccess","referencedDeclaration":1709,"src":"12715:11:9","typeDescriptions":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"}},"src":"12703:23:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"nodeType":"BinaryOperation","operator":"&&","rightExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2559,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2557,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"hexValue":"31","id":2552,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"12730:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"nodeType":"BinaryOperation","operator":"<<","rightExpression":{"components":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2555,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2553,"name":"result","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2542,"src":"12736:6:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"<<","rightExpression":{"hexValue":"33","id":2554,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"12746:1:9","typeDescriptions":{"typeIdentifier":"t_rational_3_by_1","typeString":"int_const 3"},"value":"3"},"src":"12736:11:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"id":2556,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"12735:13:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"12730:18:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":"<","rightExpression":{"id":2558,"name":"value","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2533,"src":"12751:5:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"src":"12730:26:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"src":"12703:53:9","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"falseExpression":{"hexValue":"30","id":2562,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"12763:1:9","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"id":2563,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"Conditional","src":"12703:61:9","trueExpression":{"hexValue":"31","id":2561,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"12759:1:9","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"}}],"id":2564,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"12702:63:9","typeDescriptions":{"typeIdentifier":"t_uint8","typeString":"uint8"}},"src":"12693:72:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"functionReturnParameters":2540,"id":2566,"nodeType":"Return","src":"12686:79:9"}]}]},"documentation":{"id":2531,"nodeType":"StructuredDocumentation","src":"12377:144:9","text":" @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n Returns 0 if given 0."},"id":2569,"implemented":true,"kind":"function","modifiers":[],"name":"log256","nameLocation":"12535:6:9","nodeType":"FunctionDefinition","parameters":{"id":2537,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2533,"mutability":"mutable","name":"value","nameLocation":"12550:5:9","nodeType":"VariableDeclaration","scope":2569,"src":"12542:13:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2532,"name":"uint256","nodeType":"ElementaryTypeName","src":"12542:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2536,"mutability":"mutable","name":"rounding","nameLocation":"12566:8:9","nodeType":"VariableDeclaration","scope":2569,"src":"12557:17:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"},"typeName":{"id":2535,"nodeType":"UserDefinedTypeName","pathNode":{"id":2534,"name":"Rounding","nameLocations":["12557:8:9"],"nodeType":"IdentifierPath","referencedDeclaration":1711,"src":"12557:8:9"},"referencedDeclaration":1711,"src":"12557:8:9","typeDescriptions":{"typeIdentifier":"t_enum$_Rounding_$1711","typeString":"enum Math.Rounding"}},"visibility":"internal"}],"src":"12541:34:9"},"returnParameters":{"id":2540,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2539,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":2569,"src":"12599:7:9","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2538,"name":"uint256","nodeType":"ElementaryTypeName","src":"12599:7:9","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"12598:9:9"},"scope":2570,"src":"12526:256:9","stateMutability":"pure","virtual":false,"visibility":"internal"}],"scope":2571,"src":"202:12582:9","usedErrors":[]}],"src":"103:12682:9"},"id":9},"@openzeppelin/contracts/utils/math/SignedMath.sol":{"ast":{"absolutePath":"@openzeppelin/contracts/utils/math/SignedMath.sol","exportedSymbols":{"SignedMath":[2675]},"id":2676,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":2572,"literals":["solidity","^","0.8",".0"],"nodeType":"PragmaDirective","src":"109:23:10"},{"abstract":false,"baseContracts":[],"canonicalName":"SignedMath","contractDependencies":[],"contractKind":"library","documentation":{"id":2573,"nodeType":"StructuredDocumentation","src":"134:80:10","text":" @dev Standard signed math utilities missing in the Solidity language."},"fullyImplemented":true,"id":2675,"linearizedBaseContracts":[2675],"name":"SignedMath","nameLocation":"223:10:10","nodeType":"ContractDefinition","nodes":[{"body":{"id":2590,"nodeType":"Block","src":"375:37:10","statements":[{"expression":{"condition":{"commonType":{"typeIdentifier":"t_int256","typeString":"int256"},"id":2585,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2583,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2576,"src":"392:1:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"nodeType":"BinaryOperation","operator":">","rightExpression":{"id":2584,"name":"b","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2578,"src":"396:1:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"src":"392:5:10","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"falseExpression":{"id":2587,"name":"b","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2578,"src":"404:1:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"id":2588,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"Conditional","src":"392:13:10","trueExpression":{"id":2586,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2576,"src":"400:1:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"functionReturnParameters":2582,"id":2589,"nodeType":"Return","src":"385:20:10"}]},"documentation":{"id":2574,"nodeType":"StructuredDocumentation","src":"240:66:10","text":" @dev Returns the largest of two signed numbers."},"id":2591,"implemented":true,"kind":"function","modifiers":[],"name":"max","nameLocation":"320:3:10","nodeType":"FunctionDefinition","parameters":{"id":2579,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2576,"mutability":"mutable","name":"a","nameLocation":"331:1:10","nodeType":"VariableDeclaration","scope":2591,"src":"324:8:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"},"typeName":{"id":2575,"name":"int256","nodeType":"ElementaryTypeName","src":"324:6:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"visibility":"internal"},{"constant":false,"id":2578,"mutability":"mutable","name":"b","nameLocation":"341:1:10","nodeType":"VariableDeclaration","scope":2591,"src":"334:8:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"},"typeName":{"id":2577,"name":"int256","nodeType":"ElementaryTypeName","src":"334:6:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"visibility":"internal"}],"src":"323:20:10"},"returnParameters":{"id":2582,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2581,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":2591,"src":"367:6:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"},"typeName":{"id":2580,"name":"int256","nodeType":"ElementaryTypeName","src":"367:6:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"visibility":"internal"}],"src":"366:8:10"},"scope":2675,"src":"311:101:10","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":2608,"nodeType":"Block","src":"554:37:10","statements":[{"expression":{"condition":{"commonType":{"typeIdentifier":"t_int256","typeString":"int256"},"id":2603,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2601,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2594,"src":"571:1:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"nodeType":"BinaryOperation","operator":"<","rightExpression":{"id":2602,"name":"b","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2596,"src":"575:1:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"src":"571:5:10","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"falseExpression":{"id":2605,"name":"b","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2596,"src":"583:1:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"id":2606,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"Conditional","src":"571:13:10","trueExpression":{"id":2604,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2594,"src":"579:1:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"functionReturnParameters":2600,"id":2607,"nodeType":"Return","src":"564:20:10"}]},"documentation":{"id":2592,"nodeType":"StructuredDocumentation","src":"418:67:10","text":" @dev Returns the smallest of two signed numbers."},"id":2609,"implemented":true,"kind":"function","modifiers":[],"name":"min","nameLocation":"499:3:10","nodeType":"FunctionDefinition","parameters":{"id":2597,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2594,"mutability":"mutable","name":"a","nameLocation":"510:1:10","nodeType":"VariableDeclaration","scope":2609,"src":"503:8:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"},"typeName":{"id":2593,"name":"int256","nodeType":"ElementaryTypeName","src":"503:6:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"visibility":"internal"},{"constant":false,"id":2596,"mutability":"mutable","name":"b","nameLocation":"520:1:10","nodeType":"VariableDeclaration","scope":2609,"src":"513:8:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"},"typeName":{"id":2595,"name":"int256","nodeType":"ElementaryTypeName","src":"513:6:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"visibility":"internal"}],"src":"502:20:10"},"returnParameters":{"id":2600,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2599,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":2609,"src":"546:6:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"},"typeName":{"id":2598,"name":"int256","nodeType":"ElementaryTypeName","src":"546:6:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"visibility":"internal"}],"src":"545:8:10"},"scope":2675,"src":"490:101:10","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":2652,"nodeType":"Block","src":"796:162:10","statements":[{"assignments":[2620],"declarations":[{"constant":false,"id":2620,"mutability":"mutable","name":"x","nameLocation":"865:1:10","nodeType":"VariableDeclaration","scope":2652,"src":"858:8:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"},"typeName":{"id":2619,"name":"int256","nodeType":"ElementaryTypeName","src":"858:6:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"visibility":"internal"}],"id":2633,"initialValue":{"commonType":{"typeIdentifier":"t_int256","typeString":"int256"},"id":2632,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"components":[{"commonType":{"typeIdentifier":"t_int256","typeString":"int256"},"id":2623,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2621,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2612,"src":"870:1:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"nodeType":"BinaryOperation","operator":"&","rightExpression":{"id":2622,"name":"b","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2614,"src":"874:1:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"src":"870:5:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}}],"id":2624,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"869:7:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"components":[{"commonType":{"typeIdentifier":"t_int256","typeString":"int256"},"id":2630,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"components":[{"commonType":{"typeIdentifier":"t_int256","typeString":"int256"},"id":2627,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2625,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2612,"src":"881:1:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"nodeType":"BinaryOperation","operator":"^","rightExpression":{"id":2626,"name":"b","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2614,"src":"885:1:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"src":"881:5:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}}],"id":2628,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"880:7:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"31","id":2629,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"891:1:10","typeDescriptions":{"typeIdentifier":"t_rational_1_by_1","typeString":"int_const 1"},"value":"1"},"src":"880:12:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}}],"id":2631,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"879:14:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"src":"869:24:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"nodeType":"VariableDeclarationStatement","src":"858:35:10"},{"expression":{"commonType":{"typeIdentifier":"t_int256","typeString":"int256"},"id":2650,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2634,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2620,"src":"910:1:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"nodeType":"BinaryOperation","operator":"+","rightExpression":{"components":[{"commonType":{"typeIdentifier":"t_int256","typeString":"int256"},"id":2648,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[{"commonType":{"typeIdentifier":"t_uint256","typeString":"uint256"},"id":2642,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"arguments":[{"id":2639,"name":"x","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2620,"src":"930:1:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_int256","typeString":"int256"}],"id":2638,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"922:7:10","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":2637,"name":"uint256","nodeType":"ElementaryTypeName","src":"922:7:10","typeDescriptions":{}}},"id":2640,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"922:10:10","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"nodeType":"BinaryOperation","operator":">>","rightExpression":{"hexValue":"323535","id":2641,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"936:3:10","typeDescriptions":{"typeIdentifier":"t_rational_255_by_1","typeString":"int_const 255"},"value":"255"},"src":"922:17:10","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":2636,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"915:6:10","typeDescriptions":{"typeIdentifier":"t_type$_t_int256_$","typeString":"type(int256)"},"typeName":{"id":2635,"name":"int256","nodeType":"ElementaryTypeName","src":"915:6:10","typeDescriptions":{}}},"id":2643,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"915:25:10","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"nodeType":"BinaryOperation","operator":"&","rightExpression":{"components":[{"commonType":{"typeIdentifier":"t_int256","typeString":"int256"},"id":2646,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2644,"name":"a","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2612,"src":"944:1:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"nodeType":"BinaryOperation","operator":"^","rightExpression":{"id":2645,"name":"b","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2614,"src":"948:1:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"src":"944:5:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}}],"id":2647,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"943:7:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"src":"915:35:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}}],"id":2649,"isConstant":false,"isInlineArray":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"TupleExpression","src":"914:37:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"src":"910:41:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"functionReturnParameters":2618,"id":2651,"nodeType":"Return","src":"903:48:10"}]},"documentation":{"id":2610,"nodeType":"StructuredDocumentation","src":"597:126:10","text":" @dev Returns the average of two signed numbers without overflow.\n The result is rounded towards zero."},"id":2653,"implemented":true,"kind":"function","modifiers":[],"name":"average","nameLocation":"737:7:10","nodeType":"FunctionDefinition","parameters":{"id":2615,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2612,"mutability":"mutable","name":"a","nameLocation":"752:1:10","nodeType":"VariableDeclaration","scope":2653,"src":"745:8:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"},"typeName":{"id":2611,"name":"int256","nodeType":"ElementaryTypeName","src":"745:6:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"visibility":"internal"},{"constant":false,"id":2614,"mutability":"mutable","name":"b","nameLocation":"762:1:10","nodeType":"VariableDeclaration","scope":2653,"src":"755:8:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"},"typeName":{"id":2613,"name":"int256","nodeType":"ElementaryTypeName","src":"755:6:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"visibility":"internal"}],"src":"744:20:10"},"returnParameters":{"id":2618,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2617,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":2653,"src":"788:6:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"},"typeName":{"id":2616,"name":"int256","nodeType":"ElementaryTypeName","src":"788:6:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"visibility":"internal"}],"src":"787:8:10"},"scope":2675,"src":"728:230:10","stateMutability":"pure","virtual":false,"visibility":"internal"},{"body":{"id":2673,"nodeType":"Block","src":"1102:158:10","statements":[{"id":2672,"nodeType":"UncheckedBlock","src":"1112:142:10","statements":[{"expression":{"arguments":[{"condition":{"commonType":{"typeIdentifier":"t_int256","typeString":"int256"},"id":2665,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"leftExpression":{"id":2663,"name":"n","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2656,"src":"1227:1:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"nodeType":"BinaryOperation","operator":">=","rightExpression":{"hexValue":"30","id":2664,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"1232:1:10","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},"src":"1227:6:10","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"falseExpression":{"id":2668,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"UnaryOperation","operator":"-","prefix":true,"src":"1240:2:10","subExpression":{"id":2667,"name":"n","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2656,"src":"1241:1:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"id":2669,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"nodeType":"Conditional","src":"1227:15:10","trueExpression":{"id":2666,"name":"n","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2656,"src":"1236:1:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_int256","typeString":"int256"}],"id":2662,"isConstant":false,"isLValue":false,"isPure":true,"lValueRequested":false,"nodeType":"ElementaryTypeNameExpression","src":"1219:7:10","typeDescriptions":{"typeIdentifier":"t_type$_t_uint256_$","typeString":"type(uint256)"},"typeName":{"id":2661,"name":"uint256","nodeType":"ElementaryTypeName","src":"1219:7:10","typeDescriptions":{}}},"id":2670,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"1219:24:10","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"functionReturnParameters":2660,"id":2671,"nodeType":"Return","src":"1212:31:10"}]}]},"documentation":{"id":2654,"nodeType":"StructuredDocumentation","src":"964:78:10","text":" @dev Returns the absolute unsigned value of a signed value."},"id":2674,"implemented":true,"kind":"function","modifiers":[],"name":"abs","nameLocation":"1056:3:10","nodeType":"FunctionDefinition","parameters":{"id":2657,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2656,"mutability":"mutable","name":"n","nameLocation":"1067:1:10","nodeType":"VariableDeclaration","scope":2674,"src":"1060:8:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"},"typeName":{"id":2655,"name":"int256","nodeType":"ElementaryTypeName","src":"1060:6:10","typeDescriptions":{"typeIdentifier":"t_int256","typeString":"int256"}},"visibility":"internal"}],"src":"1059:10:10"},"returnParameters":{"id":2660,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2659,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":2674,"src":"1093:7:10","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2658,"name":"uint256","nodeType":"ElementaryTypeName","src":"1093:7:10","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1092:9:10"},"scope":2675,"src":"1047:213:10","stateMutability":"pure","virtual":false,"visibility":"internal"}],"scope":2676,"src":"215:1047:10","usedErrors":[]}],"src":"109:1154:10"},"id":10},"contracts/AccountRegistryBridge.sol":{"ast":{"absolutePath":"contracts/AccountRegistryBridge.sol","exportedSymbols":{"AccountRegistryBridge":[2730],"IRegistry":[3207]},"id":2731,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":2677,"literals":["solidity","^","0.8",".13"],"nodeType":"PragmaDirective","src":"33:24:11"},{"absolutePath":"contracts/interfaces/IRegistry.sol","file":"./interfaces/IRegistry.sol","id":2678,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":2731,"sourceUnit":3208,"src":"59:36:11","symbolAliases":[],"unitAlias":""},{"abstract":false,"baseContracts":[],"canonicalName":"AccountRegistryBridge","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"id":2730,"linearizedBaseContracts":[2730],"name":"AccountRegistryBridge","nameLocation":"105:21:11","nodeType":"ContractDefinition","nodes":[{"constant":true,"functionSelector":"06433b1b","id":2681,"mutability":"constant","name":"REGISTRY","nameLocation":"157:8:11","nodeType":"VariableDeclaration","scope":2730,"src":"133:78:11","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2679,"name":"address","nodeType":"ElementaryTypeName","src":"133:7:11","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"hexValue":"307830323130316466423737464445303236343134383237466463363034646441463232344630393231","id":2680,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"169:42:11","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x02101dfB77FDE026414827Fdc604ddAF224F0921"},"visibility":"public"},{"constant":true,"functionSelector":"7fdfc7b2","id":2684,"mutability":"constant","name":"IMPLMENTATION","nameLocation":"241:13:11","nodeType":"VariableDeclaration","scope":2730,"src":"217:82:11","stateVariable":true,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2682,"name":"address","nodeType":"ElementaryTypeName","src":"217:7:11","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"value":{"hexValue":"307832443235363032353531343837433366333335346444383044373644353433383341323433333538","id":2683,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"257:42:11","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"value":"0x2D25602551487C3f3354dD80D76D54383A243358"},"visibility":"public"},{"body":{"id":2706,"nodeType":"Block","src":"418:202:11","statements":[{"expression":{"arguments":[{"id":2697,"name":"IMPLMENTATION","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2684,"src":"482:13:11","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"expression":{"id":2698,"name":"block","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-4,"src":"509:5:11","typeDescriptions":{"typeIdentifier":"t_magic_block","typeString":"block"}},"id":2699,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"515:7:11","memberName":"chainid","nodeType":"MemberAccess","src":"509:13:11","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":2700,"name":"contractAddress","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2686,"src":"536:15:11","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":2701,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2688,"src":"565:7:11","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"hexValue":"30","id":2702,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"586:1:11","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"},{"hexValue":"","id":2703,"isConstant":false,"isLValue":false,"isPure":true,"kind":"string","lValueRequested":false,"nodeType":"Literal","src":"601:2:11","typeDescriptions":{"typeIdentifier":"t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","typeString":"literal_string \"\""},"value":""}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},{"typeIdentifier":"t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","typeString":"literal_string \"\""}],"expression":{"arguments":[{"id":2694,"name":"REGISTRY","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2681,"src":"445:8:11","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":2693,"name":"IRegistry","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":3207,"src":"435:9:11","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IRegistry_$3207_$","typeString":"type(contract IRegistry)"}},"id":2695,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"435:19:11","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_IRegistry_$3207","typeString":"contract IRegistry"}},"id":2696,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"455:13:11","memberName":"createAccount","nodeType":"MemberAccess","referencedDeclaration":3191,"src":"435:33:11","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$_t_uint256_$_t_address_$_t_uint256_$_t_uint256_$_t_bytes_memory_ptr_$returns$_t_address_$","typeString":"function (address,uint256,address,uint256,uint256,bytes memory) external returns (address)"}},"id":2704,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"435:178:11","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"functionReturnParameters":2692,"id":2705,"nodeType":"Return","src":"428:185:11"}]},"functionSelector":"5fbfb9cf","id":2707,"implemented":true,"kind":"function","modifiers":[],"name":"createAccount","nameLocation":"315:13:11","nodeType":"FunctionDefinition","parameters":{"id":2689,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2686,"mutability":"mutable","name":"contractAddress","nameLocation":"337:15:11","nodeType":"VariableDeclaration","scope":2707,"src":"329:23:11","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2685,"name":"address","nodeType":"ElementaryTypeName","src":"329:7:11","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2688,"mutability":"mutable","name":"tokenId","nameLocation":"362:7:11","nodeType":"VariableDeclaration","scope":2707,"src":"354:15:11","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2687,"name":"uint256","nodeType":"ElementaryTypeName","src":"354:7:11","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"328:42:11"},"returnParameters":{"id":2692,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2691,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":2707,"src":"405:7:11","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2690,"name":"address","nodeType":"ElementaryTypeName","src":"405:7:11","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"404:9:11"},"scope":2730,"src":"306:314:11","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":2728,"nodeType":"Block","src":"745:180:11","statements":[{"expression":{"arguments":[{"id":2720,"name":"IMPLMENTATION","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2684,"src":"803:13:11","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"expression":{"id":2721,"name":"block","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-4,"src":"830:5:11","typeDescriptions":{"typeIdentifier":"t_magic_block","typeString":"block"}},"id":2722,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"836:7:11","memberName":"chainid","nodeType":"MemberAccess","src":"830:13:11","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"id":2723,"name":"contractAddress","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2709,"src":"857:15:11","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":2724,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2711,"src":"886:7:11","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},{"hexValue":"30","id":2725,"isConstant":false,"isLValue":false,"isPure":true,"kind":"number","lValueRequested":false,"nodeType":"Literal","src":"907:1:11","typeDescriptions":{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"},"value":"0"}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"},{"typeIdentifier":"t_rational_0_by_1","typeString":"int_const 0"}],"expression":{"arguments":[{"id":2717,"name":"REGISTRY","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2681,"src":"772:8:11","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":2716,"name":"IRegistry","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":3207,"src":"762:9:11","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IRegistry_$3207_$","typeString":"type(contract IRegistry)"}},"id":2718,"isConstant":false,"isLValue":false,"isPure":true,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"762:19:11","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_IRegistry_$3207","typeString":"contract IRegistry"}},"id":2719,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"782:7:11","memberName":"account","nodeType":"MemberAccess","referencedDeclaration":3206,"src":"762:27:11","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$_t_uint256_$_t_address_$_t_uint256_$_t_uint256_$returns$_t_address_$","typeString":"function (address,uint256,address,uint256,uint256) view external returns (address)"}},"id":2726,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"762:156:11","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"functionReturnParameters":2715,"id":2727,"nodeType":"Return","src":"755:163:11"}]},"functionSelector":"192df655","id":2729,"implemented":true,"kind":"function","modifiers":[],"name":"account","nameLocation":"635:7:11","nodeType":"FunctionDefinition","parameters":{"id":2712,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2709,"mutability":"mutable","name":"contractAddress","nameLocation":"651:15:11","nodeType":"VariableDeclaration","scope":2729,"src":"643:23:11","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2708,"name":"address","nodeType":"ElementaryTypeName","src":"643:7:11","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2711,"mutability":"mutable","name":"tokenId","nameLocation":"676:7:11","nodeType":"VariableDeclaration","scope":2729,"src":"668:15:11","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2710,"name":"uint256","nodeType":"ElementaryTypeName","src":"668:7:11","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"642:42:11"},"returnParameters":{"id":2715,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2714,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":2729,"src":"732:7:11","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2713,"name":"address","nodeType":"ElementaryTypeName","src":"732:7:11","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"731:9:11"},"scope":2730,"src":"626:299:11","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":2731,"src":"96:831:11","usedErrors":[]}],"src":"33:894:11"},"id":11},"contracts/ChargedParticles.sol":{"ast":{"absolutePath":"contracts/ChargedParticles.sol","exportedSymbols":{"AccountRegistryBridge":[2730],"ChargedParticles":[2906],"IChargedParticles":[3172],"IERC165":[1704],"IERC721":[1042],"IRegistry":[3207]},"id":2907,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":2732,"literals":["solidity","^","0.8",".13"],"nodeType":"PragmaDirective","src":"33:24:12"},{"absolutePath":"contracts/interfaces/IChargedParticles.sol","file":"./interfaces/IChargedParticles.sol","id":2733,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":2907,"sourceUnit":3173,"src":"59:44:12","symbolAliases":[],"unitAlias":""},{"absolutePath":"contracts/AccountRegistryBridge.sol","file":"./AccountRegistryBridge.sol","id":2734,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":2907,"sourceUnit":2731,"src":"104:37:12","symbolAliases":[],"unitAlias":""},{"absolutePath":"@openzeppelin/contracts/token/ERC721/IERC721.sol","file":"@openzeppelin/contracts/token/ERC721/IERC721.sol","id":2735,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":2907,"sourceUnit":1043,"src":"143:58:12","symbolAliases":[],"unitAlias":""},{"abstract":false,"baseContracts":[{"baseName":{"id":2736,"name":"AccountRegistryBridge","nameLocations":["231:21:12"],"nodeType":"IdentifierPath","referencedDeclaration":2730,"src":"231:21:12"},"id":2737,"nodeType":"InheritanceSpecifier","src":"231:21:12"}],"canonicalName":"ChargedParticles","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"id":2906,"linearizedBaseContracts":[2906,2730],"name":"ChargedParticles","nameLocation":"211:16:12","nodeType":"ContractDefinition","nodes":[{"body":{"id":2754,"nodeType":"Block","src":"518:16:12","statements":[]},"functionSelector":"0bdde2ca","id":2755,"implemented":true,"kind":"function","modifiers":[],"name":"energizeParticle","nameLocation":"268:16:12","nodeType":"FunctionDefinition","parameters":{"id":2750,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2739,"mutability":"mutable","name":"contractAddress","nameLocation":"302:15:12","nodeType":"VariableDeclaration","scope":2755,"src":"294:23:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2738,"name":"address","nodeType":"ElementaryTypeName","src":"294:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2741,"mutability":"mutable","name":"tokenId","nameLocation":"335:7:12","nodeType":"VariableDeclaration","scope":2755,"src":"327:15:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2740,"name":"uint256","nodeType":"ElementaryTypeName","src":"327:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2743,"mutability":"mutable","name":"walletManagerId","nameLocation":"368:15:12","nodeType":"VariableDeclaration","scope":2755,"src":"352:31:12","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2742,"name":"string","nodeType":"ElementaryTypeName","src":"352:6:12","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":2745,"mutability":"mutable","name":"assetToken","nameLocation":"401:10:12","nodeType":"VariableDeclaration","scope":2755,"src":"393:18:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2744,"name":"address","nodeType":"ElementaryTypeName","src":"393:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2747,"mutability":"mutable","name":"assetAmount","nameLocation":"429:11:12","nodeType":"VariableDeclaration","scope":2755,"src":"421:19:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2746,"name":"uint256","nodeType":"ElementaryTypeName","src":"421:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2749,"mutability":"mutable","name":"referrer","nameLocation":"458:8:12","nodeType":"VariableDeclaration","scope":2755,"src":"450:16:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2748,"name":"address","nodeType":"ElementaryTypeName","src":"450:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"284:188:12"},"returnParameters":{"id":2753,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2752,"mutability":"mutable","name":"yieldTokensAmount","nameLocation":"499:17:12","nodeType":"VariableDeclaration","scope":2755,"src":"491:25:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2751,"name":"uint256","nodeType":"ElementaryTypeName","src":"491:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"490:27:12"},"scope":2906,"src":"259:275:12","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":2772,"nodeType":"Block","src":"791:8:12","statements":[]},"functionSelector":"621a3b70","id":2773,"implemented":true,"kind":"function","modifiers":[],"name":"dischargeParticle","nameLocation":"549:17:12","nodeType":"FunctionDefinition","parameters":{"id":2766,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2757,"mutability":"mutable","name":"receiver","nameLocation":"584:8:12","nodeType":"VariableDeclaration","scope":2773,"src":"576:16:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2756,"name":"address","nodeType":"ElementaryTypeName","src":"576:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2759,"mutability":"mutable","name":"contractAddress","nameLocation":"610:15:12","nodeType":"VariableDeclaration","scope":2773,"src":"602:23:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2758,"name":"address","nodeType":"ElementaryTypeName","src":"602:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2761,"mutability":"mutable","name":"tokenId","nameLocation":"643:7:12","nodeType":"VariableDeclaration","scope":2773,"src":"635:15:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2760,"name":"uint256","nodeType":"ElementaryTypeName","src":"635:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2763,"mutability":"mutable","name":"walletManagerId","nameLocation":"676:15:12","nodeType":"VariableDeclaration","scope":2773,"src":"660:31:12","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2762,"name":"string","nodeType":"ElementaryTypeName","src":"660:6:12","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":2765,"mutability":"mutable","name":"assetToken","nameLocation":"709:10:12","nodeType":"VariableDeclaration","scope":2773,"src":"701:18:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2764,"name":"address","nodeType":"ElementaryTypeName","src":"701:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"566:159:12"},"returnParameters":{"id":2771,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2768,"mutability":"mutable","name":"creatorAmount","nameLocation":"752:13:12","nodeType":"VariableDeclaration","scope":2773,"src":"744:21:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2767,"name":"uint256","nodeType":"ElementaryTypeName","src":"744:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2770,"mutability":"mutable","name":"receiverAmount","nameLocation":"775:14:12","nodeType":"VariableDeclaration","scope":2773,"src":"767:22:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2769,"name":"uint256","nodeType":"ElementaryTypeName","src":"767:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"743:47:12"},"scope":2906,"src":"540:259:12","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":2792,"nodeType":"Block","src":"1091:8:12","statements":[]},"functionSelector":"6697b359","id":2793,"implemented":true,"kind":"function","modifiers":[],"name":"dischargeParticleAmount","nameLocation":"814:23:12","nodeType":"FunctionDefinition","parameters":{"id":2786,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2775,"mutability":"mutable","name":"receiver","nameLocation":"855:8:12","nodeType":"VariableDeclaration","scope":2793,"src":"847:16:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2774,"name":"address","nodeType":"ElementaryTypeName","src":"847:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2777,"mutability":"mutable","name":"contractAddress","nameLocation":"881:15:12","nodeType":"VariableDeclaration","scope":2793,"src":"873:23:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2776,"name":"address","nodeType":"ElementaryTypeName","src":"873:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2779,"mutability":"mutable","name":"tokenId","nameLocation":"914:7:12","nodeType":"VariableDeclaration","scope":2793,"src":"906:15:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2778,"name":"uint256","nodeType":"ElementaryTypeName","src":"906:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2781,"mutability":"mutable","name":"walletManagerId","nameLocation":"947:15:12","nodeType":"VariableDeclaration","scope":2793,"src":"931:31:12","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2780,"name":"string","nodeType":"ElementaryTypeName","src":"931:6:12","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":2783,"mutability":"mutable","name":"assetToken","nameLocation":"980:10:12","nodeType":"VariableDeclaration","scope":2793,"src":"972:18:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2782,"name":"address","nodeType":"ElementaryTypeName","src":"972:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2785,"mutability":"mutable","name":"assetAmount","nameLocation":"1008:11:12","nodeType":"VariableDeclaration","scope":2793,"src":"1000:19:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2784,"name":"uint256","nodeType":"ElementaryTypeName","src":"1000:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"837:188:12"},"returnParameters":{"id":2791,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2788,"mutability":"mutable","name":"creatorAmount","nameLocation":"1052:13:12","nodeType":"VariableDeclaration","scope":2793,"src":"1044:21:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2787,"name":"uint256","nodeType":"ElementaryTypeName","src":"1044:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2790,"mutability":"mutable","name":"receiverAmount","nameLocation":"1075:14:12","nodeType":"VariableDeclaration","scope":2793,"src":"1067:22:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2789,"name":"uint256","nodeType":"ElementaryTypeName","src":"1067:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1043:47:12"},"scope":2906,"src":"805:294:12","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":2810,"nodeType":"Block","src":"1372:8:12","statements":[]},"functionSelector":"65d20ce2","id":2811,"implemented":true,"kind":"function","modifiers":[],"name":"dischargeParticleForCreator","nameLocation":"1114:27:12","nodeType":"FunctionDefinition","parameters":{"id":2806,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2795,"mutability":"mutable","name":"receiver","nameLocation":"1159:8:12","nodeType":"VariableDeclaration","scope":2811,"src":"1151:16:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2794,"name":"address","nodeType":"ElementaryTypeName","src":"1151:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2797,"mutability":"mutable","name":"contractAddress","nameLocation":"1185:15:12","nodeType":"VariableDeclaration","scope":2811,"src":"1177:23:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2796,"name":"address","nodeType":"ElementaryTypeName","src":"1177:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2799,"mutability":"mutable","name":"tokenId","nameLocation":"1218:7:12","nodeType":"VariableDeclaration","scope":2811,"src":"1210:15:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2798,"name":"uint256","nodeType":"ElementaryTypeName","src":"1210:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2801,"mutability":"mutable","name":"walletManagerId","nameLocation":"1251:15:12","nodeType":"VariableDeclaration","scope":2811,"src":"1235:31:12","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2800,"name":"string","nodeType":"ElementaryTypeName","src":"1235:6:12","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":2803,"mutability":"mutable","name":"assetToken","nameLocation":"1284:10:12","nodeType":"VariableDeclaration","scope":2811,"src":"1276:18:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2802,"name":"address","nodeType":"ElementaryTypeName","src":"1276:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2805,"mutability":"mutable","name":"assetAmount","nameLocation":"1312:11:12","nodeType":"VariableDeclaration","scope":2811,"src":"1304:19:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2804,"name":"uint256","nodeType":"ElementaryTypeName","src":"1304:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1141:188:12"},"returnParameters":{"id":2809,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2808,"mutability":"mutable","name":"receiverAmount","nameLocation":"1356:14:12","nodeType":"VariableDeclaration","scope":2811,"src":"1348:22:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2807,"name":"uint256","nodeType":"ElementaryTypeName","src":"1348:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1347:24:12"},"scope":2906,"src":"1105:275:12","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":2828,"nodeType":"Block","src":"1635:8:12","statements":[]},"functionSelector":"acab923c","id":2829,"implemented":true,"kind":"function","modifiers":[],"name":"releaseParticle","nameLocation":"1395:15:12","nodeType":"FunctionDefinition","parameters":{"id":2822,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2813,"mutability":"mutable","name":"receiver","nameLocation":"1428:8:12","nodeType":"VariableDeclaration","scope":2829,"src":"1420:16:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2812,"name":"address","nodeType":"ElementaryTypeName","src":"1420:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2815,"mutability":"mutable","name":"contractAddress","nameLocation":"1454:15:12","nodeType":"VariableDeclaration","scope":2829,"src":"1446:23:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2814,"name":"address","nodeType":"ElementaryTypeName","src":"1446:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2817,"mutability":"mutable","name":"tokenId","nameLocation":"1487:7:12","nodeType":"VariableDeclaration","scope":2829,"src":"1479:15:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2816,"name":"uint256","nodeType":"ElementaryTypeName","src":"1479:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2819,"mutability":"mutable","name":"walletManagerId","nameLocation":"1520:15:12","nodeType":"VariableDeclaration","scope":2829,"src":"1504:31:12","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2818,"name":"string","nodeType":"ElementaryTypeName","src":"1504:6:12","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":2821,"mutability":"mutable","name":"assetToken","nameLocation":"1553:10:12","nodeType":"VariableDeclaration","scope":2829,"src":"1545:18:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2820,"name":"address","nodeType":"ElementaryTypeName","src":"1545:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1410:159:12"},"returnParameters":{"id":2827,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2824,"mutability":"mutable","name":"creatorAmount","nameLocation":"1596:13:12","nodeType":"VariableDeclaration","scope":2829,"src":"1588:21:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2823,"name":"uint256","nodeType":"ElementaryTypeName","src":"1588:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2826,"mutability":"mutable","name":"receiverAmount","nameLocation":"1619:14:12","nodeType":"VariableDeclaration","scope":2829,"src":"1611:22:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2825,"name":"uint256","nodeType":"ElementaryTypeName","src":"1611:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1587:47:12"},"scope":2906,"src":"1386:257:12","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":2848,"nodeType":"Block","src":"1933:8:12","statements":[]},"functionSelector":"a8abef47","id":2849,"implemented":true,"kind":"function","modifiers":[],"name":"releaseParticleAmount","nameLocation":"1658:21:12","nodeType":"FunctionDefinition","parameters":{"id":2842,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2831,"mutability":"mutable","name":"receiver","nameLocation":"1697:8:12","nodeType":"VariableDeclaration","scope":2849,"src":"1689:16:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2830,"name":"address","nodeType":"ElementaryTypeName","src":"1689:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2833,"mutability":"mutable","name":"contractAddress","nameLocation":"1723:15:12","nodeType":"VariableDeclaration","scope":2849,"src":"1715:23:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2832,"name":"address","nodeType":"ElementaryTypeName","src":"1715:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2835,"mutability":"mutable","name":"tokenId","nameLocation":"1756:7:12","nodeType":"VariableDeclaration","scope":2849,"src":"1748:15:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2834,"name":"uint256","nodeType":"ElementaryTypeName","src":"1748:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2837,"mutability":"mutable","name":"walletManagerId","nameLocation":"1789:15:12","nodeType":"VariableDeclaration","scope":2849,"src":"1773:31:12","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2836,"name":"string","nodeType":"ElementaryTypeName","src":"1773:6:12","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":2839,"mutability":"mutable","name":"assetToken","nameLocation":"1822:10:12","nodeType":"VariableDeclaration","scope":2849,"src":"1814:18:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2838,"name":"address","nodeType":"ElementaryTypeName","src":"1814:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2841,"mutability":"mutable","name":"assetAmount","nameLocation":"1850:11:12","nodeType":"VariableDeclaration","scope":2849,"src":"1842:19:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2840,"name":"uint256","nodeType":"ElementaryTypeName","src":"1842:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1679:188:12"},"returnParameters":{"id":2847,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2844,"mutability":"mutable","name":"creatorAmount","nameLocation":"1894:13:12","nodeType":"VariableDeclaration","scope":2849,"src":"1886:21:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2843,"name":"uint256","nodeType":"ElementaryTypeName","src":"1886:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2846,"mutability":"mutable","name":"receiverAmount","nameLocation":"1917:14:12","nodeType":"VariableDeclaration","scope":2849,"src":"1909:22:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2845,"name":"uint256","nodeType":"ElementaryTypeName","src":"1909:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1885:47:12"},"scope":2906,"src":"1649:292:12","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":2884,"nodeType":"Block","src":"2199:178:12","statements":[{"assignments":[2867],"declarations":[{"constant":false,"id":2867,"mutability":"mutable","name":"tokenBoundAccount","nameLocation":"2217:17:12","nodeType":"VariableDeclaration","scope":2884,"src":"2209:25:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2866,"name":"address","nodeType":"ElementaryTypeName","src":"2209:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"id":2873,"initialValue":{"arguments":[{"id":2870,"name":"contractAddress","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2851,"src":"2250:15:12","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":2871,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2853,"src":"2267:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"id":2868,"name":"this","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-28,"src":"2237:4:12","typeDescriptions":{"typeIdentifier":"t_contract$_ChargedParticles_$2906","typeString":"contract ChargedParticles"}},"id":2869,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"2242:7:12","memberName":"account","nodeType":"MemberAccess","referencedDeclaration":2729,"src":"2237:12:12","typeDescriptions":{"typeIdentifier":"t_function_external_view$_t_address_$_t_uint256_$returns$_t_address_$","typeString":"function (address,uint256) view external returns (address)"}},"id":2872,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2237:38:12","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"nodeType":"VariableDeclarationStatement","src":"2209:66:12"},{"expression":{"arguments":[{"expression":{"id":2878,"name":"msg","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":-15,"src":"2328:3:12","typeDescriptions":{"typeIdentifier":"t_magic_message","typeString":"msg"}},"id":2879,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"2332:6:12","memberName":"sender","nodeType":"MemberAccess","src":"2328:10:12","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":2880,"name":"tokenBoundAccount","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2867,"src":"2340:17:12","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":2881,"name":"nftTokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2859,"src":"2359:10:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"expression":{"arguments":[{"id":2875,"name":"nftTokenAddress","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":2857,"src":"2294:15:12","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"}],"id":2874,"name":"IERC721","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":1042,"src":"2286:7:12","typeDescriptions":{"typeIdentifier":"t_type$_t_contract$_IERC721_$1042_$","typeString":"type(contract IERC721)"}},"id":2876,"isConstant":false,"isLValue":false,"isPure":false,"kind":"typeConversion","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2286:24:12","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_contract$_IERC721_$1042","typeString":"contract IERC721"}},"id":2877,"isConstant":false,"isLValue":false,"isPure":false,"lValueRequested":false,"memberLocation":"2311:16:12","memberName":"safeTransferFrom","nodeType":"MemberAccess","referencedDeclaration":997,"src":"2286:41:12","typeDescriptions":{"typeIdentifier":"t_function_external_nonpayable$_t_address_$_t_address_$_t_uint256_$returns$__$","typeString":"function (address,address,uint256) external"}},"id":2882,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"2286:84:12","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":2883,"nodeType":"ExpressionStatement","src":"2286:84:12"}]},"functionSelector":"3ff956cc","id":2885,"implemented":true,"kind":"function","modifiers":[],"name":"covalentBond","nameLocation":"1956:12:12","nodeType":"FunctionDefinition","parameters":{"id":2862,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2851,"mutability":"mutable","name":"contractAddress","nameLocation":"1986:15:12","nodeType":"VariableDeclaration","scope":2885,"src":"1978:23:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2850,"name":"address","nodeType":"ElementaryTypeName","src":"1978:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2853,"mutability":"mutable","name":"tokenId","nameLocation":"2019:7:12","nodeType":"VariableDeclaration","scope":2885,"src":"2011:15:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2852,"name":"uint256","nodeType":"ElementaryTypeName","src":"2011:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2855,"mutability":"mutable","name":"basketManagerId","nameLocation":"2052:15:12","nodeType":"VariableDeclaration","scope":2885,"src":"2036:31:12","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2854,"name":"string","nodeType":"ElementaryTypeName","src":"2036:6:12","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":2857,"mutability":"mutable","name":"nftTokenAddress","nameLocation":"2085:15:12","nodeType":"VariableDeclaration","scope":2885,"src":"2077:23:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2856,"name":"address","nodeType":"ElementaryTypeName","src":"2077:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2859,"mutability":"mutable","name":"nftTokenId","nameLocation":"2118:10:12","nodeType":"VariableDeclaration","scope":2885,"src":"2110:18:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2858,"name":"uint256","nodeType":"ElementaryTypeName","src":"2110:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2861,"mutability":"mutable","name":"nftTokenAmount","nameLocation":"2146:14:12","nodeType":"VariableDeclaration","scope":2885,"src":"2138:22:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2860,"name":"uint256","nodeType":"ElementaryTypeName","src":"2138:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1968:198:12"},"returnParameters":{"id":2865,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2864,"mutability":"mutable","name":"success","nameLocation":"2190:7:12","nodeType":"VariableDeclaration","scope":2885,"src":"2185:12:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":2863,"name":"bool","nodeType":"ElementaryTypeName","src":"2185:4:12","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"2184:14:12"},"scope":2906,"src":"1947:430:12","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"body":{"id":2904,"nodeType":"Block","src":"2666:8:12","statements":[]},"functionSelector":"fe02fb00","id":2905,"implemented":true,"kind":"function","modifiers":[],"name":"breakCovalentBond","nameLocation":"2392:17:12","nodeType":"FunctionDefinition","parameters":{"id":2900,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2887,"mutability":"mutable","name":"receiver","nameLocation":"2427:8:12","nodeType":"VariableDeclaration","scope":2905,"src":"2419:16:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2886,"name":"address","nodeType":"ElementaryTypeName","src":"2419:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2889,"mutability":"mutable","name":"contractAddress","nameLocation":"2453:15:12","nodeType":"VariableDeclaration","scope":2905,"src":"2445:23:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2888,"name":"address","nodeType":"ElementaryTypeName","src":"2445:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2891,"mutability":"mutable","name":"tokenId","nameLocation":"2486:7:12","nodeType":"VariableDeclaration","scope":2905,"src":"2478:15:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2890,"name":"uint256","nodeType":"ElementaryTypeName","src":"2478:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2893,"mutability":"mutable","name":"basketManagerId","nameLocation":"2519:15:12","nodeType":"VariableDeclaration","scope":2905,"src":"2503:31:12","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2892,"name":"string","nodeType":"ElementaryTypeName","src":"2503:6:12","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":2895,"mutability":"mutable","name":"nftTokenAddress","nameLocation":"2552:15:12","nodeType":"VariableDeclaration","scope":2905,"src":"2544:23:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2894,"name":"address","nodeType":"ElementaryTypeName","src":"2544:7:12","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2897,"mutability":"mutable","name":"nftTokenId","nameLocation":"2585:10:12","nodeType":"VariableDeclaration","scope":2905,"src":"2577:18:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2896,"name":"uint256","nodeType":"ElementaryTypeName","src":"2577:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2899,"mutability":"mutable","name":"nftTokenAmount","nameLocation":"2613:14:12","nodeType":"VariableDeclaration","scope":2905,"src":"2605:22:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2898,"name":"uint256","nodeType":"ElementaryTypeName","src":"2605:7:12","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2409:224:12"},"returnParameters":{"id":2903,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2902,"mutability":"mutable","name":"success","nameLocation":"2657:7:12","nodeType":"VariableDeclaration","scope":2905,"src":"2652:12:12","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":2901,"name":"bool","nodeType":"ElementaryTypeName","src":"2652:4:12","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"2651:14:12"},"scope":2906,"src":"2383:291:12","stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"scope":2907,"src":"202:2475:12","usedErrors":[]}],"src":"33:2645:12"},"id":12},"contracts/interfaces/IAccount.sol":{"ast":{"absolutePath":"contracts/interfaces/IAccount.sol","exportedSymbols":{"IAccount":[2932]},"id":2933,"license":"UNLICENSED","nodeType":"SourceUnit","nodes":[{"id":2908,"literals":["solidity","^","0.8",".13"],"nodeType":"PragmaDirective","src":"39:24:13"},{"abstract":false,"baseContracts":[],"canonicalName":"IAccount","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"id":2932,"linearizedBaseContracts":[2932],"name":"IAccount","nameLocation":"75:8:13","nodeType":"ContractDefinition","nodes":[{"functionSelector":"8da5cb5b","id":2913,"implemented":false,"kind":"function","modifiers":[],"name":"owner","nameLocation":"99:5:13","nodeType":"FunctionDefinition","parameters":{"id":2909,"nodeType":"ParameterList","parameters":[],"src":"104:2:13"},"returnParameters":{"id":2912,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2911,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":2913,"src":"130:7:13","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2910,"name":"address","nodeType":"ElementaryTypeName","src":"130:7:13","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"129:9:13"},"scope":2932,"src":"90:49:13","stateMutability":"view","virtual":false,"visibility":"external"},{"functionSelector":"fc0c546a","id":2920,"implemented":false,"kind":"function","modifiers":[],"name":"token","nameLocation":"154:5:13","nodeType":"FunctionDefinition","parameters":{"id":2914,"nodeType":"ParameterList","parameters":[],"src":"159:2:13"},"returnParameters":{"id":2919,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2916,"mutability":"mutable","name":"tokenContract","nameLocation":"217:13:13","nodeType":"VariableDeclaration","scope":2920,"src":"209:21:13","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2915,"name":"address","nodeType":"ElementaryTypeName","src":"209:7:13","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2918,"mutability":"mutable","name":"tokenId","nameLocation":"240:7:13","nodeType":"VariableDeclaration","scope":2920,"src":"232:15:13","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2917,"name":"uint256","nodeType":"ElementaryTypeName","src":"232:7:13","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"208:40:13"},"scope":2932,"src":"145:104:13","stateMutability":"view","virtual":false,"visibility":"external"},{"functionSelector":"9e5d4c49","id":2931,"implemented":false,"kind":"function","modifiers":[],"name":"executeCall","nameLocation":"264:11:13","nodeType":"FunctionDefinition","parameters":{"id":2927,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2922,"mutability":"mutable","name":"to","nameLocation":"293:2:13","nodeType":"VariableDeclaration","scope":2931,"src":"285:10:13","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2921,"name":"address","nodeType":"ElementaryTypeName","src":"285:7:13","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2924,"mutability":"mutable","name":"value","nameLocation":"313:5:13","nodeType":"VariableDeclaration","scope":2931,"src":"305:13:13","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2923,"name":"uint256","nodeType":"ElementaryTypeName","src":"305:7:13","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2926,"mutability":"mutable","name":"data","nameLocation":"343:4:13","nodeType":"VariableDeclaration","scope":2931,"src":"328:19:13","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":2925,"name":"bytes","nodeType":"ElementaryTypeName","src":"328:5:13","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"275:78:13"},"returnParameters":{"id":2930,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2929,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":2931,"src":"380:12:13","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_bytes_memory_ptr","typeString":"bytes"},"typeName":{"id":2928,"name":"bytes","nodeType":"ElementaryTypeName","src":"380:5:13","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"379:14:13"},"scope":2932,"src":"255:139:13","stateMutability":"payable","virtual":false,"visibility":"external"}],"scope":2933,"src":"65:331:13","usedErrors":[]}],"src":"39:358:13"},"id":13},"contracts/interfaces/IChargedParticles.sol":{"ast":{"absolutePath":"contracts/interfaces/IChargedParticles.sol","exportedSymbols":{"IChargedParticles":[3172]},"id":3173,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":2934,"literals":["solidity",">=","0.6",".0"],"nodeType":"PragmaDirective","src":"1236:24:14"},{"abstract":false,"baseContracts":[],"canonicalName":"IChargedParticles","contractDependencies":[],"contractKind":"interface","documentation":{"id":2935,"nodeType":"StructuredDocumentation","src":"1262:50:14","text":" @notice Interface for Charged Particles"},"fullyImplemented":false,"id":3172,"linearizedBaseContracts":[3172],"name":"IChargedParticles","nameLocation":"1323:17:14","nodeType":"ContractDefinition","nodes":[{"functionSelector":"31969e57","id":2940,"implemented":false,"kind":"function","modifiers":[],"name":"getStateAddress","nameLocation":"1476:15:14","nodeType":"FunctionDefinition","parameters":{"id":2936,"nodeType":"ParameterList","parameters":[],"src":"1491:2:14"},"returnParameters":{"id":2939,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2938,"mutability":"mutable","name":"stateAddress","nameLocation":"1525:12:14","nodeType":"VariableDeclaration","scope":2940,"src":"1517:20:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2937,"name":"address","nodeType":"ElementaryTypeName","src":"1517:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1516:22:14"},"scope":3172,"src":"1467:72:14","stateMutability":"view","virtual":false,"visibility":"external"},{"functionSelector":"d00999fe","id":2945,"implemented":false,"kind":"function","modifiers":[],"name":"getSettingsAddress","nameLocation":"1551:18:14","nodeType":"FunctionDefinition","parameters":{"id":2941,"nodeType":"ParameterList","parameters":[],"src":"1569:2:14"},"returnParameters":{"id":2944,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2943,"mutability":"mutable","name":"settingsAddress","nameLocation":"1603:15:14","nodeType":"VariableDeclaration","scope":2945,"src":"1595:23:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2942,"name":"address","nodeType":"ElementaryTypeName","src":"1595:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1594:25:14"},"scope":3172,"src":"1542:78:14","stateMutability":"view","virtual":false,"visibility":"external"},{"functionSelector":"8742f168","id":2950,"implemented":false,"kind":"function","modifiers":[],"name":"getManagersAddress","nameLocation":"1632:18:14","nodeType":"FunctionDefinition","parameters":{"id":2946,"nodeType":"ParameterList","parameters":[],"src":"1650:2:14"},"returnParameters":{"id":2949,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2948,"mutability":"mutable","name":"managersAddress","nameLocation":"1684:15:14","nodeType":"VariableDeclaration","scope":2950,"src":"1676:23:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2947,"name":"address","nodeType":"ElementaryTypeName","src":"1676:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1675:25:14"},"scope":3172,"src":"1623:78:14","stateMutability":"view","virtual":false,"visibility":"external"},{"functionSelector":"ee895623","id":2957,"implemented":false,"kind":"function","modifiers":[],"name":"getFeesForDeposit","nameLocation":"1714:17:14","nodeType":"FunctionDefinition","parameters":{"id":2953,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2952,"mutability":"mutable","name":"assetAmount","nameLocation":"1740:11:14","nodeType":"VariableDeclaration","scope":2957,"src":"1732:19:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2951,"name":"uint256","nodeType":"ElementaryTypeName","src":"1732:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1731:21:14"},"returnParameters":{"id":2956,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2955,"mutability":"mutable","name":"protocolFee","nameLocation":"1784:11:14","nodeType":"VariableDeclaration","scope":2957,"src":"1776:19:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2954,"name":"uint256","nodeType":"ElementaryTypeName","src":"1776:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1775:21:14"},"scope":3172,"src":"1705:92:14","stateMutability":"view","virtual":false,"visibility":"external"},{"functionSelector":"e6ea6ce7","id":2970,"implemented":false,"kind":"function","modifiers":[],"name":"baseParticleMass","nameLocation":"1809:16:14","nodeType":"FunctionDefinition","parameters":{"id":2966,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2959,"mutability":"mutable","name":"contractAddress","nameLocation":"1834:15:14","nodeType":"VariableDeclaration","scope":2970,"src":"1826:23:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2958,"name":"address","nodeType":"ElementaryTypeName","src":"1826:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2961,"mutability":"mutable","name":"tokenId","nameLocation":"1859:7:14","nodeType":"VariableDeclaration","scope":2970,"src":"1851:15:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2960,"name":"uint256","nodeType":"ElementaryTypeName","src":"1851:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2963,"mutability":"mutable","name":"walletManagerId","nameLocation":"1884:15:14","nodeType":"VariableDeclaration","scope":2970,"src":"1868:31:14","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2962,"name":"string","nodeType":"ElementaryTypeName","src":"1868:6:14","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":2965,"mutability":"mutable","name":"assetToken","nameLocation":"1909:10:14","nodeType":"VariableDeclaration","scope":2970,"src":"1901:18:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2964,"name":"address","nodeType":"ElementaryTypeName","src":"1901:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1825:95:14"},"returnParameters":{"id":2969,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2968,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":2970,"src":"1939:7:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2967,"name":"uint256","nodeType":"ElementaryTypeName","src":"1939:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"1938:9:14"},"scope":3172,"src":"1800:148:14","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"99fa4c73","id":2983,"implemented":false,"kind":"function","modifiers":[],"name":"currentParticleCharge","nameLocation":"1960:21:14","nodeType":"FunctionDefinition","parameters":{"id":2979,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2972,"mutability":"mutable","name":"contractAddress","nameLocation":"1990:15:14","nodeType":"VariableDeclaration","scope":2983,"src":"1982:23:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2971,"name":"address","nodeType":"ElementaryTypeName","src":"1982:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2974,"mutability":"mutable","name":"tokenId","nameLocation":"2015:7:14","nodeType":"VariableDeclaration","scope":2983,"src":"2007:15:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2973,"name":"uint256","nodeType":"ElementaryTypeName","src":"2007:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2976,"mutability":"mutable","name":"walletManagerId","nameLocation":"2040:15:14","nodeType":"VariableDeclaration","scope":2983,"src":"2024:31:14","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2975,"name":"string","nodeType":"ElementaryTypeName","src":"2024:6:14","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":2978,"mutability":"mutable","name":"assetToken","nameLocation":"2065:10:14","nodeType":"VariableDeclaration","scope":2983,"src":"2057:18:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2977,"name":"address","nodeType":"ElementaryTypeName","src":"2057:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"1981:95:14"},"returnParameters":{"id":2982,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2981,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":2983,"src":"2095:7:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2980,"name":"uint256","nodeType":"ElementaryTypeName","src":"2095:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2094:9:14"},"scope":3172,"src":"1951:153:14","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"ca92acd0","id":2996,"implemented":false,"kind":"function","modifiers":[],"name":"currentParticleKinetics","nameLocation":"2116:23:14","nodeType":"FunctionDefinition","parameters":{"id":2992,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2985,"mutability":"mutable","name":"contractAddress","nameLocation":"2148:15:14","nodeType":"VariableDeclaration","scope":2996,"src":"2140:23:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2984,"name":"address","nodeType":"ElementaryTypeName","src":"2140:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":2987,"mutability":"mutable","name":"tokenId","nameLocation":"2173:7:14","nodeType":"VariableDeclaration","scope":2996,"src":"2165:15:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2986,"name":"uint256","nodeType":"ElementaryTypeName","src":"2165:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":2989,"mutability":"mutable","name":"walletManagerId","nameLocation":"2198:15:14","nodeType":"VariableDeclaration","scope":2996,"src":"2182:31:14","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":2988,"name":"string","nodeType":"ElementaryTypeName","src":"2182:6:14","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":2991,"mutability":"mutable","name":"assetToken","nameLocation":"2223:10:14","nodeType":"VariableDeclaration","scope":2996,"src":"2215:18:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2990,"name":"address","nodeType":"ElementaryTypeName","src":"2215:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"2139:95:14"},"returnParameters":{"id":2995,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2994,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":2996,"src":"2253:7:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2993,"name":"uint256","nodeType":"ElementaryTypeName","src":"2253:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2252:9:14"},"scope":3172,"src":"2107:155:14","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"a13eafd5","id":3007,"implemented":false,"kind":"function","modifiers":[],"name":"currentParticleCovalentBonds","nameLocation":"2274:28:14","nodeType":"FunctionDefinition","parameters":{"id":3003,"nodeType":"ParameterList","parameters":[{"constant":false,"id":2998,"mutability":"mutable","name":"contractAddress","nameLocation":"2311:15:14","nodeType":"VariableDeclaration","scope":3007,"src":"2303:23:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":2997,"name":"address","nodeType":"ElementaryTypeName","src":"2303:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3000,"mutability":"mutable","name":"tokenId","nameLocation":"2336:7:14","nodeType":"VariableDeclaration","scope":3007,"src":"2328:15:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":2999,"name":"uint256","nodeType":"ElementaryTypeName","src":"2328:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3002,"mutability":"mutable","name":"basketManagerId","nameLocation":"2361:15:14","nodeType":"VariableDeclaration","scope":3007,"src":"2345:31:14","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":3001,"name":"string","nodeType":"ElementaryTypeName","src":"2345:6:14","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"2302:75:14"},"returnParameters":{"id":3006,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3005,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":3007,"src":"2401:7:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3004,"name":"uint256","nodeType":"ElementaryTypeName","src":"2401:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2400:9:14"},"scope":3172,"src":"2265:145:14","stateMutability":"view","virtual":false,"visibility":"external"},{"functionSelector":"0bdde2ca","id":3024,"implemented":false,"kind":"function","modifiers":[],"name":"energizeParticle","nameLocation":"2544:16:14","nodeType":"FunctionDefinition","parameters":{"id":3020,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3009,"mutability":"mutable","name":"contractAddress","nameLocation":"2576:15:14","nodeType":"VariableDeclaration","scope":3024,"src":"2568:23:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3008,"name":"address","nodeType":"ElementaryTypeName","src":"2568:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3011,"mutability":"mutable","name":"tokenId","nameLocation":"2607:7:14","nodeType":"VariableDeclaration","scope":3024,"src":"2599:15:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3010,"name":"uint256","nodeType":"ElementaryTypeName","src":"2599:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3013,"mutability":"mutable","name":"walletManagerId","nameLocation":"2638:15:14","nodeType":"VariableDeclaration","scope":3024,"src":"2622:31:14","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":3012,"name":"string","nodeType":"ElementaryTypeName","src":"2622:6:14","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":3015,"mutability":"mutable","name":"assetToken","nameLocation":"2669:10:14","nodeType":"VariableDeclaration","scope":3024,"src":"2661:18:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3014,"name":"address","nodeType":"ElementaryTypeName","src":"2661:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3017,"mutability":"mutable","name":"assetAmount","nameLocation":"2695:11:14","nodeType":"VariableDeclaration","scope":3024,"src":"2687:19:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3016,"name":"uint256","nodeType":"ElementaryTypeName","src":"2687:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3019,"mutability":"mutable","name":"referrer","nameLocation":"2722:8:14","nodeType":"VariableDeclaration","scope":3024,"src":"2714:16:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3018,"name":"address","nodeType":"ElementaryTypeName","src":"2714:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"2560:174:14"},"returnParameters":{"id":3023,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3022,"mutability":"mutable","name":"yieldTokensAmount","nameLocation":"2761:17:14","nodeType":"VariableDeclaration","scope":3024,"src":"2753:25:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3021,"name":"uint256","nodeType":"ElementaryTypeName","src":"2753:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2752:27:14"},"scope":3172,"src":"2535:245:14","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"621a3b70","id":3041,"implemented":false,"kind":"function","modifiers":[],"name":"dischargeParticle","nameLocation":"2793:17:14","nodeType":"FunctionDefinition","parameters":{"id":3035,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3026,"mutability":"mutable","name":"receiver","nameLocation":"2826:8:14","nodeType":"VariableDeclaration","scope":3041,"src":"2818:16:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3025,"name":"address","nodeType":"ElementaryTypeName","src":"2818:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3028,"mutability":"mutable","name":"contractAddress","nameLocation":"2850:15:14","nodeType":"VariableDeclaration","scope":3041,"src":"2842:23:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3027,"name":"address","nodeType":"ElementaryTypeName","src":"2842:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3030,"mutability":"mutable","name":"tokenId","nameLocation":"2881:7:14","nodeType":"VariableDeclaration","scope":3041,"src":"2873:15:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3029,"name":"uint256","nodeType":"ElementaryTypeName","src":"2873:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3032,"mutability":"mutable","name":"walletManagerId","nameLocation":"2912:15:14","nodeType":"VariableDeclaration","scope":3041,"src":"2896:31:14","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":3031,"name":"string","nodeType":"ElementaryTypeName","src":"2896:6:14","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":3034,"mutability":"mutable","name":"assetToken","nameLocation":"2943:10:14","nodeType":"VariableDeclaration","scope":3041,"src":"2935:18:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3033,"name":"address","nodeType":"ElementaryTypeName","src":"2935:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"2810:147:14"},"returnParameters":{"id":3040,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3037,"mutability":"mutable","name":"creatorAmount","nameLocation":"2984:13:14","nodeType":"VariableDeclaration","scope":3041,"src":"2976:21:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3036,"name":"uint256","nodeType":"ElementaryTypeName","src":"2976:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3039,"mutability":"mutable","name":"receiverAmount","nameLocation":"3007:14:14","nodeType":"VariableDeclaration","scope":3041,"src":"2999:22:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3038,"name":"uint256","nodeType":"ElementaryTypeName","src":"2999:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"2975:47:14"},"scope":3172,"src":"2784:239:14","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"6697b359","id":3060,"implemented":false,"kind":"function","modifiers":[],"name":"dischargeParticleAmount","nameLocation":"3036:23:14","nodeType":"FunctionDefinition","parameters":{"id":3054,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3043,"mutability":"mutable","name":"receiver","nameLocation":"3075:8:14","nodeType":"VariableDeclaration","scope":3060,"src":"3067:16:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3042,"name":"address","nodeType":"ElementaryTypeName","src":"3067:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3045,"mutability":"mutable","name":"contractAddress","nameLocation":"3099:15:14","nodeType":"VariableDeclaration","scope":3060,"src":"3091:23:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3044,"name":"address","nodeType":"ElementaryTypeName","src":"3091:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3047,"mutability":"mutable","name":"tokenId","nameLocation":"3130:7:14","nodeType":"VariableDeclaration","scope":3060,"src":"3122:15:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3046,"name":"uint256","nodeType":"ElementaryTypeName","src":"3122:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3049,"mutability":"mutable","name":"walletManagerId","nameLocation":"3161:15:14","nodeType":"VariableDeclaration","scope":3060,"src":"3145:31:14","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":3048,"name":"string","nodeType":"ElementaryTypeName","src":"3145:6:14","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":3051,"mutability":"mutable","name":"assetToken","nameLocation":"3192:10:14","nodeType":"VariableDeclaration","scope":3060,"src":"3184:18:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3050,"name":"address","nodeType":"ElementaryTypeName","src":"3184:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3053,"mutability":"mutable","name":"assetAmount","nameLocation":"3218:11:14","nodeType":"VariableDeclaration","scope":3060,"src":"3210:19:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3052,"name":"uint256","nodeType":"ElementaryTypeName","src":"3210:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3059:174:14"},"returnParameters":{"id":3059,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3056,"mutability":"mutable","name":"creatorAmount","nameLocation":"3260:13:14","nodeType":"VariableDeclaration","scope":3060,"src":"3252:21:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3055,"name":"uint256","nodeType":"ElementaryTypeName","src":"3252:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3058,"mutability":"mutable","name":"receiverAmount","nameLocation":"3283:14:14","nodeType":"VariableDeclaration","scope":3060,"src":"3275:22:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3057,"name":"uint256","nodeType":"ElementaryTypeName","src":"3275:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3251:47:14"},"scope":3172,"src":"3027:272:14","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"65d20ce2","id":3077,"implemented":false,"kind":"function","modifiers":[],"name":"dischargeParticleForCreator","nameLocation":"3312:27:14","nodeType":"FunctionDefinition","parameters":{"id":3073,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3062,"mutability":"mutable","name":"receiver","nameLocation":"3355:8:14","nodeType":"VariableDeclaration","scope":3077,"src":"3347:16:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3061,"name":"address","nodeType":"ElementaryTypeName","src":"3347:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3064,"mutability":"mutable","name":"contractAddress","nameLocation":"3379:15:14","nodeType":"VariableDeclaration","scope":3077,"src":"3371:23:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3063,"name":"address","nodeType":"ElementaryTypeName","src":"3371:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3066,"mutability":"mutable","name":"tokenId","nameLocation":"3410:7:14","nodeType":"VariableDeclaration","scope":3077,"src":"3402:15:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3065,"name":"uint256","nodeType":"ElementaryTypeName","src":"3402:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3068,"mutability":"mutable","name":"walletManagerId","nameLocation":"3441:15:14","nodeType":"VariableDeclaration","scope":3077,"src":"3425:31:14","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":3067,"name":"string","nodeType":"ElementaryTypeName","src":"3425:6:14","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":3070,"mutability":"mutable","name":"assetToken","nameLocation":"3472:10:14","nodeType":"VariableDeclaration","scope":3077,"src":"3464:18:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3069,"name":"address","nodeType":"ElementaryTypeName","src":"3464:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3072,"mutability":"mutable","name":"assetAmount","nameLocation":"3498:11:14","nodeType":"VariableDeclaration","scope":3077,"src":"3490:19:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3071,"name":"uint256","nodeType":"ElementaryTypeName","src":"3490:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3339:174:14"},"returnParameters":{"id":3076,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3075,"mutability":"mutable","name":"receiverAmount","nameLocation":"3540:14:14","nodeType":"VariableDeclaration","scope":3077,"src":"3532:22:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3074,"name":"uint256","nodeType":"ElementaryTypeName","src":"3532:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3531:24:14"},"scope":3172,"src":"3303:253:14","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"acab923c","id":3094,"implemented":false,"kind":"function","modifiers":[],"name":"releaseParticle","nameLocation":"3569:15:14","nodeType":"FunctionDefinition","parameters":{"id":3088,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3079,"mutability":"mutable","name":"receiver","nameLocation":"3600:8:14","nodeType":"VariableDeclaration","scope":3094,"src":"3592:16:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3078,"name":"address","nodeType":"ElementaryTypeName","src":"3592:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3081,"mutability":"mutable","name":"contractAddress","nameLocation":"3624:15:14","nodeType":"VariableDeclaration","scope":3094,"src":"3616:23:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3080,"name":"address","nodeType":"ElementaryTypeName","src":"3616:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3083,"mutability":"mutable","name":"tokenId","nameLocation":"3655:7:14","nodeType":"VariableDeclaration","scope":3094,"src":"3647:15:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3082,"name":"uint256","nodeType":"ElementaryTypeName","src":"3647:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3085,"mutability":"mutable","name":"walletManagerId","nameLocation":"3686:15:14","nodeType":"VariableDeclaration","scope":3094,"src":"3670:31:14","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":3084,"name":"string","nodeType":"ElementaryTypeName","src":"3670:6:14","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":3087,"mutability":"mutable","name":"assetToken","nameLocation":"3717:10:14","nodeType":"VariableDeclaration","scope":3094,"src":"3709:18:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3086,"name":"address","nodeType":"ElementaryTypeName","src":"3709:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"3584:147:14"},"returnParameters":{"id":3093,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3090,"mutability":"mutable","name":"creatorAmount","nameLocation":"3758:13:14","nodeType":"VariableDeclaration","scope":3094,"src":"3750:21:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3089,"name":"uint256","nodeType":"ElementaryTypeName","src":"3750:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3092,"mutability":"mutable","name":"receiverAmount","nameLocation":"3781:14:14","nodeType":"VariableDeclaration","scope":3094,"src":"3773:22:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3091,"name":"uint256","nodeType":"ElementaryTypeName","src":"3773:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3749:47:14"},"scope":3172,"src":"3560:237:14","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"a8abef47","id":3113,"implemented":false,"kind":"function","modifiers":[],"name":"releaseParticleAmount","nameLocation":"3810:21:14","nodeType":"FunctionDefinition","parameters":{"id":3107,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3096,"mutability":"mutable","name":"receiver","nameLocation":"3845:8:14","nodeType":"VariableDeclaration","scope":3113,"src":"3837:16:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3095,"name":"address","nodeType":"ElementaryTypeName","src":"3837:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3098,"mutability":"mutable","name":"contractAddress","nameLocation":"3867:15:14","nodeType":"VariableDeclaration","scope":3113,"src":"3859:23:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3097,"name":"address","nodeType":"ElementaryTypeName","src":"3859:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3100,"mutability":"mutable","name":"tokenId","nameLocation":"3896:7:14","nodeType":"VariableDeclaration","scope":3113,"src":"3888:15:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3099,"name":"uint256","nodeType":"ElementaryTypeName","src":"3888:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3102,"mutability":"mutable","name":"walletManagerId","nameLocation":"3925:15:14","nodeType":"VariableDeclaration","scope":3113,"src":"3909:31:14","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":3101,"name":"string","nodeType":"ElementaryTypeName","src":"3909:6:14","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":3104,"mutability":"mutable","name":"assetToken","nameLocation":"3954:10:14","nodeType":"VariableDeclaration","scope":3113,"src":"3946:18:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3103,"name":"address","nodeType":"ElementaryTypeName","src":"3946:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3106,"mutability":"mutable","name":"assetAmount","nameLocation":"3978:11:14","nodeType":"VariableDeclaration","scope":3113,"src":"3970:19:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3105,"name":"uint256","nodeType":"ElementaryTypeName","src":"3970:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"3831:162:14"},"returnParameters":{"id":3112,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3109,"mutability":"mutable","name":"creatorAmount","nameLocation":"4020:13:14","nodeType":"VariableDeclaration","scope":3113,"src":"4012:21:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3108,"name":"uint256","nodeType":"ElementaryTypeName","src":"4012:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3111,"mutability":"mutable","name":"receiverAmount","nameLocation":"4043:14:14","nodeType":"VariableDeclaration","scope":3113,"src":"4035:22:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3110,"name":"uint256","nodeType":"ElementaryTypeName","src":"4035:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"4011:47:14"},"scope":3172,"src":"3801:258:14","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"3ff956cc","id":3130,"implemented":false,"kind":"function","modifiers":[],"name":"covalentBond","nameLocation":"4072:12:14","nodeType":"FunctionDefinition","parameters":{"id":3126,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3115,"mutability":"mutable","name":"contractAddress","nameLocation":"4098:15:14","nodeType":"VariableDeclaration","scope":3130,"src":"4090:23:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3114,"name":"address","nodeType":"ElementaryTypeName","src":"4090:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3117,"mutability":"mutable","name":"tokenId","nameLocation":"4127:7:14","nodeType":"VariableDeclaration","scope":3130,"src":"4119:15:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3116,"name":"uint256","nodeType":"ElementaryTypeName","src":"4119:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3119,"mutability":"mutable","name":"basketManagerId","nameLocation":"4156:15:14","nodeType":"VariableDeclaration","scope":3130,"src":"4140:31:14","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":3118,"name":"string","nodeType":"ElementaryTypeName","src":"4140:6:14","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":3121,"mutability":"mutable","name":"nftTokenAddress","nameLocation":"4185:15:14","nodeType":"VariableDeclaration","scope":3130,"src":"4177:23:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3120,"name":"address","nodeType":"ElementaryTypeName","src":"4177:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3123,"mutability":"mutable","name":"nftTokenId","nameLocation":"4214:10:14","nodeType":"VariableDeclaration","scope":3130,"src":"4206:18:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3122,"name":"uint256","nodeType":"ElementaryTypeName","src":"4206:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3125,"mutability":"mutable","name":"nftTokenAmount","nameLocation":"4238:14:14","nodeType":"VariableDeclaration","scope":3130,"src":"4230:22:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3124,"name":"uint256","nodeType":"ElementaryTypeName","src":"4230:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"4084:172:14"},"returnParameters":{"id":3129,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3128,"mutability":"mutable","name":"success","nameLocation":"4280:7:14","nodeType":"VariableDeclaration","scope":3130,"src":"4275:12:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":3127,"name":"bool","nodeType":"ElementaryTypeName","src":"4275:4:14","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"4274:14:14"},"scope":3172,"src":"4063:226:14","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"fe02fb00","id":3149,"implemented":false,"kind":"function","modifiers":[],"name":"breakCovalentBond","nameLocation":"4302:17:14","nodeType":"FunctionDefinition","parameters":{"id":3145,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3132,"mutability":"mutable","name":"receiver","nameLocation":"4333:8:14","nodeType":"VariableDeclaration","scope":3149,"src":"4325:16:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3131,"name":"address","nodeType":"ElementaryTypeName","src":"4325:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3134,"mutability":"mutable","name":"contractAddress","nameLocation":"4355:15:14","nodeType":"VariableDeclaration","scope":3149,"src":"4347:23:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3133,"name":"address","nodeType":"ElementaryTypeName","src":"4347:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3136,"mutability":"mutable","name":"tokenId","nameLocation":"4384:7:14","nodeType":"VariableDeclaration","scope":3149,"src":"4376:15:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3135,"name":"uint256","nodeType":"ElementaryTypeName","src":"4376:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3138,"mutability":"mutable","name":"basketManagerId","nameLocation":"4413:15:14","nodeType":"VariableDeclaration","scope":3149,"src":"4397:31:14","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_string_calldata_ptr","typeString":"string"},"typeName":{"id":3137,"name":"string","nodeType":"ElementaryTypeName","src":"4397:6:14","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":3140,"mutability":"mutable","name":"nftTokenAddress","nameLocation":"4442:15:14","nodeType":"VariableDeclaration","scope":3149,"src":"4434:23:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3139,"name":"address","nodeType":"ElementaryTypeName","src":"4434:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3142,"mutability":"mutable","name":"nftTokenId","nameLocation":"4471:10:14","nodeType":"VariableDeclaration","scope":3149,"src":"4463:18:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3141,"name":"uint256","nodeType":"ElementaryTypeName","src":"4463:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3144,"mutability":"mutable","name":"nftTokenAmount","nameLocation":"4495:14:14","nodeType":"VariableDeclaration","scope":3149,"src":"4487:22:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3143,"name":"uint256","nodeType":"ElementaryTypeName","src":"4487:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"4319:194:14"},"returnParameters":{"id":3148,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3147,"mutability":"mutable","name":"success","nameLocation":"4537:7:14","nodeType":"VariableDeclaration","scope":3149,"src":"4532:12:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"},"typeName":{"id":3146,"name":"bool","nodeType":"ElementaryTypeName","src":"4532:4:14","typeDescriptions":{"typeIdentifier":"t_bool","typeString":"bool"}},"visibility":"internal"}],"src":"4531:14:14"},"scope":3172,"src":"4293:253:14","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"anonymous":false,"eventSelector":"908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e6","id":3153,"name":"Initialized","nameLocation":"4677:11:14","nodeType":"EventDefinition","parameters":{"id":3152,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3151,"indexed":true,"mutability":"mutable","name":"initiator","nameLocation":"4705:9:14","nodeType":"VariableDeclaration","scope":3153,"src":"4689:25:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3150,"name":"address","nodeType":"ElementaryTypeName","src":"4689:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"4688:27:14"},"src":"4671:45:14"},{"anonymous":false,"eventSelector":"d28287e4c8d4f4d61f75c41e3e0732ca8d95f32ccddc45658621a7ae71f8ce95","id":3159,"name":"ControllerSet","nameLocation":"4725:13:14","nodeType":"EventDefinition","parameters":{"id":3158,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3155,"indexed":true,"mutability":"mutable","name":"controllerAddress","nameLocation":"4755:17:14","nodeType":"VariableDeclaration","scope":3159,"src":"4739:33:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3154,"name":"address","nodeType":"ElementaryTypeName","src":"4739:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3157,"indexed":false,"mutability":"mutable","name":"controllerId","nameLocation":"4781:12:14","nodeType":"VariableDeclaration","scope":3159,"src":"4774:19:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":3156,"name":"string","nodeType":"ElementaryTypeName","src":"4774:6:14","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"4738:56:14"},"src":"4719:76:14"},{"anonymous":false,"eventSelector":"12865465a7036a0232cbf9fb63ce880a3ee54f702775fe7abbc3c416e7968cd5","id":3163,"name":"DepositFeeSet","nameLocation":"4804:13:14","nodeType":"EventDefinition","parameters":{"id":3162,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3161,"indexed":false,"mutability":"mutable","name":"depositFee","nameLocation":"4826:10:14","nodeType":"VariableDeclaration","scope":3163,"src":"4818:18:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3160,"name":"uint256","nodeType":"ElementaryTypeName","src":"4818:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"4817:20:14"},"src":"4798:40:14"},{"anonymous":false,"eventSelector":"d24ccccf373129a9579bb9f5edc41c09218d54ae950e90b4d5ca2927b7c29b11","id":3171,"name":"ProtocolFeesCollected","nameLocation":"4847:21:14","nodeType":"EventDefinition","parameters":{"id":3170,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3165,"indexed":true,"mutability":"mutable","name":"assetToken","nameLocation":"4885:10:14","nodeType":"VariableDeclaration","scope":3171,"src":"4869:26:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3164,"name":"address","nodeType":"ElementaryTypeName","src":"4869:7:14","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3167,"indexed":false,"mutability":"mutable","name":"depositAmount","nameLocation":"4905:13:14","nodeType":"VariableDeclaration","scope":3171,"src":"4897:21:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3166,"name":"uint256","nodeType":"ElementaryTypeName","src":"4897:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3169,"indexed":false,"mutability":"mutable","name":"feesCollected","nameLocation":"4928:13:14","nodeType":"VariableDeclaration","scope":3171,"src":"4920:21:14","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3168,"name":"uint256","nodeType":"ElementaryTypeName","src":"4920:7:14","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"4868:74:14"},"src":"4841:102:14"}],"scope":3173,"src":"1313:3632:14","usedErrors":[]}],"src":"1236:3710:14"},"id":14},"contracts/interfaces/IRegistry.sol":{"ast":{"absolutePath":"contracts/interfaces/IRegistry.sol","exportedSymbols":{"IRegistry":[3207]},"id":3208,"license":"UNLICENSED","nodeType":"SourceUnit","nodes":[{"id":3174,"literals":["solidity","^","0.8",".13"],"nodeType":"PragmaDirective","src":"39:24:15"},{"abstract":false,"baseContracts":[],"canonicalName":"IRegistry","contractDependencies":[],"contractKind":"interface","fullyImplemented":false,"id":3207,"linearizedBaseContracts":[3207],"name":"IRegistry","nameLocation":"75:9:15","nodeType":"ContractDefinition","nodes":[{"functionSelector":"da7323b3","id":3191,"implemented":false,"kind":"function","modifiers":[],"name":"createAccount","nameLocation":"100:13:15","nodeType":"FunctionDefinition","parameters":{"id":3187,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3176,"mutability":"mutable","name":"implementation","nameLocation":"131:14:15","nodeType":"VariableDeclaration","scope":3191,"src":"123:22:15","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3175,"name":"address","nodeType":"ElementaryTypeName","src":"123:7:15","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3178,"mutability":"mutable","name":"chainId","nameLocation":"163:7:15","nodeType":"VariableDeclaration","scope":3191,"src":"155:15:15","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3177,"name":"uint256","nodeType":"ElementaryTypeName","src":"155:7:15","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3180,"mutability":"mutable","name":"tokenContract","nameLocation":"188:13:15","nodeType":"VariableDeclaration","scope":3191,"src":"180:21:15","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3179,"name":"address","nodeType":"ElementaryTypeName","src":"180:7:15","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3182,"mutability":"mutable","name":"tokenId","nameLocation":"219:7:15","nodeType":"VariableDeclaration","scope":3191,"src":"211:15:15","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3181,"name":"uint256","nodeType":"ElementaryTypeName","src":"211:7:15","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3184,"mutability":"mutable","name":"salt","nameLocation":"244:4:15","nodeType":"VariableDeclaration","scope":3191,"src":"236:12:15","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3183,"name":"uint256","nodeType":"ElementaryTypeName","src":"236:7:15","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3186,"mutability":"mutable","name":"initData","nameLocation":"273:8:15","nodeType":"VariableDeclaration","scope":3191,"src":"258:23:15","stateVariable":false,"storageLocation":"calldata","typeDescriptions":{"typeIdentifier":"t_bytes_calldata_ptr","typeString":"bytes"},"typeName":{"id":3185,"name":"bytes","nodeType":"ElementaryTypeName","src":"258:5:15","typeDescriptions":{"typeIdentifier":"t_bytes_storage_ptr","typeString":"bytes"}},"visibility":"internal"}],"src":"113:174:15"},"returnParameters":{"id":3190,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3189,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":3191,"src":"306:7:15","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3188,"name":"address","nodeType":"ElementaryTypeName","src":"306:7:15","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"305:9:15"},"scope":3207,"src":"91:224:15","stateMutability":"nonpayable","virtual":false,"visibility":"external"},{"functionSelector":"5e9bc536","id":3206,"implemented":false,"kind":"function","modifiers":[],"name":"account","nameLocation":"330:7:15","nodeType":"FunctionDefinition","parameters":{"id":3202,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3193,"mutability":"mutable","name":"implementation","nameLocation":"355:14:15","nodeType":"VariableDeclaration","scope":3206,"src":"347:22:15","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3192,"name":"address","nodeType":"ElementaryTypeName","src":"347:7:15","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3195,"mutability":"mutable","name":"chainId","nameLocation":"387:7:15","nodeType":"VariableDeclaration","scope":3206,"src":"379:15:15","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3194,"name":"uint256","nodeType":"ElementaryTypeName","src":"379:7:15","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3197,"mutability":"mutable","name":"tokenContract","nameLocation":"412:13:15","nodeType":"VariableDeclaration","scope":3206,"src":"404:21:15","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3196,"name":"address","nodeType":"ElementaryTypeName","src":"404:7:15","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3199,"mutability":"mutable","name":"tokenId","nameLocation":"443:7:15","nodeType":"VariableDeclaration","scope":3206,"src":"435:15:15","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3198,"name":"uint256","nodeType":"ElementaryTypeName","src":"435:7:15","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"},{"constant":false,"id":3201,"mutability":"mutable","name":"salt","nameLocation":"468:4:15","nodeType":"VariableDeclaration","scope":3206,"src":"460:12:15","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3200,"name":"uint256","nodeType":"ElementaryTypeName","src":"460:7:15","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"337:141:15"},"returnParameters":{"id":3205,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3204,"mutability":"mutable","name":"","nameLocation":"-1:-1:-1","nodeType":"VariableDeclaration","scope":3206,"src":"502:7:15","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3203,"name":"address","nodeType":"ElementaryTypeName","src":"502:7:15","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"}],"src":"501:9:15"},"scope":3207,"src":"321:190:15","stateMutability":"view","virtual":false,"visibility":"external"}],"scope":3208,"src":"65:448:15","usedErrors":[]}],"src":"39:475:15"},"id":15},"contracts/mock/NFTMock.sol":{"ast":{"absolutePath":"contracts/mock/NFTMock.sol","exportedSymbols":{"Address":[1417],"Context":[1439],"ERC165":[1692],"ERC721":[926],"IERC165":[1704],"IERC721":[1042],"IERC721Metadata":[1087],"IERC721Receiver":[1060],"Math":[2570],"NFTMock":[3238],"SignedMath":[2675],"Strings":[1668]},"id":3239,"license":"MIT","nodeType":"SourceUnit","nodes":[{"id":3209,"literals":["solidity","^","0.8",".8"],"nodeType":"PragmaDirective","src":"33:23:16"},{"absolutePath":"@openzeppelin/contracts/token/ERC721/ERC721.sol","file":"@openzeppelin/contracts/token/ERC721/ERC721.sol","id":3210,"nameLocation":"-1:-1:-1","nodeType":"ImportDirective","scope":3239,"sourceUnit":927,"src":"58:57:16","symbolAliases":[],"unitAlias":""},{"abstract":false,"baseContracts":[{"baseName":{"id":3211,"name":"ERC721","nameLocations":["137:6:16"],"nodeType":"IdentifierPath","referencedDeclaration":926,"src":"137:6:16"},"id":3212,"nodeType":"InheritanceSpecifier","src":"137:6:16"}],"canonicalName":"NFTMock","contractDependencies":[],"contractKind":"contract","fullyImplemented":true,"id":3238,"linearizedBaseContracts":[3238,926,1087,1042,1692,1704,1439],"name":"NFTMock","nameLocation":"126:7:16","nodeType":"ContractDefinition","nodes":[{"body":{"id":3223,"nodeType":"Block","src":"278:7:16","statements":[]},"id":3224,"implemented":true,"kind":"constructor","modifiers":[{"arguments":[{"id":3219,"name":"name_","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":3214,"src":"262:5:16","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}},{"id":3220,"name":"symbol_","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":3216,"src":"269:7:16","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string memory"}}],"id":3221,"kind":"baseConstructorSpecifier","modifierName":{"id":3218,"name":"ERC721","nameLocations":["255:6:16"],"nodeType":"IdentifierPath","referencedDeclaration":926,"src":"255:6:16"},"nodeType":"ModifierInvocation","src":"255:22:16"}],"name":"","nameLocation":"-1:-1:-1","nodeType":"FunctionDefinition","parameters":{"id":3217,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3214,"mutability":"mutable","name":"name_","nameLocation":"225:5:16","nodeType":"VariableDeclaration","scope":3224,"src":"211:19:16","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":3213,"name":"string","nodeType":"ElementaryTypeName","src":"211:6:16","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"},{"constant":false,"id":3216,"mutability":"mutable","name":"symbol_","nameLocation":"246:7:16","nodeType":"VariableDeclaration","scope":3224,"src":"232:21:16","stateVariable":false,"storageLocation":"memory","typeDescriptions":{"typeIdentifier":"t_string_memory_ptr","typeString":"string"},"typeName":{"id":3215,"name":"string","nodeType":"ElementaryTypeName","src":"232:6:16","typeDescriptions":{"typeIdentifier":"t_string_storage_ptr","typeString":"string"}},"visibility":"internal"}],"src":"210:44:16"},"returnParameters":{"id":3222,"nodeType":"ParameterList","parameters":[],"src":"278:0:16"},"scope":3238,"src":"199:86:16","stateMutability":"nonpayable","virtual":false,"visibility":"public"},{"body":{"id":3236,"nodeType":"Block","src":"343:35:16","statements":[{"expression":{"arguments":[{"id":3232,"name":"to","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":3226,"src":"359:2:16","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},{"id":3233,"name":"tokenId","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":3228,"src":"363:7:16","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}}],"expression":{"argumentTypes":[{"typeIdentifier":"t_address","typeString":"address"},{"typeIdentifier":"t_uint256","typeString":"uint256"}],"id":3231,"name":"_mint","nodeType":"Identifier","overloadedDeclarations":[],"referencedDeclaration":600,"src":"353:5:16","typeDescriptions":{"typeIdentifier":"t_function_internal_nonpayable$_t_address_$_t_uint256_$returns$__$","typeString":"function (address,uint256)"}},"id":3234,"isConstant":false,"isLValue":false,"isPure":false,"kind":"functionCall","lValueRequested":false,"nameLocations":[],"names":[],"nodeType":"FunctionCall","src":"353:18:16","tryCall":false,"typeDescriptions":{"typeIdentifier":"t_tuple$__$","typeString":"tuple()"}},"id":3235,"nodeType":"ExpressionStatement","src":"353:18:16"}]},"functionSelector":"40c10f19","id":3237,"implemented":true,"kind":"function","modifiers":[],"name":"mint","nameLocation":"300:4:16","nodeType":"FunctionDefinition","parameters":{"id":3229,"nodeType":"ParameterList","parameters":[{"constant":false,"id":3226,"mutability":"mutable","name":"to","nameLocation":"313:2:16","nodeType":"VariableDeclaration","scope":3237,"src":"305:10:16","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"},"typeName":{"id":3225,"name":"address","nodeType":"ElementaryTypeName","src":"305:7:16","stateMutability":"nonpayable","typeDescriptions":{"typeIdentifier":"t_address","typeString":"address"}},"visibility":"internal"},{"constant":false,"id":3228,"mutability":"mutable","name":"tokenId","nameLocation":"325:7:16","nodeType":"VariableDeclaration","scope":3237,"src":"317:15:16","stateVariable":false,"storageLocation":"default","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"},"typeName":{"id":3227,"name":"uint256","nodeType":"ElementaryTypeName","src":"317:7:16","typeDescriptions":{"typeIdentifier":"t_uint256","typeString":"uint256"}},"visibility":"internal"}],"src":"304:29:16"},"returnParameters":{"id":3230,"nodeType":"ParameterList","parameters":[],"src":"343:0:16"},"scope":3238,"src":"291:87:16","stateMutability":"nonpayable","virtual":false,"visibility":"external"}],"scope":3239,"src":"117:263:16","usedErrors":[]}],"src":"33:347:16"},"id":16}},"contracts":{"@openzeppelin/contracts/token/ERC721/ERC721.sol":{"ERC721":{"abi":[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"details":"Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including the Metadata extension, but not including the Enumerable extension, which is available separately as {ERC721Enumerable}.","kind":"dev","methods":{"approve(address,uint256)":{"details":"See {IERC721-approve}."},"balanceOf(address)":{"details":"See {IERC721-balanceOf}."},"constructor":{"details":"Initializes the contract by setting a `name` and a `symbol` to the token collection."},"getApproved(uint256)":{"details":"See {IERC721-getApproved}."},"isApprovedForAll(address,address)":{"details":"See {IERC721-isApprovedForAll}."},"name()":{"details":"See {IERC721Metadata-name}."},"ownerOf(uint256)":{"details":"See {IERC721-ownerOf}."},"safeTransferFrom(address,address,uint256)":{"details":"See {IERC721-safeTransferFrom}."},"safeTransferFrom(address,address,uint256,bytes)":{"details":"See {IERC721-safeTransferFrom}."},"setApprovalForAll(address,bool)":{"details":"See {IERC721-setApprovalForAll}."},"supportsInterface(bytes4)":{"details":"See {IERC165-supportsInterface}."},"symbol()":{"details":"See {IERC721Metadata-symbol}."},"tokenURI(uint256)":{"details":"See {IERC721Metadata-tokenURI}."},"transferFrom(address,address,uint256)":{"details":"See {IERC721-transferFrom}."}},"version":1},"evm":{"bytecode":{"functionDebugData":{"@_62":{"entryPoint":null,"id":62,"parameterSlots":2,"returnSlots":0},"abi_decode_string_fromMemory":{"entryPoint":112,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_string_memory_ptrt_string_memory_ptr_fromMemory":{"entryPoint":287,"id":null,"parameterSlots":2,"returnSlots":2},"array_dataslot_string_storage":{"entryPoint":null,"id":null,"parameterSlots":1,"returnSlots":1},"clean_up_bytearray_end_slots_string_storage":{"entryPoint":453,"id":null,"parameterSlots":3,"returnSlots":0},"copy_byte_array_to_storage_from_t_string_memory_ptr_to_t_string_storage":{"entryPoint":536,"id":null,"parameterSlots":2,"returnSlots":0},"extract_byte_array_length":{"entryPoint":393,"id":null,"parameterSlots":1,"returnSlots":1},"extract_used_part_and_set_length_of_short_byte_array":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"panic_error_0x41":{"entryPoint":90,"id":null,"parameterSlots":0,"returnSlots":0}},"generatedSources":[{"ast":{"nodeType":"YulBlock","src":"0:4144:17","statements":[{"nodeType":"YulBlock","src":"6:3:17","statements":[]},{"body":{"nodeType":"YulBlock","src":"46:95:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"63:1:17","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"70:3:17","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"75:10:17","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"66:3:17"},"nodeType":"YulFunctionCall","src":"66:20:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"56:6:17"},"nodeType":"YulFunctionCall","src":"56:31:17"},"nodeType":"YulExpressionStatement","src":"56:31:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"103:1:17","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"106:4:17","type":"","value":"0x41"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"96:6:17"},"nodeType":"YulFunctionCall","src":"96:15:17"},"nodeType":"YulExpressionStatement","src":"96:15:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"127:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"130:4:17","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"120:6:17"},"nodeType":"YulFunctionCall","src":"120:15:17"},"nodeType":"YulExpressionStatement","src":"120:15:17"}]},"name":"panic_error_0x41","nodeType":"YulFunctionDefinition","src":"14:127:17"},{"body":{"nodeType":"YulBlock","src":"210:776:17","statements":[{"body":{"nodeType":"YulBlock","src":"259:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"268:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"271:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"261:6:17"},"nodeType":"YulFunctionCall","src":"261:12:17"},"nodeType":"YulExpressionStatement","src":"261:12:17"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"238:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"246:4:17","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"234:3:17"},"nodeType":"YulFunctionCall","src":"234:17:17"},{"name":"end","nodeType":"YulIdentifier","src":"253:3:17"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"230:3:17"},"nodeType":"YulFunctionCall","src":"230:27:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"223:6:17"},"nodeType":"YulFunctionCall","src":"223:35:17"},"nodeType":"YulIf","src":"220:55:17"},{"nodeType":"YulVariableDeclaration","src":"284:23:17","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"300:6:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"294:5:17"},"nodeType":"YulFunctionCall","src":"294:13:17"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"288:2:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"316:28:17","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"334:2:17","type":"","value":"64"},{"kind":"number","nodeType":"YulLiteral","src":"338:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"330:3:17"},"nodeType":"YulFunctionCall","src":"330:10:17"},{"kind":"number","nodeType":"YulLiteral","src":"342:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"326:3:17"},"nodeType":"YulFunctionCall","src":"326:18:17"},"variables":[{"name":"_2","nodeType":"YulTypedName","src":"320:2:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"367:22:17","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"369:16:17"},"nodeType":"YulFunctionCall","src":"369:18:17"},"nodeType":"YulExpressionStatement","src":"369:18:17"}]},"condition":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"359:2:17"},{"name":"_2","nodeType":"YulIdentifier","src":"363:2:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"356:2:17"},"nodeType":"YulFunctionCall","src":"356:10:17"},"nodeType":"YulIf","src":"353:36:17"},{"nodeType":"YulVariableDeclaration","src":"398:17:17","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"412:2:17","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"408:3:17"},"nodeType":"YulFunctionCall","src":"408:7:17"},"variables":[{"name":"_3","nodeType":"YulTypedName","src":"402:2:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"424:23:17","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"444:2:17","type":"","value":"64"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"438:5:17"},"nodeType":"YulFunctionCall","src":"438:9:17"},"variables":[{"name":"memPtr","nodeType":"YulTypedName","src":"428:6:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"456:71:17","value":{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"478:6:17"},{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"502:2:17"},{"kind":"number","nodeType":"YulLiteral","src":"506:4:17","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"498:3:17"},"nodeType":"YulFunctionCall","src":"498:13:17"},{"name":"_3","nodeType":"YulIdentifier","src":"513:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"494:3:17"},"nodeType":"YulFunctionCall","src":"494:22:17"},{"kind":"number","nodeType":"YulLiteral","src":"518:2:17","type":"","value":"63"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"490:3:17"},"nodeType":"YulFunctionCall","src":"490:31:17"},{"name":"_3","nodeType":"YulIdentifier","src":"523:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"486:3:17"},"nodeType":"YulFunctionCall","src":"486:40:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"474:3:17"},"nodeType":"YulFunctionCall","src":"474:53:17"},"variables":[{"name":"newFreePtr","nodeType":"YulTypedName","src":"460:10:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"586:22:17","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"588:16:17"},"nodeType":"YulFunctionCall","src":"588:18:17"},"nodeType":"YulExpressionStatement","src":"588:18:17"}]},"condition":{"arguments":[{"arguments":[{"name":"newFreePtr","nodeType":"YulIdentifier","src":"545:10:17"},{"name":"_2","nodeType":"YulIdentifier","src":"557:2:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"542:2:17"},"nodeType":"YulFunctionCall","src":"542:18:17"},{"arguments":[{"name":"newFreePtr","nodeType":"YulIdentifier","src":"565:10:17"},{"name":"memPtr","nodeType":"YulIdentifier","src":"577:6:17"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"562:2:17"},"nodeType":"YulFunctionCall","src":"562:22:17"}],"functionName":{"name":"or","nodeType":"YulIdentifier","src":"539:2:17"},"nodeType":"YulFunctionCall","src":"539:46:17"},"nodeType":"YulIf","src":"536:72:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"624:2:17","type":"","value":"64"},{"name":"newFreePtr","nodeType":"YulIdentifier","src":"628:10:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"617:6:17"},"nodeType":"YulFunctionCall","src":"617:22:17"},"nodeType":"YulExpressionStatement","src":"617:22:17"},{"expression":{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"655:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"663:2:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"648:6:17"},"nodeType":"YulFunctionCall","src":"648:18:17"},"nodeType":"YulExpressionStatement","src":"648:18:17"},{"nodeType":"YulVariableDeclaration","src":"675:14:17","value":{"kind":"number","nodeType":"YulLiteral","src":"685:4:17","type":"","value":"0x20"},"variables":[{"name":"_4","nodeType":"YulTypedName","src":"679:2:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"735:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"744:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"747:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"737:6:17"},"nodeType":"YulFunctionCall","src":"737:12:17"},"nodeType":"YulExpressionStatement","src":"737:12:17"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"712:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"720:2:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"708:3:17"},"nodeType":"YulFunctionCall","src":"708:15:17"},{"name":"_4","nodeType":"YulIdentifier","src":"725:2:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"704:3:17"},"nodeType":"YulFunctionCall","src":"704:24:17"},{"name":"end","nodeType":"YulIdentifier","src":"730:3:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"701:2:17"},"nodeType":"YulFunctionCall","src":"701:33:17"},"nodeType":"YulIf","src":"698:53:17"},{"nodeType":"YulVariableDeclaration","src":"760:10:17","value":{"kind":"number","nodeType":"YulLiteral","src":"769:1:17","type":"","value":"0"},"variables":[{"name":"i","nodeType":"YulTypedName","src":"764:1:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"825:87:17","statements":[{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"854:6:17"},{"name":"i","nodeType":"YulIdentifier","src":"862:1:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"850:3:17"},"nodeType":"YulFunctionCall","src":"850:14:17"},{"name":"_4","nodeType":"YulIdentifier","src":"866:2:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"846:3:17"},"nodeType":"YulFunctionCall","src":"846:23:17"},{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"885:6:17"},{"name":"i","nodeType":"YulIdentifier","src":"893:1:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"881:3:17"},"nodeType":"YulFunctionCall","src":"881:14:17"},{"name":"_4","nodeType":"YulIdentifier","src":"897:2:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"877:3:17"},"nodeType":"YulFunctionCall","src":"877:23:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"871:5:17"},"nodeType":"YulFunctionCall","src":"871:30:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"839:6:17"},"nodeType":"YulFunctionCall","src":"839:63:17"},"nodeType":"YulExpressionStatement","src":"839:63:17"}]},"condition":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"790:1:17"},{"name":"_1","nodeType":"YulIdentifier","src":"793:2:17"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"787:2:17"},"nodeType":"YulFunctionCall","src":"787:9:17"},"nodeType":"YulForLoop","post":{"nodeType":"YulBlock","src":"797:19:17","statements":[{"nodeType":"YulAssignment","src":"799:15:17","value":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"808:1:17"},{"name":"_4","nodeType":"YulIdentifier","src":"811:2:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"804:3:17"},"nodeType":"YulFunctionCall","src":"804:10:17"},"variableNames":[{"name":"i","nodeType":"YulIdentifier","src":"799:1:17"}]}]},"pre":{"nodeType":"YulBlock","src":"783:3:17","statements":[]},"src":"779:133:17"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"936:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"944:2:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"932:3:17"},"nodeType":"YulFunctionCall","src":"932:15:17"},{"name":"_4","nodeType":"YulIdentifier","src":"949:2:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"928:3:17"},"nodeType":"YulFunctionCall","src":"928:24:17"},{"kind":"number","nodeType":"YulLiteral","src":"954:1:17","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"921:6:17"},"nodeType":"YulFunctionCall","src":"921:35:17"},"nodeType":"YulExpressionStatement","src":"921:35:17"},{"nodeType":"YulAssignment","src":"965:15:17","value":{"name":"memPtr","nodeType":"YulIdentifier","src":"974:6:17"},"variableNames":[{"name":"array","nodeType":"YulIdentifier","src":"965:5:17"}]}]},"name":"abi_decode_string_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"184:6:17","type":""},{"name":"end","nodeType":"YulTypedName","src":"192:3:17","type":""}],"returnVariables":[{"name":"array","nodeType":"YulTypedName","src":"200:5:17","type":""}],"src":"146:840:17"},{"body":{"nodeType":"YulBlock","src":"1109:444:17","statements":[{"body":{"nodeType":"YulBlock","src":"1155:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1164:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1167:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1157:6:17"},"nodeType":"YulFunctionCall","src":"1157:12:17"},"nodeType":"YulExpressionStatement","src":"1157:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"1130:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"1139:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1126:3:17"},"nodeType":"YulFunctionCall","src":"1126:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"1151:2:17","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"1122:3:17"},"nodeType":"YulFunctionCall","src":"1122:32:17"},"nodeType":"YulIf","src":"1119:52:17"},{"nodeType":"YulVariableDeclaration","src":"1180:30:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1200:9:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"1194:5:17"},"nodeType":"YulFunctionCall","src":"1194:16:17"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"1184:6:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1219:28:17","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1237:2:17","type":"","value":"64"},{"kind":"number","nodeType":"YulLiteral","src":"1241:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1233:3:17"},"nodeType":"YulFunctionCall","src":"1233:10:17"},{"kind":"number","nodeType":"YulLiteral","src":"1245:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1229:3:17"},"nodeType":"YulFunctionCall","src":"1229:18:17"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"1223:2:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"1274:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1283:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1286:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1276:6:17"},"nodeType":"YulFunctionCall","src":"1276:12:17"},"nodeType":"YulExpressionStatement","src":"1276:12:17"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"1262:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"1270:2:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"1259:2:17"},"nodeType":"YulFunctionCall","src":"1259:14:17"},"nodeType":"YulIf","src":"1256:34:17"},{"nodeType":"YulAssignment","src":"1299:71:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1342:9:17"},{"name":"offset","nodeType":"YulIdentifier","src":"1353:6:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1338:3:17"},"nodeType":"YulFunctionCall","src":"1338:22:17"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"1362:7:17"}],"functionName":{"name":"abi_decode_string_fromMemory","nodeType":"YulIdentifier","src":"1309:28:17"},"nodeType":"YulFunctionCall","src":"1309:61:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"1299:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"1379:41:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1405:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1416:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1401:3:17"},"nodeType":"YulFunctionCall","src":"1401:18:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"1395:5:17"},"nodeType":"YulFunctionCall","src":"1395:25:17"},"variables":[{"name":"offset_1","nodeType":"YulTypedName","src":"1383:8:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"1449:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1458:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1461:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1451:6:17"},"nodeType":"YulFunctionCall","src":"1451:12:17"},"nodeType":"YulExpressionStatement","src":"1451:12:17"}]},"condition":{"arguments":[{"name":"offset_1","nodeType":"YulIdentifier","src":"1435:8:17"},{"name":"_1","nodeType":"YulIdentifier","src":"1445:2:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"1432:2:17"},"nodeType":"YulFunctionCall","src":"1432:16:17"},"nodeType":"YulIf","src":"1429:36:17"},{"nodeType":"YulAssignment","src":"1474:73:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1517:9:17"},{"name":"offset_1","nodeType":"YulIdentifier","src":"1528:8:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1513:3:17"},"nodeType":"YulFunctionCall","src":"1513:24:17"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"1539:7:17"}],"functionName":{"name":"abi_decode_string_fromMemory","nodeType":"YulIdentifier","src":"1484:28:17"},"nodeType":"YulFunctionCall","src":"1484:63:17"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"1474:6:17"}]}]},"name":"abi_decode_tuple_t_string_memory_ptrt_string_memory_ptr_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"1067:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"1078:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"1090:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"1098:6:17","type":""}],"src":"991:562:17"},{"body":{"nodeType":"YulBlock","src":"1613:325:17","statements":[{"nodeType":"YulAssignment","src":"1623:22:17","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1637:1:17","type":"","value":"1"},{"name":"data","nodeType":"YulIdentifier","src":"1640:4:17"}],"functionName":{"name":"shr","nodeType":"YulIdentifier","src":"1633:3:17"},"nodeType":"YulFunctionCall","src":"1633:12:17"},"variableNames":[{"name":"length","nodeType":"YulIdentifier","src":"1623:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"1654:38:17","value":{"arguments":[{"name":"data","nodeType":"YulIdentifier","src":"1684:4:17"},{"kind":"number","nodeType":"YulLiteral","src":"1690:1:17","type":"","value":"1"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1680:3:17"},"nodeType":"YulFunctionCall","src":"1680:12:17"},"variables":[{"name":"outOfPlaceEncoding","nodeType":"YulTypedName","src":"1658:18:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"1731:31:17","statements":[{"nodeType":"YulAssignment","src":"1733:27:17","value":{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"1747:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"1755:4:17","type":"","value":"0x7f"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1743:3:17"},"nodeType":"YulFunctionCall","src":"1743:17:17"},"variableNames":[{"name":"length","nodeType":"YulIdentifier","src":"1733:6:17"}]}]},"condition":{"arguments":[{"name":"outOfPlaceEncoding","nodeType":"YulIdentifier","src":"1711:18:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"1704:6:17"},"nodeType":"YulFunctionCall","src":"1704:26:17"},"nodeType":"YulIf","src":"1701:61:17"},{"body":{"nodeType":"YulBlock","src":"1821:111:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1842:1:17","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1849:3:17","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"1854:10:17","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1845:3:17"},"nodeType":"YulFunctionCall","src":"1845:20:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1835:6:17"},"nodeType":"YulFunctionCall","src":"1835:31:17"},"nodeType":"YulExpressionStatement","src":"1835:31:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1886:1:17","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"1889:4:17","type":"","value":"0x22"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1879:6:17"},"nodeType":"YulFunctionCall","src":"1879:15:17"},"nodeType":"YulExpressionStatement","src":"1879:15:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1914:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1917:4:17","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1907:6:17"},"nodeType":"YulFunctionCall","src":"1907:15:17"},"nodeType":"YulExpressionStatement","src":"1907:15:17"}]},"condition":{"arguments":[{"name":"outOfPlaceEncoding","nodeType":"YulIdentifier","src":"1777:18:17"},{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"1800:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"1808:2:17","type":"","value":"32"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"1797:2:17"},"nodeType":"YulFunctionCall","src":"1797:14:17"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"1774:2:17"},"nodeType":"YulFunctionCall","src":"1774:38:17"},"nodeType":"YulIf","src":"1771:161:17"}]},"name":"extract_byte_array_length","nodeType":"YulFunctionDefinition","parameters":[{"name":"data","nodeType":"YulTypedName","src":"1593:4:17","type":""}],"returnVariables":[{"name":"length","nodeType":"YulTypedName","src":"1602:6:17","type":""}],"src":"1558:380:17"},{"body":{"nodeType":"YulBlock","src":"1999:65:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2016:1:17","type":"","value":"0"},{"name":"ptr","nodeType":"YulIdentifier","src":"2019:3:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2009:6:17"},"nodeType":"YulFunctionCall","src":"2009:14:17"},"nodeType":"YulExpressionStatement","src":"2009:14:17"},{"nodeType":"YulAssignment","src":"2032:26:17","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2050:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2053:4:17","type":"","value":"0x20"}],"functionName":{"name":"keccak256","nodeType":"YulIdentifier","src":"2040:9:17"},"nodeType":"YulFunctionCall","src":"2040:18:17"},"variableNames":[{"name":"data","nodeType":"YulIdentifier","src":"2032:4:17"}]}]},"name":"array_dataslot_string_storage","nodeType":"YulFunctionDefinition","parameters":[{"name":"ptr","nodeType":"YulTypedName","src":"1982:3:17","type":""}],"returnVariables":[{"name":"data","nodeType":"YulTypedName","src":"1990:4:17","type":""}],"src":"1943:121:17"},{"body":{"nodeType":"YulBlock","src":"2150:464:17","statements":[{"body":{"nodeType":"YulBlock","src":"2183:425:17","statements":[{"nodeType":"YulVariableDeclaration","src":"2197:11:17","value":{"kind":"number","nodeType":"YulLiteral","src":"2207:1:17","type":"","value":"0"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"2201:2:17","type":""}]},{"expression":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"2228:2:17"},{"name":"array","nodeType":"YulIdentifier","src":"2232:5:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2221:6:17"},"nodeType":"YulFunctionCall","src":"2221:17:17"},"nodeType":"YulExpressionStatement","src":"2221:17:17"},{"nodeType":"YulVariableDeclaration","src":"2251:31:17","value":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"2273:2:17"},{"kind":"number","nodeType":"YulLiteral","src":"2277:4:17","type":"","value":"0x20"}],"functionName":{"name":"keccak256","nodeType":"YulIdentifier","src":"2263:9:17"},"nodeType":"YulFunctionCall","src":"2263:19:17"},"variables":[{"name":"data","nodeType":"YulTypedName","src":"2255:4:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"2295:57:17","value":{"arguments":[{"name":"data","nodeType":"YulIdentifier","src":"2318:4:17"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2328:1:17","type":"","value":"5"},{"arguments":[{"name":"startIndex","nodeType":"YulIdentifier","src":"2335:10:17"},{"kind":"number","nodeType":"YulLiteral","src":"2347:2:17","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2331:3:17"},"nodeType":"YulFunctionCall","src":"2331:19:17"}],"functionName":{"name":"shr","nodeType":"YulIdentifier","src":"2324:3:17"},"nodeType":"YulFunctionCall","src":"2324:27:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2314:3:17"},"nodeType":"YulFunctionCall","src":"2314:38:17"},"variables":[{"name":"deleteStart","nodeType":"YulTypedName","src":"2299:11:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"2389:23:17","statements":[{"nodeType":"YulAssignment","src":"2391:19:17","value":{"name":"data","nodeType":"YulIdentifier","src":"2406:4:17"},"variableNames":[{"name":"deleteStart","nodeType":"YulIdentifier","src":"2391:11:17"}]}]},"condition":{"arguments":[{"name":"startIndex","nodeType":"YulIdentifier","src":"2371:10:17"},{"kind":"number","nodeType":"YulLiteral","src":"2383:4:17","type":"","value":"0x20"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"2368:2:17"},"nodeType":"YulFunctionCall","src":"2368:20:17"},"nodeType":"YulIf","src":"2365:47:17"},{"nodeType":"YulVariableDeclaration","src":"2425:41:17","value":{"arguments":[{"name":"data","nodeType":"YulIdentifier","src":"2439:4:17"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2449:1:17","type":"","value":"5"},{"arguments":[{"name":"len","nodeType":"YulIdentifier","src":"2456:3:17"},{"kind":"number","nodeType":"YulLiteral","src":"2461:2:17","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2452:3:17"},"nodeType":"YulFunctionCall","src":"2452:12:17"}],"functionName":{"name":"shr","nodeType":"YulIdentifier","src":"2445:3:17"},"nodeType":"YulFunctionCall","src":"2445:20:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2435:3:17"},"nodeType":"YulFunctionCall","src":"2435:31:17"},"variables":[{"name":"_2","nodeType":"YulTypedName","src":"2429:2:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"2479:24:17","value":{"name":"deleteStart","nodeType":"YulIdentifier","src":"2492:11:17"},"variables":[{"name":"start","nodeType":"YulTypedName","src":"2483:5:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"2577:21:17","statements":[{"expression":{"arguments":[{"name":"start","nodeType":"YulIdentifier","src":"2586:5:17"},{"name":"_1","nodeType":"YulIdentifier","src":"2593:2:17"}],"functionName":{"name":"sstore","nodeType":"YulIdentifier","src":"2579:6:17"},"nodeType":"YulFunctionCall","src":"2579:17:17"},"nodeType":"YulExpressionStatement","src":"2579:17:17"}]},"condition":{"arguments":[{"name":"start","nodeType":"YulIdentifier","src":"2527:5:17"},{"name":"_2","nodeType":"YulIdentifier","src":"2534:2:17"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"2524:2:17"},"nodeType":"YulFunctionCall","src":"2524:13:17"},"nodeType":"YulForLoop","post":{"nodeType":"YulBlock","src":"2538:26:17","statements":[{"nodeType":"YulAssignment","src":"2540:22:17","value":{"arguments":[{"name":"start","nodeType":"YulIdentifier","src":"2553:5:17"},{"kind":"number","nodeType":"YulLiteral","src":"2560:1:17","type":"","value":"1"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2549:3:17"},"nodeType":"YulFunctionCall","src":"2549:13:17"},"variableNames":[{"name":"start","nodeType":"YulIdentifier","src":"2540:5:17"}]}]},"pre":{"nodeType":"YulBlock","src":"2520:3:17","statements":[]},"src":"2516:82:17"}]},"condition":{"arguments":[{"name":"len","nodeType":"YulIdentifier","src":"2166:3:17"},{"kind":"number","nodeType":"YulLiteral","src":"2171:2:17","type":"","value":"31"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2163:2:17"},"nodeType":"YulFunctionCall","src":"2163:11:17"},"nodeType":"YulIf","src":"2160:448:17"}]},"name":"clean_up_bytearray_end_slots_string_storage","nodeType":"YulFunctionDefinition","parameters":[{"name":"array","nodeType":"YulTypedName","src":"2122:5:17","type":""},{"name":"len","nodeType":"YulTypedName","src":"2129:3:17","type":""},{"name":"startIndex","nodeType":"YulTypedName","src":"2134:10:17","type":""}],"src":"2069:545:17"},{"body":{"nodeType":"YulBlock","src":"2704:81:17","statements":[{"nodeType":"YulAssignment","src":"2714:65:17","value":{"arguments":[{"arguments":[{"name":"data","nodeType":"YulIdentifier","src":"2729:4:17"},{"arguments":[{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2747:1:17","type":"","value":"3"},{"name":"len","nodeType":"YulIdentifier","src":"2750:3:17"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"2743:3:17"},"nodeType":"YulFunctionCall","src":"2743:11:17"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2760:1:17","type":"","value":"0"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"2756:3:17"},"nodeType":"YulFunctionCall","src":"2756:6:17"}],"functionName":{"name":"shr","nodeType":"YulIdentifier","src":"2739:3:17"},"nodeType":"YulFunctionCall","src":"2739:24:17"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"2735:3:17"},"nodeType":"YulFunctionCall","src":"2735:29:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"2725:3:17"},"nodeType":"YulFunctionCall","src":"2725:40:17"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2771:1:17","type":"","value":"1"},{"name":"len","nodeType":"YulIdentifier","src":"2774:3:17"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"2767:3:17"},"nodeType":"YulFunctionCall","src":"2767:11:17"}],"functionName":{"name":"or","nodeType":"YulIdentifier","src":"2722:2:17"},"nodeType":"YulFunctionCall","src":"2722:57:17"},"variableNames":[{"name":"used","nodeType":"YulIdentifier","src":"2714:4:17"}]}]},"name":"extract_used_part_and_set_length_of_short_byte_array","nodeType":"YulFunctionDefinition","parameters":[{"name":"data","nodeType":"YulTypedName","src":"2681:4:17","type":""},{"name":"len","nodeType":"YulTypedName","src":"2687:3:17","type":""}],"returnVariables":[{"name":"used","nodeType":"YulTypedName","src":"2695:4:17","type":""}],"src":"2619:166:17"},{"body":{"nodeType":"YulBlock","src":"2886:1256:17","statements":[{"nodeType":"YulVariableDeclaration","src":"2896:24:17","value":{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"2916:3:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"2910:5:17"},"nodeType":"YulFunctionCall","src":"2910:10:17"},"variables":[{"name":"newLen","nodeType":"YulTypedName","src":"2900:6:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"2963:22:17","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"2965:16:17"},"nodeType":"YulFunctionCall","src":"2965:18:17"},"nodeType":"YulExpressionStatement","src":"2965:18:17"}]},"condition":{"arguments":[{"name":"newLen","nodeType":"YulIdentifier","src":"2935:6:17"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2951:2:17","type":"","value":"64"},{"kind":"number","nodeType":"YulLiteral","src":"2955:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"2947:3:17"},"nodeType":"YulFunctionCall","src":"2947:10:17"},{"kind":"number","nodeType":"YulLiteral","src":"2959:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"2943:3:17"},"nodeType":"YulFunctionCall","src":"2943:18:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2932:2:17"},"nodeType":"YulFunctionCall","src":"2932:30:17"},"nodeType":"YulIf","src":"2929:56:17"},{"expression":{"arguments":[{"name":"slot","nodeType":"YulIdentifier","src":"3038:4:17"},{"arguments":[{"arguments":[{"name":"slot","nodeType":"YulIdentifier","src":"3076:4:17"}],"functionName":{"name":"sload","nodeType":"YulIdentifier","src":"3070:5:17"},"nodeType":"YulFunctionCall","src":"3070:11:17"}],"functionName":{"name":"extract_byte_array_length","nodeType":"YulIdentifier","src":"3044:25:17"},"nodeType":"YulFunctionCall","src":"3044:38:17"},{"name":"newLen","nodeType":"YulIdentifier","src":"3084:6:17"}],"functionName":{"name":"clean_up_bytearray_end_slots_string_storage","nodeType":"YulIdentifier","src":"2994:43:17"},"nodeType":"YulFunctionCall","src":"2994:97:17"},"nodeType":"YulExpressionStatement","src":"2994:97:17"},{"nodeType":"YulVariableDeclaration","src":"3100:18:17","value":{"kind":"number","nodeType":"YulLiteral","src":"3117:1:17","type":"","value":"0"},"variables":[{"name":"srcOffset","nodeType":"YulTypedName","src":"3104:9:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"3127:23:17","value":{"kind":"number","nodeType":"YulLiteral","src":"3146:4:17","type":"","value":"0x20"},"variables":[{"name":"srcOffset_1","nodeType":"YulTypedName","src":"3131:11:17","type":""}]},{"nodeType":"YulAssignment","src":"3159:24:17","value":{"name":"srcOffset_1","nodeType":"YulIdentifier","src":"3172:11:17"},"variableNames":[{"name":"srcOffset","nodeType":"YulIdentifier","src":"3159:9:17"}]},{"cases":[{"body":{"nodeType":"YulBlock","src":"3229:656:17","statements":[{"nodeType":"YulVariableDeclaration","src":"3243:35:17","value":{"arguments":[{"name":"newLen","nodeType":"YulIdentifier","src":"3262:6:17"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3274:2:17","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"3270:3:17"},"nodeType":"YulFunctionCall","src":"3270:7:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"3258:3:17"},"nodeType":"YulFunctionCall","src":"3258:20:17"},"variables":[{"name":"loopEnd","nodeType":"YulTypedName","src":"3247:7:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"3291:49:17","value":{"arguments":[{"name":"slot","nodeType":"YulIdentifier","src":"3335:4:17"}],"functionName":{"name":"array_dataslot_string_storage","nodeType":"YulIdentifier","src":"3305:29:17"},"nodeType":"YulFunctionCall","src":"3305:35:17"},"variables":[{"name":"dstPtr","nodeType":"YulTypedName","src":"3295:6:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"3353:10:17","value":{"kind":"number","nodeType":"YulLiteral","src":"3362:1:17","type":"","value":"0"},"variables":[{"name":"i","nodeType":"YulTypedName","src":"3357:1:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"3440:172:17","statements":[{"expression":{"arguments":[{"name":"dstPtr","nodeType":"YulIdentifier","src":"3465:6:17"},{"arguments":[{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"3483:3:17"},{"name":"srcOffset","nodeType":"YulIdentifier","src":"3488:9:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3479:3:17"},"nodeType":"YulFunctionCall","src":"3479:19:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"3473:5:17"},"nodeType":"YulFunctionCall","src":"3473:26:17"}],"functionName":{"name":"sstore","nodeType":"YulIdentifier","src":"3458:6:17"},"nodeType":"YulFunctionCall","src":"3458:42:17"},"nodeType":"YulExpressionStatement","src":"3458:42:17"},{"nodeType":"YulAssignment","src":"3517:24:17","value":{"arguments":[{"name":"dstPtr","nodeType":"YulIdentifier","src":"3531:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"3539:1:17","type":"","value":"1"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3527:3:17"},"nodeType":"YulFunctionCall","src":"3527:14:17"},"variableNames":[{"name":"dstPtr","nodeType":"YulIdentifier","src":"3517:6:17"}]},{"nodeType":"YulAssignment","src":"3558:40:17","value":{"arguments":[{"name":"srcOffset","nodeType":"YulIdentifier","src":"3575:9:17"},{"name":"srcOffset_1","nodeType":"YulIdentifier","src":"3586:11:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3571:3:17"},"nodeType":"YulFunctionCall","src":"3571:27:17"},"variableNames":[{"name":"srcOffset","nodeType":"YulIdentifier","src":"3558:9:17"}]}]},"condition":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"3387:1:17"},{"name":"loopEnd","nodeType":"YulIdentifier","src":"3390:7:17"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"3384:2:17"},"nodeType":"YulFunctionCall","src":"3384:14:17"},"nodeType":"YulForLoop","post":{"nodeType":"YulBlock","src":"3399:28:17","statements":[{"nodeType":"YulAssignment","src":"3401:24:17","value":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"3410:1:17"},{"name":"srcOffset_1","nodeType":"YulIdentifier","src":"3413:11:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3406:3:17"},"nodeType":"YulFunctionCall","src":"3406:19:17"},"variableNames":[{"name":"i","nodeType":"YulIdentifier","src":"3401:1:17"}]}]},"pre":{"nodeType":"YulBlock","src":"3380:3:17","statements":[]},"src":"3376:236:17"},{"body":{"nodeType":"YulBlock","src":"3660:166:17","statements":[{"nodeType":"YulVariableDeclaration","src":"3678:43:17","value":{"arguments":[{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"3705:3:17"},{"name":"srcOffset","nodeType":"YulIdentifier","src":"3710:9:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3701:3:17"},"nodeType":"YulFunctionCall","src":"3701:19:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"3695:5:17"},"nodeType":"YulFunctionCall","src":"3695:26:17"},"variables":[{"name":"lastValue","nodeType":"YulTypedName","src":"3682:9:17","type":""}]},{"expression":{"arguments":[{"name":"dstPtr","nodeType":"YulIdentifier","src":"3745:6:17"},{"arguments":[{"name":"lastValue","nodeType":"YulIdentifier","src":"3757:9:17"},{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3784:1:17","type":"","value":"3"},{"name":"newLen","nodeType":"YulIdentifier","src":"3787:6:17"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"3780:3:17"},"nodeType":"YulFunctionCall","src":"3780:14:17"},{"kind":"number","nodeType":"YulLiteral","src":"3796:3:17","type":"","value":"248"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"3776:3:17"},"nodeType":"YulFunctionCall","src":"3776:24:17"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3806:1:17","type":"","value":"0"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"3802:3:17"},"nodeType":"YulFunctionCall","src":"3802:6:17"}],"functionName":{"name":"shr","nodeType":"YulIdentifier","src":"3772:3:17"},"nodeType":"YulFunctionCall","src":"3772:37:17"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"3768:3:17"},"nodeType":"YulFunctionCall","src":"3768:42:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"3753:3:17"},"nodeType":"YulFunctionCall","src":"3753:58:17"}],"functionName":{"name":"sstore","nodeType":"YulIdentifier","src":"3738:6:17"},"nodeType":"YulFunctionCall","src":"3738:74:17"},"nodeType":"YulExpressionStatement","src":"3738:74:17"}]},"condition":{"arguments":[{"name":"loopEnd","nodeType":"YulIdentifier","src":"3631:7:17"},{"name":"newLen","nodeType":"YulIdentifier","src":"3640:6:17"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"3628:2:17"},"nodeType":"YulFunctionCall","src":"3628:19:17"},"nodeType":"YulIf","src":"3625:201:17"},{"expression":{"arguments":[{"name":"slot","nodeType":"YulIdentifier","src":"3846:4:17"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3860:1:17","type":"","value":"1"},{"name":"newLen","nodeType":"YulIdentifier","src":"3863:6:17"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"3856:3:17"},"nodeType":"YulFunctionCall","src":"3856:14:17"},{"kind":"number","nodeType":"YulLiteral","src":"3872:1:17","type":"","value":"1"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3852:3:17"},"nodeType":"YulFunctionCall","src":"3852:22:17"}],"functionName":{"name":"sstore","nodeType":"YulIdentifier","src":"3839:6:17"},"nodeType":"YulFunctionCall","src":"3839:36:17"},"nodeType":"YulExpressionStatement","src":"3839:36:17"}]},"nodeType":"YulCase","src":"3222:663:17","value":{"kind":"number","nodeType":"YulLiteral","src":"3227:1:17","type":"","value":"1"}},{"body":{"nodeType":"YulBlock","src":"3902:234:17","statements":[{"nodeType":"YulVariableDeclaration","src":"3916:14:17","value":{"kind":"number","nodeType":"YulLiteral","src":"3929:1:17","type":"","value":"0"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"3920:5:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"3965:67:17","statements":[{"nodeType":"YulAssignment","src":"3983:35:17","value":{"arguments":[{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"4002:3:17"},{"name":"srcOffset","nodeType":"YulIdentifier","src":"4007:9:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3998:3:17"},"nodeType":"YulFunctionCall","src":"3998:19:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"3992:5:17"},"nodeType":"YulFunctionCall","src":"3992:26:17"},"variableNames":[{"name":"value","nodeType":"YulIdentifier","src":"3983:5:17"}]}]},"condition":{"name":"newLen","nodeType":"YulIdentifier","src":"3946:6:17"},"nodeType":"YulIf","src":"3943:89:17"},{"expression":{"arguments":[{"name":"slot","nodeType":"YulIdentifier","src":"4052:4:17"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"4111:5:17"},{"name":"newLen","nodeType":"YulIdentifier","src":"4118:6:17"}],"functionName":{"name":"extract_used_part_and_set_length_of_short_byte_array","nodeType":"YulIdentifier","src":"4058:52:17"},"nodeType":"YulFunctionCall","src":"4058:67:17"}],"functionName":{"name":"sstore","nodeType":"YulIdentifier","src":"4045:6:17"},"nodeType":"YulFunctionCall","src":"4045:81:17"},"nodeType":"YulExpressionStatement","src":"4045:81:17"}]},"nodeType":"YulCase","src":"3894:242:17","value":"default"}],"expression":{"arguments":[{"name":"newLen","nodeType":"YulIdentifier","src":"3202:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"3210:2:17","type":"","value":"31"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"3199:2:17"},"nodeType":"YulFunctionCall","src":"3199:14:17"},"nodeType":"YulSwitch","src":"3192:944:17"}]},"name":"copy_byte_array_to_storage_from_t_string_memory_ptr_to_t_string_storage","nodeType":"YulFunctionDefinition","parameters":[{"name":"slot","nodeType":"YulTypedName","src":"2871:4:17","type":""},{"name":"src","nodeType":"YulTypedName","src":"2877:3:17","type":""}],"src":"2790:1352:17"}]},"contents":"{\n { }\n function panic_error_0x41()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x41)\n revert(0, 0x24)\n }\n function abi_decode_string_fromMemory(offset, end) -> array\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n let _1 := mload(offset)\n let _2 := sub(shl(64, 1), 1)\n if gt(_1, _2) { panic_error_0x41() }\n let _3 := not(31)\n let memPtr := mload(64)\n let newFreePtr := add(memPtr, and(add(and(add(_1, 0x1f), _3), 63), _3))\n if or(gt(newFreePtr, _2), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n mstore(64, newFreePtr)\n mstore(memPtr, _1)\n let _4 := 0x20\n if gt(add(add(offset, _1), _4), end) { revert(0, 0) }\n let i := 0\n for { } lt(i, _1) { i := add(i, _4) }\n {\n mstore(add(add(memPtr, i), _4), mload(add(add(offset, i), _4)))\n }\n mstore(add(add(memPtr, _1), _4), 0)\n array := memPtr\n }\n function abi_decode_tuple_t_string_memory_ptrt_string_memory_ptr_fromMemory(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n let offset := mload(headStart)\n let _1 := sub(shl(64, 1), 1)\n if gt(offset, _1) { revert(0, 0) }\n value0 := abi_decode_string_fromMemory(add(headStart, offset), dataEnd)\n let offset_1 := mload(add(headStart, 32))\n if gt(offset_1, _1) { revert(0, 0) }\n value1 := abi_decode_string_fromMemory(add(headStart, offset_1), dataEnd)\n }\n function extract_byte_array_length(data) -> length\n {\n length := shr(1, data)\n let outOfPlaceEncoding := and(data, 1)\n if iszero(outOfPlaceEncoding) { length := and(length, 0x7f) }\n if eq(outOfPlaceEncoding, lt(length, 32))\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x22)\n revert(0, 0x24)\n }\n }\n function array_dataslot_string_storage(ptr) -> data\n {\n mstore(0, ptr)\n data := keccak256(0, 0x20)\n }\n function clean_up_bytearray_end_slots_string_storage(array, len, startIndex)\n {\n if gt(len, 31)\n {\n let _1 := 0\n mstore(_1, array)\n let data := keccak256(_1, 0x20)\n let deleteStart := add(data, shr(5, add(startIndex, 31)))\n if lt(startIndex, 0x20) { deleteStart := data }\n let _2 := add(data, shr(5, add(len, 31)))\n let start := deleteStart\n for { } lt(start, _2) { start := add(start, 1) }\n { sstore(start, _1) }\n }\n }\n function extract_used_part_and_set_length_of_short_byte_array(data, len) -> used\n {\n used := or(and(data, not(shr(shl(3, len), not(0)))), shl(1, len))\n }\n function copy_byte_array_to_storage_from_t_string_memory_ptr_to_t_string_storage(slot, src)\n {\n let newLen := mload(src)\n if gt(newLen, sub(shl(64, 1), 1)) { panic_error_0x41() }\n clean_up_bytearray_end_slots_string_storage(slot, extract_byte_array_length(sload(slot)), newLen)\n let srcOffset := 0\n let srcOffset_1 := 0x20\n srcOffset := srcOffset_1\n switch gt(newLen, 31)\n case 1 {\n let loopEnd := and(newLen, not(31))\n let dstPtr := array_dataslot_string_storage(slot)\n let i := 0\n for { } lt(i, loopEnd) { i := add(i, srcOffset_1) }\n {\n sstore(dstPtr, mload(add(src, srcOffset)))\n dstPtr := add(dstPtr, 1)\n srcOffset := add(srcOffset, srcOffset_1)\n }\n if lt(loopEnd, newLen)\n {\n let lastValue := mload(add(src, srcOffset))\n sstore(dstPtr, and(lastValue, not(shr(and(shl(3, newLen), 248), not(0)))))\n }\n sstore(slot, add(shl(1, newLen), 1))\n }\n default {\n let value := 0\n if newLen\n {\n value := mload(add(src, srcOffset))\n }\n sstore(slot, extract_used_part_and_set_length_of_short_byte_array(value, newLen))\n }\n }\n}","id":17,"language":"Yul","name":"#utility.yul"}],"linkReferences":{},"object":"60806040523480156200001157600080fd5b50604051620013e7380380620013e783398101604081905262000034916200011f565b600062000042838262000218565b50600162000051828262000218565b505050620002e4565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200008257600080fd5b81516001600160401b03808211156200009f576200009f6200005a565b604051601f8301601f19908116603f01168101908282118183101715620000ca57620000ca6200005a565b81604052838152602092508683858801011115620000e757600080fd5b600091505b838210156200010b5785820183015181830184015290820190620000ec565b600093810190920192909252949350505050565b600080604083850312156200013357600080fd5b82516001600160401b03808211156200014b57600080fd5b620001598683870162000070565b935060208501519150808211156200017057600080fd5b506200017f8582860162000070565b9150509250929050565b600181811c908216806200019e57607f821691505b602082108103620001bf57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200021357600081815260208120601f850160051c81016020861015620001ee5750805b601f850160051c820191505b818110156200020f57828155600101620001fa565b5050505b505050565b81516001600160401b038111156200023457620002346200005a565b6200024c8162000245845462000189565b84620001c5565b602080601f8311600181146200028457600084156200026b5750858301515b600019600386901b1c1916600185901b1785556200020f565b600085815260208120601f198616915b82811015620002b55788860151825594840194600190910190840162000294565b5085821015620002d45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6110f380620002f46000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c80636352211e1161008c578063a22cb46511610066578063a22cb465146101b3578063b88d4fde146101c6578063c87b56dd146101d9578063e985e9c5146101ec57600080fd5b80636352211e1461017757806370a082311461018a57806395d89b41146101ab57600080fd5b806301ffc9a7146100d457806306fdde03146100fc578063081812fc14610111578063095ea7b31461013c57806323b872dd1461015157806342842e0e14610164575b600080fd5b6100e76100e2366004610c7f565b610228565b60405190151581526020015b60405180910390f35b61010461027a565b6040516100f39190610cec565b61012461011f366004610cff565b61030c565b6040516001600160a01b0390911681526020016100f3565b61014f61014a366004610d34565b610333565b005b61014f61015f366004610d5e565b61044d565b61014f610172366004610d5e565b61047e565b610124610185366004610cff565b610499565b61019d610198366004610d9a565b6104f9565b6040519081526020016100f3565b61010461057f565b61014f6101c1366004610db5565b61058e565b61014f6101d4366004610e07565b61059d565b6101046101e7366004610cff565b6105d5565b6100e76101fa366004610ee3565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60006001600160e01b031982166380ac58cd60e01b148061025957506001600160e01b03198216635b5e139f60e01b145b8061027457506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606000805461028990610f16565b80601f01602080910402602001604051908101604052809291908181526020018280546102b590610f16565b80156103025780601f106102d757610100808354040283529160200191610302565b820191906000526020600020905b8154815290600101906020018083116102e557829003601f168201915b5050505050905090565b600061031782610649565b506000908152600460205260409020546001600160a01b031690565b600061033e82610499565b9050806001600160a01b0316836001600160a01b0316036103b05760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806103cc57506103cc81336101fa565b61043e5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c00000060648201526084016103a7565b61044883836106ab565b505050565b6104573382610719565b6104735760405162461bcd60e51b81526004016103a790610f50565b610448838383610798565b6104488383836040518060200160405280600081525061059d565b6000818152600260205260408120546001600160a01b0316806102745760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103a7565b60006001600160a01b0382166105635760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016103a7565b506001600160a01b031660009081526003602052604090205490565b60606001805461028990610f16565b6105993383836108fc565b5050565b6105a73383610719565b6105c35760405162461bcd60e51b81526004016103a790610f50565b6105cf848484846109ca565b50505050565b60606105e082610649565b60006105f760408051602081019091526000815290565b905060008151116106175760405180602001604052806000815250610642565b80610621846109fd565b604051602001610632929190610f9d565b6040516020818303038152906040525b9392505050565b6000818152600260205260409020546001600160a01b03166106a85760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103a7565b50565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906106e082610499565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061072583610499565b9050806001600160a01b0316846001600160a01b0316148061076c57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b806107905750836001600160a01b03166107858461030c565b6001600160a01b0316145b949350505050565b826001600160a01b03166107ab82610499565b6001600160a01b0316146107d15760405162461bcd60e51b81526004016103a790610fcc565b6001600160a01b0382166108335760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016103a7565b826001600160a01b031661084682610499565b6001600160a01b03161461086c5760405162461bcd60e51b81526004016103a790610fcc565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b816001600160a01b0316836001600160a01b03160361095d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016103a7565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6109d5848484610798565b6109e184848484610a90565b6105cf5760405162461bcd60e51b81526004016103a790611011565b60606000610a0a83610b91565b600101905060008167ffffffffffffffff811115610a2a57610a2a610df1565b6040519080825280601f01601f191660200182016040528015610a54576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084610a5e57509392505050565b60006001600160a01b0384163b15610b8657604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290610ad4903390899088908890600401611063565b6020604051808303816000875af1925050508015610b0f575060408051601f3d908101601f19168201909252610b0c918101906110a0565b60015b610b6c573d808015610b3d576040519150601f19603f3d011682016040523d82523d6000602084013e610b42565b606091505b508051600003610b645760405162461bcd60e51b81526004016103a790611011565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610790565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310610bd05772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310610bfc576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310610c1a57662386f26fc10000830492506010015b6305f5e1008310610c32576305f5e100830492506008015b6127108310610c4657612710830492506004015b60648310610c58576064830492506002015b600a83106102745760010192915050565b6001600160e01b0319811681146106a857600080fd5b600060208284031215610c9157600080fd5b813561064281610c69565b60005b83811015610cb7578181015183820152602001610c9f565b50506000910152565b60008151808452610cd8816020860160208601610c9c565b601f01601f19169290920160200192915050565b6020815260006106426020830184610cc0565b600060208284031215610d1157600080fd5b5035919050565b80356001600160a01b0381168114610d2f57600080fd5b919050565b60008060408385031215610d4757600080fd5b610d5083610d18565b946020939093013593505050565b600080600060608486031215610d7357600080fd5b610d7c84610d18565b9250610d8a60208501610d18565b9150604084013590509250925092565b600060208284031215610dac57600080fd5b61064282610d18565b60008060408385031215610dc857600080fd5b610dd183610d18565b915060208301358015158114610de657600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215610e1d57600080fd5b610e2685610d18565b9350610e3460208601610d18565b925060408501359150606085013567ffffffffffffffff80821115610e5857600080fd5b818701915087601f830112610e6c57600080fd5b813581811115610e7e57610e7e610df1565b604051601f8201601f19908116603f01168101908382118183101715610ea657610ea6610df1565b816040528281528a6020848701011115610ebf57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215610ef657600080fd5b610eff83610d18565b9150610f0d60208401610d18565b90509250929050565b600181811c90821680610f2a57607f821691505b602082108103610f4a57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b60008351610faf818460208801610c9c565b835190830190610fc3818360208801610c9c565b01949350505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061109690830184610cc0565b9695505050505050565b6000602082840312156110b257600080fd5b815161064281610c6956fea2646970667358221220572b001af737f9d43203516808c567baf41baf8d490bb57390158191aafea9c264736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH3 0x11 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 MLOAD PUSH3 0x13E7 CODESIZE SUB DUP1 PUSH3 0x13E7 DUP4 CODECOPY DUP2 ADD PUSH1 0x40 DUP2 SWAP1 MSTORE PUSH3 0x34 SWAP2 PUSH3 0x11F JUMP JUMPDEST PUSH1 0x0 PUSH3 0x42 DUP4 DUP3 PUSH3 0x218 JUMP JUMPDEST POP PUSH1 0x1 PUSH3 0x51 DUP3 DUP3 PUSH3 0x218 JUMP JUMPDEST POP POP POP PUSH3 0x2E4 JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH3 0x82 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0x40 SHL SUB DUP1 DUP3 GT ISZERO PUSH3 0x9F JUMPI PUSH3 0x9F PUSH3 0x5A JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP4 ADD PUSH1 0x1F NOT SWAP1 DUP2 AND PUSH1 0x3F ADD AND DUP2 ADD SWAP1 DUP3 DUP3 GT DUP2 DUP4 LT OR ISZERO PUSH3 0xCA JUMPI PUSH3 0xCA PUSH3 0x5A JUMP JUMPDEST DUP2 PUSH1 0x40 MSTORE DUP4 DUP2 MSTORE PUSH1 0x20 SWAP3 POP DUP7 DUP4 DUP6 DUP9 ADD ADD GT ISZERO PUSH3 0xE7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 SWAP2 POP JUMPDEST DUP4 DUP3 LT ISZERO PUSH3 0x10B JUMPI DUP6 DUP3 ADD DUP4 ADD MLOAD DUP2 DUP4 ADD DUP5 ADD MSTORE SWAP1 DUP3 ADD SWAP1 PUSH3 0xEC JUMP JUMPDEST PUSH1 0x0 SWAP4 DUP2 ADD SWAP1 SWAP3 ADD SWAP3 SWAP1 SWAP3 MSTORE SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH3 0x133 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0x40 SHL SUB DUP1 DUP3 GT ISZERO PUSH3 0x14B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH3 0x159 DUP7 DUP4 DUP8 ADD PUSH3 0x70 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD MLOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH3 0x170 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH3 0x17F DUP6 DUP3 DUP7 ADD PUSH3 0x70 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x1 DUP2 DUP2 SHR SWAP1 DUP3 AND DUP1 PUSH3 0x19E JUMPI PUSH1 0x7F DUP3 AND SWAP2 POP JUMPDEST PUSH1 0x20 DUP3 LT DUP2 SUB PUSH3 0x1BF JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x22 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x1F DUP3 GT ISZERO PUSH3 0x213 JUMPI PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 KECCAK256 PUSH1 0x1F DUP6 ADD PUSH1 0x5 SHR DUP2 ADD PUSH1 0x20 DUP7 LT ISZERO PUSH3 0x1EE JUMPI POP DUP1 JUMPDEST PUSH1 0x1F DUP6 ADD PUSH1 0x5 SHR DUP3 ADD SWAP2 POP JUMPDEST DUP2 DUP2 LT ISZERO PUSH3 0x20F JUMPI DUP3 DUP2 SSTORE PUSH1 0x1 ADD PUSH3 0x1FA JUMP JUMPDEST POP POP POP JUMPDEST POP POP POP JUMP JUMPDEST DUP2 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0x40 SHL SUB DUP2 GT ISZERO PUSH3 0x234 JUMPI PUSH3 0x234 PUSH3 0x5A JUMP JUMPDEST PUSH3 0x24C DUP2 PUSH3 0x245 DUP5 SLOAD PUSH3 0x189 JUMP JUMPDEST DUP5 PUSH3 0x1C5 JUMP JUMPDEST PUSH1 0x20 DUP1 PUSH1 0x1F DUP4 GT PUSH1 0x1 DUP2 EQ PUSH3 0x284 JUMPI PUSH1 0x0 DUP5 ISZERO PUSH3 0x26B JUMPI POP DUP6 DUP4 ADD MLOAD JUMPDEST PUSH1 0x0 NOT PUSH1 0x3 DUP7 SWAP1 SHL SHR NOT AND PUSH1 0x1 DUP6 SWAP1 SHL OR DUP6 SSTORE PUSH3 0x20F JUMP JUMPDEST PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x20 DUP2 KECCAK256 PUSH1 0x1F NOT DUP7 AND SWAP2 JUMPDEST DUP3 DUP2 LT ISZERO PUSH3 0x2B5 JUMPI DUP9 DUP7 ADD MLOAD DUP3 SSTORE SWAP5 DUP5 ADD SWAP5 PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 DUP5 ADD PUSH3 0x294 JUMP JUMPDEST POP DUP6 DUP3 LT ISZERO PUSH3 0x2D4 JUMPI DUP8 DUP6 ADD MLOAD PUSH1 0x0 NOT PUSH1 0x3 DUP9 SWAP1 SHL PUSH1 0xF8 AND SHR NOT AND DUP2 SSTORE JUMPDEST POP POP POP POP POP PUSH1 0x1 SWAP1 DUP2 SHL ADD SWAP1 SSTORE POP JUMP JUMPDEST PUSH2 0x10F3 DUP1 PUSH3 0x2F4 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0xCF JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x6352211E GT PUSH2 0x8C JUMPI DUP1 PUSH4 0xA22CB465 GT PUSH2 0x66 JUMPI DUP1 PUSH4 0xA22CB465 EQ PUSH2 0x1B3 JUMPI DUP1 PUSH4 0xB88D4FDE EQ PUSH2 0x1C6 JUMPI DUP1 PUSH4 0xC87B56DD EQ PUSH2 0x1D9 JUMPI DUP1 PUSH4 0xE985E9C5 EQ PUSH2 0x1EC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x6352211E EQ PUSH2 0x177 JUMPI DUP1 PUSH4 0x70A08231 EQ PUSH2 0x18A JUMPI DUP1 PUSH4 0x95D89B41 EQ PUSH2 0x1AB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1FFC9A7 EQ PUSH2 0xD4 JUMPI DUP1 PUSH4 0x6FDDE03 EQ PUSH2 0xFC JUMPI DUP1 PUSH4 0x81812FC EQ PUSH2 0x111 JUMPI DUP1 PUSH4 0x95EA7B3 EQ PUSH2 0x13C JUMPI DUP1 PUSH4 0x23B872DD EQ PUSH2 0x151 JUMPI DUP1 PUSH4 0x42842E0E EQ PUSH2 0x164 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xE7 PUSH2 0xE2 CALLDATASIZE PUSH1 0x4 PUSH2 0xC7F JUMP JUMPDEST PUSH2 0x228 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x104 PUSH2 0x27A JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xF3 SWAP2 SWAP1 PUSH2 0xCEC JUMP JUMPDEST PUSH2 0x124 PUSH2 0x11F CALLDATASIZE PUSH1 0x4 PUSH2 0xCFF JUMP JUMPDEST PUSH2 0x30C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xF3 JUMP JUMPDEST PUSH2 0x14F PUSH2 0x14A CALLDATASIZE PUSH1 0x4 PUSH2 0xD34 JUMP JUMPDEST PUSH2 0x333 JUMP JUMPDEST STOP JUMPDEST PUSH2 0x14F PUSH2 0x15F CALLDATASIZE PUSH1 0x4 PUSH2 0xD5E JUMP JUMPDEST PUSH2 0x44D JUMP JUMPDEST PUSH2 0x14F PUSH2 0x172 CALLDATASIZE PUSH1 0x4 PUSH2 0xD5E JUMP JUMPDEST PUSH2 0x47E JUMP JUMPDEST PUSH2 0x124 PUSH2 0x185 CALLDATASIZE PUSH1 0x4 PUSH2 0xCFF JUMP JUMPDEST PUSH2 0x499 JUMP JUMPDEST PUSH2 0x19D PUSH2 0x198 CALLDATASIZE PUSH1 0x4 PUSH2 0xD9A JUMP JUMPDEST PUSH2 0x4F9 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xF3 JUMP JUMPDEST PUSH2 0x104 PUSH2 0x57F JUMP JUMPDEST PUSH2 0x14F PUSH2 0x1C1 CALLDATASIZE PUSH1 0x4 PUSH2 0xDB5 JUMP JUMPDEST PUSH2 0x58E JUMP JUMPDEST PUSH2 0x14F PUSH2 0x1D4 CALLDATASIZE PUSH1 0x4 PUSH2 0xE07 JUMP JUMPDEST PUSH2 0x59D JUMP JUMPDEST PUSH2 0x104 PUSH2 0x1E7 CALLDATASIZE PUSH1 0x4 PUSH2 0xCFF JUMP JUMPDEST PUSH2 0x5D5 JUMP JUMPDEST PUSH2 0xE7 PUSH2 0x1FA CALLDATASIZE PUSH1 0x4 PUSH2 0xEE3 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP2 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 SWAP1 SWAP5 AND DUP3 MSTORE SWAP2 SWAP1 SWAP2 MSTORE KECCAK256 SLOAD PUSH1 0xFF AND SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP3 AND PUSH4 0x80AC58CD PUSH1 0xE0 SHL EQ DUP1 PUSH2 0x259 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP3 AND PUSH4 0x5B5E139F PUSH1 0xE0 SHL EQ JUMPDEST DUP1 PUSH2 0x274 JUMPI POP PUSH4 0x1FFC9A7 PUSH1 0xE0 SHL PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND EQ JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 SLOAD PUSH2 0x289 SWAP1 PUSH2 0xF16 JUMP JUMPDEST DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD PUSH2 0x2B5 SWAP1 PUSH2 0xF16 JUMP JUMPDEST DUP1 ISZERO PUSH2 0x302 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2D7 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x302 JUMP JUMPDEST DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD DUP2 MSTORE SWAP1 PUSH1 0x1 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0x2E5 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x317 DUP3 PUSH2 0x649 JUMP JUMPDEST POP PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x4 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x33E DUP3 PUSH2 0x499 JUMP JUMPDEST SWAP1 POP DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP4 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SUB PUSH2 0x3B0 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x21 PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A20617070726F76616C20746F2063757272656E74206F776E65 PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x39 PUSH1 0xF9 SHL PUSH1 0x64 DUP3 ADD MSTORE PUSH1 0x84 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND EQ DUP1 PUSH2 0x3CC JUMPI POP PUSH2 0x3CC DUP2 CALLER PUSH2 0x1FA JUMP JUMPDEST PUSH2 0x43E JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x3D PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A20617070726F76652063616C6C6572206973206E6F7420746F PUSH1 0x44 DUP3 ADD MSTORE PUSH32 0x6B656E206F776E6572206F7220617070726F76656420666F7220616C6C000000 PUSH1 0x64 DUP3 ADD MSTORE PUSH1 0x84 ADD PUSH2 0x3A7 JUMP JUMPDEST PUSH2 0x448 DUP4 DUP4 PUSH2 0x6AB JUMP JUMPDEST POP POP POP JUMP JUMPDEST PUSH2 0x457 CALLER DUP3 PUSH2 0x719 JUMP JUMPDEST PUSH2 0x473 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3A7 SWAP1 PUSH2 0xF50 JUMP JUMPDEST PUSH2 0x448 DUP4 DUP4 DUP4 PUSH2 0x798 JUMP JUMPDEST PUSH2 0x448 DUP4 DUP4 DUP4 PUSH1 0x40 MLOAD DUP1 PUSH1 0x20 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 DUP2 MSTORE POP PUSH2 0x59D JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP1 PUSH2 0x274 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x18 PUSH1 0x24 DUP3 ADD MSTORE PUSH24 0x115490CDCC8C4E881A5B9D985B1A59081D1BDAD95B881251 PUSH1 0x42 SHL PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3A7 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND PUSH2 0x563 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x29 PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A2061646472657373207A65726F206973206E6F742061207661 PUSH1 0x44 DUP3 ADD MSTORE PUSH9 0x3634B21037BBB732B9 PUSH1 0xB9 SHL PUSH1 0x64 DUP3 ADD MSTORE PUSH1 0x84 ADD PUSH2 0x3A7 JUMP JUMPDEST POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x3 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x1 DUP1 SLOAD PUSH2 0x289 SWAP1 PUSH2 0xF16 JUMP JUMPDEST PUSH2 0x599 CALLER DUP4 DUP4 PUSH2 0x8FC JUMP JUMPDEST POP POP JUMP JUMPDEST PUSH2 0x5A7 CALLER DUP4 PUSH2 0x719 JUMP JUMPDEST PUSH2 0x5C3 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3A7 SWAP1 PUSH2 0xF50 JUMP JUMPDEST PUSH2 0x5CF DUP5 DUP5 DUP5 DUP5 PUSH2 0x9CA JUMP JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x60 PUSH2 0x5E0 DUP3 PUSH2 0x649 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x5F7 PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 DUP2 ADD SWAP1 SWAP2 MSTORE PUSH1 0x0 DUP2 MSTORE SWAP1 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 DUP2 MLOAD GT PUSH2 0x617 JUMPI PUSH1 0x40 MLOAD DUP1 PUSH1 0x20 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 DUP2 MSTORE POP PUSH2 0x642 JUMP JUMPDEST DUP1 PUSH2 0x621 DUP5 PUSH2 0x9FD JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0x632 SWAP3 SWAP2 SWAP1 PUSH2 0xF9D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH2 0x6A8 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x18 PUSH1 0x24 DUP3 ADD MSTORE PUSH24 0x115490CDCC8C4E881A5B9D985B1A59081D1BDAD95B881251 PUSH1 0x42 SHL PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3A7 JUMP JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x4 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 DUP1 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB NOT AND PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE DUP2 SWAP1 PUSH2 0x6E0 DUP3 PUSH2 0x499 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH32 0x8C5BE1E5EBEC7D5BD14F71427D1E84F3DD0314C0F7B2291E5B200AC8C7C3B925 PUSH1 0x40 MLOAD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG4 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH2 0x725 DUP4 PUSH2 0x499 JUMP JUMPDEST SWAP1 POP DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP5 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ DUP1 PUSH2 0x76C JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP1 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP9 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD PUSH1 0xFF AND JUMPDEST DUP1 PUSH2 0x790 JUMPI POP DUP4 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH2 0x785 DUP5 PUSH2 0x30C JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST DUP3 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH2 0x7AB DUP3 PUSH2 0x499 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ PUSH2 0x7D1 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3A7 SWAP1 PUSH2 0xFCC JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND PUSH2 0x833 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x24 DUP1 DUP3 ADD MSTORE PUSH32 0x4552433732313A207472616E7366657220746F20746865207A65726F20616464 PUSH1 0x44 DUP3 ADD MSTORE PUSH4 0x72657373 PUSH1 0xE0 SHL PUSH1 0x64 DUP3 ADD MSTORE PUSH1 0x84 ADD PUSH2 0x3A7 JUMP JUMPDEST DUP3 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH2 0x846 DUP3 PUSH2 0x499 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ PUSH2 0x86C JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3A7 SWAP1 PUSH2 0xFCC JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x4 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 DUP1 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB NOT SWAP1 DUP2 AND SWAP1 SWAP2 SSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP8 DUP2 AND DUP1 DUP7 MSTORE PUSH1 0x3 DUP6 MSTORE DUP4 DUP7 KECCAK256 DUP1 SLOAD PUSH1 0x0 NOT ADD SWAP1 SSTORE SWAP1 DUP8 AND DUP1 DUP7 MSTORE DUP4 DUP7 KECCAK256 DUP1 SLOAD PUSH1 0x1 ADD SWAP1 SSTORE DUP7 DUP7 MSTORE PUSH1 0x2 SWAP1 SWAP5 MSTORE DUP3 DUP6 KECCAK256 DUP1 SLOAD SWAP1 SWAP3 AND DUP5 OR SWAP1 SWAP2 SSTORE SWAP1 MLOAD DUP5 SWAP4 PUSH32 0xDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF SWAP2 LOG4 POP POP POP JUMP JUMPDEST DUP2 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP4 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SUB PUSH2 0x95D JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x19 PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A20617070726F766520746F2063616C6C657200000000000000 PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3A7 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 DUP2 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP5 DUP8 AND DUP1 DUP5 MSTORE SWAP5 DUP3 MSTORE SWAP2 DUP3 SWAP1 KECCAK256 DUP1 SLOAD PUSH1 0xFF NOT AND DUP7 ISZERO ISZERO SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE SWAP2 MLOAD SWAP2 DUP3 MSTORE PUSH32 0x17307EAB39AB6107E8899845AD3D59BD9653F200F220920489CA2B5937696C31 SWAP2 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 POP POP POP JUMP JUMPDEST PUSH2 0x9D5 DUP5 DUP5 DUP5 PUSH2 0x798 JUMP JUMPDEST PUSH2 0x9E1 DUP5 DUP5 DUP5 DUP5 PUSH2 0xA90 JUMP JUMPDEST PUSH2 0x5CF JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3A7 SWAP1 PUSH2 0x1011 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 PUSH2 0xA0A DUP4 PUSH2 0xB91 JUMP JUMPDEST PUSH1 0x1 ADD SWAP1 POP PUSH1 0x0 DUP2 PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xA2A JUMPI PUSH2 0xA2A PUSH2 0xDF1 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x1F ADD PUSH1 0x1F NOT AND PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xA54 JUMPI PUSH1 0x20 DUP3 ADD DUP2 DUP1 CALLDATASIZE DUP4 CALLDATACOPY ADD SWAP1 POP JUMPDEST POP SWAP1 POP DUP2 DUP2 ADD PUSH1 0x20 ADD JUMPDEST PUSH1 0x0 NOT ADD PUSH16 0x181899199A1A9B1B9C1CB0B131B232B3 PUSH1 0x81 SHL PUSH1 0xA DUP7 MOD BYTE DUP2 MSTORE8 PUSH1 0xA DUP6 DIV SWAP5 POP DUP5 PUSH2 0xA5E JUMPI POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND EXTCODESIZE ISZERO PUSH2 0xB86 JUMPI PUSH1 0x40 MLOAD PUSH4 0xA85BD01 PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP6 AND SWAP1 PUSH4 0x150B7A02 SWAP1 PUSH2 0xAD4 SWAP1 CALLER SWAP1 DUP10 SWAP1 DUP9 SWAP1 DUP9 SWAP1 PUSH1 0x4 ADD PUSH2 0x1063 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL SWAP3 POP POP POP DUP1 ISZERO PUSH2 0xB0F JUMPI POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x1F RETURNDATASIZE SWAP1 DUP2 ADD PUSH1 0x1F NOT AND DUP3 ADD SWAP1 SWAP3 MSTORE PUSH2 0xB0C SWAP2 DUP2 ADD SWAP1 PUSH2 0x10A0 JUMP JUMPDEST PUSH1 0x1 JUMPDEST PUSH2 0xB6C JUMPI RETURNDATASIZE DUP1 DUP1 ISZERO PUSH2 0xB3D JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0xB42 JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP DUP1 MLOAD PUSH1 0x0 SUB PUSH2 0xB64 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3A7 SWAP1 PUSH2 0x1011 JUMP JUMPDEST DUP1 MLOAD DUP2 PUSH1 0x20 ADD REVERT JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT AND PUSH4 0xA85BD01 PUSH1 0xE1 SHL EQ SWAP1 POP PUSH2 0x790 JUMP JUMPDEST POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH19 0x184F03E93FF9F4DAA797ED6E38ED64BF6A1F01 PUSH1 0x40 SHL DUP4 LT PUSH2 0xBD0 JUMPI PUSH19 0x184F03E93FF9F4DAA797ED6E38ED64BF6A1F01 PUSH1 0x40 SHL DUP4 DIV SWAP3 POP PUSH1 0x40 ADD JUMPDEST PUSH14 0x4EE2D6D415B85ACEF8100000000 DUP4 LT PUSH2 0xBFC JUMPI PUSH14 0x4EE2D6D415B85ACEF8100000000 DUP4 DIV SWAP3 POP PUSH1 0x20 ADD JUMPDEST PUSH7 0x2386F26FC10000 DUP4 LT PUSH2 0xC1A JUMPI PUSH7 0x2386F26FC10000 DUP4 DIV SWAP3 POP PUSH1 0x10 ADD JUMPDEST PUSH4 0x5F5E100 DUP4 LT PUSH2 0xC32 JUMPI PUSH4 0x5F5E100 DUP4 DIV SWAP3 POP PUSH1 0x8 ADD JUMPDEST PUSH2 0x2710 DUP4 LT PUSH2 0xC46 JUMPI PUSH2 0x2710 DUP4 DIV SWAP3 POP PUSH1 0x4 ADD JUMPDEST PUSH1 0x64 DUP4 LT PUSH2 0xC58 JUMPI PUSH1 0x64 DUP4 DIV SWAP3 POP PUSH1 0x2 ADD JUMPDEST PUSH1 0xA DUP4 LT PUSH2 0x274 JUMPI PUSH1 0x1 ADD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP2 AND DUP2 EQ PUSH2 0x6A8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xC91 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x642 DUP2 PUSH2 0xC69 JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0xCB7 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0xC9F JUMP JUMPDEST POP POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD DUP1 DUP5 MSTORE PUSH2 0xCD8 DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0xC9C JUMP JUMPDEST PUSH1 0x1F ADD PUSH1 0x1F NOT AND SWAP3 SWAP1 SWAP3 ADD PUSH1 0x20 ADD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE PUSH1 0x0 PUSH2 0x642 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0xCC0 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xD11 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 CALLDATALOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0xD2F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xD47 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD50 DUP4 PUSH2 0xD18 JUMP JUMPDEST SWAP5 PUSH1 0x20 SWAP4 SWAP1 SWAP4 ADD CALLDATALOAD SWAP4 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xD73 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD7C DUP5 PUSH2 0xD18 JUMP JUMPDEST SWAP3 POP PUSH2 0xD8A PUSH1 0x20 DUP6 ADD PUSH2 0xD18 JUMP JUMPDEST SWAP2 POP PUSH1 0x40 DUP5 ADD CALLDATALOAD SWAP1 POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xDAC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x642 DUP3 PUSH2 0xD18 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xDC8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xDD1 DUP4 PUSH2 0xD18 JUMP JUMPDEST SWAP2 POP PUSH1 0x20 DUP4 ADD CALLDATALOAD DUP1 ISZERO ISZERO DUP2 EQ PUSH2 0xDE6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xE1D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xE26 DUP6 PUSH2 0xD18 JUMP JUMPDEST SWAP4 POP PUSH2 0xE34 PUSH1 0x20 DUP7 ADD PUSH2 0xD18 JUMP JUMPDEST SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD SWAP2 POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xE58 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP8 ADD SWAP2 POP DUP8 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xE6C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP2 DUP2 GT ISZERO PUSH2 0xE7E JUMPI PUSH2 0xE7E PUSH2 0xDF1 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT SWAP1 DUP2 AND PUSH1 0x3F ADD AND DUP2 ADD SWAP1 DUP4 DUP3 GT DUP2 DUP4 LT OR ISZERO PUSH2 0xEA6 JUMPI PUSH2 0xEA6 PUSH2 0xDF1 JUMP JUMPDEST DUP2 PUSH1 0x40 MSTORE DUP3 DUP2 MSTORE DUP11 PUSH1 0x20 DUP5 DUP8 ADD ADD GT ISZERO PUSH2 0xEBF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 PUSH1 0x20 DUP5 DUP4 ADD ADD MSTORE DUP1 SWAP6 POP POP POP POP POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xEF6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xEFF DUP4 PUSH2 0xD18 JUMP JUMPDEST SWAP2 POP PUSH2 0xF0D PUSH1 0x20 DUP5 ADD PUSH2 0xD18 JUMP JUMPDEST SWAP1 POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x1 DUP2 DUP2 SHR SWAP1 DUP3 AND DUP1 PUSH2 0xF2A JUMPI PUSH1 0x7F DUP3 AND SWAP2 POP JUMPDEST PUSH1 0x20 DUP3 LT DUP2 SUB PUSH2 0xF4A JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x22 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE PUSH1 0x2D SWAP1 DUP3 ADD MSTORE PUSH32 0x4552433732313A2063616C6C6572206973206E6F7420746F6B656E206F776E65 PUSH1 0x40 DUP3 ADD MSTORE PUSH13 0x1C881BDC88185C1C1C9BDD9959 PUSH1 0x9A SHL PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP4 MLOAD PUSH2 0xFAF DUP2 DUP5 PUSH1 0x20 DUP9 ADD PUSH2 0xC9C JUMP JUMPDEST DUP4 MLOAD SWAP1 DUP4 ADD SWAP1 PUSH2 0xFC3 DUP2 DUP4 PUSH1 0x20 DUP9 ADD PUSH2 0xC9C JUMP JUMPDEST ADD SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE PUSH1 0x25 SWAP1 DUP3 ADD MSTORE PUSH32 0x4552433732313A207472616E736665722066726F6D20696E636F727265637420 PUSH1 0x40 DUP3 ADD MSTORE PUSH5 0x37BBB732B9 PUSH1 0xD9 SHL PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE PUSH1 0x32 SWAP1 DUP3 ADD MSTORE PUSH32 0x4552433732313A207472616E7366657220746F206E6F6E204552433732315265 PUSH1 0x40 DUP3 ADD MSTORE PUSH18 0x31B2B4BB32B91034B6B83632B6B2B73A32B9 PUSH1 0x71 SHL PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP6 DUP2 AND DUP3 MSTORE DUP5 AND PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 DUP2 ADD DUP4 SWAP1 MSTORE PUSH1 0x80 PUSH1 0x60 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0x0 SWAP1 PUSH2 0x1096 SWAP1 DUP4 ADD DUP5 PUSH2 0xCC0 JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x10B2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x642 DUP2 PUSH2 0xC69 JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 JUMPI 0x2B STOP BYTE 0xF7 CALLDATACOPY 0xF9 0xD4 ORIGIN SUB MLOAD PUSH9 0x8C567BAF41BAF8D49 SIGNEXTEND 0xB5 PUSH20 0x90158191AAFEA9C264736F6C6343000811003300 ","sourceMap":"628:16377:0:-:0;;;1390:113;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1456:5;:13;1464:5;1456;:13;:::i;:::-;-1:-1:-1;1479:7:0;:17;1489:7;1479;:17;:::i;:::-;;1390:113;;628:16377;;14:127:17;75:10;70:3;66:20;63:1;56:31;106:4;103:1;96:15;130:4;127:1;120:15;146:840;200:5;253:3;246:4;238:6;234:17;230:27;220:55;;271:1;268;261:12;220:55;294:13;;-1:-1:-1;;;;;356:10:17;;;353:36;;;369:18;;:::i;:::-;444:2;438:9;412:2;498:13;;-1:-1:-1;;494:22:17;;;518:2;490:31;486:40;474:53;;;542:18;;;562:22;;;539:46;536:72;;;588:18;;:::i;:::-;628:10;624:2;617:22;663:2;655:6;648:18;685:4;675:14;;730:3;725:2;720;712:6;708:15;704:24;701:33;698:53;;;747:1;744;737:12;698:53;769:1;760:10;;779:133;793:2;790:1;787:9;779:133;;;881:14;;;877:23;;871:30;850:14;;;846:23;;839:63;804:10;;;;779:133;;;954:1;932:15;;;928:24;;;921:35;;;;936:6;146:840;-1:-1:-1;;;;146:840:17:o;991:562::-;1090:6;1098;1151:2;1139:9;1130:7;1126:23;1122:32;1119:52;;;1167:1;1164;1157:12;1119:52;1194:16;;-1:-1:-1;;;;;1259:14:17;;;1256:34;;;1286:1;1283;1276:12;1256:34;1309:61;1362:7;1353:6;1342:9;1338:22;1309:61;:::i;:::-;1299:71;;1416:2;1405:9;1401:18;1395:25;1379:41;;1445:2;1435:8;1432:16;1429:36;;;1461:1;1458;1451:12;1429:36;;1484:63;1539:7;1528:8;1517:9;1513:24;1484:63;:::i;:::-;1474:73;;;991:562;;;;;:::o;1558:380::-;1637:1;1633:12;;;;1680;;;1701:61;;1755:4;1747:6;1743:17;1733:27;;1701:61;1808:2;1800:6;1797:14;1777:18;1774:38;1771:161;;1854:10;1849:3;1845:20;1842:1;1835:31;1889:4;1886:1;1879:15;1917:4;1914:1;1907:15;1771:161;;1558:380;;;:::o;2069:545::-;2171:2;2166:3;2163:11;2160:448;;;2207:1;2232:5;2228:2;2221:17;2277:4;2273:2;2263:19;2347:2;2335:10;2331:19;2328:1;2324:27;2318:4;2314:38;2383:4;2371:10;2368:20;2365:47;;;-1:-1:-1;2406:4:17;2365:47;2461:2;2456:3;2452:12;2449:1;2445:20;2439:4;2435:31;2425:41;;2516:82;2534:2;2527:5;2524:13;2516:82;;;2579:17;;;2560:1;2549:13;2516:82;;;2520:3;;;2160:448;2069:545;;;:::o;2790:1352::-;2910:10;;-1:-1:-1;;;;;2932:30:17;;2929:56;;;2965:18;;:::i;:::-;2994:97;3084:6;3044:38;3076:4;3070:11;3044:38;:::i;:::-;3038:4;2994:97;:::i;:::-;3146:4;;3210:2;3199:14;;3227:1;3222:663;;;;3929:1;3946:6;3943:89;;;-1:-1:-1;3998:19:17;;;3992:26;3943:89;-1:-1:-1;;2747:1:17;2743:11;;;2739:24;2735:29;2725:40;2771:1;2767:11;;;2722:57;4045:81;;3192:944;;3222:663;2016:1;2009:14;;;2053:4;2040:18;;-1:-1:-1;;3258:20:17;;;3376:236;3390:7;3387:1;3384:14;3376:236;;;3479:19;;;3473:26;3458:42;;3571:27;;;;3539:1;3527:14;;;;3406:19;;3376:236;;;3380:3;3640:6;3631:7;3628:19;3625:201;;;3701:19;;;3695:26;-1:-1:-1;;3784:1:17;3780:14;;;3796:3;3776:24;3772:37;3768:42;3753:58;3738:74;;3625:201;-1:-1:-1;;;;;3872:1:17;3856:14;;;3852:22;3839:36;;-1:-1:-1;2790:1352:17:o;:::-;628:16377:0;;;;;;"},"deployedBytecode":{"functionDebugData":{"@_afterTokenTransfer_910":{"entryPoint":null,"id":910,"parameterSlots":4,"returnSlots":0},"@_approve_776":{"entryPoint":1707,"id":776,"parameterSlots":2,"returnSlots":0},"@_baseURI_213":{"entryPoint":null,"id":213,"parameterSlots":0,"returnSlots":1},"@_beforeTokenTransfer_897":{"entryPoint":null,"id":897,"parameterSlots":4,"returnSlots":0},"@_checkOnERC721Received_884":{"entryPoint":2704,"id":884,"parameterSlots":4,"returnSlots":1},"@_exists_445":{"entryPoint":null,"id":445,"parameterSlots":1,"returnSlots":1},"@_isApprovedOrOwner_479":{"entryPoint":1817,"id":479,"parameterSlots":2,"returnSlots":1},"@_msgSender_1429":{"entryPoint":null,"id":1429,"parameterSlots":0,"returnSlots":1},"@_ownerOf_427":{"entryPoint":null,"id":427,"parameterSlots":1,"returnSlots":1},"@_requireMinted_822":{"entryPoint":1609,"id":822,"parameterSlots":1,"returnSlots":0},"@_safeTransfer_414":{"entryPoint":2506,"id":414,"parameterSlots":4,"returnSlots":0},"@_setApprovalForAll_808":{"entryPoint":2300,"id":808,"parameterSlots":3,"returnSlots":0},"@_transfer_752":{"entryPoint":1944,"id":752,"parameterSlots":3,"returnSlots":0},"@approve_256":{"entryPoint":819,"id":256,"parameterSlots":2,"returnSlots":0},"@balanceOf_117":{"entryPoint":1273,"id":117,"parameterSlots":1,"returnSlots":1},"@getApproved_274":{"entryPoint":780,"id":274,"parameterSlots":1,"returnSlots":1},"@isApprovedForAll_309":{"entryPoint":null,"id":309,"parameterSlots":2,"returnSlots":1},"@isContract_1105":{"entryPoint":null,"id":1105,"parameterSlots":1,"returnSlots":1},"@log10_2407":{"entryPoint":2961,"id":2407,"parameterSlots":1,"returnSlots":1},"@name_155":{"entryPoint":634,"id":155,"parameterSlots":0,"returnSlots":1},"@ownerOf_145":{"entryPoint":1177,"id":145,"parameterSlots":1,"returnSlots":1},"@safeTransferFrom_355":{"entryPoint":1150,"id":355,"parameterSlots":3,"returnSlots":0},"@safeTransferFrom_385":{"entryPoint":1437,"id":385,"parameterSlots":4,"returnSlots":0},"@setApprovalForAll_291":{"entryPoint":1422,"id":291,"parameterSlots":2,"returnSlots":0},"@supportsInterface_1691":{"entryPoint":null,"id":1691,"parameterSlots":1,"returnSlots":1},"@supportsInterface_93":{"entryPoint":552,"id":93,"parameterSlots":1,"returnSlots":1},"@symbol_165":{"entryPoint":1407,"id":165,"parameterSlots":0,"returnSlots":1},"@toString_1498":{"entryPoint":2557,"id":1498,"parameterSlots":1,"returnSlots":1},"@tokenURI_204":{"entryPoint":1493,"id":204,"parameterSlots":1,"returnSlots":1},"@transferFrom_336":{"entryPoint":1101,"id":336,"parameterSlots":3,"returnSlots":0},"abi_decode_address":{"entryPoint":3352,"id":null,"parameterSlots":1,"returnSlots":1},"abi_decode_tuple_t_address":{"entryPoint":3482,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_addresst_address":{"entryPoint":3811,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_tuple_t_addresst_addresst_uint256":{"entryPoint":3422,"id":null,"parameterSlots":2,"returnSlots":3},"abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr":{"entryPoint":3591,"id":null,"parameterSlots":2,"returnSlots":4},"abi_decode_tuple_t_addresst_bool":{"entryPoint":3509,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_tuple_t_addresst_uint256":{"entryPoint":3380,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_tuple_t_bytes4":{"entryPoint":3199,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_bytes4_fromMemory":{"entryPoint":4256,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_uint256":{"entryPoint":3327,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_string":{"entryPoint":3264,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_packed_t_string_memory_ptr_t_string_memory_ptr__to_t_string_memory_ptr_t_string_memory_ptr__nonPadded_inplace_fromStack_reversed":{"entryPoint":3997,"id":null,"parameterSlots":3,"returnSlots":1},"abi_encode_tuple_t_address__to_t_address__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_address_t_address_t_uint256_t_bytes_memory_ptr__to_t_address_t_address_t_uint256_t_bytes_memory_ptr__fromStack_reversed":{"entryPoint":4195,"id":null,"parameterSlots":5,"returnSlots":1},"abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":3308,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_stringliteral_12a8e5623d251e191fe4a291d9a59bcc01a4db7a1f5c20fc8de44358c18308af__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":3920,"id":null,"parameterSlots":1,"returnSlots":1},"abi_encode_tuple_t_stringliteral_1e766a06da43a53d0f4c380e06e5a342e14d5af1bf8501996c844905530ca84e__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":4113,"id":null,"parameterSlots":1,"returnSlots":1},"abi_encode_tuple_t_stringliteral_277f8ee9d5b4fc3c4149386f24de0fc1bbc63a8210e2197bfd1c0376a2ac5f48__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":4044,"id":null,"parameterSlots":1,"returnSlots":1},"abi_encode_tuple_t_stringliteral_455fea98ea03c32d7dd1a6f1426917d80529bf47b3ccbde74e7206e889e709f4__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":1,"returnSlots":1},"abi_encode_tuple_t_stringliteral_45fe4329685be5ecd250fd0e6a25aea0ea4d0e30fb6a73c118b95749e6d70d05__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":1,"returnSlots":1},"abi_encode_tuple_t_stringliteral_6d05c90094f31cfeb8f0eb86f0a513af3f7f8992991fbde41b08aa7960677159__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":1,"returnSlots":1},"abi_encode_tuple_t_stringliteral_b08d2b0fec7cc108ab049809a8beb42779d969a49299d0c317c907d9db22974f__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":1,"returnSlots":1},"abi_encode_tuple_t_stringliteral_b51b4875eede07862961e8f9365c6749f5fe55c6ee5d7a9e42b6912ad0b15942__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":1,"returnSlots":1},"abi_encode_tuple_t_stringliteral_c6e14a63ffb144eeef7cce6988e5dce07c60a7e0a7b1ef25dbe18c61483e0a83__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":1,"returnSlots":1},"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"copy_memory_to_memory_with_cleanup":{"entryPoint":3228,"id":null,"parameterSlots":3,"returnSlots":0},"extract_byte_array_length":{"entryPoint":3862,"id":null,"parameterSlots":1,"returnSlots":1},"panic_error_0x12":{"entryPoint":null,"id":null,"parameterSlots":0,"returnSlots":0},"panic_error_0x41":{"entryPoint":3569,"id":null,"parameterSlots":0,"returnSlots":0},"validator_revert_bytes4":{"entryPoint":3177,"id":null,"parameterSlots":1,"returnSlots":0}},"generatedSources":[{"ast":{"nodeType":"YulBlock","src":"0:10132:17","statements":[{"nodeType":"YulBlock","src":"6:3:17","statements":[]},{"body":{"nodeType":"YulBlock","src":"58:87:17","statements":[{"body":{"nodeType":"YulBlock","src":"123:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"132:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"135:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"125:6:17"},"nodeType":"YulFunctionCall","src":"125:12:17"},"nodeType":"YulExpressionStatement","src":"125:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"81:5:17"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"92:5:17"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"103:3:17","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"108:10:17","type":"","value":"0xffffffff"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"99:3:17"},"nodeType":"YulFunctionCall","src":"99:20:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"88:3:17"},"nodeType":"YulFunctionCall","src":"88:32:17"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"78:2:17"},"nodeType":"YulFunctionCall","src":"78:43:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"71:6:17"},"nodeType":"YulFunctionCall","src":"71:51:17"},"nodeType":"YulIf","src":"68:71:17"}]},"name":"validator_revert_bytes4","nodeType":"YulFunctionDefinition","parameters":[{"name":"value","nodeType":"YulTypedName","src":"47:5:17","type":""}],"src":"14:131:17"},{"body":{"nodeType":"YulBlock","src":"219:176:17","statements":[{"body":{"nodeType":"YulBlock","src":"265:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"274:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"277:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"267:6:17"},"nodeType":"YulFunctionCall","src":"267:12:17"},"nodeType":"YulExpressionStatement","src":"267:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"240:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"249:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"236:3:17"},"nodeType":"YulFunctionCall","src":"236:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"261:2:17","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"232:3:17"},"nodeType":"YulFunctionCall","src":"232:32:17"},"nodeType":"YulIf","src":"229:52:17"},{"nodeType":"YulVariableDeclaration","src":"290:36:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"316:9:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"303:12:17"},"nodeType":"YulFunctionCall","src":"303:23:17"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"294:5:17","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"359:5:17"}],"functionName":{"name":"validator_revert_bytes4","nodeType":"YulIdentifier","src":"335:23:17"},"nodeType":"YulFunctionCall","src":"335:30:17"},"nodeType":"YulExpressionStatement","src":"335:30:17"},{"nodeType":"YulAssignment","src":"374:15:17","value":{"name":"value","nodeType":"YulIdentifier","src":"384:5:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"374:6:17"}]}]},"name":"abi_decode_tuple_t_bytes4","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"185:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"196:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"208:6:17","type":""}],"src":"150:245:17"},{"body":{"nodeType":"YulBlock","src":"495:92:17","statements":[{"nodeType":"YulAssignment","src":"505:26:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"517:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"528:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"513:3:17"},"nodeType":"YulFunctionCall","src":"513:18:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"505:4:17"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"547:9:17"},{"arguments":[{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"572:6:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"565:6:17"},"nodeType":"YulFunctionCall","src":"565:14:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"558:6:17"},"nodeType":"YulFunctionCall","src":"558:22:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"540:6:17"},"nodeType":"YulFunctionCall","src":"540:41:17"},"nodeType":"YulExpressionStatement","src":"540:41:17"}]},"name":"abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"464:9:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"475:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"486:4:17","type":""}],"src":"400:187:17"},{"body":{"nodeType":"YulBlock","src":"658:184:17","statements":[{"nodeType":"YulVariableDeclaration","src":"668:10:17","value":{"kind":"number","nodeType":"YulLiteral","src":"677:1:17","type":"","value":"0"},"variables":[{"name":"i","nodeType":"YulTypedName","src":"672:1:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"737:63:17","statements":[{"expression":{"arguments":[{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"762:3:17"},{"name":"i","nodeType":"YulIdentifier","src":"767:1:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"758:3:17"},"nodeType":"YulFunctionCall","src":"758:11:17"},{"arguments":[{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"781:3:17"},{"name":"i","nodeType":"YulIdentifier","src":"786:1:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"777:3:17"},"nodeType":"YulFunctionCall","src":"777:11:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"771:5:17"},"nodeType":"YulFunctionCall","src":"771:18:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"751:6:17"},"nodeType":"YulFunctionCall","src":"751:39:17"},"nodeType":"YulExpressionStatement","src":"751:39:17"}]},"condition":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"698:1:17"},{"name":"length","nodeType":"YulIdentifier","src":"701:6:17"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"695:2:17"},"nodeType":"YulFunctionCall","src":"695:13:17"},"nodeType":"YulForLoop","post":{"nodeType":"YulBlock","src":"709:19:17","statements":[{"nodeType":"YulAssignment","src":"711:15:17","value":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"720:1:17"},{"kind":"number","nodeType":"YulLiteral","src":"723:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"716:3:17"},"nodeType":"YulFunctionCall","src":"716:10:17"},"variableNames":[{"name":"i","nodeType":"YulIdentifier","src":"711:1:17"}]}]},"pre":{"nodeType":"YulBlock","src":"691:3:17","statements":[]},"src":"687:113:17"},{"expression":{"arguments":[{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"820:3:17"},{"name":"length","nodeType":"YulIdentifier","src":"825:6:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"816:3:17"},"nodeType":"YulFunctionCall","src":"816:16:17"},{"kind":"number","nodeType":"YulLiteral","src":"834:1:17","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"809:6:17"},"nodeType":"YulFunctionCall","src":"809:27:17"},"nodeType":"YulExpressionStatement","src":"809:27:17"}]},"name":"copy_memory_to_memory_with_cleanup","nodeType":"YulFunctionDefinition","parameters":[{"name":"src","nodeType":"YulTypedName","src":"636:3:17","type":""},{"name":"dst","nodeType":"YulTypedName","src":"641:3:17","type":""},{"name":"length","nodeType":"YulTypedName","src":"646:6:17","type":""}],"src":"592:250:17"},{"body":{"nodeType":"YulBlock","src":"897:221:17","statements":[{"nodeType":"YulVariableDeclaration","src":"907:26:17","value":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"927:5:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"921:5:17"},"nodeType":"YulFunctionCall","src":"921:12:17"},"variables":[{"name":"length","nodeType":"YulTypedName","src":"911:6:17","type":""}]},{"expression":{"arguments":[{"name":"pos","nodeType":"YulIdentifier","src":"949:3:17"},{"name":"length","nodeType":"YulIdentifier","src":"954:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"942:6:17"},"nodeType":"YulFunctionCall","src":"942:19:17"},"nodeType":"YulExpressionStatement","src":"942:19:17"},{"expression":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1009:5:17"},{"kind":"number","nodeType":"YulLiteral","src":"1016:4:17","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1005:3:17"},"nodeType":"YulFunctionCall","src":"1005:16:17"},{"arguments":[{"name":"pos","nodeType":"YulIdentifier","src":"1027:3:17"},{"kind":"number","nodeType":"YulLiteral","src":"1032:4:17","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1023:3:17"},"nodeType":"YulFunctionCall","src":"1023:14:17"},{"name":"length","nodeType":"YulIdentifier","src":"1039:6:17"}],"functionName":{"name":"copy_memory_to_memory_with_cleanup","nodeType":"YulIdentifier","src":"970:34:17"},"nodeType":"YulFunctionCall","src":"970:76:17"},"nodeType":"YulExpressionStatement","src":"970:76:17"},{"nodeType":"YulAssignment","src":"1055:57:17","value":{"arguments":[{"arguments":[{"name":"pos","nodeType":"YulIdentifier","src":"1070:3:17"},{"arguments":[{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"1083:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"1091:2:17","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1079:3:17"},"nodeType":"YulFunctionCall","src":"1079:15:17"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1100:2:17","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"1096:3:17"},"nodeType":"YulFunctionCall","src":"1096:7:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1075:3:17"},"nodeType":"YulFunctionCall","src":"1075:29:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1066:3:17"},"nodeType":"YulFunctionCall","src":"1066:39:17"},{"kind":"number","nodeType":"YulLiteral","src":"1107:4:17","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1062:3:17"},"nodeType":"YulFunctionCall","src":"1062:50:17"},"variableNames":[{"name":"end","nodeType":"YulIdentifier","src":"1055:3:17"}]}]},"name":"abi_encode_string","nodeType":"YulFunctionDefinition","parameters":[{"name":"value","nodeType":"YulTypedName","src":"874:5:17","type":""},{"name":"pos","nodeType":"YulTypedName","src":"881:3:17","type":""}],"returnVariables":[{"name":"end","nodeType":"YulTypedName","src":"889:3:17","type":""}],"src":"847:271:17"},{"body":{"nodeType":"YulBlock","src":"1244:99:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1261:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1272:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1254:6:17"},"nodeType":"YulFunctionCall","src":"1254:21:17"},"nodeType":"YulExpressionStatement","src":"1254:21:17"},{"nodeType":"YulAssignment","src":"1284:53:17","value":{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"1310:6:17"},{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1322:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1333:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1318:3:17"},"nodeType":"YulFunctionCall","src":"1318:18:17"}],"functionName":{"name":"abi_encode_string","nodeType":"YulIdentifier","src":"1292:17:17"},"nodeType":"YulFunctionCall","src":"1292:45:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"1284:4:17"}]}]},"name":"abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"1213:9:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"1224:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"1235:4:17","type":""}],"src":"1123:220:17"},{"body":{"nodeType":"YulBlock","src":"1418:110:17","statements":[{"body":{"nodeType":"YulBlock","src":"1464:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1473:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1476:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1466:6:17"},"nodeType":"YulFunctionCall","src":"1466:12:17"},"nodeType":"YulExpressionStatement","src":"1466:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"1439:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"1448:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1435:3:17"},"nodeType":"YulFunctionCall","src":"1435:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"1460:2:17","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"1431:3:17"},"nodeType":"YulFunctionCall","src":"1431:32:17"},"nodeType":"YulIf","src":"1428:52:17"},{"nodeType":"YulAssignment","src":"1489:33:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1512:9:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1499:12:17"},"nodeType":"YulFunctionCall","src":"1499:23:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"1489:6:17"}]}]},"name":"abi_decode_tuple_t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"1384:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"1395:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"1407:6:17","type":""}],"src":"1348:180:17"},{"body":{"nodeType":"YulBlock","src":"1634:102:17","statements":[{"nodeType":"YulAssignment","src":"1644:26:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1656:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1667:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1652:3:17"},"nodeType":"YulFunctionCall","src":"1652:18:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"1644:4:17"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1686:9:17"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"1701:6:17"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1717:3:17","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"1722:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1713:3:17"},"nodeType":"YulFunctionCall","src":"1713:11:17"},{"kind":"number","nodeType":"YulLiteral","src":"1726:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1709:3:17"},"nodeType":"YulFunctionCall","src":"1709:19:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1697:3:17"},"nodeType":"YulFunctionCall","src":"1697:32:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1679:6:17"},"nodeType":"YulFunctionCall","src":"1679:51:17"},"nodeType":"YulExpressionStatement","src":"1679:51:17"}]},"name":"abi_encode_tuple_t_address__to_t_address__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"1603:9:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"1614:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"1625:4:17","type":""}],"src":"1533:203:17"},{"body":{"nodeType":"YulBlock","src":"1790:124:17","statements":[{"nodeType":"YulAssignment","src":"1800:29:17","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"1822:6:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1809:12:17"},"nodeType":"YulFunctionCall","src":"1809:20:17"},"variableNames":[{"name":"value","nodeType":"YulIdentifier","src":"1800:5:17"}]},{"body":{"nodeType":"YulBlock","src":"1892:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1901:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1904:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1894:6:17"},"nodeType":"YulFunctionCall","src":"1894:12:17"},"nodeType":"YulExpressionStatement","src":"1894:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1851:5:17"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1862:5:17"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1877:3:17","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"1882:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1873:3:17"},"nodeType":"YulFunctionCall","src":"1873:11:17"},{"kind":"number","nodeType":"YulLiteral","src":"1886:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1869:3:17"},"nodeType":"YulFunctionCall","src":"1869:19:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1858:3:17"},"nodeType":"YulFunctionCall","src":"1858:31:17"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"1848:2:17"},"nodeType":"YulFunctionCall","src":"1848:42:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"1841:6:17"},"nodeType":"YulFunctionCall","src":"1841:50:17"},"nodeType":"YulIf","src":"1838:70:17"}]},"name":"abi_decode_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"1769:6:17","type":""}],"returnVariables":[{"name":"value","nodeType":"YulTypedName","src":"1780:5:17","type":""}],"src":"1741:173:17"},{"body":{"nodeType":"YulBlock","src":"2006:167:17","statements":[{"body":{"nodeType":"YulBlock","src":"2052:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2061:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2064:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2054:6:17"},"nodeType":"YulFunctionCall","src":"2054:12:17"},"nodeType":"YulExpressionStatement","src":"2054:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"2027:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"2036:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"2023:3:17"},"nodeType":"YulFunctionCall","src":"2023:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"2048:2:17","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"2019:3:17"},"nodeType":"YulFunctionCall","src":"2019:32:17"},"nodeType":"YulIf","src":"2016:52:17"},{"nodeType":"YulAssignment","src":"2077:39:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2106:9:17"}],"functionName":{"name":"abi_decode_address","nodeType":"YulIdentifier","src":"2087:18:17"},"nodeType":"YulFunctionCall","src":"2087:29:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"2077:6:17"}]},{"nodeType":"YulAssignment","src":"2125:42:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2152:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"2163:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2148:3:17"},"nodeType":"YulFunctionCall","src":"2148:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2135:12:17"},"nodeType":"YulFunctionCall","src":"2135:32:17"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"2125:6:17"}]}]},"name":"abi_decode_tuple_t_addresst_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"1964:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"1975:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"1987:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"1995:6:17","type":""}],"src":"1919:254:17"},{"body":{"nodeType":"YulBlock","src":"2282:224:17","statements":[{"body":{"nodeType":"YulBlock","src":"2328:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2337:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2340:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2330:6:17"},"nodeType":"YulFunctionCall","src":"2330:12:17"},"nodeType":"YulExpressionStatement","src":"2330:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"2303:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"2312:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"2299:3:17"},"nodeType":"YulFunctionCall","src":"2299:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"2324:2:17","type":"","value":"96"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"2295:3:17"},"nodeType":"YulFunctionCall","src":"2295:32:17"},"nodeType":"YulIf","src":"2292:52:17"},{"nodeType":"YulAssignment","src":"2353:39:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2382:9:17"}],"functionName":{"name":"abi_decode_address","nodeType":"YulIdentifier","src":"2363:18:17"},"nodeType":"YulFunctionCall","src":"2363:29:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"2353:6:17"}]},{"nodeType":"YulAssignment","src":"2401:48:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2434:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"2445:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2430:3:17"},"nodeType":"YulFunctionCall","src":"2430:18:17"}],"functionName":{"name":"abi_decode_address","nodeType":"YulIdentifier","src":"2411:18:17"},"nodeType":"YulFunctionCall","src":"2411:38:17"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"2401:6:17"}]},{"nodeType":"YulAssignment","src":"2458:42:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2485:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"2496:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2481:3:17"},"nodeType":"YulFunctionCall","src":"2481:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2468:12:17"},"nodeType":"YulFunctionCall","src":"2468:32:17"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"2458:6:17"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"2232:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"2243:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"2255:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"2263:6:17","type":""},{"name":"value2","nodeType":"YulTypedName","src":"2271:6:17","type":""}],"src":"2178:328:17"},{"body":{"nodeType":"YulBlock","src":"2581:116:17","statements":[{"body":{"nodeType":"YulBlock","src":"2627:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2636:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2639:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2629:6:17"},"nodeType":"YulFunctionCall","src":"2629:12:17"},"nodeType":"YulExpressionStatement","src":"2629:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"2602:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"2611:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"2598:3:17"},"nodeType":"YulFunctionCall","src":"2598:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"2623:2:17","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"2594:3:17"},"nodeType":"YulFunctionCall","src":"2594:32:17"},"nodeType":"YulIf","src":"2591:52:17"},{"nodeType":"YulAssignment","src":"2652:39:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2681:9:17"}],"functionName":{"name":"abi_decode_address","nodeType":"YulIdentifier","src":"2662:18:17"},"nodeType":"YulFunctionCall","src":"2662:29:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"2652:6:17"}]}]},"name":"abi_decode_tuple_t_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"2547:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"2558:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"2570:6:17","type":""}],"src":"2511:186:17"},{"body":{"nodeType":"YulBlock","src":"2803:76:17","statements":[{"nodeType":"YulAssignment","src":"2813:26:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2825:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"2836:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2821:3:17"},"nodeType":"YulFunctionCall","src":"2821:18:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"2813:4:17"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2855:9:17"},{"name":"value0","nodeType":"YulIdentifier","src":"2866:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2848:6:17"},"nodeType":"YulFunctionCall","src":"2848:25:17"},"nodeType":"YulExpressionStatement","src":"2848:25:17"}]},"name":"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"2772:9:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"2783:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"2794:4:17","type":""}],"src":"2702:177:17"},{"body":{"nodeType":"YulBlock","src":"2968:263:17","statements":[{"body":{"nodeType":"YulBlock","src":"3014:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3023:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3026:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3016:6:17"},"nodeType":"YulFunctionCall","src":"3016:12:17"},"nodeType":"YulExpressionStatement","src":"3016:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"2989:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"2998:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"2985:3:17"},"nodeType":"YulFunctionCall","src":"2985:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"3010:2:17","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"2981:3:17"},"nodeType":"YulFunctionCall","src":"2981:32:17"},"nodeType":"YulIf","src":"2978:52:17"},{"nodeType":"YulAssignment","src":"3039:39:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3068:9:17"}],"functionName":{"name":"abi_decode_address","nodeType":"YulIdentifier","src":"3049:18:17"},"nodeType":"YulFunctionCall","src":"3049:29:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"3039:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"3087:45:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3117:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"3128:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3113:3:17"},"nodeType":"YulFunctionCall","src":"3113:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3100:12:17"},"nodeType":"YulFunctionCall","src":"3100:32:17"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"3091:5:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"3185:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3194:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3197:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3187:6:17"},"nodeType":"YulFunctionCall","src":"3187:12:17"},"nodeType":"YulExpressionStatement","src":"3187:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"3154:5:17"},{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"3175:5:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"3168:6:17"},"nodeType":"YulFunctionCall","src":"3168:13:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"3161:6:17"},"nodeType":"YulFunctionCall","src":"3161:21:17"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"3151:2:17"},"nodeType":"YulFunctionCall","src":"3151:32:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"3144:6:17"},"nodeType":"YulFunctionCall","src":"3144:40:17"},"nodeType":"YulIf","src":"3141:60:17"},{"nodeType":"YulAssignment","src":"3210:15:17","value":{"name":"value","nodeType":"YulIdentifier","src":"3220:5:17"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"3210:6:17"}]}]},"name":"abi_decode_tuple_t_addresst_bool","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"2926:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"2937:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"2949:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"2957:6:17","type":""}],"src":"2884:347:17"},{"body":{"nodeType":"YulBlock","src":"3268:95:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3285:1:17","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3292:3:17","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"3297:10:17","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"3288:3:17"},"nodeType":"YulFunctionCall","src":"3288:20:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"3278:6:17"},"nodeType":"YulFunctionCall","src":"3278:31:17"},"nodeType":"YulExpressionStatement","src":"3278:31:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3325:1:17","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"3328:4:17","type":"","value":"0x41"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"3318:6:17"},"nodeType":"YulFunctionCall","src":"3318:15:17"},"nodeType":"YulExpressionStatement","src":"3318:15:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3349:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3352:4:17","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3342:6:17"},"nodeType":"YulFunctionCall","src":"3342:15:17"},"nodeType":"YulExpressionStatement","src":"3342:15:17"}]},"name":"panic_error_0x41","nodeType":"YulFunctionDefinition","src":"3236:127:17"},{"body":{"nodeType":"YulBlock","src":"3498:1008:17","statements":[{"body":{"nodeType":"YulBlock","src":"3545:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3554:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3557:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3547:6:17"},"nodeType":"YulFunctionCall","src":"3547:12:17"},"nodeType":"YulExpressionStatement","src":"3547:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"3519:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"3528:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"3515:3:17"},"nodeType":"YulFunctionCall","src":"3515:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"3540:3:17","type":"","value":"128"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"3511:3:17"},"nodeType":"YulFunctionCall","src":"3511:33:17"},"nodeType":"YulIf","src":"3508:53:17"},{"nodeType":"YulAssignment","src":"3570:39:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3599:9:17"}],"functionName":{"name":"abi_decode_address","nodeType":"YulIdentifier","src":"3580:18:17"},"nodeType":"YulFunctionCall","src":"3580:29:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"3570:6:17"}]},{"nodeType":"YulAssignment","src":"3618:48:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3651:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"3662:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3647:3:17"},"nodeType":"YulFunctionCall","src":"3647:18:17"}],"functionName":{"name":"abi_decode_address","nodeType":"YulIdentifier","src":"3628:18:17"},"nodeType":"YulFunctionCall","src":"3628:38:17"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"3618:6:17"}]},{"nodeType":"YulAssignment","src":"3675:42:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3702:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"3713:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3698:3:17"},"nodeType":"YulFunctionCall","src":"3698:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3685:12:17"},"nodeType":"YulFunctionCall","src":"3685:32:17"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"3675:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"3726:46:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3757:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"3768:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3753:3:17"},"nodeType":"YulFunctionCall","src":"3753:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3740:12:17"},"nodeType":"YulFunctionCall","src":"3740:32:17"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"3730:6:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"3781:28:17","value":{"kind":"number","nodeType":"YulLiteral","src":"3791:18:17","type":"","value":"0xffffffffffffffff"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"3785:2:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"3836:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3845:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3848:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3838:6:17"},"nodeType":"YulFunctionCall","src":"3838:12:17"},"nodeType":"YulExpressionStatement","src":"3838:12:17"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"3824:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"3832:2:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"3821:2:17"},"nodeType":"YulFunctionCall","src":"3821:14:17"},"nodeType":"YulIf","src":"3818:34:17"},{"nodeType":"YulVariableDeclaration","src":"3861:32:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3875:9:17"},{"name":"offset","nodeType":"YulIdentifier","src":"3886:6:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3871:3:17"},"nodeType":"YulFunctionCall","src":"3871:22:17"},"variables":[{"name":"_2","nodeType":"YulTypedName","src":"3865:2:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"3941:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3950:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3953:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3943:6:17"},"nodeType":"YulFunctionCall","src":"3943:12:17"},"nodeType":"YulExpressionStatement","src":"3943:12:17"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"3920:2:17"},{"kind":"number","nodeType":"YulLiteral","src":"3924:4:17","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3916:3:17"},"nodeType":"YulFunctionCall","src":"3916:13:17"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"3931:7:17"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"3912:3:17"},"nodeType":"YulFunctionCall","src":"3912:27:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"3905:6:17"},"nodeType":"YulFunctionCall","src":"3905:35:17"},"nodeType":"YulIf","src":"3902:55:17"},{"nodeType":"YulVariableDeclaration","src":"3966:26:17","value":{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"3989:2:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3976:12:17"},"nodeType":"YulFunctionCall","src":"3976:16:17"},"variables":[{"name":"_3","nodeType":"YulTypedName","src":"3970:2:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"4015:22:17","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"4017:16:17"},"nodeType":"YulFunctionCall","src":"4017:18:17"},"nodeType":"YulExpressionStatement","src":"4017:18:17"}]},"condition":{"arguments":[{"name":"_3","nodeType":"YulIdentifier","src":"4007:2:17"},{"name":"_1","nodeType":"YulIdentifier","src":"4011:2:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"4004:2:17"},"nodeType":"YulFunctionCall","src":"4004:10:17"},"nodeType":"YulIf","src":"4001:36:17"},{"nodeType":"YulVariableDeclaration","src":"4046:17:17","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4060:2:17","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"4056:3:17"},"nodeType":"YulFunctionCall","src":"4056:7:17"},"variables":[{"name":"_4","nodeType":"YulTypedName","src":"4050:2:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"4072:23:17","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4092:2:17","type":"","value":"64"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"4086:5:17"},"nodeType":"YulFunctionCall","src":"4086:9:17"},"variables":[{"name":"memPtr","nodeType":"YulTypedName","src":"4076:6:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"4104:71:17","value":{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"4126:6:17"},{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"name":"_3","nodeType":"YulIdentifier","src":"4150:2:17"},{"kind":"number","nodeType":"YulLiteral","src":"4154:4:17","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4146:3:17"},"nodeType":"YulFunctionCall","src":"4146:13:17"},{"name":"_4","nodeType":"YulIdentifier","src":"4161:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"4142:3:17"},"nodeType":"YulFunctionCall","src":"4142:22:17"},{"kind":"number","nodeType":"YulLiteral","src":"4166:2:17","type":"","value":"63"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4138:3:17"},"nodeType":"YulFunctionCall","src":"4138:31:17"},{"name":"_4","nodeType":"YulIdentifier","src":"4171:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"4134:3:17"},"nodeType":"YulFunctionCall","src":"4134:40:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4122:3:17"},"nodeType":"YulFunctionCall","src":"4122:53:17"},"variables":[{"name":"newFreePtr","nodeType":"YulTypedName","src":"4108:10:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"4234:22:17","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"4236:16:17"},"nodeType":"YulFunctionCall","src":"4236:18:17"},"nodeType":"YulExpressionStatement","src":"4236:18:17"}]},"condition":{"arguments":[{"arguments":[{"name":"newFreePtr","nodeType":"YulIdentifier","src":"4193:10:17"},{"name":"_1","nodeType":"YulIdentifier","src":"4205:2:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"4190:2:17"},"nodeType":"YulFunctionCall","src":"4190:18:17"},{"arguments":[{"name":"newFreePtr","nodeType":"YulIdentifier","src":"4213:10:17"},{"name":"memPtr","nodeType":"YulIdentifier","src":"4225:6:17"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"4210:2:17"},"nodeType":"YulFunctionCall","src":"4210:22:17"}],"functionName":{"name":"or","nodeType":"YulIdentifier","src":"4187:2:17"},"nodeType":"YulFunctionCall","src":"4187:46:17"},"nodeType":"YulIf","src":"4184:72:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4272:2:17","type":"","value":"64"},{"name":"newFreePtr","nodeType":"YulIdentifier","src":"4276:10:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"4265:6:17"},"nodeType":"YulFunctionCall","src":"4265:22:17"},"nodeType":"YulExpressionStatement","src":"4265:22:17"},{"expression":{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"4303:6:17"},{"name":"_3","nodeType":"YulIdentifier","src":"4311:2:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"4296:6:17"},"nodeType":"YulFunctionCall","src":"4296:18:17"},"nodeType":"YulExpressionStatement","src":"4296:18:17"},{"body":{"nodeType":"YulBlock","src":"4360:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4369:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4372:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4362:6:17"},"nodeType":"YulFunctionCall","src":"4362:12:17"},"nodeType":"YulExpressionStatement","src":"4362:12:17"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"4337:2:17"},{"name":"_3","nodeType":"YulIdentifier","src":"4341:2:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4333:3:17"},"nodeType":"YulFunctionCall","src":"4333:11:17"},{"kind":"number","nodeType":"YulLiteral","src":"4346:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4329:3:17"},"nodeType":"YulFunctionCall","src":"4329:20:17"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"4351:7:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"4326:2:17"},"nodeType":"YulFunctionCall","src":"4326:33:17"},"nodeType":"YulIf","src":"4323:53:17"},{"expression":{"arguments":[{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"4402:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"4410:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4398:3:17"},"nodeType":"YulFunctionCall","src":"4398:15:17"},{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"4419:2:17"},{"kind":"number","nodeType":"YulLiteral","src":"4423:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4415:3:17"},"nodeType":"YulFunctionCall","src":"4415:11:17"},{"name":"_3","nodeType":"YulIdentifier","src":"4428:2:17"}],"functionName":{"name":"calldatacopy","nodeType":"YulIdentifier","src":"4385:12:17"},"nodeType":"YulFunctionCall","src":"4385:46:17"},"nodeType":"YulExpressionStatement","src":"4385:46:17"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"4455:6:17"},{"name":"_3","nodeType":"YulIdentifier","src":"4463:2:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4451:3:17"},"nodeType":"YulFunctionCall","src":"4451:15:17"},{"kind":"number","nodeType":"YulLiteral","src":"4468:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4447:3:17"},"nodeType":"YulFunctionCall","src":"4447:24:17"},{"kind":"number","nodeType":"YulLiteral","src":"4473:1:17","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"4440:6:17"},"nodeType":"YulFunctionCall","src":"4440:35:17"},"nodeType":"YulExpressionStatement","src":"4440:35:17"},{"nodeType":"YulAssignment","src":"4484:16:17","value":{"name":"memPtr","nodeType":"YulIdentifier","src":"4494:6:17"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"4484:6:17"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"3440:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"3451:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"3463:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"3471:6:17","type":""},{"name":"value2","nodeType":"YulTypedName","src":"3479:6:17","type":""},{"name":"value3","nodeType":"YulTypedName","src":"3487:6:17","type":""}],"src":"3368:1138:17"},{"body":{"nodeType":"YulBlock","src":"4598:173:17","statements":[{"body":{"nodeType":"YulBlock","src":"4644:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4653:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4656:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4646:6:17"},"nodeType":"YulFunctionCall","src":"4646:12:17"},"nodeType":"YulExpressionStatement","src":"4646:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"4619:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"4628:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"4615:3:17"},"nodeType":"YulFunctionCall","src":"4615:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"4640:2:17","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"4611:3:17"},"nodeType":"YulFunctionCall","src":"4611:32:17"},"nodeType":"YulIf","src":"4608:52:17"},{"nodeType":"YulAssignment","src":"4669:39:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4698:9:17"}],"functionName":{"name":"abi_decode_address","nodeType":"YulIdentifier","src":"4679:18:17"},"nodeType":"YulFunctionCall","src":"4679:29:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"4669:6:17"}]},{"nodeType":"YulAssignment","src":"4717:48:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4750:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"4761:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4746:3:17"},"nodeType":"YulFunctionCall","src":"4746:18:17"}],"functionName":{"name":"abi_decode_address","nodeType":"YulIdentifier","src":"4727:18:17"},"nodeType":"YulFunctionCall","src":"4727:38:17"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"4717:6:17"}]}]},"name":"abi_decode_tuple_t_addresst_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"4556:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"4567:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"4579:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"4587:6:17","type":""}],"src":"4511:260:17"},{"body":{"nodeType":"YulBlock","src":"4831:325:17","statements":[{"nodeType":"YulAssignment","src":"4841:22:17","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4855:1:17","type":"","value":"1"},{"name":"data","nodeType":"YulIdentifier","src":"4858:4:17"}],"functionName":{"name":"shr","nodeType":"YulIdentifier","src":"4851:3:17"},"nodeType":"YulFunctionCall","src":"4851:12:17"},"variableNames":[{"name":"length","nodeType":"YulIdentifier","src":"4841:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"4872:38:17","value":{"arguments":[{"name":"data","nodeType":"YulIdentifier","src":"4902:4:17"},{"kind":"number","nodeType":"YulLiteral","src":"4908:1:17","type":"","value":"1"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"4898:3:17"},"nodeType":"YulFunctionCall","src":"4898:12:17"},"variables":[{"name":"outOfPlaceEncoding","nodeType":"YulTypedName","src":"4876:18:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"4949:31:17","statements":[{"nodeType":"YulAssignment","src":"4951:27:17","value":{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"4965:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"4973:4:17","type":"","value":"0x7f"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"4961:3:17"},"nodeType":"YulFunctionCall","src":"4961:17:17"},"variableNames":[{"name":"length","nodeType":"YulIdentifier","src":"4951:6:17"}]}]},"condition":{"arguments":[{"name":"outOfPlaceEncoding","nodeType":"YulIdentifier","src":"4929:18:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"4922:6:17"},"nodeType":"YulFunctionCall","src":"4922:26:17"},"nodeType":"YulIf","src":"4919:61:17"},{"body":{"nodeType":"YulBlock","src":"5039:111:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5060:1:17","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5067:3:17","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"5072:10:17","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"5063:3:17"},"nodeType":"YulFunctionCall","src":"5063:20:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5053:6:17"},"nodeType":"YulFunctionCall","src":"5053:31:17"},"nodeType":"YulExpressionStatement","src":"5053:31:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5104:1:17","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"5107:4:17","type":"","value":"0x22"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5097:6:17"},"nodeType":"YulFunctionCall","src":"5097:15:17"},"nodeType":"YulExpressionStatement","src":"5097:15:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5132:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"5135:4:17","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"5125:6:17"},"nodeType":"YulFunctionCall","src":"5125:15:17"},"nodeType":"YulExpressionStatement","src":"5125:15:17"}]},"condition":{"arguments":[{"name":"outOfPlaceEncoding","nodeType":"YulIdentifier","src":"4995:18:17"},{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"5018:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"5026:2:17","type":"","value":"32"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"5015:2:17"},"nodeType":"YulFunctionCall","src":"5015:14:17"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"4992:2:17"},"nodeType":"YulFunctionCall","src":"4992:38:17"},"nodeType":"YulIf","src":"4989:161:17"}]},"name":"extract_byte_array_length","nodeType":"YulFunctionDefinition","parameters":[{"name":"data","nodeType":"YulTypedName","src":"4811:4:17","type":""}],"returnVariables":[{"name":"length","nodeType":"YulTypedName","src":"4820:6:17","type":""}],"src":"4776:380:17"},{"body":{"nodeType":"YulBlock","src":"5335:223:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5352:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5363:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5345:6:17"},"nodeType":"YulFunctionCall","src":"5345:21:17"},"nodeType":"YulExpressionStatement","src":"5345:21:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5386:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5397:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5382:3:17"},"nodeType":"YulFunctionCall","src":"5382:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"5402:2:17","type":"","value":"33"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5375:6:17"},"nodeType":"YulFunctionCall","src":"5375:30:17"},"nodeType":"YulExpressionStatement","src":"5375:30:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5425:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5436:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5421:3:17"},"nodeType":"YulFunctionCall","src":"5421:18:17"},{"hexValue":"4552433732313a20617070726f76616c20746f2063757272656e74206f776e65","kind":"string","nodeType":"YulLiteral","src":"5441:34:17","type":"","value":"ERC721: approval to current owne"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5414:6:17"},"nodeType":"YulFunctionCall","src":"5414:62:17"},"nodeType":"YulExpressionStatement","src":"5414:62:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5496:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5507:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5492:3:17"},"nodeType":"YulFunctionCall","src":"5492:18:17"},{"hexValue":"72","kind":"string","nodeType":"YulLiteral","src":"5512:3:17","type":"","value":"r"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5485:6:17"},"nodeType":"YulFunctionCall","src":"5485:31:17"},"nodeType":"YulExpressionStatement","src":"5485:31:17"},{"nodeType":"YulAssignment","src":"5525:27:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5537:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5548:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5533:3:17"},"nodeType":"YulFunctionCall","src":"5533:19:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"5525:4:17"}]}]},"name":"abi_encode_tuple_t_stringliteral_b51b4875eede07862961e8f9365c6749f5fe55c6ee5d7a9e42b6912ad0b15942__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"5312:9:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"5326:4:17","type":""}],"src":"5161:397:17"},{"body":{"nodeType":"YulBlock","src":"5737:251:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5754:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5765:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5747:6:17"},"nodeType":"YulFunctionCall","src":"5747:21:17"},"nodeType":"YulExpressionStatement","src":"5747:21:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5788:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5799:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5784:3:17"},"nodeType":"YulFunctionCall","src":"5784:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"5804:2:17","type":"","value":"61"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5777:6:17"},"nodeType":"YulFunctionCall","src":"5777:30:17"},"nodeType":"YulExpressionStatement","src":"5777:30:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5827:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5838:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5823:3:17"},"nodeType":"YulFunctionCall","src":"5823:18:17"},{"hexValue":"4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f","kind":"string","nodeType":"YulLiteral","src":"5843:34:17","type":"","value":"ERC721: approve caller is not to"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5816:6:17"},"nodeType":"YulFunctionCall","src":"5816:62:17"},"nodeType":"YulExpressionStatement","src":"5816:62:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5898:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5909:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5894:3:17"},"nodeType":"YulFunctionCall","src":"5894:18:17"},{"hexValue":"6b656e206f776e6572206f7220617070726f76656420666f7220616c6c","kind":"string","nodeType":"YulLiteral","src":"5914:31:17","type":"","value":"ken owner or approved for all"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5887:6:17"},"nodeType":"YulFunctionCall","src":"5887:59:17"},"nodeType":"YulExpressionStatement","src":"5887:59:17"},{"nodeType":"YulAssignment","src":"5955:27:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5967:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5978:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5963:3:17"},"nodeType":"YulFunctionCall","src":"5963:19:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"5955:4:17"}]}]},"name":"abi_encode_tuple_t_stringliteral_c6e14a63ffb144eeef7cce6988e5dce07c60a7e0a7b1ef25dbe18c61483e0a83__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"5714:9:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"5728:4:17","type":""}],"src":"5563:425:17"},{"body":{"nodeType":"YulBlock","src":"6167:235:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6184:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6195:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6177:6:17"},"nodeType":"YulFunctionCall","src":"6177:21:17"},"nodeType":"YulExpressionStatement","src":"6177:21:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6218:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6229:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6214:3:17"},"nodeType":"YulFunctionCall","src":"6214:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"6234:2:17","type":"","value":"45"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6207:6:17"},"nodeType":"YulFunctionCall","src":"6207:30:17"},"nodeType":"YulExpressionStatement","src":"6207:30:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6257:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6268:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6253:3:17"},"nodeType":"YulFunctionCall","src":"6253:18:17"},{"hexValue":"4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e65","kind":"string","nodeType":"YulLiteral","src":"6273:34:17","type":"","value":"ERC721: caller is not token owne"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6246:6:17"},"nodeType":"YulFunctionCall","src":"6246:62:17"},"nodeType":"YulExpressionStatement","src":"6246:62:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6328:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6339:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6324:3:17"},"nodeType":"YulFunctionCall","src":"6324:18:17"},{"hexValue":"72206f7220617070726f766564","kind":"string","nodeType":"YulLiteral","src":"6344:15:17","type":"","value":"r or approved"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6317:6:17"},"nodeType":"YulFunctionCall","src":"6317:43:17"},"nodeType":"YulExpressionStatement","src":"6317:43:17"},{"nodeType":"YulAssignment","src":"6369:27:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6381:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6392:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6377:3:17"},"nodeType":"YulFunctionCall","src":"6377:19:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"6369:4:17"}]}]},"name":"abi_encode_tuple_t_stringliteral_12a8e5623d251e191fe4a291d9a59bcc01a4db7a1f5c20fc8de44358c18308af__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"6144:9:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"6158:4:17","type":""}],"src":"5993:409:17"},{"body":{"nodeType":"YulBlock","src":"6581:174:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6598:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6609:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6591:6:17"},"nodeType":"YulFunctionCall","src":"6591:21:17"},"nodeType":"YulExpressionStatement","src":"6591:21:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6632:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6643:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6628:3:17"},"nodeType":"YulFunctionCall","src":"6628:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"6648:2:17","type":"","value":"24"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6621:6:17"},"nodeType":"YulFunctionCall","src":"6621:30:17"},"nodeType":"YulExpressionStatement","src":"6621:30:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6671:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6682:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6667:3:17"},"nodeType":"YulFunctionCall","src":"6667:18:17"},{"hexValue":"4552433732313a20696e76616c696420746f6b656e204944","kind":"string","nodeType":"YulLiteral","src":"6687:26:17","type":"","value":"ERC721: invalid token ID"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6660:6:17"},"nodeType":"YulFunctionCall","src":"6660:54:17"},"nodeType":"YulExpressionStatement","src":"6660:54:17"},{"nodeType":"YulAssignment","src":"6723:26:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6735:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6746:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6731:3:17"},"nodeType":"YulFunctionCall","src":"6731:18:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"6723:4:17"}]}]},"name":"abi_encode_tuple_t_stringliteral_b08d2b0fec7cc108ab049809a8beb42779d969a49299d0c317c907d9db22974f__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"6558:9:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"6572:4:17","type":""}],"src":"6407:348:17"},{"body":{"nodeType":"YulBlock","src":"6934:231:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6951:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6962:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6944:6:17"},"nodeType":"YulFunctionCall","src":"6944:21:17"},"nodeType":"YulExpressionStatement","src":"6944:21:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6985:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6996:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6981:3:17"},"nodeType":"YulFunctionCall","src":"6981:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"7001:2:17","type":"","value":"41"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6974:6:17"},"nodeType":"YulFunctionCall","src":"6974:30:17"},"nodeType":"YulExpressionStatement","src":"6974:30:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7024:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"7035:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7020:3:17"},"nodeType":"YulFunctionCall","src":"7020:18:17"},{"hexValue":"4552433732313a2061646472657373207a65726f206973206e6f742061207661","kind":"string","nodeType":"YulLiteral","src":"7040:34:17","type":"","value":"ERC721: address zero is not a va"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7013:6:17"},"nodeType":"YulFunctionCall","src":"7013:62:17"},"nodeType":"YulExpressionStatement","src":"7013:62:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7095:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"7106:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7091:3:17"},"nodeType":"YulFunctionCall","src":"7091:18:17"},{"hexValue":"6c6964206f776e6572","kind":"string","nodeType":"YulLiteral","src":"7111:11:17","type":"","value":"lid owner"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7084:6:17"},"nodeType":"YulFunctionCall","src":"7084:39:17"},"nodeType":"YulExpressionStatement","src":"7084:39:17"},{"nodeType":"YulAssignment","src":"7132:27:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7144:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"7155:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7140:3:17"},"nodeType":"YulFunctionCall","src":"7140:19:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"7132:4:17"}]}]},"name":"abi_encode_tuple_t_stringliteral_6d05c90094f31cfeb8f0eb86f0a513af3f7f8992991fbde41b08aa7960677159__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"6911:9:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"6925:4:17","type":""}],"src":"6760:405:17"},{"body":{"nodeType":"YulBlock","src":"7357:309:17","statements":[{"nodeType":"YulVariableDeclaration","src":"7367:27:17","value":{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"7387:6:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"7381:5:17"},"nodeType":"YulFunctionCall","src":"7381:13:17"},"variables":[{"name":"length","nodeType":"YulTypedName","src":"7371:6:17","type":""}]},{"expression":{"arguments":[{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"7442:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"7450:4:17","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7438:3:17"},"nodeType":"YulFunctionCall","src":"7438:17:17"},{"name":"pos","nodeType":"YulIdentifier","src":"7457:3:17"},{"name":"length","nodeType":"YulIdentifier","src":"7462:6:17"}],"functionName":{"name":"copy_memory_to_memory_with_cleanup","nodeType":"YulIdentifier","src":"7403:34:17"},"nodeType":"YulFunctionCall","src":"7403:66:17"},"nodeType":"YulExpressionStatement","src":"7403:66:17"},{"nodeType":"YulVariableDeclaration","src":"7478:29:17","value":{"arguments":[{"name":"pos","nodeType":"YulIdentifier","src":"7495:3:17"},{"name":"length","nodeType":"YulIdentifier","src":"7500:6:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7491:3:17"},"nodeType":"YulFunctionCall","src":"7491:16:17"},"variables":[{"name":"end_1","nodeType":"YulTypedName","src":"7482:5:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"7516:29:17","value":{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"7538:6:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"7532:5:17"},"nodeType":"YulFunctionCall","src":"7532:13:17"},"variables":[{"name":"length_1","nodeType":"YulTypedName","src":"7520:8:17","type":""}]},{"expression":{"arguments":[{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"7593:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"7601:4:17","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7589:3:17"},"nodeType":"YulFunctionCall","src":"7589:17:17"},{"name":"end_1","nodeType":"YulIdentifier","src":"7608:5:17"},{"name":"length_1","nodeType":"YulIdentifier","src":"7615:8:17"}],"functionName":{"name":"copy_memory_to_memory_with_cleanup","nodeType":"YulIdentifier","src":"7554:34:17"},"nodeType":"YulFunctionCall","src":"7554:70:17"},"nodeType":"YulExpressionStatement","src":"7554:70:17"},{"nodeType":"YulAssignment","src":"7633:27:17","value":{"arguments":[{"name":"end_1","nodeType":"YulIdentifier","src":"7644:5:17"},{"name":"length_1","nodeType":"YulIdentifier","src":"7651:8:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7640:3:17"},"nodeType":"YulFunctionCall","src":"7640:20:17"},"variableNames":[{"name":"end","nodeType":"YulIdentifier","src":"7633:3:17"}]}]},"name":"abi_encode_tuple_packed_t_string_memory_ptr_t_string_memory_ptr__to_t_string_memory_ptr_t_string_memory_ptr__nonPadded_inplace_fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"pos","nodeType":"YulTypedName","src":"7325:3:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"7330:6:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"7338:6:17","type":""}],"returnVariables":[{"name":"end","nodeType":"YulTypedName","src":"7349:3:17","type":""}],"src":"7170:496:17"},{"body":{"nodeType":"YulBlock","src":"7845:227:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7862:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"7873:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7855:6:17"},"nodeType":"YulFunctionCall","src":"7855:21:17"},"nodeType":"YulExpressionStatement","src":"7855:21:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7896:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"7907:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7892:3:17"},"nodeType":"YulFunctionCall","src":"7892:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"7912:2:17","type":"","value":"37"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7885:6:17"},"nodeType":"YulFunctionCall","src":"7885:30:17"},"nodeType":"YulExpressionStatement","src":"7885:30:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7935:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"7946:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7931:3:17"},"nodeType":"YulFunctionCall","src":"7931:18:17"},{"hexValue":"4552433732313a207472616e736665722066726f6d20696e636f727265637420","kind":"string","nodeType":"YulLiteral","src":"7951:34:17","type":"","value":"ERC721: transfer from incorrect "}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7924:6:17"},"nodeType":"YulFunctionCall","src":"7924:62:17"},"nodeType":"YulExpressionStatement","src":"7924:62:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8006:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8017:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8002:3:17"},"nodeType":"YulFunctionCall","src":"8002:18:17"},{"hexValue":"6f776e6572","kind":"string","nodeType":"YulLiteral","src":"8022:7:17","type":"","value":"owner"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7995:6:17"},"nodeType":"YulFunctionCall","src":"7995:35:17"},"nodeType":"YulExpressionStatement","src":"7995:35:17"},{"nodeType":"YulAssignment","src":"8039:27:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8051:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8062:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8047:3:17"},"nodeType":"YulFunctionCall","src":"8047:19:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"8039:4:17"}]}]},"name":"abi_encode_tuple_t_stringliteral_277f8ee9d5b4fc3c4149386f24de0fc1bbc63a8210e2197bfd1c0376a2ac5f48__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"7822:9:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"7836:4:17","type":""}],"src":"7671:401:17"},{"body":{"nodeType":"YulBlock","src":"8251:226:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8268:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8279:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8261:6:17"},"nodeType":"YulFunctionCall","src":"8261:21:17"},"nodeType":"YulExpressionStatement","src":"8261:21:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8302:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8313:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8298:3:17"},"nodeType":"YulFunctionCall","src":"8298:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"8318:2:17","type":"","value":"36"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8291:6:17"},"nodeType":"YulFunctionCall","src":"8291:30:17"},"nodeType":"YulExpressionStatement","src":"8291:30:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8341:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8352:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8337:3:17"},"nodeType":"YulFunctionCall","src":"8337:18:17"},{"hexValue":"4552433732313a207472616e7366657220746f20746865207a65726f20616464","kind":"string","nodeType":"YulLiteral","src":"8357:34:17","type":"","value":"ERC721: transfer to the zero add"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8330:6:17"},"nodeType":"YulFunctionCall","src":"8330:62:17"},"nodeType":"YulExpressionStatement","src":"8330:62:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8412:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8423:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8408:3:17"},"nodeType":"YulFunctionCall","src":"8408:18:17"},{"hexValue":"72657373","kind":"string","nodeType":"YulLiteral","src":"8428:6:17","type":"","value":"ress"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8401:6:17"},"nodeType":"YulFunctionCall","src":"8401:34:17"},"nodeType":"YulExpressionStatement","src":"8401:34:17"},{"nodeType":"YulAssignment","src":"8444:27:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8456:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8467:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8452:3:17"},"nodeType":"YulFunctionCall","src":"8452:19:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"8444:4:17"}]}]},"name":"abi_encode_tuple_t_stringliteral_455fea98ea03c32d7dd1a6f1426917d80529bf47b3ccbde74e7206e889e709f4__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"8228:9:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"8242:4:17","type":""}],"src":"8077:400:17"},{"body":{"nodeType":"YulBlock","src":"8656:175:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8673:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8684:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8666:6:17"},"nodeType":"YulFunctionCall","src":"8666:21:17"},"nodeType":"YulExpressionStatement","src":"8666:21:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8707:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8718:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8703:3:17"},"nodeType":"YulFunctionCall","src":"8703:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"8723:2:17","type":"","value":"25"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8696:6:17"},"nodeType":"YulFunctionCall","src":"8696:30:17"},"nodeType":"YulExpressionStatement","src":"8696:30:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8746:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8757:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8742:3:17"},"nodeType":"YulFunctionCall","src":"8742:18:17"},{"hexValue":"4552433732313a20617070726f766520746f2063616c6c6572","kind":"string","nodeType":"YulLiteral","src":"8762:27:17","type":"","value":"ERC721: approve to caller"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8735:6:17"},"nodeType":"YulFunctionCall","src":"8735:55:17"},"nodeType":"YulExpressionStatement","src":"8735:55:17"},{"nodeType":"YulAssignment","src":"8799:26:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8811:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8822:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8807:3:17"},"nodeType":"YulFunctionCall","src":"8807:18:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"8799:4:17"}]}]},"name":"abi_encode_tuple_t_stringliteral_45fe4329685be5ecd250fd0e6a25aea0ea4d0e30fb6a73c118b95749e6d70d05__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"8633:9:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"8647:4:17","type":""}],"src":"8482:349:17"},{"body":{"nodeType":"YulBlock","src":"9010:240:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9027:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9038:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9020:6:17"},"nodeType":"YulFunctionCall","src":"9020:21:17"},"nodeType":"YulExpressionStatement","src":"9020:21:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9061:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9072:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9057:3:17"},"nodeType":"YulFunctionCall","src":"9057:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"9077:2:17","type":"","value":"50"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9050:6:17"},"nodeType":"YulFunctionCall","src":"9050:30:17"},"nodeType":"YulExpressionStatement","src":"9050:30:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9100:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9111:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9096:3:17"},"nodeType":"YulFunctionCall","src":"9096:18:17"},{"hexValue":"4552433732313a207472616e7366657220746f206e6f6e204552433732315265","kind":"string","nodeType":"YulLiteral","src":"9116:34:17","type":"","value":"ERC721: transfer to non ERC721Re"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9089:6:17"},"nodeType":"YulFunctionCall","src":"9089:62:17"},"nodeType":"YulExpressionStatement","src":"9089:62:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9171:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9182:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9167:3:17"},"nodeType":"YulFunctionCall","src":"9167:18:17"},{"hexValue":"63656976657220696d706c656d656e746572","kind":"string","nodeType":"YulLiteral","src":"9187:20:17","type":"","value":"ceiver implementer"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9160:6:17"},"nodeType":"YulFunctionCall","src":"9160:48:17"},"nodeType":"YulExpressionStatement","src":"9160:48:17"},{"nodeType":"YulAssignment","src":"9217:27:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9229:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9240:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9225:3:17"},"nodeType":"YulFunctionCall","src":"9225:19:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"9217:4:17"}]}]},"name":"abi_encode_tuple_t_stringliteral_1e766a06da43a53d0f4c380e06e5a342e14d5af1bf8501996c844905530ca84e__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"8987:9:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"9001:4:17","type":""}],"src":"8836:414:17"},{"body":{"nodeType":"YulBlock","src":"9287:95:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9304:1:17","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9311:3:17","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"9316:10:17","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"9307:3:17"},"nodeType":"YulFunctionCall","src":"9307:20:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9297:6:17"},"nodeType":"YulFunctionCall","src":"9297:31:17"},"nodeType":"YulExpressionStatement","src":"9297:31:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9344:1:17","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"9347:4:17","type":"","value":"0x12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9337:6:17"},"nodeType":"YulFunctionCall","src":"9337:15:17"},"nodeType":"YulExpressionStatement","src":"9337:15:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9368:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"9371:4:17","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"9361:6:17"},"nodeType":"YulFunctionCall","src":"9361:15:17"},"nodeType":"YulExpressionStatement","src":"9361:15:17"}]},"name":"panic_error_0x12","nodeType":"YulFunctionDefinition","src":"9255:127:17"},{"body":{"nodeType":"YulBlock","src":"9590:286:17","statements":[{"nodeType":"YulVariableDeclaration","src":"9600:29:17","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"9618:3:17","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"9623:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"9614:3:17"},"nodeType":"YulFunctionCall","src":"9614:11:17"},{"kind":"number","nodeType":"YulLiteral","src":"9627:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"9610:3:17"},"nodeType":"YulFunctionCall","src":"9610:19:17"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"9604:2:17","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9645:9:17"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"9660:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"9668:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"9656:3:17"},"nodeType":"YulFunctionCall","src":"9656:15:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9638:6:17"},"nodeType":"YulFunctionCall","src":"9638:34:17"},"nodeType":"YulExpressionStatement","src":"9638:34:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9692:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9703:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9688:3:17"},"nodeType":"YulFunctionCall","src":"9688:18:17"},{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"9712:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"9720:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"9708:3:17"},"nodeType":"YulFunctionCall","src":"9708:15:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9681:6:17"},"nodeType":"YulFunctionCall","src":"9681:43:17"},"nodeType":"YulExpressionStatement","src":"9681:43:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9744:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9755:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9740:3:17"},"nodeType":"YulFunctionCall","src":"9740:18:17"},{"name":"value2","nodeType":"YulIdentifier","src":"9760:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9733:6:17"},"nodeType":"YulFunctionCall","src":"9733:34:17"},"nodeType":"YulExpressionStatement","src":"9733:34:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9787:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9798:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9783:3:17"},"nodeType":"YulFunctionCall","src":"9783:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"9803:3:17","type":"","value":"128"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9776:6:17"},"nodeType":"YulFunctionCall","src":"9776:31:17"},"nodeType":"YulExpressionStatement","src":"9776:31:17"},{"nodeType":"YulAssignment","src":"9816:54:17","value":{"arguments":[{"name":"value3","nodeType":"YulIdentifier","src":"9842:6:17"},{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9854:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9865:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9850:3:17"},"nodeType":"YulFunctionCall","src":"9850:19:17"}],"functionName":{"name":"abi_encode_string","nodeType":"YulIdentifier","src":"9824:17:17"},"nodeType":"YulFunctionCall","src":"9824:46:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"9816:4:17"}]}]},"name":"abi_encode_tuple_t_address_t_address_t_uint256_t_bytes_memory_ptr__to_t_address_t_address_t_uint256_t_bytes_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"9535:9:17","type":""},{"name":"value3","nodeType":"YulTypedName","src":"9546:6:17","type":""},{"name":"value2","nodeType":"YulTypedName","src":"9554:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"9562:6:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"9570:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"9581:4:17","type":""}],"src":"9387:489:17"},{"body":{"nodeType":"YulBlock","src":"9961:169:17","statements":[{"body":{"nodeType":"YulBlock","src":"10007:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10016:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"10019:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"10009:6:17"},"nodeType":"YulFunctionCall","src":"10009:12:17"},"nodeType":"YulExpressionStatement","src":"10009:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"9982:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"9991:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"9978:3:17"},"nodeType":"YulFunctionCall","src":"9978:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"10003:2:17","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"9974:3:17"},"nodeType":"YulFunctionCall","src":"9974:32:17"},"nodeType":"YulIf","src":"9971:52:17"},{"nodeType":"YulVariableDeclaration","src":"10032:29:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10051:9:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"10045:5:17"},"nodeType":"YulFunctionCall","src":"10045:16:17"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"10036:5:17","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"10094:5:17"}],"functionName":{"name":"validator_revert_bytes4","nodeType":"YulIdentifier","src":"10070:23:17"},"nodeType":"YulFunctionCall","src":"10070:30:17"},"nodeType":"YulExpressionStatement","src":"10070:30:17"},{"nodeType":"YulAssignment","src":"10109:15:17","value":{"name":"value","nodeType":"YulIdentifier","src":"10119:5:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"10109:6:17"}]}]},"name":"abi_decode_tuple_t_bytes4_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"9927:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"9938:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"9950:6:17","type":""}],"src":"9881:249:17"}]},"contents":"{\n { }\n function validator_revert_bytes4(value)\n {\n if iszero(eq(value, and(value, shl(224, 0xffffffff)))) { revert(0, 0) }\n }\n function abi_decode_tuple_t_bytes4(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_bytes4(value)\n value0 := value\n }\n function abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, iszero(iszero(value0)))\n }\n function copy_memory_to_memory_with_cleanup(src, dst, length)\n {\n let i := 0\n for { } lt(i, length) { i := add(i, 32) }\n {\n mstore(add(dst, i), mload(add(src, i)))\n }\n mstore(add(dst, length), 0)\n }\n function abi_encode_string(value, pos) -> end\n {\n let length := mload(value)\n mstore(pos, length)\n copy_memory_to_memory_with_cleanup(add(value, 0x20), add(pos, 0x20), length)\n end := add(add(pos, and(add(length, 31), not(31))), 0x20)\n }\n function abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack_reversed(headStart, value0) -> tail\n {\n mstore(headStart, 32)\n tail := abi_encode_string(value0, add(headStart, 32))\n }\n function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n value0 := calldataload(headStart)\n }\n function abi_encode_tuple_t_address__to_t_address__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, sub(shl(160, 1), 1)))\n }\n function abi_decode_address(offset) -> value\n {\n value := calldataload(offset)\n if iszero(eq(value, and(value, sub(shl(160, 1), 1)))) { revert(0, 0) }\n }\n function abi_decode_tuple_t_addresst_uint256(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n value0 := abi_decode_address(headStart)\n value1 := calldataload(add(headStart, 32))\n }\n function abi_decode_tuple_t_addresst_addresst_uint256(headStart, dataEnd) -> value0, value1, value2\n {\n if slt(sub(dataEnd, headStart), 96) { revert(0, 0) }\n value0 := abi_decode_address(headStart)\n value1 := abi_decode_address(add(headStart, 32))\n value2 := calldataload(add(headStart, 64))\n }\n function abi_decode_tuple_t_address(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n value0 := abi_decode_address(headStart)\n }\n function abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, value0)\n }\n function abi_decode_tuple_t_addresst_bool(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n value0 := abi_decode_address(headStart)\n let value := calldataload(add(headStart, 32))\n if iszero(eq(value, iszero(iszero(value)))) { revert(0, 0) }\n value1 := value\n }\n function panic_error_0x41()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x41)\n revert(0, 0x24)\n }\n function abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 128) { revert(0, 0) }\n value0 := abi_decode_address(headStart)\n value1 := abi_decode_address(add(headStart, 32))\n value2 := calldataload(add(headStart, 64))\n let offset := calldataload(add(headStart, 96))\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n let _2 := add(headStart, offset)\n if iszero(slt(add(_2, 0x1f), dataEnd)) { revert(0, 0) }\n let _3 := calldataload(_2)\n if gt(_3, _1) { panic_error_0x41() }\n let _4 := not(31)\n let memPtr := mload(64)\n let newFreePtr := add(memPtr, and(add(and(add(_3, 0x1f), _4), 63), _4))\n if or(gt(newFreePtr, _1), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n mstore(64, newFreePtr)\n mstore(memPtr, _3)\n if gt(add(add(_2, _3), 32), dataEnd) { revert(0, 0) }\n calldatacopy(add(memPtr, 32), add(_2, 32), _3)\n mstore(add(add(memPtr, _3), 32), 0)\n value3 := memPtr\n }\n function abi_decode_tuple_t_addresst_address(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n value0 := abi_decode_address(headStart)\n value1 := abi_decode_address(add(headStart, 32))\n }\n function extract_byte_array_length(data) -> length\n {\n length := shr(1, data)\n let outOfPlaceEncoding := and(data, 1)\n if iszero(outOfPlaceEncoding) { length := and(length, 0x7f) }\n if eq(outOfPlaceEncoding, lt(length, 32))\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x22)\n revert(0, 0x24)\n }\n }\n function abi_encode_tuple_t_stringliteral_b51b4875eede07862961e8f9365c6749f5fe55c6ee5d7a9e42b6912ad0b15942__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 33)\n mstore(add(headStart, 64), \"ERC721: approval to current owne\")\n mstore(add(headStart, 96), \"r\")\n tail := add(headStart, 128)\n }\n function abi_encode_tuple_t_stringliteral_c6e14a63ffb144eeef7cce6988e5dce07c60a7e0a7b1ef25dbe18c61483e0a83__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 61)\n mstore(add(headStart, 64), \"ERC721: approve caller is not to\")\n mstore(add(headStart, 96), \"ken owner or approved for all\")\n tail := add(headStart, 128)\n }\n function abi_encode_tuple_t_stringliteral_12a8e5623d251e191fe4a291d9a59bcc01a4db7a1f5c20fc8de44358c18308af__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 45)\n mstore(add(headStart, 64), \"ERC721: caller is not token owne\")\n mstore(add(headStart, 96), \"r or approved\")\n tail := add(headStart, 128)\n }\n function abi_encode_tuple_t_stringliteral_b08d2b0fec7cc108ab049809a8beb42779d969a49299d0c317c907d9db22974f__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 24)\n mstore(add(headStart, 64), \"ERC721: invalid token ID\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_6d05c90094f31cfeb8f0eb86f0a513af3f7f8992991fbde41b08aa7960677159__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 41)\n mstore(add(headStart, 64), \"ERC721: address zero is not a va\")\n mstore(add(headStart, 96), \"lid owner\")\n tail := add(headStart, 128)\n }\n function abi_encode_tuple_packed_t_string_memory_ptr_t_string_memory_ptr__to_t_string_memory_ptr_t_string_memory_ptr__nonPadded_inplace_fromStack_reversed(pos, value1, value0) -> end\n {\n let length := mload(value0)\n copy_memory_to_memory_with_cleanup(add(value0, 0x20), pos, length)\n let end_1 := add(pos, length)\n let length_1 := mload(value1)\n copy_memory_to_memory_with_cleanup(add(value1, 0x20), end_1, length_1)\n end := add(end_1, length_1)\n }\n function abi_encode_tuple_t_stringliteral_277f8ee9d5b4fc3c4149386f24de0fc1bbc63a8210e2197bfd1c0376a2ac5f48__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 37)\n mstore(add(headStart, 64), \"ERC721: transfer from incorrect \")\n mstore(add(headStart, 96), \"owner\")\n tail := add(headStart, 128)\n }\n function abi_encode_tuple_t_stringliteral_455fea98ea03c32d7dd1a6f1426917d80529bf47b3ccbde74e7206e889e709f4__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 36)\n mstore(add(headStart, 64), \"ERC721: transfer to the zero add\")\n mstore(add(headStart, 96), \"ress\")\n tail := add(headStart, 128)\n }\n function abi_encode_tuple_t_stringliteral_45fe4329685be5ecd250fd0e6a25aea0ea4d0e30fb6a73c118b95749e6d70d05__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 25)\n mstore(add(headStart, 64), \"ERC721: approve to caller\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_1e766a06da43a53d0f4c380e06e5a342e14d5af1bf8501996c844905530ca84e__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 50)\n mstore(add(headStart, 64), \"ERC721: transfer to non ERC721Re\")\n mstore(add(headStart, 96), \"ceiver implementer\")\n tail := add(headStart, 128)\n }\n function panic_error_0x12()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x12)\n revert(0, 0x24)\n }\n function abi_encode_tuple_t_address_t_address_t_uint256_t_bytes_memory_ptr__to_t_address_t_address_t_uint256_t_bytes_memory_ptr__fromStack_reversed(headStart, value3, value2, value1, value0) -> tail\n {\n let _1 := sub(shl(160, 1), 1)\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), and(value1, _1))\n mstore(add(headStart, 64), value2)\n mstore(add(headStart, 96), 128)\n tail := abi_encode_string(value3, add(headStart, 128))\n }\n function abi_decode_tuple_t_bytes4_fromMemory(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := mload(headStart)\n validator_revert_bytes4(value)\n value0 := value\n }\n}","id":17,"language":"Yul","name":"#utility.yul"}],"immutableReferences":{},"linkReferences":{},"object":"608060405234801561001057600080fd5b50600436106100cf5760003560e01c80636352211e1161008c578063a22cb46511610066578063a22cb465146101b3578063b88d4fde146101c6578063c87b56dd146101d9578063e985e9c5146101ec57600080fd5b80636352211e1461017757806370a082311461018a57806395d89b41146101ab57600080fd5b806301ffc9a7146100d457806306fdde03146100fc578063081812fc14610111578063095ea7b31461013c57806323b872dd1461015157806342842e0e14610164575b600080fd5b6100e76100e2366004610c7f565b610228565b60405190151581526020015b60405180910390f35b61010461027a565b6040516100f39190610cec565b61012461011f366004610cff565b61030c565b6040516001600160a01b0390911681526020016100f3565b61014f61014a366004610d34565b610333565b005b61014f61015f366004610d5e565b61044d565b61014f610172366004610d5e565b61047e565b610124610185366004610cff565b610499565b61019d610198366004610d9a565b6104f9565b6040519081526020016100f3565b61010461057f565b61014f6101c1366004610db5565b61058e565b61014f6101d4366004610e07565b61059d565b6101046101e7366004610cff565b6105d5565b6100e76101fa366004610ee3565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60006001600160e01b031982166380ac58cd60e01b148061025957506001600160e01b03198216635b5e139f60e01b145b8061027457506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606000805461028990610f16565b80601f01602080910402602001604051908101604052809291908181526020018280546102b590610f16565b80156103025780601f106102d757610100808354040283529160200191610302565b820191906000526020600020905b8154815290600101906020018083116102e557829003601f168201915b5050505050905090565b600061031782610649565b506000908152600460205260409020546001600160a01b031690565b600061033e82610499565b9050806001600160a01b0316836001600160a01b0316036103b05760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806103cc57506103cc81336101fa565b61043e5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c00000060648201526084016103a7565b61044883836106ab565b505050565b6104573382610719565b6104735760405162461bcd60e51b81526004016103a790610f50565b610448838383610798565b6104488383836040518060200160405280600081525061059d565b6000818152600260205260408120546001600160a01b0316806102745760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103a7565b60006001600160a01b0382166105635760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016103a7565b506001600160a01b031660009081526003602052604090205490565b60606001805461028990610f16565b6105993383836108fc565b5050565b6105a73383610719565b6105c35760405162461bcd60e51b81526004016103a790610f50565b6105cf848484846109ca565b50505050565b60606105e082610649565b60006105f760408051602081019091526000815290565b905060008151116106175760405180602001604052806000815250610642565b80610621846109fd565b604051602001610632929190610f9d565b6040516020818303038152906040525b9392505050565b6000818152600260205260409020546001600160a01b03166106a85760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103a7565b50565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906106e082610499565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061072583610499565b9050806001600160a01b0316846001600160a01b0316148061076c57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b806107905750836001600160a01b03166107858461030c565b6001600160a01b0316145b949350505050565b826001600160a01b03166107ab82610499565b6001600160a01b0316146107d15760405162461bcd60e51b81526004016103a790610fcc565b6001600160a01b0382166108335760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016103a7565b826001600160a01b031661084682610499565b6001600160a01b03161461086c5760405162461bcd60e51b81526004016103a790610fcc565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b816001600160a01b0316836001600160a01b03160361095d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016103a7565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6109d5848484610798565b6109e184848484610a90565b6105cf5760405162461bcd60e51b81526004016103a790611011565b60606000610a0a83610b91565b600101905060008167ffffffffffffffff811115610a2a57610a2a610df1565b6040519080825280601f01601f191660200182016040528015610a54576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084610a5e57509392505050565b60006001600160a01b0384163b15610b8657604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290610ad4903390899088908890600401611063565b6020604051808303816000875af1925050508015610b0f575060408051601f3d908101601f19168201909252610b0c918101906110a0565b60015b610b6c573d808015610b3d576040519150601f19603f3d011682016040523d82523d6000602084013e610b42565b606091505b508051600003610b645760405162461bcd60e51b81526004016103a790611011565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610790565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310610bd05772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310610bfc576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310610c1a57662386f26fc10000830492506010015b6305f5e1008310610c32576305f5e100830492506008015b6127108310610c4657612710830492506004015b60648310610c58576064830492506002015b600a83106102745760010192915050565b6001600160e01b0319811681146106a857600080fd5b600060208284031215610c9157600080fd5b813561064281610c69565b60005b83811015610cb7578181015183820152602001610c9f565b50506000910152565b60008151808452610cd8816020860160208601610c9c565b601f01601f19169290920160200192915050565b6020815260006106426020830184610cc0565b600060208284031215610d1157600080fd5b5035919050565b80356001600160a01b0381168114610d2f57600080fd5b919050565b60008060408385031215610d4757600080fd5b610d5083610d18565b946020939093013593505050565b600080600060608486031215610d7357600080fd5b610d7c84610d18565b9250610d8a60208501610d18565b9150604084013590509250925092565b600060208284031215610dac57600080fd5b61064282610d18565b60008060408385031215610dc857600080fd5b610dd183610d18565b915060208301358015158114610de657600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215610e1d57600080fd5b610e2685610d18565b9350610e3460208601610d18565b925060408501359150606085013567ffffffffffffffff80821115610e5857600080fd5b818701915087601f830112610e6c57600080fd5b813581811115610e7e57610e7e610df1565b604051601f8201601f19908116603f01168101908382118183101715610ea657610ea6610df1565b816040528281528a6020848701011115610ebf57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215610ef657600080fd5b610eff83610d18565b9150610f0d60208401610d18565b90509250929050565b600181811c90821680610f2a57607f821691505b602082108103610f4a57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b60008351610faf818460208801610c9c565b835190830190610fc3818360208801610c9c565b01949350505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061109690830184610cc0565b9695505050505050565b6000602082840312156110b257600080fd5b815161064281610c6956fea2646970667358221220572b001af737f9d43203516808c567baf41baf8d490bb57390158191aafea9c264736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0xCF JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x6352211E GT PUSH2 0x8C JUMPI DUP1 PUSH4 0xA22CB465 GT PUSH2 0x66 JUMPI DUP1 PUSH4 0xA22CB465 EQ PUSH2 0x1B3 JUMPI DUP1 PUSH4 0xB88D4FDE EQ PUSH2 0x1C6 JUMPI DUP1 PUSH4 0xC87B56DD EQ PUSH2 0x1D9 JUMPI DUP1 PUSH4 0xE985E9C5 EQ PUSH2 0x1EC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x6352211E EQ PUSH2 0x177 JUMPI DUP1 PUSH4 0x70A08231 EQ PUSH2 0x18A JUMPI DUP1 PUSH4 0x95D89B41 EQ PUSH2 0x1AB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1FFC9A7 EQ PUSH2 0xD4 JUMPI DUP1 PUSH4 0x6FDDE03 EQ PUSH2 0xFC JUMPI DUP1 PUSH4 0x81812FC EQ PUSH2 0x111 JUMPI DUP1 PUSH4 0x95EA7B3 EQ PUSH2 0x13C JUMPI DUP1 PUSH4 0x23B872DD EQ PUSH2 0x151 JUMPI DUP1 PUSH4 0x42842E0E EQ PUSH2 0x164 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xE7 PUSH2 0xE2 CALLDATASIZE PUSH1 0x4 PUSH2 0xC7F JUMP JUMPDEST PUSH2 0x228 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x104 PUSH2 0x27A JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0xF3 SWAP2 SWAP1 PUSH2 0xCEC JUMP JUMPDEST PUSH2 0x124 PUSH2 0x11F CALLDATASIZE PUSH1 0x4 PUSH2 0xCFF JUMP JUMPDEST PUSH2 0x30C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xF3 JUMP JUMPDEST PUSH2 0x14F PUSH2 0x14A CALLDATASIZE PUSH1 0x4 PUSH2 0xD34 JUMP JUMPDEST PUSH2 0x333 JUMP JUMPDEST STOP JUMPDEST PUSH2 0x14F PUSH2 0x15F CALLDATASIZE PUSH1 0x4 PUSH2 0xD5E JUMP JUMPDEST PUSH2 0x44D JUMP JUMPDEST PUSH2 0x14F PUSH2 0x172 CALLDATASIZE PUSH1 0x4 PUSH2 0xD5E JUMP JUMPDEST PUSH2 0x47E JUMP JUMPDEST PUSH2 0x124 PUSH2 0x185 CALLDATASIZE PUSH1 0x4 PUSH2 0xCFF JUMP JUMPDEST PUSH2 0x499 JUMP JUMPDEST PUSH2 0x19D PUSH2 0x198 CALLDATASIZE PUSH1 0x4 PUSH2 0xD9A JUMP JUMPDEST PUSH2 0x4F9 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xF3 JUMP JUMPDEST PUSH2 0x104 PUSH2 0x57F JUMP JUMPDEST PUSH2 0x14F PUSH2 0x1C1 CALLDATASIZE PUSH1 0x4 PUSH2 0xDB5 JUMP JUMPDEST PUSH2 0x58E JUMP JUMPDEST PUSH2 0x14F PUSH2 0x1D4 CALLDATASIZE PUSH1 0x4 PUSH2 0xE07 JUMP JUMPDEST PUSH2 0x59D JUMP JUMPDEST PUSH2 0x104 PUSH2 0x1E7 CALLDATASIZE PUSH1 0x4 PUSH2 0xCFF JUMP JUMPDEST PUSH2 0x5D5 JUMP JUMPDEST PUSH2 0xE7 PUSH2 0x1FA CALLDATASIZE PUSH1 0x4 PUSH2 0xEE3 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP2 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 SWAP1 SWAP5 AND DUP3 MSTORE SWAP2 SWAP1 SWAP2 MSTORE KECCAK256 SLOAD PUSH1 0xFF AND SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP3 AND PUSH4 0x80AC58CD PUSH1 0xE0 SHL EQ DUP1 PUSH2 0x259 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP3 AND PUSH4 0x5B5E139F PUSH1 0xE0 SHL EQ JUMPDEST DUP1 PUSH2 0x274 JUMPI POP PUSH4 0x1FFC9A7 PUSH1 0xE0 SHL PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND EQ JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 SLOAD PUSH2 0x289 SWAP1 PUSH2 0xF16 JUMP JUMPDEST DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD PUSH2 0x2B5 SWAP1 PUSH2 0xF16 JUMP JUMPDEST DUP1 ISZERO PUSH2 0x302 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x2D7 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x302 JUMP JUMPDEST DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD DUP2 MSTORE SWAP1 PUSH1 0x1 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0x2E5 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x317 DUP3 PUSH2 0x649 JUMP JUMPDEST POP PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x4 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x33E DUP3 PUSH2 0x499 JUMP JUMPDEST SWAP1 POP DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP4 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SUB PUSH2 0x3B0 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x21 PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A20617070726F76616C20746F2063757272656E74206F776E65 PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x39 PUSH1 0xF9 SHL PUSH1 0x64 DUP3 ADD MSTORE PUSH1 0x84 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND EQ DUP1 PUSH2 0x3CC JUMPI POP PUSH2 0x3CC DUP2 CALLER PUSH2 0x1FA JUMP JUMPDEST PUSH2 0x43E JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x3D PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A20617070726F76652063616C6C6572206973206E6F7420746F PUSH1 0x44 DUP3 ADD MSTORE PUSH32 0x6B656E206F776E6572206F7220617070726F76656420666F7220616C6C000000 PUSH1 0x64 DUP3 ADD MSTORE PUSH1 0x84 ADD PUSH2 0x3A7 JUMP JUMPDEST PUSH2 0x448 DUP4 DUP4 PUSH2 0x6AB JUMP JUMPDEST POP POP POP JUMP JUMPDEST PUSH2 0x457 CALLER DUP3 PUSH2 0x719 JUMP JUMPDEST PUSH2 0x473 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3A7 SWAP1 PUSH2 0xF50 JUMP JUMPDEST PUSH2 0x448 DUP4 DUP4 DUP4 PUSH2 0x798 JUMP JUMPDEST PUSH2 0x448 DUP4 DUP4 DUP4 PUSH1 0x40 MLOAD DUP1 PUSH1 0x20 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 DUP2 MSTORE POP PUSH2 0x59D JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP1 PUSH2 0x274 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x18 PUSH1 0x24 DUP3 ADD MSTORE PUSH24 0x115490CDCC8C4E881A5B9D985B1A59081D1BDAD95B881251 PUSH1 0x42 SHL PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3A7 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND PUSH2 0x563 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x29 PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A2061646472657373207A65726F206973206E6F742061207661 PUSH1 0x44 DUP3 ADD MSTORE PUSH9 0x3634B21037BBB732B9 PUSH1 0xB9 SHL PUSH1 0x64 DUP3 ADD MSTORE PUSH1 0x84 ADD PUSH2 0x3A7 JUMP JUMPDEST POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x3 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x1 DUP1 SLOAD PUSH2 0x289 SWAP1 PUSH2 0xF16 JUMP JUMPDEST PUSH2 0x599 CALLER DUP4 DUP4 PUSH2 0x8FC JUMP JUMPDEST POP POP JUMP JUMPDEST PUSH2 0x5A7 CALLER DUP4 PUSH2 0x719 JUMP JUMPDEST PUSH2 0x5C3 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3A7 SWAP1 PUSH2 0xF50 JUMP JUMPDEST PUSH2 0x5CF DUP5 DUP5 DUP5 DUP5 PUSH2 0x9CA JUMP JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x60 PUSH2 0x5E0 DUP3 PUSH2 0x649 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x5F7 PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 DUP2 ADD SWAP1 SWAP2 MSTORE PUSH1 0x0 DUP2 MSTORE SWAP1 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 DUP2 MLOAD GT PUSH2 0x617 JUMPI PUSH1 0x40 MLOAD DUP1 PUSH1 0x20 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 DUP2 MSTORE POP PUSH2 0x642 JUMP JUMPDEST DUP1 PUSH2 0x621 DUP5 PUSH2 0x9FD JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0x632 SWAP3 SWAP2 SWAP1 PUSH2 0xF9D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH2 0x6A8 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x18 PUSH1 0x24 DUP3 ADD MSTORE PUSH24 0x115490CDCC8C4E881A5B9D985B1A59081D1BDAD95B881251 PUSH1 0x42 SHL PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3A7 JUMP JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x4 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 DUP1 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB NOT AND PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE DUP2 SWAP1 PUSH2 0x6E0 DUP3 PUSH2 0x499 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH32 0x8C5BE1E5EBEC7D5BD14F71427D1E84F3DD0314C0F7B2291E5B200AC8C7C3B925 PUSH1 0x40 MLOAD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG4 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH2 0x725 DUP4 PUSH2 0x499 JUMP JUMPDEST SWAP1 POP DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP5 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ DUP1 PUSH2 0x76C JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP1 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP9 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD PUSH1 0xFF AND JUMPDEST DUP1 PUSH2 0x790 JUMPI POP DUP4 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH2 0x785 DUP5 PUSH2 0x30C JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST DUP3 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH2 0x7AB DUP3 PUSH2 0x499 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ PUSH2 0x7D1 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3A7 SWAP1 PUSH2 0xFCC JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND PUSH2 0x833 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x24 DUP1 DUP3 ADD MSTORE PUSH32 0x4552433732313A207472616E7366657220746F20746865207A65726F20616464 PUSH1 0x44 DUP3 ADD MSTORE PUSH4 0x72657373 PUSH1 0xE0 SHL PUSH1 0x64 DUP3 ADD MSTORE PUSH1 0x84 ADD PUSH2 0x3A7 JUMP JUMPDEST DUP3 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH2 0x846 DUP3 PUSH2 0x499 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ PUSH2 0x86C JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3A7 SWAP1 PUSH2 0xFCC JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x4 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 DUP1 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB NOT SWAP1 DUP2 AND SWAP1 SWAP2 SSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP8 DUP2 AND DUP1 DUP7 MSTORE PUSH1 0x3 DUP6 MSTORE DUP4 DUP7 KECCAK256 DUP1 SLOAD PUSH1 0x0 NOT ADD SWAP1 SSTORE SWAP1 DUP8 AND DUP1 DUP7 MSTORE DUP4 DUP7 KECCAK256 DUP1 SLOAD PUSH1 0x1 ADD SWAP1 SSTORE DUP7 DUP7 MSTORE PUSH1 0x2 SWAP1 SWAP5 MSTORE DUP3 DUP6 KECCAK256 DUP1 SLOAD SWAP1 SWAP3 AND DUP5 OR SWAP1 SWAP2 SSTORE SWAP1 MLOAD DUP5 SWAP4 PUSH32 0xDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF SWAP2 LOG4 POP POP POP JUMP JUMPDEST DUP2 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP4 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SUB PUSH2 0x95D JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x19 PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A20617070726F766520746F2063616C6C657200000000000000 PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3A7 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 DUP2 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP5 DUP8 AND DUP1 DUP5 MSTORE SWAP5 DUP3 MSTORE SWAP2 DUP3 SWAP1 KECCAK256 DUP1 SLOAD PUSH1 0xFF NOT AND DUP7 ISZERO ISZERO SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE SWAP2 MLOAD SWAP2 DUP3 MSTORE PUSH32 0x17307EAB39AB6107E8899845AD3D59BD9653F200F220920489CA2B5937696C31 SWAP2 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 POP POP POP JUMP JUMPDEST PUSH2 0x9D5 DUP5 DUP5 DUP5 PUSH2 0x798 JUMP JUMPDEST PUSH2 0x9E1 DUP5 DUP5 DUP5 DUP5 PUSH2 0xA90 JUMP JUMPDEST PUSH2 0x5CF JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3A7 SWAP1 PUSH2 0x1011 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 PUSH2 0xA0A DUP4 PUSH2 0xB91 JUMP JUMPDEST PUSH1 0x1 ADD SWAP1 POP PUSH1 0x0 DUP2 PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xA2A JUMPI PUSH2 0xA2A PUSH2 0xDF1 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x1F ADD PUSH1 0x1F NOT AND PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xA54 JUMPI PUSH1 0x20 DUP3 ADD DUP2 DUP1 CALLDATASIZE DUP4 CALLDATACOPY ADD SWAP1 POP JUMPDEST POP SWAP1 POP DUP2 DUP2 ADD PUSH1 0x20 ADD JUMPDEST PUSH1 0x0 NOT ADD PUSH16 0x181899199A1A9B1B9C1CB0B131B232B3 PUSH1 0x81 SHL PUSH1 0xA DUP7 MOD BYTE DUP2 MSTORE8 PUSH1 0xA DUP6 DIV SWAP5 POP DUP5 PUSH2 0xA5E JUMPI POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND EXTCODESIZE ISZERO PUSH2 0xB86 JUMPI PUSH1 0x40 MLOAD PUSH4 0xA85BD01 PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP6 AND SWAP1 PUSH4 0x150B7A02 SWAP1 PUSH2 0xAD4 SWAP1 CALLER SWAP1 DUP10 SWAP1 DUP9 SWAP1 DUP9 SWAP1 PUSH1 0x4 ADD PUSH2 0x1063 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL SWAP3 POP POP POP DUP1 ISZERO PUSH2 0xB0F JUMPI POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x1F RETURNDATASIZE SWAP1 DUP2 ADD PUSH1 0x1F NOT AND DUP3 ADD SWAP1 SWAP3 MSTORE PUSH2 0xB0C SWAP2 DUP2 ADD SWAP1 PUSH2 0x10A0 JUMP JUMPDEST PUSH1 0x1 JUMPDEST PUSH2 0xB6C JUMPI RETURNDATASIZE DUP1 DUP1 ISZERO PUSH2 0xB3D JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0xB42 JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP DUP1 MLOAD PUSH1 0x0 SUB PUSH2 0xB64 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3A7 SWAP1 PUSH2 0x1011 JUMP JUMPDEST DUP1 MLOAD DUP2 PUSH1 0x20 ADD REVERT JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT AND PUSH4 0xA85BD01 PUSH1 0xE1 SHL EQ SWAP1 POP PUSH2 0x790 JUMP JUMPDEST POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH19 0x184F03E93FF9F4DAA797ED6E38ED64BF6A1F01 PUSH1 0x40 SHL DUP4 LT PUSH2 0xBD0 JUMPI PUSH19 0x184F03E93FF9F4DAA797ED6E38ED64BF6A1F01 PUSH1 0x40 SHL DUP4 DIV SWAP3 POP PUSH1 0x40 ADD JUMPDEST PUSH14 0x4EE2D6D415B85ACEF8100000000 DUP4 LT PUSH2 0xBFC JUMPI PUSH14 0x4EE2D6D415B85ACEF8100000000 DUP4 DIV SWAP3 POP PUSH1 0x20 ADD JUMPDEST PUSH7 0x2386F26FC10000 DUP4 LT PUSH2 0xC1A JUMPI PUSH7 0x2386F26FC10000 DUP4 DIV SWAP3 POP PUSH1 0x10 ADD JUMPDEST PUSH4 0x5F5E100 DUP4 LT PUSH2 0xC32 JUMPI PUSH4 0x5F5E100 DUP4 DIV SWAP3 POP PUSH1 0x8 ADD JUMPDEST PUSH2 0x2710 DUP4 LT PUSH2 0xC46 JUMPI PUSH2 0x2710 DUP4 DIV SWAP3 POP PUSH1 0x4 ADD JUMPDEST PUSH1 0x64 DUP4 LT PUSH2 0xC58 JUMPI PUSH1 0x64 DUP4 DIV SWAP3 POP PUSH1 0x2 ADD JUMPDEST PUSH1 0xA DUP4 LT PUSH2 0x274 JUMPI PUSH1 0x1 ADD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP2 AND DUP2 EQ PUSH2 0x6A8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xC91 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x642 DUP2 PUSH2 0xC69 JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0xCB7 JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0xC9F JUMP JUMPDEST POP POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD DUP1 DUP5 MSTORE PUSH2 0xCD8 DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0xC9C JUMP JUMPDEST PUSH1 0x1F ADD PUSH1 0x1F NOT AND SWAP3 SWAP1 SWAP3 ADD PUSH1 0x20 ADD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE PUSH1 0x0 PUSH2 0x642 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0xCC0 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xD11 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 CALLDATALOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0xD2F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xD47 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD50 DUP4 PUSH2 0xD18 JUMP JUMPDEST SWAP5 PUSH1 0x20 SWAP4 SWAP1 SWAP4 ADD CALLDATALOAD SWAP4 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xD73 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD7C DUP5 PUSH2 0xD18 JUMP JUMPDEST SWAP3 POP PUSH2 0xD8A PUSH1 0x20 DUP6 ADD PUSH2 0xD18 JUMP JUMPDEST SWAP2 POP PUSH1 0x40 DUP5 ADD CALLDATALOAD SWAP1 POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xDAC JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x642 DUP3 PUSH2 0xD18 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xDC8 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xDD1 DUP4 PUSH2 0xD18 JUMP JUMPDEST SWAP2 POP PUSH1 0x20 DUP4 ADD CALLDATALOAD DUP1 ISZERO ISZERO DUP2 EQ PUSH2 0xDE6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xE1D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xE26 DUP6 PUSH2 0xD18 JUMP JUMPDEST SWAP4 POP PUSH2 0xE34 PUSH1 0x20 DUP7 ADD PUSH2 0xD18 JUMP JUMPDEST SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD SWAP2 POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0xE58 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP8 ADD SWAP2 POP DUP8 PUSH1 0x1F DUP4 ADD SLT PUSH2 0xE6C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP2 DUP2 GT ISZERO PUSH2 0xE7E JUMPI PUSH2 0xE7E PUSH2 0xDF1 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT SWAP1 DUP2 AND PUSH1 0x3F ADD AND DUP2 ADD SWAP1 DUP4 DUP3 GT DUP2 DUP4 LT OR ISZERO PUSH2 0xEA6 JUMPI PUSH2 0xEA6 PUSH2 0xDF1 JUMP JUMPDEST DUP2 PUSH1 0x40 MSTORE DUP3 DUP2 MSTORE DUP11 PUSH1 0x20 DUP5 DUP8 ADD ADD GT ISZERO PUSH2 0xEBF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 PUSH1 0x20 DUP5 DUP4 ADD ADD MSTORE DUP1 SWAP6 POP POP POP POP POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xEF6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xEFF DUP4 PUSH2 0xD18 JUMP JUMPDEST SWAP2 POP PUSH2 0xF0D PUSH1 0x20 DUP5 ADD PUSH2 0xD18 JUMP JUMPDEST SWAP1 POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x1 DUP2 DUP2 SHR SWAP1 DUP3 AND DUP1 PUSH2 0xF2A JUMPI PUSH1 0x7F DUP3 AND SWAP2 POP JUMPDEST PUSH1 0x20 DUP3 LT DUP2 SUB PUSH2 0xF4A JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x22 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE PUSH1 0x2D SWAP1 DUP3 ADD MSTORE PUSH32 0x4552433732313A2063616C6C6572206973206E6F7420746F6B656E206F776E65 PUSH1 0x40 DUP3 ADD MSTORE PUSH13 0x1C881BDC88185C1C1C9BDD9959 PUSH1 0x9A SHL PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP4 MLOAD PUSH2 0xFAF DUP2 DUP5 PUSH1 0x20 DUP9 ADD PUSH2 0xC9C JUMP JUMPDEST DUP4 MLOAD SWAP1 DUP4 ADD SWAP1 PUSH2 0xFC3 DUP2 DUP4 PUSH1 0x20 DUP9 ADD PUSH2 0xC9C JUMP JUMPDEST ADD SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE PUSH1 0x25 SWAP1 DUP3 ADD MSTORE PUSH32 0x4552433732313A207472616E736665722066726F6D20696E636F727265637420 PUSH1 0x40 DUP3 ADD MSTORE PUSH5 0x37BBB732B9 PUSH1 0xD9 SHL PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE PUSH1 0x32 SWAP1 DUP3 ADD MSTORE PUSH32 0x4552433732313A207472616E7366657220746F206E6F6E204552433732315265 PUSH1 0x40 DUP3 ADD MSTORE PUSH18 0x31B2B4BB32B91034B6B83632B6B2B73A32B9 PUSH1 0x71 SHL PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP6 DUP2 AND DUP3 MSTORE DUP5 AND PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 DUP2 ADD DUP4 SWAP1 MSTORE PUSH1 0x80 PUSH1 0x60 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0x0 SWAP1 PUSH2 0x1096 SWAP1 DUP4 ADD DUP5 PUSH2 0xCC0 JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x10B2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x642 DUP2 PUSH2 0xC69 JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 JUMPI 0x2B STOP BYTE 0xF7 CALLDATACOPY 0xF9 0xD4 ORIGIN SUB MLOAD PUSH9 0x8C567BAF41BAF8D49 SIGNEXTEND 0xB5 PUSH20 0x90158191AAFEA9C264736F6C6343000811003300 ","sourceMap":"628:16377:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1570:300;;;;;;:::i;:::-;;:::i;:::-;;;565:14:17;;558:22;540:41;;528:2;513:18;1570:300:0;;;;;;;;2471:98;;;:::i;:::-;;;;;;;:::i;3935:167::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1697:32:17;;;1679:51;;1667:2;1652:18;3935:167:0;1533:203:17;3468:406:0;;;;;;:::i;:::-;;:::i;:::-;;4612:296;;;;;;:::i;:::-;;:::i;4974:149::-;;;;;;:::i;:::-;;:::i;2190:219::-;;;;;;:::i;:::-;;:::i;1929:204::-;;;;;;:::i;:::-;;:::i;:::-;;;2848:25:17;;;2836:2;2821:18;1929:204:0;2702:177:17;2633:102:0;;;:::i;4169:153::-;;;;;;:::i;:::-;;:::i;5189:276::-;;;;;;:::i;:::-;;:::i;2801:::-;;;;;;:::i;:::-;;:::i;4388:162::-;;;;;;:::i;:::-;-1:-1:-1;;;;;4508:25:0;;;4485:4;4508:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;4388:162;1570:300;1672:4;-1:-1:-1;;;;;;1707:40:0;;-1:-1:-1;;;1707:40:0;;:104;;-1:-1:-1;;;;;;;1763:48:0;;-1:-1:-1;;;1763:48:0;1707:104;:156;;;-1:-1:-1;;;;;;;;;;937:40:7;;;1827:36:0;1688:175;1570:300;-1:-1:-1;;1570:300:0:o;2471:98::-;2525:13;2557:5;2550:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2471:98;:::o;3935:167::-;4011:7;4030:23;4045:7;4030:14;:23::i;:::-;-1:-1:-1;4071:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;4071:24:0;;3935:167::o;3468:406::-;3548:13;3564:23;3579:7;3564:14;:23::i;:::-;3548:39;;3611:5;-1:-1:-1;;;;;3605:11:0;:2;-1:-1:-1;;;;;3605:11:0;;3597:57;;;;-1:-1:-1;;;3597:57:0;;5363:2:17;3597:57:0;;;5345:21:17;5402:2;5382:18;;;5375:30;5441:34;5421:18;;;5414:62;-1:-1:-1;;;5492:18:17;;;5485:31;5533:19;;3597:57:0;;;;;;;;;719:10:5;-1:-1:-1;;;;;3686:21:0;;;;:62;;-1:-1:-1;3711:37:0;3728:5;719:10:5;4388:162:0;:::i;3711:37::-;3665:170;;;;-1:-1:-1;;;3665:170:0;;5765:2:17;3665:170:0;;;5747:21:17;5804:2;5784:18;;;5777:30;5843:34;5823:18;;;5816:62;5914:31;5894:18;;;5887:59;5963:19;;3665:170:0;5563:425:17;3665:170:0;3846:21;3855:2;3859:7;3846:8;:21::i;:::-;3538:336;3468:406;;:::o;4612:296::-;4771:41;719:10:5;4804:7:0;4771:18;:41::i;:::-;4763:99;;;;-1:-1:-1;;;4763:99:0;;;;;;;:::i;:::-;4873:28;4883:4;4889:2;4893:7;4873:9;:28::i;4974:149::-;5077:39;5094:4;5100:2;5104:7;5077:39;;;;;;;;;;;;:16;:39::i;2190:219::-;2262:7;6794:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6794:16:0;;2324:56;;;;-1:-1:-1;;;2324:56:0;;6609:2:17;2324:56:0;;;6591:21:17;6648:2;6628:18;;;6621:30;-1:-1:-1;;;6667:18:17;;;6660:54;6731:18;;2324:56:0;6407:348:17;1929:204:0;2001:7;-1:-1:-1;;;;;2028:19:0;;2020:73;;;;-1:-1:-1;;;2020:73:0;;6962:2:17;2020:73:0;;;6944:21:17;7001:2;6981:18;;;6974:30;7040:34;7020:18;;;7013:62;-1:-1:-1;;;7091:18:17;;;7084:39;7140:19;;2020:73:0;6760:405:17;2020:73:0;-1:-1:-1;;;;;;2110:16:0;;;;;:9;:16;;;;;;;1929:204::o;2633:102::-;2689:13;2721:7;2714:14;;;;;:::i;4169:153::-;4263:52;719:10:5;4296:8:0;4306;4263:18;:52::i;:::-;4169:153;;:::o;5189:276::-;5319:41;719:10:5;5352:7:0;5319:18;:41::i;:::-;5311:99;;;;-1:-1:-1;;;5311:99:0;;;;;;;:::i;:::-;5420:38;5434:4;5440:2;5444:7;5453:4;5420:13;:38::i;:::-;5189:276;;;;:::o;2801:::-;2874:13;2899:23;2914:7;2899:14;:23::i;:::-;2933:21;2957:10;3395:9;;;;;;;;;-1:-1:-1;3395:9:0;;;3319:92;2957:10;2933:34;;3008:1;2990:7;2984:21;:25;:86;;;;;;;;;;;;;;;;;3036:7;3045:18;:7;:16;:18::i;:::-;3019:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;2984:86;2977:93;2801:276;-1:-1:-1;;;2801:276:0:o;13240:133::-;7185:4;6794:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6794:16:0;13313:53;;;;-1:-1:-1;;;13313:53:0;;6609:2:17;13313:53:0;;;6591:21:17;6648:2;6628:18;;;6621:30;-1:-1:-1;;;6667:18:17;;;6660:54;6731:18;;13313:53:0;6407:348:17;13313:53:0;13240:133;:::o;12572:171::-;12646:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;12646:29:0;-1:-1:-1;;;;;12646:29:0;;;;;;;;:24;;12699:23;12646:24;12699:14;:23::i;:::-;-1:-1:-1;;;;;12690:46:0;;;;;;;;;;;12572:171;;:::o;7404:261::-;7497:4;7513:13;7529:23;7544:7;7529:14;:23::i;:::-;7513:39;;7581:5;-1:-1:-1;;;;;7570:16:0;:7;-1:-1:-1;;;;;7570:16:0;;:52;;;-1:-1:-1;;;;;;4508:25:0;;;4485:4;4508:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;7590:32;7570:87;;;;7650:7;-1:-1:-1;;;;;7626:31:0;:20;7638:7;7626:11;:20::i;:::-;-1:-1:-1;;;;;7626:31:0;;7570:87;7562:96;7404:261;-1:-1:-1;;;;7404:261:0:o;11257:1203::-;11381:4;-1:-1:-1;;;;;11354:31:0;:23;11369:7;11354:14;:23::i;:::-;-1:-1:-1;;;;;11354:31:0;;11346:81;;;;-1:-1:-1;;;11346:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;11445:16:0;;11437:65;;;;-1:-1:-1;;;11437:65:0;;8279:2:17;11437:65:0;;;8261:21:17;8318:2;8298:18;;;8291:30;8357:34;8337:18;;;8330:62;-1:-1:-1;;;8408:18:17;;;8401:34;8452:19;;11437:65:0;8077:400:17;11437:65:0;11682:4;-1:-1:-1;;;;;11655:31:0;:23;11670:7;11655:14;:23::i;:::-;-1:-1:-1;;;;;11655:31:0;;11647:81;;;;-1:-1:-1;;;11647:81:0;;;;;;;:::i;:::-;11797:24;;;;:15;:24;;;;;;;;11790:31;;-1:-1:-1;;;;;;11790:31:0;;;;;;-1:-1:-1;;;;;12265:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;12265:20:0;;;12299:13;;;;;;;;;:18;;11790:31;12299:18;;;12337:16;;;:7;:16;;;;;;:21;;;;;;;;;;12374:27;;11813:7;;12374:27;;;3538:336;3468:406;;:::o;12879:277::-;12999:8;-1:-1:-1;;;;;12990:17:0;:5;-1:-1:-1;;;;;12990:17:0;;12982:55;;;;-1:-1:-1;;;12982:55:0;;8684:2:17;12982:55:0;;;8666:21:17;8723:2;8703:18;;;8696:30;8762:27;8742:18;;;8735:55;8807:18;;12982:55:0;8482:349:17;12982:55:0;-1:-1:-1;;;;;13047:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;13047:46:0;;;;;;;;;;13108:41;;540::17;;;13108::0;;513:18:17;13108:41:0;;;;;;;12879:277;;;:::o;6326:267::-;6438:28;6448:4;6454:2;6458:7;6438:9;:28::i;:::-;6484:47;6507:4;6513:2;6517:7;6526:4;6484:22;:47::i;:::-;6476:110;;;;-1:-1:-1;;;6476:110:0;;;;;;;:::i;447:696:6:-;503:13;552:14;569:17;580:5;569:10;:17::i;:::-;589:1;569:21;552:38;;604:20;638:6;627:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;627:18:6;-1:-1:-1;604:41:6;-1:-1:-1;765:28:6;;;781:2;765:28;820:280;-1:-1:-1;;851:5:6;-1:-1:-1;;;985:2:6;974:14;;969:30;851:5;956:44;1044:2;1035:11;;;-1:-1:-1;1064:21:6;820:280;1064:21;-1:-1:-1;1120:6:6;447:696;-1:-1:-1;;;447:696:6:o;13925:831:0:-;14074:4;-1:-1:-1;;;;;14094:13:0;;1702:19:4;:23;14090:660:0;;14129:71;;-1:-1:-1;;;14129:71:0;;-1:-1:-1;;;;;14129:36:0;;;;;:71;;719:10:5;;14180:4:0;;14186:7;;14195:4;;14129:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14129:71:0;;;;;;;;-1:-1:-1;;14129:71:0;;;;;;;;;;;;:::i;:::-;;;14125:573;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14367:6;:13;14384:1;14367:18;14363:321;;14409:60;;-1:-1:-1;;;14409:60:0;;;;;;;:::i;14363:321::-;14636:6;14630:13;14621:6;14617:2;14613:15;14606:38;14125:573;-1:-1:-1;;;;;;14250:51:0;-1:-1:-1;;;14250:51:0;;-1:-1:-1;14243:58:0;;14090:660;-1:-1:-1;14735:4:0;13925:831;;;;;;:::o;10139:916:9:-;10192:7;;-1:-1:-1;;;10267:17:9;;10263:103;;-1:-1:-1;;;10304:17:9;;;-1:-1:-1;10349:2:9;10339:12;10263:103;10392:8;10383:5;:17;10379:103;;10429:8;10420:17;;;-1:-1:-1;10465:2:9;10455:12;10379:103;10508:8;10499:5;:17;10495:103;;10545:8;10536:17;;;-1:-1:-1;10581:2:9;10571:12;10495:103;10624:7;10615:5;:16;10611:100;;10660:7;10651:16;;;-1:-1:-1;10695:1:9;10685:11;10611:100;10737:7;10728:5;:16;10724:100;;10773:7;10764:16;;;-1:-1:-1;10808:1:9;10798:11;10724:100;10850:7;10841:5;:16;10837:100;;10886:7;10877:16;;;-1:-1:-1;10921:1:9;10911:11;10837:100;10963:7;10954:5;:16;10950:66;;11000:1;10990:11;11042:6;10139:916;-1:-1:-1;;10139:916:9:o;14:131:17:-;-1:-1:-1;;;;;;88:32:17;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:250::-;677:1;687:113;701:6;698:1;695:13;687:113;;;777:11;;;771:18;758:11;;;751:39;723:2;716:10;687:113;;;-1:-1:-1;;834:1:17;816:16;;809:27;592:250::o;847:271::-;889:3;927:5;921:12;954:6;949:3;942:19;970:76;1039:6;1032:4;1027:3;1023:14;1016:4;1009:5;1005:16;970:76;:::i;:::-;1100:2;1079:15;-1:-1:-1;;1075:29:17;1066:39;;;;1107:4;1062:50;;847:271;-1:-1:-1;;847:271:17:o;1123:220::-;1272:2;1261:9;1254:21;1235:4;1292:45;1333:2;1322:9;1318:18;1310:6;1292:45;:::i;1348:180::-;1407:6;1460:2;1448:9;1439:7;1435:23;1431:32;1428:52;;;1476:1;1473;1466:12;1428:52;-1:-1:-1;1499:23:17;;1348:180;-1:-1:-1;1348:180:17:o;1741:173::-;1809:20;;-1:-1:-1;;;;;1858:31:17;;1848:42;;1838:70;;1904:1;1901;1894:12;1838:70;1741:173;;;:::o;1919:254::-;1987:6;1995;2048:2;2036:9;2027:7;2023:23;2019:32;2016:52;;;2064:1;2061;2054:12;2016:52;2087:29;2106:9;2087:29;:::i;:::-;2077:39;2163:2;2148:18;;;;2135:32;;-1:-1:-1;;;1919:254:17:o;2178:328::-;2255:6;2263;2271;2324:2;2312:9;2303:7;2299:23;2295:32;2292:52;;;2340:1;2337;2330:12;2292:52;2363:29;2382:9;2363:29;:::i;:::-;2353:39;;2411:38;2445:2;2434:9;2430:18;2411:38;:::i;:::-;2401:48;;2496:2;2485:9;2481:18;2468:32;2458:42;;2178:328;;;;;:::o;2511:186::-;2570:6;2623:2;2611:9;2602:7;2598:23;2594:32;2591:52;;;2639:1;2636;2629:12;2591:52;2662:29;2681:9;2662:29;:::i;2884:347::-;2949:6;2957;3010:2;2998:9;2989:7;2985:23;2981:32;2978:52;;;3026:1;3023;3016:12;2978:52;3049:29;3068:9;3049:29;:::i;:::-;3039:39;;3128:2;3117:9;3113:18;3100:32;3175:5;3168:13;3161:21;3154:5;3151:32;3141:60;;3197:1;3194;3187:12;3141:60;3220:5;3210:15;;;2884:347;;;;;:::o;3236:127::-;3297:10;3292:3;3288:20;3285:1;3278:31;3328:4;3325:1;3318:15;3352:4;3349:1;3342:15;3368:1138;3463:6;3471;3479;3487;3540:3;3528:9;3519:7;3515:23;3511:33;3508:53;;;3557:1;3554;3547:12;3508:53;3580:29;3599:9;3580:29;:::i;:::-;3570:39;;3628:38;3662:2;3651:9;3647:18;3628:38;:::i;:::-;3618:48;;3713:2;3702:9;3698:18;3685:32;3675:42;;3768:2;3757:9;3753:18;3740:32;3791:18;3832:2;3824:6;3821:14;3818:34;;;3848:1;3845;3838:12;3818:34;3886:6;3875:9;3871:22;3861:32;;3931:7;3924:4;3920:2;3916:13;3912:27;3902:55;;3953:1;3950;3943:12;3902:55;3989:2;3976:16;4011:2;4007;4004:10;4001:36;;;4017:18;;:::i;:::-;4092:2;4086:9;4060:2;4146:13;;-1:-1:-1;;4142:22:17;;;4166:2;4138:31;4134:40;4122:53;;;4190:18;;;4210:22;;;4187:46;4184:72;;;4236:18;;:::i;:::-;4276:10;4272:2;4265:22;4311:2;4303:6;4296:18;4351:7;4346:2;4341;4337;4333:11;4329:20;4326:33;4323:53;;;4372:1;4369;4362:12;4323:53;4428:2;4423;4419;4415:11;4410:2;4402:6;4398:15;4385:46;4473:1;4468:2;4463;4455:6;4451:15;4447:24;4440:35;4494:6;4484:16;;;;;;;3368:1138;;;;;;;:::o;4511:260::-;4579:6;4587;4640:2;4628:9;4619:7;4615:23;4611:32;4608:52;;;4656:1;4653;4646:12;4608:52;4679:29;4698:9;4679:29;:::i;:::-;4669:39;;4727:38;4761:2;4750:9;4746:18;4727:38;:::i;:::-;4717:48;;4511:260;;;;;:::o;4776:380::-;4855:1;4851:12;;;;4898;;;4919:61;;4973:4;4965:6;4961:17;4951:27;;4919:61;5026:2;5018:6;5015:14;4995:18;4992:38;4989:161;;5072:10;5067:3;5063:20;5060:1;5053:31;5107:4;5104:1;5097:15;5135:4;5132:1;5125:15;4989:161;;4776:380;;;:::o;5993:409::-;6195:2;6177:21;;;6234:2;6214:18;;;6207:30;6273:34;6268:2;6253:18;;6246:62;-1:-1:-1;;;6339:2:17;6324:18;;6317:43;6392:3;6377:19;;5993:409::o;7170:496::-;7349:3;7387:6;7381:13;7403:66;7462:6;7457:3;7450:4;7442:6;7438:17;7403:66;:::i;:::-;7532:13;;7491:16;;;;7554:70;7532:13;7491:16;7601:4;7589:17;;7554:70;:::i;:::-;7640:20;;7170:496;-1:-1:-1;;;;7170:496:17:o;7671:401::-;7873:2;7855:21;;;7912:2;7892:18;;;7885:30;7951:34;7946:2;7931:18;;7924:62;-1:-1:-1;;;8017:2:17;8002:18;;7995:35;8062:3;8047:19;;7671:401::o;8836:414::-;9038:2;9020:21;;;9077:2;9057:18;;;9050:30;9116:34;9111:2;9096:18;;9089:62;-1:-1:-1;;;9182:2:17;9167:18;;9160:48;9240:3;9225:19;;8836:414::o;9387:489::-;-1:-1:-1;;;;;9656:15:17;;;9638:34;;9708:15;;9703:2;9688:18;;9681:43;9755:2;9740:18;;9733:34;;;9803:3;9798:2;9783:18;;9776:31;;;9581:4;;9824:46;;9850:19;;9842:6;9824:46;:::i;:::-;9816:54;9387:489;-1:-1:-1;;;;;;9387:489:17:o;9881:249::-;9950:6;10003:2;9991:9;9982:7;9978:23;9974:32;9971:52;;;10019:1;10016;10009:12;9971:52;10051:9;10045:16;10070:30;10094:5;10070:30;:::i"},"gasEstimates":{"creation":{"codeDepositCost":"867800","executionCost":"infinite","totalCost":"infinite"},"external":{"approve(address,uint256)":"infinite","balanceOf(address)":"2634","getApproved(uint256)":"4769","isApprovedForAll(address,address)":"infinite","name()":"infinite","ownerOf(uint256)":"2561","safeTransferFrom(address,address,uint256)":"infinite","safeTransferFrom(address,address,uint256,bytes)":"infinite","setApprovalForAll(address,bool)":"26705","supportsInterface(bytes4)":"511","symbol()":"infinite","tokenURI(uint256)":"infinite","transferFrom(address,address,uint256)":"infinite"},"internal":{"__unsafe_increaseBalance(address,uint256)":"infinite","_afterTokenTransfer(address,address,uint256,uint256)":"infinite","_approve(address,uint256)":"infinite","_baseURI()":"infinite","_beforeTokenTransfer(address,address,uint256,uint256)":"infinite","_burn(uint256)":"infinite","_checkOnERC721Received(address,address,uint256,bytes memory)":"infinite","_exists(uint256)":"infinite","_isApprovedOrOwner(address,uint256)":"infinite","_mint(address,uint256)":"infinite","_ownerOf(uint256)":"infinite","_requireMinted(uint256)":"infinite","_safeMint(address,uint256)":"infinite","_safeMint(address,uint256,bytes memory)":"infinite","_safeTransfer(address,address,uint256,bytes memory)":"infinite","_setApprovalForAll(address,address,bool)":"infinite","_transfer(address,address,uint256)":"infinite"}},"methodIdentifiers":{"approve(address,uint256)":"095ea7b3","balanceOf(address)":"70a08231","getApproved(uint256)":"081812fc","isApprovedForAll(address,address)":"e985e9c5","name()":"06fdde03","ownerOf(uint256)":"6352211e","safeTransferFrom(address,address,uint256)":"42842e0e","safeTransferFrom(address,address,uint256,bytes)":"b88d4fde","setApprovalForAll(address,bool)":"a22cb465","supportsInterface(bytes4)":"01ffc9a7","symbol()":"95d89b41","tokenURI(uint256)":"c87b56dd","transferFrom(address,address,uint256)":"23b872dd"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including the Metadata extension, but not including the Enumerable extension, which is available separately as {ERC721Enumerable}.\",\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"details\":\"See {IERC721-approve}.\"},\"balanceOf(address)\":{\"details\":\"See {IERC721-balanceOf}.\"},\"constructor\":{\"details\":\"Initializes the contract by setting a `name` and a `symbol` to the token collection.\"},\"getApproved(uint256)\":{\"details\":\"See {IERC721-getApproved}.\"},\"isApprovedForAll(address,address)\":{\"details\":\"See {IERC721-isApprovedForAll}.\"},\"name()\":{\"details\":\"See {IERC721Metadata-name}.\"},\"ownerOf(uint256)\":{\"details\":\"See {IERC721-ownerOf}.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"See {IERC721-setApprovalForAll}.\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"symbol()\":{\"details\":\"See {IERC721Metadata-symbol}.\"},\"tokenURI(uint256)\":{\"details\":\"See {IERC721Metadata-tokenURI}.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-transferFrom}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":\"ERC721\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _ownerOf(tokenId);\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = 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 token owner or approved for all\\\"\\n );\\n\\n _approve(to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-getApproved}.\\n */\\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\\n _requireMinted(tokenId);\\n\\n return _tokenApprovals[tokenId];\\n }\\n\\n /**\\n * @dev See {IERC721-setApprovalForAll}.\\n */\\n function setApprovalForAll(address operator, bool approved) public virtual override {\\n _setApprovalForAll(_msgSender(), operator, approved);\\n }\\n\\n /**\\n * @dev See {IERC721-isApprovedForAll}.\\n */\\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\\n return _operatorApprovals[owner][operator];\\n }\\n\\n /**\\n * @dev See {IERC721-transferFrom}.\\n */\\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner or approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner or 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(address from, address to, uint256 tokenId, bytes memory data) 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 the owner of the `tokenId`. Does NOT revert if token doesn't exist\\n */\\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\\n return _owners[tokenId];\\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 _ownerOf(tokenId) != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(address to, uint256 tokenId, bytes memory data) 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, 1);\\n\\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\\n require(!_exists(tokenId), \\\"ERC721: token already minted\\\");\\n\\n unchecked {\\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\\n // Given that tokens are minted one by one, it is impossible in practice that\\n // this ever happens. Might change if we allow batch minting.\\n // The ERC fails to describe this case.\\n _balances[to] += 1;\\n }\\n\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId, 1);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n * This is an internal function that does not check if the sender is authorized to operate on the token.\\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, 1);\\n\\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\\n owner = ERC721.ownerOf(tokenId);\\n\\n // Clear approvals\\n delete _tokenApprovals[tokenId];\\n\\n unchecked {\\n // Cannot overflow, as that would require more tokens to be burned/transferred\\n // out than the owner initially received through minting and transferring in.\\n _balances[owner] -= 1;\\n }\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId, 1);\\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(address from, address to, uint256 tokenId) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId, 1);\\n\\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n\\n // Clear approvals from the previous owner\\n delete _tokenApprovals[tokenId];\\n\\n unchecked {\\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\\n // `from`'s balance is the number of token held, which is at least one before the current\\n // transfer.\\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\\n // all 2**256 token ids to be minted, which in practice is impossible.\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n }\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId, 1);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try 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 /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\\n * - When `from` is zero, the tokens will be minted for `to`.\\n * - When `to` is zero, ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n * - `batchSize` is non-zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\\n * - When `from` is zero, the tokens were minted for `to`.\\n * - When `to` is zero, ``from``'s tokens were burned.\\n * - `from` and `to` are never both zero.\\n * - `batchSize` is non-zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\\n\\n /**\\n * @dev Unsafe write access to the balances, used by extensions that \\\"mint\\\" tokens using an {ownerOf} override.\\n *\\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\\n * that `ownerOf(tokenId)` is `a`.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\\n _balances[account] += amount;\\n }\\n}\\n\",\"keccak256\":\"0x2c309e7df9e05e6ce15bedfe74f3c61b467fc37e0fae9eab496acf5ea0bbd7ff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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`.\\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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\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(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface 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 `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, \\\"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(address target, bytes memory data, uint256 value) 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 (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or 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 _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\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 unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\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] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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 enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\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 == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >= 10 ** 64) {\\n value /= 10 ** 64;\\n result += 64;\\n }\\n if (value >= 10 ** 32) {\\n value /= 10 ** 32;\\n result += 32;\\n }\\n if (value >= 10 ** 16) {\\n value /= 10 ** 16;\\n result += 16;\\n }\\n if (value >= 10 ** 8) {\\n value /= 10 ** 8;\\n result += 8;\\n }\\n if (value >= 10 ** 4) {\\n value /= 10 ** 4;\\n result += 4;\\n }\\n if (value >= 10 ** 2) {\\n value /= 10 ** 2;\\n result += 2;\\n }\\n if (value >= 10 ** 1) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log10(value);\\n return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[{"astId":25,"contract":"@openzeppelin/contracts/token/ERC721/ERC721.sol:ERC721","label":"_name","offset":0,"slot":"0","type":"t_string_storage"},{"astId":27,"contract":"@openzeppelin/contracts/token/ERC721/ERC721.sol:ERC721","label":"_symbol","offset":0,"slot":"1","type":"t_string_storage"},{"astId":31,"contract":"@openzeppelin/contracts/token/ERC721/ERC721.sol:ERC721","label":"_owners","offset":0,"slot":"2","type":"t_mapping(t_uint256,t_address)"},{"astId":35,"contract":"@openzeppelin/contracts/token/ERC721/ERC721.sol:ERC721","label":"_balances","offset":0,"slot":"3","type":"t_mapping(t_address,t_uint256)"},{"astId":39,"contract":"@openzeppelin/contracts/token/ERC721/ERC721.sol:ERC721","label":"_tokenApprovals","offset":0,"slot":"4","type":"t_mapping(t_uint256,t_address)"},{"astId":45,"contract":"@openzeppelin/contracts/token/ERC721/ERC721.sol:ERC721","label":"_operatorApprovals","offset":0,"slot":"5","type":"t_mapping(t_address,t_mapping(t_address,t_bool))"}],"types":{"t_address":{"encoding":"inplace","label":"address","numberOfBytes":"20"},"t_bool":{"encoding":"inplace","label":"bool","numberOfBytes":"1"},"t_mapping(t_address,t_bool)":{"encoding":"mapping","key":"t_address","label":"mapping(address => bool)","numberOfBytes":"32","value":"t_bool"},"t_mapping(t_address,t_mapping(t_address,t_bool))":{"encoding":"mapping","key":"t_address","label":"mapping(address => mapping(address => bool))","numberOfBytes":"32","value":"t_mapping(t_address,t_bool)"},"t_mapping(t_address,t_uint256)":{"encoding":"mapping","key":"t_address","label":"mapping(address => uint256)","numberOfBytes":"32","value":"t_uint256"},"t_mapping(t_uint256,t_address)":{"encoding":"mapping","key":"t_uint256","label":"mapping(uint256 => address)","numberOfBytes":"32","value":"t_address"},"t_string_storage":{"encoding":"bytes","label":"string","numberOfBytes":"32"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/token/ERC721/IERC721.sol":{"IERC721":{"abi":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"operator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"details":"Required interface of an ERC721 compliant contract.","events":{"Approval(address,address,uint256)":{"details":"Emitted when `owner` enables `approved` to manage the `tokenId` token."},"ApprovalForAll(address,address,bool)":{"details":"Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets."},"Transfer(address,address,uint256)":{"details":"Emitted when `tokenId` token is transferred from `from` to `to`."}},"kind":"dev","methods":{"approve(address,uint256)":{"details":"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event."},"balanceOf(address)":{"details":"Returns the number of tokens in ``owner``'s account."},"getApproved(uint256)":{"details":"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist."},"isApprovedForAll(address,address)":{"details":"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}"},"ownerOf(uint256)":{"details":"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist."},"safeTransferFrom(address,address,uint256)":{"details":"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event."},"safeTransferFrom(address,address,uint256,bytes)":{"details":"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event."},"setApprovalForAll(address,bool)":{"details":"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the caller. Emits an {ApprovalForAll} event."},"supportsInterface(bytes4)":{"details":"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas."},"transferFrom(address,address,uint256)":{"details":"Transfers `tokenId` token from `from` to `to`. WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event."}},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"approve(address,uint256)":"095ea7b3","balanceOf(address)":"70a08231","getApproved(uint256)":"081812fc","isApprovedForAll(address,address)":"e985e9c5","ownerOf(uint256)":"6352211e","safeTransferFrom(address,address,uint256)":"42842e0e","safeTransferFrom(address,address,uint256,bytes)":"b88d4fde","setApprovalForAll(address,bool)":"a22cb465","supportsInterface(bytes4)":"01ffc9a7","transferFrom(address,address,uint256)":"23b872dd"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Required interface of an ERC721 compliant contract.\",\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when `owner` enables `approved` to manage the `tokenId` token.\"},\"ApprovalForAll(address,address,bool)\":{\"details\":\"Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\"},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `tokenId` token is transferred from `from` to `to`.\"}},\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"details\":\"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event.\"},\"balanceOf(address)\":{\"details\":\"Returns the number of tokens in ``owner``'s account.\"},\"getApproved(uint256)\":{\"details\":\"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist.\"},\"isApprovedForAll(address,address)\":{\"details\":\"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}\"},\"ownerOf(uint256)\":{\"details\":\"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the caller. Emits an {ApprovalForAll} event.\"},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"Transfers `tokenId` token from `from` to `to`. WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":\"IERC721\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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`.\\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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\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(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol":{"IERC721Receiver":{"abi":[{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"details":"Interface for any contract that wants to support safeTransfers from ERC721 asset contracts.","kind":"dev","methods":{"onERC721Received(address,address,uint256,bytes)":{"details":"Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} by `operator` from `from`, this function is called. It must return its Solidity selector to confirm the token transfer. If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`."}},"title":"ERC721 token receiver interface","version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"onERC721Received(address,address,uint256,bytes)":"150b7a02"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onERC721Received\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Interface for any contract that wants to support safeTransfers from ERC721 asset contracts.\",\"kind\":\"dev\",\"methods\":{\"onERC721Received(address,address,uint256,bytes)\":{\"details\":\"Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} by `operator` from `from`, this function is called. It must return its Solidity selector to confirm the token transfer. If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\"}},\"title\":\"ERC721 token receiver interface\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":\"IERC721Receiver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface 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 `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol":{"IERC721Metadata":{"abi":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"operator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"details":"See https://eips.ethereum.org/EIPS/eip-721","kind":"dev","methods":{"approve(address,uint256)":{"details":"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event."},"balanceOf(address)":{"details":"Returns the number of tokens in ``owner``'s account."},"getApproved(uint256)":{"details":"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist."},"isApprovedForAll(address,address)":{"details":"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}"},"name()":{"details":"Returns the token collection name."},"ownerOf(uint256)":{"details":"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist."},"safeTransferFrom(address,address,uint256)":{"details":"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event."},"safeTransferFrom(address,address,uint256,bytes)":{"details":"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event."},"setApprovalForAll(address,bool)":{"details":"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the caller. Emits an {ApprovalForAll} event."},"supportsInterface(bytes4)":{"details":"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas."},"symbol()":{"details":"Returns the token collection symbol."},"tokenURI(uint256)":{"details":"Returns the Uniform Resource Identifier (URI) for `tokenId` token."},"transferFrom(address,address,uint256)":{"details":"Transfers `tokenId` token from `from` to `to`. WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event."}},"title":"ERC-721 Non-Fungible Token Standard, optional metadata extension","version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"approve(address,uint256)":"095ea7b3","balanceOf(address)":"70a08231","getApproved(uint256)":"081812fc","isApprovedForAll(address,address)":"e985e9c5","name()":"06fdde03","ownerOf(uint256)":"6352211e","safeTransferFrom(address,address,uint256)":"42842e0e","safeTransferFrom(address,address,uint256,bytes)":"b88d4fde","setApprovalForAll(address,bool)":"a22cb465","supportsInterface(bytes4)":"01ffc9a7","symbol()":"95d89b41","tokenURI(uint256)":"c87b56dd","transferFrom(address,address,uint256)":"23b872dd"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"See https://eips.ethereum.org/EIPS/eip-721\",\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"details\":\"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event.\"},\"balanceOf(address)\":{\"details\":\"Returns the number of tokens in ``owner``'s account.\"},\"getApproved(uint256)\":{\"details\":\"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist.\"},\"isApprovedForAll(address,address)\":{\"details\":\"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}\"},\"name()\":{\"details\":\"Returns the token collection name.\"},\"ownerOf(uint256)\":{\"details\":\"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the caller. Emits an {ApprovalForAll} event.\"},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"symbol()\":{\"details\":\"Returns the token collection symbol.\"},\"tokenURI(uint256)\":{\"details\":\"Returns the Uniform Resource Identifier (URI) for `tokenId` token.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"Transfers `tokenId` token from `from` to `to`. WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event.\"}},\"title\":\"ERC-721 Non-Fungible Token Standard, optional metadata extension\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":\"IERC721Metadata\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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`.\\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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\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(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/utils/Address.sol":{"Address":{"abi":[],"devdoc":{"details":"Collection of functions related to the address type","kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c2f66f9f178ece4a6dd98f884b5a0716b0971dd5e11c4840c20ebf4ae264a08a64736f6c63430008110033","opcodes":"PUSH1 0x56 PUSH1 0x37 PUSH1 0xB DUP3 DUP3 DUP3 CODECOPY DUP1 MLOAD PUSH1 0x0 BYTE PUSH1 0x73 EQ PUSH1 0x2A JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x0 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST ADDRESS PUSH1 0x0 MSTORE PUSH1 0x73 DUP2 MSTORE8 DUP3 DUP2 RETURN INVALID PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0xC2 0xF6 PUSH16 0x9F178ECE4A6DD98F884B5A0716B0971D 0xD5 0xE1 SHR BASEFEE BLOCKHASH 0xC2 0xE 0xBF 0x4A 0xE2 PUSH5 0xA08A64736F PUSH13 0x63430008110033000000000000 ","sourceMap":"194:9169:4:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;194:9169:4;;;;;;;;;;;;;;;;;"},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c2f66f9f178ece4a6dd98f884b5a0716b0971dd5e11c4840c20ebf4ae264a08a64736f6c63430008110033","opcodes":"PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0xC2 0xF6 PUSH16 0x9F178ECE4A6DD98F884B5A0716B0971D 0xD5 0xE1 SHR BASEFEE BLOCKHASH 0xC2 0xE 0xBF 0x4A 0xE2 PUSH5 0xA08A64736F PUSH13 0x63430008110033000000000000 ","sourceMap":"194:9169:4:-:0;;;;;;;;"},"gasEstimates":{"creation":{"codeDepositCost":"17200","executionCost":"103","totalCost":"17303"},"internal":{"_revert(bytes memory,string memory)":"infinite","functionCall(address,bytes memory)":"infinite","functionCall(address,bytes memory,string memory)":"infinite","functionCallWithValue(address,bytes memory,uint256)":"infinite","functionCallWithValue(address,bytes memory,uint256,string memory)":"infinite","functionDelegateCall(address,bytes memory)":"infinite","functionDelegateCall(address,bytes memory,string memory)":"infinite","functionStaticCall(address,bytes memory)":"infinite","functionStaticCall(address,bytes memory,string memory)":"infinite","isContract(address)":"infinite","sendValue(address payable,uint256)":"infinite","verifyCallResult(bool,bytes memory,string memory)":"infinite","verifyCallResultFromTarget(address,bool,bytes memory,string memory)":"infinite"}},"methodIdentifiers":{}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"Collection of functions related to the address type\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/utils/Address.sol\":\"Address\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, \\\"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(address target, bytes memory data, uint256 value) 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 (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or 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 _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/utils/Context.sol":{"Context":{"abi":[],"devdoc":{"details":"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.","kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/utils/Context.sol\":\"Context\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/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\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/utils/Strings.sol":{"Strings":{"abi":[],"devdoc":{"details":"String operations.","kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207228005f573e7589cb774d97bd31101840930508a97597061bccc052adec739964736f6c63430008110033","opcodes":"PUSH1 0x56 PUSH1 0x37 PUSH1 0xB DUP3 DUP3 DUP3 CODECOPY DUP1 MLOAD PUSH1 0x0 BYTE PUSH1 0x73 EQ PUSH1 0x2A JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x0 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST ADDRESS PUSH1 0x0 MSTORE PUSH1 0x73 DUP2 MSTORE8 DUP3 DUP2 RETURN INVALID PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 PUSH19 0x28005F573E7589CB774D97BD31101840930508 0xA9 PUSH22 0x97061BCCC052ADEC739964736F6C6343000811003300 ","sourceMap":"220:2559:6:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;220:2559:6;;;;;;;;;;;;;;;;;"},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207228005f573e7589cb774d97bd31101840930508a97597061bccc052adec739964736f6c63430008110033","opcodes":"PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 PUSH19 0x28005F573E7589CB774D97BD31101840930508 0xA9 PUSH22 0x97061BCCC052ADEC739964736F6C6343000811003300 ","sourceMap":"220:2559:6:-:0;;;;;;;;"},"gasEstimates":{"creation":{"codeDepositCost":"17200","executionCost":"103","totalCost":"17303"},"internal":{"equal(string memory,string memory)":"infinite","toHexString(address)":"infinite","toHexString(uint256)":"infinite","toHexString(uint256,uint256)":"infinite","toString(int256)":"infinite","toString(uint256)":"infinite"}},"methodIdentifiers":{}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"String operations.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/utils/Strings.sol\":\"Strings\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\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 unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\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] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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 enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\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 == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >= 10 ** 64) {\\n value /= 10 ** 64;\\n result += 64;\\n }\\n if (value >= 10 ** 32) {\\n value /= 10 ** 32;\\n result += 32;\\n }\\n if (value >= 10 ** 16) {\\n value /= 10 ** 16;\\n result += 16;\\n }\\n if (value >= 10 ** 8) {\\n value /= 10 ** 8;\\n result += 8;\\n }\\n if (value >= 10 ** 4) {\\n value /= 10 ** 4;\\n result += 4;\\n }\\n if (value >= 10 ** 2) {\\n value /= 10 ** 2;\\n result += 2;\\n }\\n if (value >= 10 ** 1) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log10(value);\\n return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/utils/introspection/ERC165.sol":{"ERC165":{"abi":[{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}],"devdoc":{"details":"Implementation of the {IERC165} interface. Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check for the additional interface id that will be supported. For example: ```solidity function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); } ``` Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.","kind":"dev","methods":{"supportsInterface(bytes4)":{"details":"See {IERC165-supportsInterface}."}},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"supportsInterface(bytes4)":"01ffc9a7"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Implementation of the {IERC165} interface. Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check for the additional interface id that will be supported. For example: ```solidity function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); } ``` Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\",\"kind\":\"dev\",\"methods\":{\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":\"ERC165\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/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\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/utils/introspection/IERC165.sol":{"IERC165":{"abi":[{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}],"devdoc":{"details":"Interface of the ERC165 standard, as defined in the https://eips.ethereum.org/EIPS/eip-165[EIP]. Implementers can declare support of contract interfaces, which can then be queried by others ({ERC165Checker}). For an implementation, see {ERC165}.","kind":"dev","methods":{"supportsInterface(bytes4)":{"details":"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas."}},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"supportsInterface(bytes4)":"01ffc9a7"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Interface of the ERC165 standard, as defined in the https://eips.ethereum.org/EIPS/eip-165[EIP]. Implementers can declare support of contract interfaces, which can then be queried by others ({ERC165Checker}). For an implementation, see {ERC165}.\",\"kind\":\"dev\",\"methods\":{\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":\"IERC165\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/utils/math/Math.sol":{"Math":{"abi":[],"devdoc":{"details":"Standard math utilities missing in the Solidity language.","kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212201de9e51b61992d4bc0178d54aa4499e531ca713ec14b54fe65ee03323d4b33a064736f6c63430008110033","opcodes":"PUSH1 0x56 PUSH1 0x37 PUSH1 0xB DUP3 DUP3 DUP3 CODECOPY DUP1 MLOAD PUSH1 0x0 BYTE PUSH1 0x73 EQ PUSH1 0x2A JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x0 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST ADDRESS PUSH1 0x0 MSTORE PUSH1 0x73 DUP2 MSTORE8 DUP3 DUP2 RETURN INVALID PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 SAR 0xE9 0xE5 SHL PUSH2 0x992D 0x4B 0xC0 OR DUP14 SLOAD 0xAA DIFFICULTY SWAP10 0xE5 BALANCE 0xCA PUSH18 0x3EC14B54FE65EE03323D4B33A064736F6C63 NUMBER STOP ADDMOD GT STOP CALLER ","sourceMap":"202:12582:9:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;202:12582:9;;;;;;;;;;;;;;;;;"},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212201de9e51b61992d4bc0178d54aa4499e531ca713ec14b54fe65ee03323d4b33a064736f6c63430008110033","opcodes":"PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 SAR 0xE9 0xE5 SHL PUSH2 0x992D 0x4B 0xC0 OR DUP14 SLOAD 0xAA DIFFICULTY SWAP10 0xE5 BALANCE 0xCA PUSH18 0x3EC14B54FE65EE03323D4B33A064736F6C63 NUMBER STOP ADDMOD GT STOP CALLER ","sourceMap":"202:12582:9:-:0;;;;;;;;"},"gasEstimates":{"creation":{"codeDepositCost":"17200","executionCost":"103","totalCost":"17303"},"internal":{"average(uint256,uint256)":"infinite","ceilDiv(uint256,uint256)":"infinite","log10(uint256)":"infinite","log10(uint256,enum Math.Rounding)":"infinite","log2(uint256)":"infinite","log2(uint256,enum Math.Rounding)":"infinite","log256(uint256)":"infinite","log256(uint256,enum Math.Rounding)":"infinite","max(uint256,uint256)":"infinite","min(uint256,uint256)":"infinite","mulDiv(uint256,uint256,uint256)":"infinite","mulDiv(uint256,uint256,uint256,enum Math.Rounding)":"infinite","sqrt(uint256)":"infinite","sqrt(uint256,enum Math.Rounding)":"infinite"}},"methodIdentifiers":{}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"Standard math utilities missing in the Solidity language.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/utils/math/Math.sol\":\"Math\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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 enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\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 == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >= 10 ** 64) {\\n value /= 10 ** 64;\\n result += 64;\\n }\\n if (value >= 10 ** 32) {\\n value /= 10 ** 32;\\n result += 32;\\n }\\n if (value >= 10 ** 16) {\\n value /= 10 ** 16;\\n result += 16;\\n }\\n if (value >= 10 ** 8) {\\n value /= 10 ** 8;\\n result += 8;\\n }\\n if (value >= 10 ** 4) {\\n value /= 10 ** 4;\\n result += 4;\\n }\\n if (value >= 10 ** 2) {\\n value /= 10 ** 2;\\n result += 2;\\n }\\n if (value >= 10 ** 1) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log10(value);\\n return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"@openzeppelin/contracts/utils/math/SignedMath.sol":{"SignedMath":{"abi":[],"devdoc":{"details":"Standard signed math utilities missing in the Solidity language.","kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208d3d0f2f473dd5525584eea797d24f2cc2a25b02da4b2a4e93effba473dba0d064736f6c63430008110033","opcodes":"PUSH1 0x56 PUSH1 0x37 PUSH1 0xB DUP3 DUP3 DUP3 CODECOPY DUP1 MLOAD PUSH1 0x0 BYTE PUSH1 0x73 EQ PUSH1 0x2A JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x0 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST ADDRESS PUSH1 0x0 MSTORE PUSH1 0x73 DUP2 MSTORE8 DUP3 DUP2 RETURN INVALID PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 DUP14 RETURNDATASIZE 0xF 0x2F SELFBALANCE RETURNDATASIZE 0xD5 MSTORE SSTORE DUP5 0xEE 0xA7 SWAP8 0xD2 0x4F 0x2C 0xC2 LOG2 JUMPDEST MUL 0xDA 0x4B 0x2A 0x4E SWAP4 0xEF 0xFB LOG4 PUSH20 0xDBA0D064736F6C63430008110033000000000000 ","sourceMap":"215:1047:10:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;215:1047:10;;;;;;;;;;;;;;;;;"},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208d3d0f2f473dd5525584eea797d24f2cc2a25b02da4b2a4e93effba473dba0d064736f6c63430008110033","opcodes":"PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 DUP14 RETURNDATASIZE 0xF 0x2F SELFBALANCE RETURNDATASIZE 0xD5 MSTORE SSTORE DUP5 0xEE 0xA7 SWAP8 0xD2 0x4F 0x2C 0xC2 LOG2 JUMPDEST MUL 0xDA 0x4B 0x2A 0x4E SWAP4 0xEF 0xFB LOG4 PUSH20 0xDBA0D064736F6C63430008110033000000000000 ","sourceMap":"215:1047:10:-:0;;;;;;;;"},"gasEstimates":{"creation":{"codeDepositCost":"17200","executionCost":"103","totalCost":"17303"},"internal":{"abs(int256)":"infinite","average(int256,int256)":"infinite","max(int256,int256)":"infinite","min(int256,int256)":"infinite"}},"methodIdentifiers":{}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"Standard signed math utilities missing in the Solidity language.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"@openzeppelin/contracts/utils/math/SignedMath.sol\":\"SignedMath\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/AccountRegistryBridge.sol":{"AccountRegistryBridge":{"abi":[{"inputs":[],"name":"IMPLMENTATION","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REGISTRY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"account","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"createAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"608060405234801561001057600080fd5b506102ad806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806306433b1b14610051578063192df655146100885780635fbfb9cf1461009b5780637fdfc7b2146100ae575b600080fd5b61006c7302101dfb77fde026414827fdc604ddaf224f092181565b6040516001600160a01b03909116815260200160405180910390f35b61006c61009636600461022e565b6100c9565b61006c6100a936600461022e565b61017d565b61006c732d25602551487c3f3354dd80d76d54383a24335881565b604051632f4de29b60e11b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b038316604482015260648101829052600060848201819052907302101dfb77fde026414827fdc604ddaf224f092190635e9bc5369060a401602060405180830381865afa158015610152573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610176919061025a565b9392505050565b60405163da7323b360e01b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b03831660448201526064810182905260006084820181905260c060a483015260c48201819052907302101dfb77fde026414827fdc604ddaf224f09219063da7323b39060e4016020604051808303816000875af1158015610152573d6000803e3d6000fd5b6001600160a01b038116811461022b57600080fd5b50565b6000806040838503121561024157600080fd5b823561024c81610216565b946020939093013593505050565b60006020828403121561026c57600080fd5b81516101768161021656fea2646970667358221220f72638b68db63c3c7b140a211fbc4be6ca1d9a152259dbe8d00d66564794b6e164736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x2AD DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x4C JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x6433B1B EQ PUSH2 0x51 JUMPI DUP1 PUSH4 0x192DF655 EQ PUSH2 0x88 JUMPI DUP1 PUSH4 0x5FBFB9CF EQ PUSH2 0x9B JUMPI DUP1 PUSH4 0x7FDFC7B2 EQ PUSH2 0xAE JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x6C PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x6C PUSH2 0x96 CALLDATASIZE PUSH1 0x4 PUSH2 0x22E JUMP JUMPDEST PUSH2 0xC9 JUMP JUMPDEST PUSH2 0x6C PUSH2 0xA9 CALLDATASIZE PUSH1 0x4 PUSH2 0x22E JUMP JUMPDEST PUSH2 0x17D JUMP JUMPDEST PUSH2 0x6C PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x2F4DE29B PUSH1 0xE1 SHL DUP2 MSTORE PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 PUSH1 0x4 DUP3 ADD MSTORE CHAINID PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 PUSH1 0x84 DUP3 ADD DUP2 SWAP1 MSTORE SWAP1 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 SWAP1 PUSH4 0x5E9BC536 SWAP1 PUSH1 0xA4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x152 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x176 SWAP2 SWAP1 PUSH2 0x25A JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0xDA7323B3 PUSH1 0xE0 SHL DUP2 MSTORE PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 PUSH1 0x4 DUP3 ADD MSTORE CHAINID PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 PUSH1 0x84 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0xC0 PUSH1 0xA4 DUP4 ADD MSTORE PUSH1 0xC4 DUP3 ADD DUP2 SWAP1 MSTORE SWAP1 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 SWAP1 PUSH4 0xDA7323B3 SWAP1 PUSH1 0xE4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x152 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0x22B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x241 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH2 0x24C DUP2 PUSH2 0x216 JUMP JUMPDEST SWAP5 PUSH1 0x20 SWAP4 SWAP1 SWAP4 ADD CALLDATALOAD SWAP4 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x26C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x176 DUP2 PUSH2 0x216 JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0xF7 0x26 CODESIZE 0xB6 DUP14 0xB6 EXTCODECOPY EXTCODECOPY PUSH28 0x140A211FBC4BE6CA1D9A152259DBE8D00D66564794B6E164736F6C63 NUMBER STOP ADDMOD GT STOP CALLER ","sourceMap":"96:831:11:-:0;;;;;;;;;;;;;;;;;;;"},"deployedBytecode":{"functionDebugData":{"@IMPLMENTATION_2684":{"entryPoint":null,"id":2684,"parameterSlots":0,"returnSlots":0},"@REGISTRY_2681":{"entryPoint":null,"id":2681,"parameterSlots":0,"returnSlots":0},"@account_2729":{"entryPoint":201,"id":2729,"parameterSlots":2,"returnSlots":1},"@createAccount_2707":{"entryPoint":381,"id":2707,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_address_fromMemory":{"entryPoint":602,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_addresst_uint256":{"entryPoint":558,"id":null,"parameterSlots":2,"returnSlots":2},"abi_encode_tuple_t_address__to_t_address__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1__to_t_address_t_uint256_t_address_t_uint256_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":6,"returnSlots":1},"abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470__to_t_address_t_uint256_t_address_t_uint256_t_uint256_t_bytes_memory_ptr__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":6,"returnSlots":1},"validator_revert_address":{"entryPoint":534,"id":null,"parameterSlots":1,"returnSlots":0}},"generatedSources":[{"ast":{"nodeType":"YulBlock","src":"0:2175:17","statements":[{"nodeType":"YulBlock","src":"6:3:17","statements":[]},{"body":{"nodeType":"YulBlock","src":"115:102:17","statements":[{"nodeType":"YulAssignment","src":"125:26:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"137:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"148:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"133:3:17"},"nodeType":"YulFunctionCall","src":"133:18:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"125:4:17"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"167:9:17"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"182:6:17"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"198:3:17","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"203:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"194:3:17"},"nodeType":"YulFunctionCall","src":"194:11:17"},{"kind":"number","nodeType":"YulLiteral","src":"207:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"190:3:17"},"nodeType":"YulFunctionCall","src":"190:19:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"178:3:17"},"nodeType":"YulFunctionCall","src":"178:32:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"160:6:17"},"nodeType":"YulFunctionCall","src":"160:51:17"},"nodeType":"YulExpressionStatement","src":"160:51:17"}]},"name":"abi_encode_tuple_t_address__to_t_address__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"84:9:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"95:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"106:4:17","type":""}],"src":"14:203:17"},{"body":{"nodeType":"YulBlock","src":"267:86:17","statements":[{"body":{"nodeType":"YulBlock","src":"331:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"340:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"343:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"333:6:17"},"nodeType":"YulFunctionCall","src":"333:12:17"},"nodeType":"YulExpressionStatement","src":"333:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"290:5:17"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"301:5:17"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"316:3:17","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"321:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"312:3:17"},"nodeType":"YulFunctionCall","src":"312:11:17"},{"kind":"number","nodeType":"YulLiteral","src":"325:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"308:3:17"},"nodeType":"YulFunctionCall","src":"308:19:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"297:3:17"},"nodeType":"YulFunctionCall","src":"297:31:17"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"287:2:17"},"nodeType":"YulFunctionCall","src":"287:42:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"280:6:17"},"nodeType":"YulFunctionCall","src":"280:50:17"},"nodeType":"YulIf","src":"277:70:17"}]},"name":"validator_revert_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"value","nodeType":"YulTypedName","src":"256:5:17","type":""}],"src":"222:131:17"},{"body":{"nodeType":"YulBlock","src":"445:228:17","statements":[{"body":{"nodeType":"YulBlock","src":"491:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"500:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"503:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"493:6:17"},"nodeType":"YulFunctionCall","src":"493:12:17"},"nodeType":"YulExpressionStatement","src":"493:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"466:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"475:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"462:3:17"},"nodeType":"YulFunctionCall","src":"462:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"487:2:17","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"458:3:17"},"nodeType":"YulFunctionCall","src":"458:32:17"},"nodeType":"YulIf","src":"455:52:17"},{"nodeType":"YulVariableDeclaration","src":"516:36:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"542:9:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"529:12:17"},"nodeType":"YulFunctionCall","src":"529:23:17"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"520:5:17","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"586:5:17"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"561:24:17"},"nodeType":"YulFunctionCall","src":"561:31:17"},"nodeType":"YulExpressionStatement","src":"561:31:17"},{"nodeType":"YulAssignment","src":"601:15:17","value":{"name":"value","nodeType":"YulIdentifier","src":"611:5:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"601:6:17"}]},{"nodeType":"YulAssignment","src":"625:42:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"652:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"663:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"648:3:17"},"nodeType":"YulFunctionCall","src":"648:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"635:12:17"},"nodeType":"YulFunctionCall","src":"635:32:17"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"625:6:17"}]}]},"name":"abi_decode_tuple_t_addresst_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"403:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"414:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"426:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"434:6:17","type":""}],"src":"358:315:17"},{"body":{"nodeType":"YulBlock","src":"899:306:17","statements":[{"nodeType":"YulAssignment","src":"909:27:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"921:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"932:3:17","type":"","value":"160"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"917:3:17"},"nodeType":"YulFunctionCall","src":"917:19:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"909:4:17"}]},{"nodeType":"YulVariableDeclaration","src":"945:29:17","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"963:3:17","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"968:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"959:3:17"},"nodeType":"YulFunctionCall","src":"959:11:17"},{"kind":"number","nodeType":"YulLiteral","src":"972:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"955:3:17"},"nodeType":"YulFunctionCall","src":"955:19:17"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"949:2:17","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"990:9:17"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"1005:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"1013:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1001:3:17"},"nodeType":"YulFunctionCall","src":"1001:15:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"983:6:17"},"nodeType":"YulFunctionCall","src":"983:34:17"},"nodeType":"YulExpressionStatement","src":"983:34:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1037:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1048:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1033:3:17"},"nodeType":"YulFunctionCall","src":"1033:18:17"},{"name":"value1","nodeType":"YulIdentifier","src":"1053:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1026:6:17"},"nodeType":"YulFunctionCall","src":"1026:34:17"},"nodeType":"YulExpressionStatement","src":"1026:34:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1080:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1091:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1076:3:17"},"nodeType":"YulFunctionCall","src":"1076:18:17"},{"arguments":[{"name":"value2","nodeType":"YulIdentifier","src":"1100:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"1108:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1096:3:17"},"nodeType":"YulFunctionCall","src":"1096:15:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1069:6:17"},"nodeType":"YulFunctionCall","src":"1069:43:17"},"nodeType":"YulExpressionStatement","src":"1069:43:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1132:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1143:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1128:3:17"},"nodeType":"YulFunctionCall","src":"1128:18:17"},{"name":"value3","nodeType":"YulIdentifier","src":"1148:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1121:6:17"},"nodeType":"YulFunctionCall","src":"1121:34:17"},"nodeType":"YulExpressionStatement","src":"1121:34:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1175:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1186:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1171:3:17"},"nodeType":"YulFunctionCall","src":"1171:19:17"},{"name":"value4","nodeType":"YulIdentifier","src":"1192:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1164:6:17"},"nodeType":"YulFunctionCall","src":"1164:35:17"},"nodeType":"YulExpressionStatement","src":"1164:35:17"}]},"name":"abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1__to_t_address_t_uint256_t_address_t_uint256_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"836:9:17","type":""},{"name":"value4","nodeType":"YulTypedName","src":"847:6:17","type":""},{"name":"value3","nodeType":"YulTypedName","src":"855:6:17","type":""},{"name":"value2","nodeType":"YulTypedName","src":"863:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"871:6:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"879:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"890:4:17","type":""}],"src":"678:527:17"},{"body":{"nodeType":"YulBlock","src":"1291:170:17","statements":[{"body":{"nodeType":"YulBlock","src":"1337:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1346:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1349:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1339:6:17"},"nodeType":"YulFunctionCall","src":"1339:12:17"},"nodeType":"YulExpressionStatement","src":"1339:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"1312:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"1321:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1308:3:17"},"nodeType":"YulFunctionCall","src":"1308:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"1333:2:17","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"1304:3:17"},"nodeType":"YulFunctionCall","src":"1304:32:17"},"nodeType":"YulIf","src":"1301:52:17"},{"nodeType":"YulVariableDeclaration","src":"1362:29:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1381:9:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"1375:5:17"},"nodeType":"YulFunctionCall","src":"1375:16:17"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"1366:5:17","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1425:5:17"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"1400:24:17"},"nodeType":"YulFunctionCall","src":"1400:31:17"},"nodeType":"YulExpressionStatement","src":"1400:31:17"},{"nodeType":"YulAssignment","src":"1440:15:17","value":{"name":"value","nodeType":"YulIdentifier","src":"1450:5:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"1440:6:17"}]}]},"name":"abi_decode_tuple_t_address_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"1257:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"1268:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"1280:6:17","type":""}],"src":"1210:251:17"},{"body":{"nodeType":"YulBlock","src":"1787:386:17","statements":[{"nodeType":"YulVariableDeclaration","src":"1797:29:17","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1815:3:17","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"1820:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1811:3:17"},"nodeType":"YulFunctionCall","src":"1811:11:17"},{"kind":"number","nodeType":"YulLiteral","src":"1824:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1807:3:17"},"nodeType":"YulFunctionCall","src":"1807:19:17"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"1801:2:17","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1842:9:17"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"1857:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"1865:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1853:3:17"},"nodeType":"YulFunctionCall","src":"1853:15:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1835:6:17"},"nodeType":"YulFunctionCall","src":"1835:34:17"},"nodeType":"YulExpressionStatement","src":"1835:34:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1889:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1900:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1885:3:17"},"nodeType":"YulFunctionCall","src":"1885:18:17"},{"name":"value1","nodeType":"YulIdentifier","src":"1905:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1878:6:17"},"nodeType":"YulFunctionCall","src":"1878:34:17"},"nodeType":"YulExpressionStatement","src":"1878:34:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1932:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1943:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1928:3:17"},"nodeType":"YulFunctionCall","src":"1928:18:17"},{"arguments":[{"name":"value2","nodeType":"YulIdentifier","src":"1952:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"1960:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1948:3:17"},"nodeType":"YulFunctionCall","src":"1948:15:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1921:6:17"},"nodeType":"YulFunctionCall","src":"1921:43:17"},"nodeType":"YulExpressionStatement","src":"1921:43:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1984:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1995:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1980:3:17"},"nodeType":"YulFunctionCall","src":"1980:18:17"},{"name":"value3","nodeType":"YulIdentifier","src":"2000:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1973:6:17"},"nodeType":"YulFunctionCall","src":"1973:34:17"},"nodeType":"YulExpressionStatement","src":"1973:34:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2027:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"2038:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2023:3:17"},"nodeType":"YulFunctionCall","src":"2023:19:17"},{"name":"value4","nodeType":"YulIdentifier","src":"2044:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2016:6:17"},"nodeType":"YulFunctionCall","src":"2016:35:17"},"nodeType":"YulExpressionStatement","src":"2016:35:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2071:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"2082:3:17","type":"","value":"160"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2067:3:17"},"nodeType":"YulFunctionCall","src":"2067:19:17"},{"kind":"number","nodeType":"YulLiteral","src":"2088:3:17","type":"","value":"192"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2060:6:17"},"nodeType":"YulFunctionCall","src":"2060:32:17"},"nodeType":"YulExpressionStatement","src":"2060:32:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2112:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"2123:3:17","type":"","value":"192"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2108:3:17"},"nodeType":"YulFunctionCall","src":"2108:19:17"},{"kind":"number","nodeType":"YulLiteral","src":"2129:1:17","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2101:6:17"},"nodeType":"YulFunctionCall","src":"2101:30:17"},"nodeType":"YulExpressionStatement","src":"2101:30:17"},{"nodeType":"YulAssignment","src":"2140:27:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2152:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"2163:3:17","type":"","value":"224"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2148:3:17"},"nodeType":"YulFunctionCall","src":"2148:19:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"2140:4:17"}]}]},"name":"abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470__to_t_address_t_uint256_t_address_t_uint256_t_uint256_t_bytes_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"1724:9:17","type":""},{"name":"value4","nodeType":"YulTypedName","src":"1735:6:17","type":""},{"name":"value3","nodeType":"YulTypedName","src":"1743:6:17","type":""},{"name":"value2","nodeType":"YulTypedName","src":"1751:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"1759:6:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"1767:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"1778:4:17","type":""}],"src":"1466:707:17"}]},"contents":"{\n { }\n function abi_encode_tuple_t_address__to_t_address__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, sub(shl(160, 1), 1)))\n }\n function validator_revert_address(value)\n {\n if iszero(eq(value, and(value, sub(shl(160, 1), 1)))) { revert(0, 0) }\n }\n function abi_decode_tuple_t_addresst_uint256(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n value1 := calldataload(add(headStart, 32))\n }\n function abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1__to_t_address_t_uint256_t_address_t_uint256_t_uint256__fromStack_reversed(headStart, value4, value3, value2, value1, value0) -> tail\n {\n tail := add(headStart, 160)\n let _1 := sub(shl(160, 1), 1)\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), value1)\n mstore(add(headStart, 64), and(value2, _1))\n mstore(add(headStart, 96), value3)\n mstore(add(headStart, 128), value4)\n }\n function abi_decode_tuple_t_address_fromMemory(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := mload(headStart)\n validator_revert_address(value)\n value0 := value\n }\n function abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470__to_t_address_t_uint256_t_address_t_uint256_t_uint256_t_bytes_memory_ptr__fromStack_reversed(headStart, value4, value3, value2, value1, value0) -> tail\n {\n let _1 := sub(shl(160, 1), 1)\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), value1)\n mstore(add(headStart, 64), and(value2, _1))\n mstore(add(headStart, 96), value3)\n mstore(add(headStart, 128), value4)\n mstore(add(headStart, 160), 192)\n mstore(add(headStart, 192), 0)\n tail := add(headStart, 224)\n }\n}","id":17,"language":"Yul","name":"#utility.yul"}],"immutableReferences":{},"linkReferences":{},"object":"608060405234801561001057600080fd5b506004361061004c5760003560e01c806306433b1b14610051578063192df655146100885780635fbfb9cf1461009b5780637fdfc7b2146100ae575b600080fd5b61006c7302101dfb77fde026414827fdc604ddaf224f092181565b6040516001600160a01b03909116815260200160405180910390f35b61006c61009636600461022e565b6100c9565b61006c6100a936600461022e565b61017d565b61006c732d25602551487c3f3354dd80d76d54383a24335881565b604051632f4de29b60e11b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b038316604482015260648101829052600060848201819052907302101dfb77fde026414827fdc604ddaf224f092190635e9bc5369060a401602060405180830381865afa158015610152573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610176919061025a565b9392505050565b60405163da7323b360e01b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b03831660448201526064810182905260006084820181905260c060a483015260c48201819052907302101dfb77fde026414827fdc604ddaf224f09219063da7323b39060e4016020604051808303816000875af1158015610152573d6000803e3d6000fd5b6001600160a01b038116811461022b57600080fd5b50565b6000806040838503121561024157600080fd5b823561024c81610216565b946020939093013593505050565b60006020828403121561026c57600080fd5b81516101768161021656fea2646970667358221220f72638b68db63c3c7b140a211fbc4be6ca1d9a152259dbe8d00d66564794b6e164736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x4C JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x6433B1B EQ PUSH2 0x51 JUMPI DUP1 PUSH4 0x192DF655 EQ PUSH2 0x88 JUMPI DUP1 PUSH4 0x5FBFB9CF EQ PUSH2 0x9B JUMPI DUP1 PUSH4 0x7FDFC7B2 EQ PUSH2 0xAE JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x6C PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x6C PUSH2 0x96 CALLDATASIZE PUSH1 0x4 PUSH2 0x22E JUMP JUMPDEST PUSH2 0xC9 JUMP JUMPDEST PUSH2 0x6C PUSH2 0xA9 CALLDATASIZE PUSH1 0x4 PUSH2 0x22E JUMP JUMPDEST PUSH2 0x17D JUMP JUMPDEST PUSH2 0x6C PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x2F4DE29B PUSH1 0xE1 SHL DUP2 MSTORE PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 PUSH1 0x4 DUP3 ADD MSTORE CHAINID PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 PUSH1 0x84 DUP3 ADD DUP2 SWAP1 MSTORE SWAP1 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 SWAP1 PUSH4 0x5E9BC536 SWAP1 PUSH1 0xA4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x152 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x176 SWAP2 SWAP1 PUSH2 0x25A JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0xDA7323B3 PUSH1 0xE0 SHL DUP2 MSTORE PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 PUSH1 0x4 DUP3 ADD MSTORE CHAINID PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 PUSH1 0x84 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0xC0 PUSH1 0xA4 DUP4 ADD MSTORE PUSH1 0xC4 DUP3 ADD DUP2 SWAP1 MSTORE SWAP1 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 SWAP1 PUSH4 0xDA7323B3 SWAP1 PUSH1 0xE4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x152 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0x22B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x241 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH2 0x24C DUP2 PUSH2 0x216 JUMP JUMPDEST SWAP5 PUSH1 0x20 SWAP4 SWAP1 SWAP4 ADD CALLDATALOAD SWAP4 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x26C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x176 DUP2 PUSH2 0x216 JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0xF7 0x26 CODESIZE 0xB6 DUP14 0xB6 EXTCODECOPY EXTCODECOPY PUSH28 0x140A211FBC4BE6CA1D9A152259DBE8D00D66564794B6E164736F6C63 NUMBER STOP ADDMOD GT STOP CALLER ","sourceMap":"96:831:11:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;133:78;;169:42;133:78;;;;;-1:-1:-1;;;;;178:32:17;;;160:51;;148:2;133:18;:78:11;;;;;;;626:299;;;;;;:::i;:::-;;:::i;306:314::-;;;;;;:::i;:::-;;:::i;217:82::-;;257:42;217:82;;626:299;762:156;;-1:-1:-1;;;762:156:11;;257:42;762:156;;;983:34:17;830:13:11;1033:18:17;;;1026:34;-1:-1:-1;;;;;1096:15:17;;1076:18;;;1069:43;1128:18;;;1121:34;;;732:7:11;1171:19:17;;;1164:35;;;732:7:11;169:42;;762:27;;917:19:17;;762:156:11;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;755:163;626:299;-1:-1:-1;;;626:299:11:o;306:314::-;435:178;;-1:-1:-1;;;435:178:11;;257:42;435:178;;;1835:34:17;509:13:11;1885:18:17;;;1878:34;-1:-1:-1;;;;;1948:15:17;;1928:18;;;1921:43;1980:18;;;1973:34;;;405:7:11;2023:19:17;;;2016:35;;;2088:3;2067:19;;;2060:32;2108:19;;;2101:30;;;405:7:11;169:42;;435:33;;2148:19:17;;435:178:11;;;;;;;;;;;;;;;;;;;;;;;222:131:17;-1:-1:-1;;;;;297:31:17;;287:42;;277:70;;343:1;340;333:12;277:70;222:131;:::o;358:315::-;426:6;434;487:2;475:9;466:7;462:23;458:32;455:52;;;503:1;500;493:12;455:52;542:9;529:23;561:31;586:5;561:31;:::i;:::-;611:5;663:2;648:18;;;;635:32;;-1:-1:-1;;;358:315:17:o;1210:251::-;1280:6;1333:2;1321:9;1312:7;1308:23;1304:32;1301:52;;;1349:1;1346;1339:12;1301:52;1381:9;1375:16;1400:31;1425:5;1400:31;:::i"},"gasEstimates":{"creation":{"codeDepositCost":"137000","executionCost":"183","totalCost":"137183"},"external":{"IMPLMENTATION()":"248","REGISTRY()":"182","account(address,uint256)":"infinite","createAccount(address,uint256)":"infinite"}},"methodIdentifiers":{"IMPLMENTATION()":"7fdfc7b2","REGISTRY()":"06433b1b","account(address,uint256)":"192df655","createAccount(address,uint256)":"5fbfb9cf"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"IMPLMENTATION\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REGISTRY\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"account\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/AccountRegistryBridge.sol\":\"AccountRegistryBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/AccountRegistryBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.13;\\n\\nimport \\\"./interfaces/IRegistry.sol\\\";\\ncontract AccountRegistryBridge {\\n address public constant REGISTRY = \\t0x02101dfB77FDE026414827Fdc604ddAF224F0921;\\n address public constant IMPLMENTATION = 0x2D25602551487C3f3354dD80D76D54383A243358;\\n\\n function createAccount(address contractAddress, uint256 tokenId)\\n external\\n returns (address)\\n {\\n return IRegistry(REGISTRY).createAccount(\\n IMPLMENTATION,\\n block.chainid,\\n contractAddress,\\n tokenId,\\n 0,\\n ''\\n );\\n }\\n\\n function account(address contractAddress, uint256 tokenId)\\n external\\n view\\n returns (address)\\n {\\n return IRegistry(REGISTRY).account(\\n IMPLMENTATION,\\n block.chainid,\\n contractAddress,\\n tokenId,\\n 0\\n );\\n }\\n}\",\"keccak256\":\"0x4536af05c6fa43a3fd532415b4d39c190c35904aee16c48ea453a3b2baf976ea\",\"license\":\"MIT\"},\"contracts/interfaces/IRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\ninterface IRegistry {\\n function createAccount(\\n address implementation,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId,\\n uint256 salt,\\n bytes calldata initData\\n ) external returns (address);\\n\\n function account(\\n address implementation,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId,\\n uint256 salt\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xd24999d4d474bd349b1e2e5006eff215c5d9a64a481a9ebac3293f98603fbd27\",\"license\":\"UNLICENSED\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/ChargedParticles.sol":{"ChargedParticles":{"abi":[{"inputs":[],"name":"IMPLMENTATION","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REGISTRY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"account","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"basketManagerId","type":"string"},{"internalType":"address","name":"nftTokenAddress","type":"address"},{"internalType":"uint256","name":"nftTokenId","type":"uint256"},{"internalType":"uint256","name":"nftTokenAmount","type":"uint256"}],"name":"breakCovalentBond","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"basketManagerId","type":"string"},{"internalType":"address","name":"nftTokenAddress","type":"address"},{"internalType":"uint256","name":"nftTokenId","type":"uint256"},{"internalType":"uint256","name":"nftTokenAmount","type":"uint256"}],"name":"covalentBond","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"createAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"}],"name":"dischargeParticle","outputs":[{"internalType":"uint256","name":"creatorAmount","type":"uint256"},{"internalType":"uint256","name":"receiverAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"},{"internalType":"uint256","name":"assetAmount","type":"uint256"}],"name":"dischargeParticleAmount","outputs":[{"internalType":"uint256","name":"creatorAmount","type":"uint256"},{"internalType":"uint256","name":"receiverAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"},{"internalType":"uint256","name":"assetAmount","type":"uint256"}],"name":"dischargeParticleForCreator","outputs":[{"internalType":"uint256","name":"receiverAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"},{"internalType":"uint256","name":"assetAmount","type":"uint256"},{"internalType":"address","name":"referrer","type":"address"}],"name":"energizeParticle","outputs":[{"internalType":"uint256","name":"yieldTokensAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"}],"name":"releaseParticle","outputs":[{"internalType":"uint256","name":"creatorAmount","type":"uint256"},{"internalType":"uint256","name":"receiverAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"},{"internalType":"uint256","name":"assetAmount","type":"uint256"}],"name":"releaseParticleAmount","outputs":[{"internalType":"uint256","name":"creatorAmount","type":"uint256"},{"internalType":"uint256","name":"receiverAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"608060405234801561001057600080fd5b506107d1806100206000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c806365d20ce21161007157806365d20ce2146101945780636697b359146101a25780637fdfc7b2146101bf578063a8abef47146101a2578063acab923c14610163578063fe02fb00146101da57600080fd5b806306433b1b146100b95780630bdde2ca146100f1578063192df6551461011a5780633ff956cc1461012d5780635fbfb9cf14610150578063621a3b7014610163575b600080fd5b6100d47302101dfb77fde026414827fdc604ddaf224f092181565b6040516001600160a01b0390911681526020015b60405180910390f35b61010c6100ff366004610490565b6000979650505050505050565b6040519081526020016100e8565b6100d4610128366004610520565b6101f6565b61014061013b36600461054c565b6102aa565b60405190151581526020016100e8565b6100d461015e366004610520565b610396565b61017f6101713660046105d2565b600080965096945050505050565b604080519283526020830191909152016100e8565b61010c6100ff366004610657565b61017f6101b0366004610657565b60008097509795505050505050565b6100d4732d25602551487c3f3354dd80d76d54383a24335881565b6101406101e83660046106e7565b600098975050505050505050565b604051632f4de29b60e11b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b038316604482015260648101829052600060848201819052907302101dfb77fde026414827fdc604ddaf224f092190635e9bc5369060a401602060405180830381865afa15801561027f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102a3919061077e565b9392505050565b60405163192df65560e01b81526001600160a01b0388166004820152602481018790526000908190309063192df65590604401602060405180830381865afa1580156102fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061031e919061077e565b604051632142170760e11b81523360048201526001600160a01b03808316602483015260448201879052919250908616906342842e0e90606401600060405180830381600087803b15801561037257600080fd5b505af1158015610386573d6000803e3d6000fd5b5050505050979650505050505050565b60405163da7323b360e01b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b03831660448201526064810182905260006084820181905260c060a483015260c48201819052907302101dfb77fde026414827fdc604ddaf224f09219063da7323b39060e4016020604051808303816000875af115801561027f573d6000803e3d6000fd5b6001600160a01b038116811461044457600080fd5b50565b60008083601f84011261045957600080fd5b50813567ffffffffffffffff81111561047157600080fd5b60208301915083602082850101111561048957600080fd5b9250929050565b600080600080600080600060c0888a0312156104ab57600080fd5b87356104b68161042f565b965060208801359550604088013567ffffffffffffffff8111156104d957600080fd5b6104e58a828b01610447565b90965094505060608801356104f98161042f565b92506080880135915060a08801356105108161042f565b8091505092959891949750929550565b6000806040838503121561053357600080fd5b823561053e8161042f565b946020939093013593505050565b600080600080600080600060c0888a03121561056757600080fd5b87356105728161042f565b965060208801359550604088013567ffffffffffffffff81111561059557600080fd5b6105a18a828b01610447565b90965094505060608801356105b58161042f565b969995985093969295946080840135945060a09093013592915050565b60008060008060008060a087890312156105eb57600080fd5b86356105f68161042f565b955060208701356106068161042f565b945060408701359350606087013567ffffffffffffffff81111561062957600080fd5b61063589828a01610447565b90945092505060808701356106498161042f565b809150509295509295509295565b600080600080600080600060c0888a03121561067257600080fd5b873561067d8161042f565b9650602088013561068d8161042f565b955060408801359450606088013567ffffffffffffffff8111156106b057600080fd5b6106bc8a828b01610447565b90955093505060808801356106d08161042f565b8092505060a0880135905092959891949750929550565b60008060008060008060008060e0898b03121561070357600080fd5b883561070e8161042f565b9750602089013561071e8161042f565b965060408901359550606089013567ffffffffffffffff81111561074157600080fd5b61074d8b828c01610447565b90965094505060808901356107618161042f565b979a969950949793969295929450505060a08201359160c0013590565b60006020828403121561079057600080fd5b81516102a38161042f56fea2646970667358221220374814b7bbfe210c40d5ff478cf67868bd398bb69ad03fd0e65053cade67695d64736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x7D1 DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0xB4 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x65D20CE2 GT PUSH2 0x71 JUMPI DUP1 PUSH4 0x65D20CE2 EQ PUSH2 0x194 JUMPI DUP1 PUSH4 0x6697B359 EQ PUSH2 0x1A2 JUMPI DUP1 PUSH4 0x7FDFC7B2 EQ PUSH2 0x1BF JUMPI DUP1 PUSH4 0xA8ABEF47 EQ PUSH2 0x1A2 JUMPI DUP1 PUSH4 0xACAB923C EQ PUSH2 0x163 JUMPI DUP1 PUSH4 0xFE02FB00 EQ PUSH2 0x1DA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x6433B1B EQ PUSH2 0xB9 JUMPI DUP1 PUSH4 0xBDDE2CA EQ PUSH2 0xF1 JUMPI DUP1 PUSH4 0x192DF655 EQ PUSH2 0x11A JUMPI DUP1 PUSH4 0x3FF956CC EQ PUSH2 0x12D JUMPI DUP1 PUSH4 0x5FBFB9CF EQ PUSH2 0x150 JUMPI DUP1 PUSH4 0x621A3B70 EQ PUSH2 0x163 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD4 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x10C PUSH2 0xFF CALLDATASIZE PUSH1 0x4 PUSH2 0x490 JUMP JUMPDEST PUSH1 0x0 SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xE8 JUMP JUMPDEST PUSH2 0xD4 PUSH2 0x128 CALLDATASIZE PUSH1 0x4 PUSH2 0x520 JUMP JUMPDEST PUSH2 0x1F6 JUMP JUMPDEST PUSH2 0x140 PUSH2 0x13B CALLDATASIZE PUSH1 0x4 PUSH2 0x54C JUMP JUMPDEST PUSH2 0x2AA JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xE8 JUMP JUMPDEST PUSH2 0xD4 PUSH2 0x15E CALLDATASIZE PUSH1 0x4 PUSH2 0x520 JUMP JUMPDEST PUSH2 0x396 JUMP JUMPDEST PUSH2 0x17F PUSH2 0x171 CALLDATASIZE PUSH1 0x4 PUSH2 0x5D2 JUMP JUMPDEST PUSH1 0x0 DUP1 SWAP7 POP SWAP7 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP3 DUP4 MSTORE PUSH1 0x20 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE ADD PUSH2 0xE8 JUMP JUMPDEST PUSH2 0x10C PUSH2 0xFF CALLDATASIZE PUSH1 0x4 PUSH2 0x657 JUMP JUMPDEST PUSH2 0x17F PUSH2 0x1B0 CALLDATASIZE PUSH1 0x4 PUSH2 0x657 JUMP JUMPDEST PUSH1 0x0 DUP1 SWAP8 POP SWAP8 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH2 0xD4 PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 DUP2 JUMP JUMPDEST PUSH2 0x140 PUSH2 0x1E8 CALLDATASIZE PUSH1 0x4 PUSH2 0x6E7 JUMP JUMPDEST PUSH1 0x0 SWAP9 SWAP8 POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x2F4DE29B PUSH1 0xE1 SHL DUP2 MSTORE PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 PUSH1 0x4 DUP3 ADD MSTORE CHAINID PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 PUSH1 0x84 DUP3 ADD DUP2 SWAP1 MSTORE SWAP1 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 SWAP1 PUSH4 0x5E9BC536 SWAP1 PUSH1 0xA4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x27F JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x2A3 SWAP2 SWAP1 PUSH2 0x77E JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x192DF655 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP9 AND PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x24 DUP2 ADD DUP8 SWAP1 MSTORE PUSH1 0x0 SWAP1 DUP2 SWAP1 ADDRESS SWAP1 PUSH4 0x192DF655 SWAP1 PUSH1 0x44 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x2FA JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x31E SWAP2 SWAP1 PUSH2 0x77E JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x21421707 PUSH1 0xE1 SHL DUP2 MSTORE CALLER PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP1 DUP4 AND PUSH1 0x24 DUP4 ADD MSTORE PUSH1 0x44 DUP3 ADD DUP8 SWAP1 MSTORE SWAP2 SWAP3 POP SWAP1 DUP7 AND SWAP1 PUSH4 0x42842E0E SWAP1 PUSH1 0x64 ADD PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x372 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x386 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0xDA7323B3 PUSH1 0xE0 SHL DUP2 MSTORE PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 PUSH1 0x4 DUP3 ADD MSTORE CHAINID PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 PUSH1 0x84 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0xC0 PUSH1 0xA4 DUP4 ADD MSTORE PUSH1 0xC4 DUP3 ADD DUP2 SWAP1 MSTORE SWAP1 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 SWAP1 PUSH4 0xDA7323B3 SWAP1 PUSH1 0xE4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x27F JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0x444 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x459 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x471 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0x489 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xC0 DUP9 DUP11 SUB SLT ISZERO PUSH2 0x4AB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 CALLDATALOAD PUSH2 0x4B6 DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP7 POP PUSH1 0x20 DUP9 ADD CALLDATALOAD SWAP6 POP PUSH1 0x40 DUP9 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4D9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x4E5 DUP11 DUP3 DUP12 ADD PUSH2 0x447 JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP POP PUSH1 0x60 DUP9 ADD CALLDATALOAD PUSH2 0x4F9 DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP3 POP PUSH1 0x80 DUP9 ADD CALLDATALOAD SWAP2 POP PUSH1 0xA0 DUP9 ADD CALLDATALOAD PUSH2 0x510 DUP2 PUSH2 0x42F JUMP JUMPDEST DUP1 SWAP2 POP POP SWAP3 SWAP6 SWAP9 SWAP2 SWAP5 SWAP8 POP SWAP3 SWAP6 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x533 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH2 0x53E DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP5 PUSH1 0x20 SWAP4 SWAP1 SWAP4 ADD CALLDATALOAD SWAP4 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xC0 DUP9 DUP11 SUB SLT ISZERO PUSH2 0x567 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 CALLDATALOAD PUSH2 0x572 DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP7 POP PUSH1 0x20 DUP9 ADD CALLDATALOAD SWAP6 POP PUSH1 0x40 DUP9 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x595 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x5A1 DUP11 DUP3 DUP12 ADD PUSH2 0x447 JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP POP PUSH1 0x60 DUP9 ADD CALLDATALOAD PUSH2 0x5B5 DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP7 SWAP10 SWAP6 SWAP9 POP SWAP4 SWAP7 SWAP3 SWAP6 SWAP5 PUSH1 0x80 DUP5 ADD CALLDATALOAD SWAP5 POP PUSH1 0xA0 SWAP1 SWAP4 ADD CALLDATALOAD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0xA0 DUP8 DUP10 SUB SLT ISZERO PUSH2 0x5EB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP7 CALLDATALOAD PUSH2 0x5F6 DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP6 POP PUSH1 0x20 DUP8 ADD CALLDATALOAD PUSH2 0x606 DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP5 POP PUSH1 0x40 DUP8 ADD CALLDATALOAD SWAP4 POP PUSH1 0x60 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x629 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x635 DUP10 DUP3 DUP11 ADD PUSH2 0x447 JUMP JUMPDEST SWAP1 SWAP5 POP SWAP3 POP POP PUSH1 0x80 DUP8 ADD CALLDATALOAD PUSH2 0x649 DUP2 PUSH2 0x42F JUMP JUMPDEST DUP1 SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 POP SWAP3 SWAP6 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xC0 DUP9 DUP11 SUB SLT ISZERO PUSH2 0x672 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 CALLDATALOAD PUSH2 0x67D DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP7 POP PUSH1 0x20 DUP9 ADD CALLDATALOAD PUSH2 0x68D DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP6 POP PUSH1 0x40 DUP9 ADD CALLDATALOAD SWAP5 POP PUSH1 0x60 DUP9 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x6B0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x6BC DUP11 DUP3 DUP12 ADD PUSH2 0x447 JUMP JUMPDEST SWAP1 SWAP6 POP SWAP4 POP POP PUSH1 0x80 DUP9 ADD CALLDATALOAD PUSH2 0x6D0 DUP2 PUSH2 0x42F JUMP JUMPDEST DUP1 SWAP3 POP POP PUSH1 0xA0 DUP9 ADD CALLDATALOAD SWAP1 POP SWAP3 SWAP6 SWAP9 SWAP2 SWAP5 SWAP8 POP SWAP3 SWAP6 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0xE0 DUP10 DUP12 SUB SLT ISZERO PUSH2 0x703 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP9 CALLDATALOAD PUSH2 0x70E DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP8 POP PUSH1 0x20 DUP10 ADD CALLDATALOAD PUSH2 0x71E DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP7 POP PUSH1 0x40 DUP10 ADD CALLDATALOAD SWAP6 POP PUSH1 0x60 DUP10 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x741 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x74D DUP12 DUP3 DUP13 ADD PUSH2 0x447 JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP POP PUSH1 0x80 DUP10 ADD CALLDATALOAD PUSH2 0x761 DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP8 SWAP11 SWAP7 SWAP10 POP SWAP5 SWAP8 SWAP4 SWAP7 SWAP3 SWAP6 SWAP3 SWAP5 POP POP POP PUSH1 0xA0 DUP3 ADD CALLDATALOAD SWAP2 PUSH1 0xC0 ADD CALLDATALOAD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x790 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x2A3 DUP2 PUSH2 0x42F JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 CALLDATACOPY BASEFEE EQ 0xB7 0xBB INVALID 0x21 0xC BLOCKHASH 0xD5 SELFDESTRUCT SELFBALANCE DUP13 0xF6 PUSH25 0x68BD398BB69AD03FD0E65053CADE67695D64736F6C63430008 GT STOP CALLER ","sourceMap":"202:2475:12:-:0;;;;;;;;;;;;;;;;;;;"},"deployedBytecode":{"functionDebugData":{"@IMPLMENTATION_2684":{"entryPoint":null,"id":2684,"parameterSlots":0,"returnSlots":0},"@REGISTRY_2681":{"entryPoint":null,"id":2681,"parameterSlots":0,"returnSlots":0},"@account_2729":{"entryPoint":502,"id":2729,"parameterSlots":2,"returnSlots":1},"@breakCovalentBond_2905":{"entryPoint":null,"id":2905,"parameterSlots":8,"returnSlots":1},"@covalentBond_2885":{"entryPoint":682,"id":2885,"parameterSlots":7,"returnSlots":1},"@createAccount_2707":{"entryPoint":918,"id":2707,"parameterSlots":2,"returnSlots":1},"@dischargeParticleAmount_2793":{"entryPoint":null,"id":2793,"parameterSlots":7,"returnSlots":2},"@dischargeParticleForCreator_2811":{"entryPoint":null,"id":2811,"parameterSlots":7,"returnSlots":1},"@dischargeParticle_2773":{"entryPoint":null,"id":2773,"parameterSlots":6,"returnSlots":2},"@energizeParticle_2755":{"entryPoint":null,"id":2755,"parameterSlots":7,"returnSlots":1},"@releaseParticleAmount_2849":{"entryPoint":null,"id":2849,"parameterSlots":7,"returnSlots":2},"@releaseParticle_2829":{"entryPoint":null,"id":2829,"parameterSlots":6,"returnSlots":2},"abi_decode_string_calldata":{"entryPoint":1095,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_tuple_t_address_fromMemory":{"entryPoint":1918,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_addresst_addresst_uint256t_string_calldata_ptrt_address":{"entryPoint":1490,"id":null,"parameterSlots":2,"returnSlots":6},"abi_decode_tuple_t_addresst_addresst_uint256t_string_calldata_ptrt_addresst_uint256":{"entryPoint":1623,"id":null,"parameterSlots":2,"returnSlots":7},"abi_decode_tuple_t_addresst_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_uint256":{"entryPoint":1767,"id":null,"parameterSlots":2,"returnSlots":8},"abi_decode_tuple_t_addresst_uint256":{"entryPoint":1312,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_tuple_t_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_address":{"entryPoint":1168,"id":null,"parameterSlots":2,"returnSlots":7},"abi_decode_tuple_t_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_uint256":{"entryPoint":1356,"id":null,"parameterSlots":2,"returnSlots":7},"abi_encode_tuple_t_address__to_t_address__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_address_t_address_t_uint256__to_t_address_t_address_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":4,"returnSlots":1},"abi_encode_tuple_t_address_t_uint256__to_t_address_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":3,"returnSlots":1},"abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1__to_t_address_t_uint256_t_address_t_uint256_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":6,"returnSlots":1},"abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470__to_t_address_t_uint256_t_address_t_uint256_t_uint256_t_bytes_memory_ptr__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":6,"returnSlots":1},"abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_uint256_t_uint256__to_t_uint256_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":3,"returnSlots":1},"validator_revert_address":{"entryPoint":1071,"id":null,"parameterSlots":1,"returnSlots":0}},"generatedSources":[{"ast":{"nodeType":"YulBlock","src":"0:8601:17","statements":[{"nodeType":"YulBlock","src":"6:3:17","statements":[]},{"body":{"nodeType":"YulBlock","src":"115:102:17","statements":[{"nodeType":"YulAssignment","src":"125:26:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"137:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"148:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"133:3:17"},"nodeType":"YulFunctionCall","src":"133:18:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"125:4:17"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"167:9:17"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"182:6:17"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"198:3:17","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"203:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"194:3:17"},"nodeType":"YulFunctionCall","src":"194:11:17"},{"kind":"number","nodeType":"YulLiteral","src":"207:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"190:3:17"},"nodeType":"YulFunctionCall","src":"190:19:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"178:3:17"},"nodeType":"YulFunctionCall","src":"178:32:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"160:6:17"},"nodeType":"YulFunctionCall","src":"160:51:17"},"nodeType":"YulExpressionStatement","src":"160:51:17"}]},"name":"abi_encode_tuple_t_address__to_t_address__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"84:9:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"95:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"106:4:17","type":""}],"src":"14:203:17"},{"body":{"nodeType":"YulBlock","src":"267:86:17","statements":[{"body":{"nodeType":"YulBlock","src":"331:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"340:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"343:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"333:6:17"},"nodeType":"YulFunctionCall","src":"333:12:17"},"nodeType":"YulExpressionStatement","src":"333:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"290:5:17"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"301:5:17"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"316:3:17","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"321:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"312:3:17"},"nodeType":"YulFunctionCall","src":"312:11:17"},{"kind":"number","nodeType":"YulLiteral","src":"325:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"308:3:17"},"nodeType":"YulFunctionCall","src":"308:19:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"297:3:17"},"nodeType":"YulFunctionCall","src":"297:31:17"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"287:2:17"},"nodeType":"YulFunctionCall","src":"287:42:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"280:6:17"},"nodeType":"YulFunctionCall","src":"280:50:17"},"nodeType":"YulIf","src":"277:70:17"}]},"name":"validator_revert_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"value","nodeType":"YulTypedName","src":"256:5:17","type":""}],"src":"222:131:17"},{"body":{"nodeType":"YulBlock","src":"431:275:17","statements":[{"body":{"nodeType":"YulBlock","src":"480:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"489:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"492:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"482:6:17"},"nodeType":"YulFunctionCall","src":"482:12:17"},"nodeType":"YulExpressionStatement","src":"482:12:17"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"459:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"467:4:17","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"455:3:17"},"nodeType":"YulFunctionCall","src":"455:17:17"},{"name":"end","nodeType":"YulIdentifier","src":"474:3:17"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"451:3:17"},"nodeType":"YulFunctionCall","src":"451:27:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"444:6:17"},"nodeType":"YulFunctionCall","src":"444:35:17"},"nodeType":"YulIf","src":"441:55:17"},{"nodeType":"YulAssignment","src":"505:30:17","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"528:6:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"515:12:17"},"nodeType":"YulFunctionCall","src":"515:20:17"},"variableNames":[{"name":"length","nodeType":"YulIdentifier","src":"505:6:17"}]},{"body":{"nodeType":"YulBlock","src":"578:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"587:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"590:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"580:6:17"},"nodeType":"YulFunctionCall","src":"580:12:17"},"nodeType":"YulExpressionStatement","src":"580:12:17"}]},"condition":{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"550:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"558:18:17","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"547:2:17"},"nodeType":"YulFunctionCall","src":"547:30:17"},"nodeType":"YulIf","src":"544:50:17"},{"nodeType":"YulAssignment","src":"603:29:17","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"619:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"627:4:17","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"615:3:17"},"nodeType":"YulFunctionCall","src":"615:17:17"},"variableNames":[{"name":"arrayPos","nodeType":"YulIdentifier","src":"603:8:17"}]},{"body":{"nodeType":"YulBlock","src":"684:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"693:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"696:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"686:6:17"},"nodeType":"YulFunctionCall","src":"686:12:17"},"nodeType":"YulExpressionStatement","src":"686:12:17"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"655:6:17"},{"name":"length","nodeType":"YulIdentifier","src":"663:6:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"651:3:17"},"nodeType":"YulFunctionCall","src":"651:19:17"},{"kind":"number","nodeType":"YulLiteral","src":"672:4:17","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"647:3:17"},"nodeType":"YulFunctionCall","src":"647:30:17"},{"name":"end","nodeType":"YulIdentifier","src":"679:3:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"644:2:17"},"nodeType":"YulFunctionCall","src":"644:39:17"},"nodeType":"YulIf","src":"641:59:17"}]},"name":"abi_decode_string_calldata","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"394:6:17","type":""},{"name":"end","nodeType":"YulTypedName","src":"402:3:17","type":""}],"returnVariables":[{"name":"arrayPos","nodeType":"YulTypedName","src":"410:8:17","type":""},{"name":"length","nodeType":"YulTypedName","src":"420:6:17","type":""}],"src":"358:348:17"},{"body":{"nodeType":"YulBlock","src":"886:792:17","statements":[{"body":{"nodeType":"YulBlock","src":"933:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"942:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"945:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"935:6:17"},"nodeType":"YulFunctionCall","src":"935:12:17"},"nodeType":"YulExpressionStatement","src":"935:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"907:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"916:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"903:3:17"},"nodeType":"YulFunctionCall","src":"903:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"928:3:17","type":"","value":"192"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"899:3:17"},"nodeType":"YulFunctionCall","src":"899:33:17"},"nodeType":"YulIf","src":"896:53:17"},{"nodeType":"YulVariableDeclaration","src":"958:36:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"984:9:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"971:12:17"},"nodeType":"YulFunctionCall","src":"971:23:17"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"962:5:17","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1028:5:17"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"1003:24:17"},"nodeType":"YulFunctionCall","src":"1003:31:17"},"nodeType":"YulExpressionStatement","src":"1003:31:17"},{"nodeType":"YulAssignment","src":"1043:15:17","value":{"name":"value","nodeType":"YulIdentifier","src":"1053:5:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"1043:6:17"}]},{"nodeType":"YulAssignment","src":"1067:42:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1094:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1105:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1090:3:17"},"nodeType":"YulFunctionCall","src":"1090:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1077:12:17"},"nodeType":"YulFunctionCall","src":"1077:32:17"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"1067:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"1118:46:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1149:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1160:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1145:3:17"},"nodeType":"YulFunctionCall","src":"1145:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1132:12:17"},"nodeType":"YulFunctionCall","src":"1132:32:17"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"1122:6:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"1207:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1216:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1219:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1209:6:17"},"nodeType":"YulFunctionCall","src":"1209:12:17"},"nodeType":"YulExpressionStatement","src":"1209:12:17"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"1179:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"1187:18:17","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"1176:2:17"},"nodeType":"YulFunctionCall","src":"1176:30:17"},"nodeType":"YulIf","src":"1173:50:17"},{"nodeType":"YulVariableDeclaration","src":"1232:85:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1289:9:17"},{"name":"offset","nodeType":"YulIdentifier","src":"1300:6:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1285:3:17"},"nodeType":"YulFunctionCall","src":"1285:22:17"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"1309:7:17"}],"functionName":{"name":"abi_decode_string_calldata","nodeType":"YulIdentifier","src":"1258:26:17"},"nodeType":"YulFunctionCall","src":"1258:59:17"},"variables":[{"name":"value2_1","nodeType":"YulTypedName","src":"1236:8:17","type":""},{"name":"value3_1","nodeType":"YulTypedName","src":"1246:8:17","type":""}]},{"nodeType":"YulAssignment","src":"1326:18:17","value":{"name":"value2_1","nodeType":"YulIdentifier","src":"1336:8:17"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"1326:6:17"}]},{"nodeType":"YulAssignment","src":"1353:18:17","value":{"name":"value3_1","nodeType":"YulIdentifier","src":"1363:8:17"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"1353:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"1380:47:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1412:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1423:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1408:3:17"},"nodeType":"YulFunctionCall","src":"1408:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1395:12:17"},"nodeType":"YulFunctionCall","src":"1395:32:17"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"1384:7:17","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"1461:7:17"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"1436:24:17"},"nodeType":"YulFunctionCall","src":"1436:33:17"},"nodeType":"YulExpressionStatement","src":"1436:33:17"},{"nodeType":"YulAssignment","src":"1478:17:17","value":{"name":"value_1","nodeType":"YulIdentifier","src":"1488:7:17"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"1478:6:17"}]},{"nodeType":"YulAssignment","src":"1504:43:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1531:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1542:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1527:3:17"},"nodeType":"YulFunctionCall","src":"1527:19:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1514:12:17"},"nodeType":"YulFunctionCall","src":"1514:33:17"},"variableNames":[{"name":"value5","nodeType":"YulIdentifier","src":"1504:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"1556:48:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1588:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1599:3:17","type":"","value":"160"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1584:3:17"},"nodeType":"YulFunctionCall","src":"1584:19:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1571:12:17"},"nodeType":"YulFunctionCall","src":"1571:33:17"},"variables":[{"name":"value_2","nodeType":"YulTypedName","src":"1560:7:17","type":""}]},{"expression":{"arguments":[{"name":"value_2","nodeType":"YulIdentifier","src":"1638:7:17"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"1613:24:17"},"nodeType":"YulFunctionCall","src":"1613:33:17"},"nodeType":"YulExpressionStatement","src":"1613:33:17"},{"nodeType":"YulAssignment","src":"1655:17:17","value":{"name":"value_2","nodeType":"YulIdentifier","src":"1665:7:17"},"variableNames":[{"name":"value6","nodeType":"YulIdentifier","src":"1655:6:17"}]}]},"name":"abi_decode_tuple_t_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"804:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"815:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"827:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"835:6:17","type":""},{"name":"value2","nodeType":"YulTypedName","src":"843:6:17","type":""},{"name":"value3","nodeType":"YulTypedName","src":"851:6:17","type":""},{"name":"value4","nodeType":"YulTypedName","src":"859:6:17","type":""},{"name":"value5","nodeType":"YulTypedName","src":"867:6:17","type":""},{"name":"value6","nodeType":"YulTypedName","src":"875:6:17","type":""}],"src":"711:967:17"},{"body":{"nodeType":"YulBlock","src":"1784:76:17","statements":[{"nodeType":"YulAssignment","src":"1794:26:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1806:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1817:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1802:3:17"},"nodeType":"YulFunctionCall","src":"1802:18:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"1794:4:17"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1836:9:17"},{"name":"value0","nodeType":"YulIdentifier","src":"1847:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1829:6:17"},"nodeType":"YulFunctionCall","src":"1829:25:17"},"nodeType":"YulExpressionStatement","src":"1829:25:17"}]},"name":"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"1753:9:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"1764:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"1775:4:17","type":""}],"src":"1683:177:17"},{"body":{"nodeType":"YulBlock","src":"1952:228:17","statements":[{"body":{"nodeType":"YulBlock","src":"1998:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2007:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2010:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2000:6:17"},"nodeType":"YulFunctionCall","src":"2000:12:17"},"nodeType":"YulExpressionStatement","src":"2000:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"1973:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"1982:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1969:3:17"},"nodeType":"YulFunctionCall","src":"1969:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"1994:2:17","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"1965:3:17"},"nodeType":"YulFunctionCall","src":"1965:32:17"},"nodeType":"YulIf","src":"1962:52:17"},{"nodeType":"YulVariableDeclaration","src":"2023:36:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2049:9:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2036:12:17"},"nodeType":"YulFunctionCall","src":"2036:23:17"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"2027:5:17","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"2093:5:17"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"2068:24:17"},"nodeType":"YulFunctionCall","src":"2068:31:17"},"nodeType":"YulExpressionStatement","src":"2068:31:17"},{"nodeType":"YulAssignment","src":"2108:15:17","value":{"name":"value","nodeType":"YulIdentifier","src":"2118:5:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"2108:6:17"}]},{"nodeType":"YulAssignment","src":"2132:42:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2159:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"2170:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2155:3:17"},"nodeType":"YulFunctionCall","src":"2155:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2142:12:17"},"nodeType":"YulFunctionCall","src":"2142:32:17"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"2132:6:17"}]}]},"name":"abi_decode_tuple_t_addresst_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"1910:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"1921:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"1933:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"1941:6:17","type":""}],"src":"1865:315:17"},{"body":{"nodeType":"YulBlock","src":"2360:719:17","statements":[{"body":{"nodeType":"YulBlock","src":"2407:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2416:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2419:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2409:6:17"},"nodeType":"YulFunctionCall","src":"2409:12:17"},"nodeType":"YulExpressionStatement","src":"2409:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"2381:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"2390:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"2377:3:17"},"nodeType":"YulFunctionCall","src":"2377:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"2402:3:17","type":"","value":"192"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"2373:3:17"},"nodeType":"YulFunctionCall","src":"2373:33:17"},"nodeType":"YulIf","src":"2370:53:17"},{"nodeType":"YulVariableDeclaration","src":"2432:36:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2458:9:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2445:12:17"},"nodeType":"YulFunctionCall","src":"2445:23:17"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"2436:5:17","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"2502:5:17"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"2477:24:17"},"nodeType":"YulFunctionCall","src":"2477:31:17"},"nodeType":"YulExpressionStatement","src":"2477:31:17"},{"nodeType":"YulAssignment","src":"2517:15:17","value":{"name":"value","nodeType":"YulIdentifier","src":"2527:5:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"2517:6:17"}]},{"nodeType":"YulAssignment","src":"2541:42:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2568:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"2579:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2564:3:17"},"nodeType":"YulFunctionCall","src":"2564:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2551:12:17"},"nodeType":"YulFunctionCall","src":"2551:32:17"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"2541:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"2592:46:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2623:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"2634:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2619:3:17"},"nodeType":"YulFunctionCall","src":"2619:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2606:12:17"},"nodeType":"YulFunctionCall","src":"2606:32:17"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"2596:6:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"2681:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2690:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2693:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2683:6:17"},"nodeType":"YulFunctionCall","src":"2683:12:17"},"nodeType":"YulExpressionStatement","src":"2683:12:17"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"2653:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"2661:18:17","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2650:2:17"},"nodeType":"YulFunctionCall","src":"2650:30:17"},"nodeType":"YulIf","src":"2647:50:17"},{"nodeType":"YulVariableDeclaration","src":"2706:85:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2763:9:17"},{"name":"offset","nodeType":"YulIdentifier","src":"2774:6:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2759:3:17"},"nodeType":"YulFunctionCall","src":"2759:22:17"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"2783:7:17"}],"functionName":{"name":"abi_decode_string_calldata","nodeType":"YulIdentifier","src":"2732:26:17"},"nodeType":"YulFunctionCall","src":"2732:59:17"},"variables":[{"name":"value2_1","nodeType":"YulTypedName","src":"2710:8:17","type":""},{"name":"value3_1","nodeType":"YulTypedName","src":"2720:8:17","type":""}]},{"nodeType":"YulAssignment","src":"2800:18:17","value":{"name":"value2_1","nodeType":"YulIdentifier","src":"2810:8:17"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"2800:6:17"}]},{"nodeType":"YulAssignment","src":"2827:18:17","value":{"name":"value3_1","nodeType":"YulIdentifier","src":"2837:8:17"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"2827:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"2854:47:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2886:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"2897:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2882:3:17"},"nodeType":"YulFunctionCall","src":"2882:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2869:12:17"},"nodeType":"YulFunctionCall","src":"2869:32:17"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"2858:7:17","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"2935:7:17"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"2910:24:17"},"nodeType":"YulFunctionCall","src":"2910:33:17"},"nodeType":"YulExpressionStatement","src":"2910:33:17"},{"nodeType":"YulAssignment","src":"2952:17:17","value":{"name":"value_1","nodeType":"YulIdentifier","src":"2962:7:17"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"2952:6:17"}]},{"nodeType":"YulAssignment","src":"2978:43:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3005:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"3016:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3001:3:17"},"nodeType":"YulFunctionCall","src":"3001:19:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2988:12:17"},"nodeType":"YulFunctionCall","src":"2988:33:17"},"variableNames":[{"name":"value5","nodeType":"YulIdentifier","src":"2978:6:17"}]},{"nodeType":"YulAssignment","src":"3030:43:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3057:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"3068:3:17","type":"","value":"160"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3053:3:17"},"nodeType":"YulFunctionCall","src":"3053:19:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3040:12:17"},"nodeType":"YulFunctionCall","src":"3040:33:17"},"variableNames":[{"name":"value6","nodeType":"YulIdentifier","src":"3030:6:17"}]}]},"name":"abi_decode_tuple_t_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"2278:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"2289:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"2301:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"2309:6:17","type":""},{"name":"value2","nodeType":"YulTypedName","src":"2317:6:17","type":""},{"name":"value3","nodeType":"YulTypedName","src":"2325:6:17","type":""},{"name":"value4","nodeType":"YulTypedName","src":"2333:6:17","type":""},{"name":"value5","nodeType":"YulTypedName","src":"2341:6:17","type":""},{"name":"value6","nodeType":"YulTypedName","src":"2349:6:17","type":""}],"src":"2185:894:17"},{"body":{"nodeType":"YulBlock","src":"3179:92:17","statements":[{"nodeType":"YulAssignment","src":"3189:26:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3201:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"3212:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3197:3:17"},"nodeType":"YulFunctionCall","src":"3197:18:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"3189:4:17"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3231:9:17"},{"arguments":[{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"3256:6:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"3249:6:17"},"nodeType":"YulFunctionCall","src":"3249:14:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"3242:6:17"},"nodeType":"YulFunctionCall","src":"3242:22:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"3224:6:17"},"nodeType":"YulFunctionCall","src":"3224:41:17"},"nodeType":"YulExpressionStatement","src":"3224:41:17"}]},"name":"abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"3148:9:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"3159:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"3170:4:17","type":""}],"src":"3084:187:17"},{"body":{"nodeType":"YulBlock","src":"3434:740:17","statements":[{"body":{"nodeType":"YulBlock","src":"3481:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3490:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3493:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3483:6:17"},"nodeType":"YulFunctionCall","src":"3483:12:17"},"nodeType":"YulExpressionStatement","src":"3483:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"3455:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"3464:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"3451:3:17"},"nodeType":"YulFunctionCall","src":"3451:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"3476:3:17","type":"","value":"160"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"3447:3:17"},"nodeType":"YulFunctionCall","src":"3447:33:17"},"nodeType":"YulIf","src":"3444:53:17"},{"nodeType":"YulVariableDeclaration","src":"3506:36:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3532:9:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3519:12:17"},"nodeType":"YulFunctionCall","src":"3519:23:17"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"3510:5:17","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"3576:5:17"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"3551:24:17"},"nodeType":"YulFunctionCall","src":"3551:31:17"},"nodeType":"YulExpressionStatement","src":"3551:31:17"},{"nodeType":"YulAssignment","src":"3591:15:17","value":{"name":"value","nodeType":"YulIdentifier","src":"3601:5:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"3591:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"3615:47:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3647:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"3658:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3643:3:17"},"nodeType":"YulFunctionCall","src":"3643:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3630:12:17"},"nodeType":"YulFunctionCall","src":"3630:32:17"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"3619:7:17","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"3696:7:17"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"3671:24:17"},"nodeType":"YulFunctionCall","src":"3671:33:17"},"nodeType":"YulExpressionStatement","src":"3671:33:17"},{"nodeType":"YulAssignment","src":"3713:17:17","value":{"name":"value_1","nodeType":"YulIdentifier","src":"3723:7:17"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"3713:6:17"}]},{"nodeType":"YulAssignment","src":"3739:42:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3766:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"3777:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3762:3:17"},"nodeType":"YulFunctionCall","src":"3762:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3749:12:17"},"nodeType":"YulFunctionCall","src":"3749:32:17"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"3739:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"3790:46:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3821:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"3832:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3817:3:17"},"nodeType":"YulFunctionCall","src":"3817:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3804:12:17"},"nodeType":"YulFunctionCall","src":"3804:32:17"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"3794:6:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"3879:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3888:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3891:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3881:6:17"},"nodeType":"YulFunctionCall","src":"3881:12:17"},"nodeType":"YulExpressionStatement","src":"3881:12:17"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"3851:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"3859:18:17","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"3848:2:17"},"nodeType":"YulFunctionCall","src":"3848:30:17"},"nodeType":"YulIf","src":"3845:50:17"},{"nodeType":"YulVariableDeclaration","src":"3904:85:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3961:9:17"},{"name":"offset","nodeType":"YulIdentifier","src":"3972:6:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3957:3:17"},"nodeType":"YulFunctionCall","src":"3957:22:17"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"3981:7:17"}],"functionName":{"name":"abi_decode_string_calldata","nodeType":"YulIdentifier","src":"3930:26:17"},"nodeType":"YulFunctionCall","src":"3930:59:17"},"variables":[{"name":"value3_1","nodeType":"YulTypedName","src":"3908:8:17","type":""},{"name":"value4_1","nodeType":"YulTypedName","src":"3918:8:17","type":""}]},{"nodeType":"YulAssignment","src":"3998:18:17","value":{"name":"value3_1","nodeType":"YulIdentifier","src":"4008:8:17"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"3998:6:17"}]},{"nodeType":"YulAssignment","src":"4025:18:17","value":{"name":"value4_1","nodeType":"YulIdentifier","src":"4035:8:17"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"4025:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"4052:48:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4084:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"4095:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4080:3:17"},"nodeType":"YulFunctionCall","src":"4080:19:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4067:12:17"},"nodeType":"YulFunctionCall","src":"4067:33:17"},"variables":[{"name":"value_2","nodeType":"YulTypedName","src":"4056:7:17","type":""}]},{"expression":{"arguments":[{"name":"value_2","nodeType":"YulIdentifier","src":"4134:7:17"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"4109:24:17"},"nodeType":"YulFunctionCall","src":"4109:33:17"},"nodeType":"YulExpressionStatement","src":"4109:33:17"},{"nodeType":"YulAssignment","src":"4151:17:17","value":{"name":"value_2","nodeType":"YulIdentifier","src":"4161:7:17"},"variableNames":[{"name":"value5","nodeType":"YulIdentifier","src":"4151:6:17"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256t_string_calldata_ptrt_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"3360:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"3371:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"3383:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"3391:6:17","type":""},{"name":"value2","nodeType":"YulTypedName","src":"3399:6:17","type":""},{"name":"value3","nodeType":"YulTypedName","src":"3407:6:17","type":""},{"name":"value4","nodeType":"YulTypedName","src":"3415:6:17","type":""},{"name":"value5","nodeType":"YulTypedName","src":"3423:6:17","type":""}],"src":"3276:898:17"},{"body":{"nodeType":"YulBlock","src":"4308:119:17","statements":[{"nodeType":"YulAssignment","src":"4318:26:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4330:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"4341:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4326:3:17"},"nodeType":"YulFunctionCall","src":"4326:18:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"4318:4:17"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4360:9:17"},{"name":"value0","nodeType":"YulIdentifier","src":"4371:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"4353:6:17"},"nodeType":"YulFunctionCall","src":"4353:25:17"},"nodeType":"YulExpressionStatement","src":"4353:25:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4398:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"4409:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4394:3:17"},"nodeType":"YulFunctionCall","src":"4394:18:17"},{"name":"value1","nodeType":"YulIdentifier","src":"4414:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"4387:6:17"},"nodeType":"YulFunctionCall","src":"4387:34:17"},"nodeType":"YulExpressionStatement","src":"4387:34:17"}]},"name":"abi_encode_tuple_t_uint256_t_uint256__to_t_uint256_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"4269:9:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"4280:6:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"4288:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"4299:4:17","type":""}],"src":"4179:248:17"},{"body":{"nodeType":"YulBlock","src":"4607:792:17","statements":[{"body":{"nodeType":"YulBlock","src":"4654:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4663:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4666:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4656:6:17"},"nodeType":"YulFunctionCall","src":"4656:12:17"},"nodeType":"YulExpressionStatement","src":"4656:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"4628:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"4637:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"4624:3:17"},"nodeType":"YulFunctionCall","src":"4624:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"4649:3:17","type":"","value":"192"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"4620:3:17"},"nodeType":"YulFunctionCall","src":"4620:33:17"},"nodeType":"YulIf","src":"4617:53:17"},{"nodeType":"YulVariableDeclaration","src":"4679:36:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4705:9:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4692:12:17"},"nodeType":"YulFunctionCall","src":"4692:23:17"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"4683:5:17","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"4749:5:17"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"4724:24:17"},"nodeType":"YulFunctionCall","src":"4724:31:17"},"nodeType":"YulExpressionStatement","src":"4724:31:17"},{"nodeType":"YulAssignment","src":"4764:15:17","value":{"name":"value","nodeType":"YulIdentifier","src":"4774:5:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"4764:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"4788:47:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4820:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"4831:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4816:3:17"},"nodeType":"YulFunctionCall","src":"4816:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4803:12:17"},"nodeType":"YulFunctionCall","src":"4803:32:17"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"4792:7:17","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"4869:7:17"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"4844:24:17"},"nodeType":"YulFunctionCall","src":"4844:33:17"},"nodeType":"YulExpressionStatement","src":"4844:33:17"},{"nodeType":"YulAssignment","src":"4886:17:17","value":{"name":"value_1","nodeType":"YulIdentifier","src":"4896:7:17"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"4886:6:17"}]},{"nodeType":"YulAssignment","src":"4912:42:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4939:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"4950:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4935:3:17"},"nodeType":"YulFunctionCall","src":"4935:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4922:12:17"},"nodeType":"YulFunctionCall","src":"4922:32:17"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"4912:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"4963:46:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4994:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5005:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4990:3:17"},"nodeType":"YulFunctionCall","src":"4990:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"4977:12:17"},"nodeType":"YulFunctionCall","src":"4977:32:17"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"4967:6:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"5052:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5061:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"5064:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"5054:6:17"},"nodeType":"YulFunctionCall","src":"5054:12:17"},"nodeType":"YulExpressionStatement","src":"5054:12:17"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"5024:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"5032:18:17","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"5021:2:17"},"nodeType":"YulFunctionCall","src":"5021:30:17"},"nodeType":"YulIf","src":"5018:50:17"},{"nodeType":"YulVariableDeclaration","src":"5077:85:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5134:9:17"},{"name":"offset","nodeType":"YulIdentifier","src":"5145:6:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5130:3:17"},"nodeType":"YulFunctionCall","src":"5130:22:17"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"5154:7:17"}],"functionName":{"name":"abi_decode_string_calldata","nodeType":"YulIdentifier","src":"5103:26:17"},"nodeType":"YulFunctionCall","src":"5103:59:17"},"variables":[{"name":"value3_1","nodeType":"YulTypedName","src":"5081:8:17","type":""},{"name":"value4_1","nodeType":"YulTypedName","src":"5091:8:17","type":""}]},{"nodeType":"YulAssignment","src":"5171:18:17","value":{"name":"value3_1","nodeType":"YulIdentifier","src":"5181:8:17"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"5171:6:17"}]},{"nodeType":"YulAssignment","src":"5198:18:17","value":{"name":"value4_1","nodeType":"YulIdentifier","src":"5208:8:17"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"5198:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"5225:48:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5257:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5268:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5253:3:17"},"nodeType":"YulFunctionCall","src":"5253:19:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5240:12:17"},"nodeType":"YulFunctionCall","src":"5240:33:17"},"variables":[{"name":"value_2","nodeType":"YulTypedName","src":"5229:7:17","type":""}]},{"expression":{"arguments":[{"name":"value_2","nodeType":"YulIdentifier","src":"5307:7:17"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"5282:24:17"},"nodeType":"YulFunctionCall","src":"5282:33:17"},"nodeType":"YulExpressionStatement","src":"5282:33:17"},{"nodeType":"YulAssignment","src":"5324:17:17","value":{"name":"value_2","nodeType":"YulIdentifier","src":"5334:7:17"},"variableNames":[{"name":"value5","nodeType":"YulIdentifier","src":"5324:6:17"}]},{"nodeType":"YulAssignment","src":"5350:43:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5377:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5388:3:17","type":"","value":"160"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5373:3:17"},"nodeType":"YulFunctionCall","src":"5373:19:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5360:12:17"},"nodeType":"YulFunctionCall","src":"5360:33:17"},"variableNames":[{"name":"value6","nodeType":"YulIdentifier","src":"5350:6:17"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256t_string_calldata_ptrt_addresst_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"4525:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"4536:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"4548:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"4556:6:17","type":""},{"name":"value2","nodeType":"YulTypedName","src":"4564:6:17","type":""},{"name":"value3","nodeType":"YulTypedName","src":"4572:6:17","type":""},{"name":"value4","nodeType":"YulTypedName","src":"4580:6:17","type":""},{"name":"value5","nodeType":"YulTypedName","src":"4588:6:17","type":""},{"name":"value6","nodeType":"YulTypedName","src":"4596:6:17","type":""}],"src":"4432:967:17"},{"body":{"nodeType":"YulBlock","src":"5596:844:17","statements":[{"body":{"nodeType":"YulBlock","src":"5643:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5652:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"5655:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"5645:6:17"},"nodeType":"YulFunctionCall","src":"5645:12:17"},"nodeType":"YulExpressionStatement","src":"5645:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"5617:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"5626:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"5613:3:17"},"nodeType":"YulFunctionCall","src":"5613:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"5638:3:17","type":"","value":"224"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"5609:3:17"},"nodeType":"YulFunctionCall","src":"5609:33:17"},"nodeType":"YulIf","src":"5606:53:17"},{"nodeType":"YulVariableDeclaration","src":"5668:36:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5694:9:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5681:12:17"},"nodeType":"YulFunctionCall","src":"5681:23:17"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"5672:5:17","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"5738:5:17"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"5713:24:17"},"nodeType":"YulFunctionCall","src":"5713:31:17"},"nodeType":"YulExpressionStatement","src":"5713:31:17"},{"nodeType":"YulAssignment","src":"5753:15:17","value":{"name":"value","nodeType":"YulIdentifier","src":"5763:5:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"5753:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"5777:47:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5809:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5820:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5805:3:17"},"nodeType":"YulFunctionCall","src":"5805:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5792:12:17"},"nodeType":"YulFunctionCall","src":"5792:32:17"},"variables":[{"name":"value_1","nodeType":"YulTypedName","src":"5781:7:17","type":""}]},{"expression":{"arguments":[{"name":"value_1","nodeType":"YulIdentifier","src":"5858:7:17"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"5833:24:17"},"nodeType":"YulFunctionCall","src":"5833:33:17"},"nodeType":"YulExpressionStatement","src":"5833:33:17"},{"nodeType":"YulAssignment","src":"5875:17:17","value":{"name":"value_1","nodeType":"YulIdentifier","src":"5885:7:17"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"5875:6:17"}]},{"nodeType":"YulAssignment","src":"5901:42:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5928:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5939:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5924:3:17"},"nodeType":"YulFunctionCall","src":"5924:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5911:12:17"},"nodeType":"YulFunctionCall","src":"5911:32:17"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"5901:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"5952:46:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5983:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5994:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5979:3:17"},"nodeType":"YulFunctionCall","src":"5979:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"5966:12:17"},"nodeType":"YulFunctionCall","src":"5966:32:17"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"5956:6:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"6041:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6050:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"6053:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"6043:6:17"},"nodeType":"YulFunctionCall","src":"6043:12:17"},"nodeType":"YulExpressionStatement","src":"6043:12:17"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"6013:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"6021:18:17","type":"","value":"0xffffffffffffffff"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"6010:2:17"},"nodeType":"YulFunctionCall","src":"6010:30:17"},"nodeType":"YulIf","src":"6007:50:17"},{"nodeType":"YulVariableDeclaration","src":"6066:85:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6123:9:17"},{"name":"offset","nodeType":"YulIdentifier","src":"6134:6:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6119:3:17"},"nodeType":"YulFunctionCall","src":"6119:22:17"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"6143:7:17"}],"functionName":{"name":"abi_decode_string_calldata","nodeType":"YulIdentifier","src":"6092:26:17"},"nodeType":"YulFunctionCall","src":"6092:59:17"},"variables":[{"name":"value3_1","nodeType":"YulTypedName","src":"6070:8:17","type":""},{"name":"value4_1","nodeType":"YulTypedName","src":"6080:8:17","type":""}]},{"nodeType":"YulAssignment","src":"6160:18:17","value":{"name":"value3_1","nodeType":"YulIdentifier","src":"6170:8:17"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"6160:6:17"}]},{"nodeType":"YulAssignment","src":"6187:18:17","value":{"name":"value4_1","nodeType":"YulIdentifier","src":"6197:8:17"},"variableNames":[{"name":"value4","nodeType":"YulIdentifier","src":"6187:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"6214:48:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6246:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6257:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6242:3:17"},"nodeType":"YulFunctionCall","src":"6242:19:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6229:12:17"},"nodeType":"YulFunctionCall","src":"6229:33:17"},"variables":[{"name":"value_2","nodeType":"YulTypedName","src":"6218:7:17","type":""}]},{"expression":{"arguments":[{"name":"value_2","nodeType":"YulIdentifier","src":"6296:7:17"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"6271:24:17"},"nodeType":"YulFunctionCall","src":"6271:33:17"},"nodeType":"YulExpressionStatement","src":"6271:33:17"},{"nodeType":"YulAssignment","src":"6313:17:17","value":{"name":"value_2","nodeType":"YulIdentifier","src":"6323:7:17"},"variableNames":[{"name":"value5","nodeType":"YulIdentifier","src":"6313:6:17"}]},{"nodeType":"YulAssignment","src":"6339:43:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6366:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6377:3:17","type":"","value":"160"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6362:3:17"},"nodeType":"YulFunctionCall","src":"6362:19:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6349:12:17"},"nodeType":"YulFunctionCall","src":"6349:33:17"},"variableNames":[{"name":"value6","nodeType":"YulIdentifier","src":"6339:6:17"}]},{"nodeType":"YulAssignment","src":"6391:43:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6418:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6429:3:17","type":"","value":"192"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6414:3:17"},"nodeType":"YulFunctionCall","src":"6414:19:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"6401:12:17"},"nodeType":"YulFunctionCall","src":"6401:33:17"},"variableNames":[{"name":"value7","nodeType":"YulIdentifier","src":"6391:6:17"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"5506:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"5517:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"5529:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"5537:6:17","type":""},{"name":"value2","nodeType":"YulTypedName","src":"5545:6:17","type":""},{"name":"value3","nodeType":"YulTypedName","src":"5553:6:17","type":""},{"name":"value4","nodeType":"YulTypedName","src":"5561:6:17","type":""},{"name":"value5","nodeType":"YulTypedName","src":"5569:6:17","type":""},{"name":"value6","nodeType":"YulTypedName","src":"5577:6:17","type":""},{"name":"value7","nodeType":"YulTypedName","src":"5585:6:17","type":""}],"src":"5404:1036:17"},{"body":{"nodeType":"YulBlock","src":"6666:306:17","statements":[{"nodeType":"YulAssignment","src":"6676:27:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6688:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6699:3:17","type":"","value":"160"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6684:3:17"},"nodeType":"YulFunctionCall","src":"6684:19:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"6676:4:17"}]},{"nodeType":"YulVariableDeclaration","src":"6712:29:17","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"6730:3:17","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"6735:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"6726:3:17"},"nodeType":"YulFunctionCall","src":"6726:11:17"},{"kind":"number","nodeType":"YulLiteral","src":"6739:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"6722:3:17"},"nodeType":"YulFunctionCall","src":"6722:19:17"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"6716:2:17","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6757:9:17"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"6772:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"6780:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"6768:3:17"},"nodeType":"YulFunctionCall","src":"6768:15:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6750:6:17"},"nodeType":"YulFunctionCall","src":"6750:34:17"},"nodeType":"YulExpressionStatement","src":"6750:34:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6804:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6815:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6800:3:17"},"nodeType":"YulFunctionCall","src":"6800:18:17"},{"name":"value1","nodeType":"YulIdentifier","src":"6820:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6793:6:17"},"nodeType":"YulFunctionCall","src":"6793:34:17"},"nodeType":"YulExpressionStatement","src":"6793:34:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6847:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6858:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6843:3:17"},"nodeType":"YulFunctionCall","src":"6843:18:17"},{"arguments":[{"name":"value2","nodeType":"YulIdentifier","src":"6867:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"6875:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"6863:3:17"},"nodeType":"YulFunctionCall","src":"6863:15:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6836:6:17"},"nodeType":"YulFunctionCall","src":"6836:43:17"},"nodeType":"YulExpressionStatement","src":"6836:43:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6899:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6910:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6895:3:17"},"nodeType":"YulFunctionCall","src":"6895:18:17"},{"name":"value3","nodeType":"YulIdentifier","src":"6915:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6888:6:17"},"nodeType":"YulFunctionCall","src":"6888:34:17"},"nodeType":"YulExpressionStatement","src":"6888:34:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6942:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6953:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6938:3:17"},"nodeType":"YulFunctionCall","src":"6938:19:17"},{"name":"value4","nodeType":"YulIdentifier","src":"6959:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6931:6:17"},"nodeType":"YulFunctionCall","src":"6931:35:17"},"nodeType":"YulExpressionStatement","src":"6931:35:17"}]},"name":"abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1__to_t_address_t_uint256_t_address_t_uint256_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"6603:9:17","type":""},{"name":"value4","nodeType":"YulTypedName","src":"6614:6:17","type":""},{"name":"value3","nodeType":"YulTypedName","src":"6622:6:17","type":""},{"name":"value2","nodeType":"YulTypedName","src":"6630:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"6638:6:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"6646:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"6657:4:17","type":""}],"src":"6445:527:17"},{"body":{"nodeType":"YulBlock","src":"7058:170:17","statements":[{"body":{"nodeType":"YulBlock","src":"7104:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7113:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"7116:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"7106:6:17"},"nodeType":"YulFunctionCall","src":"7106:12:17"},"nodeType":"YulExpressionStatement","src":"7106:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"7079:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"7088:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"7075:3:17"},"nodeType":"YulFunctionCall","src":"7075:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"7100:2:17","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"7071:3:17"},"nodeType":"YulFunctionCall","src":"7071:32:17"},"nodeType":"YulIf","src":"7068:52:17"},{"nodeType":"YulVariableDeclaration","src":"7129:29:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7148:9:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"7142:5:17"},"nodeType":"YulFunctionCall","src":"7142:16:17"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"7133:5:17","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"7192:5:17"}],"functionName":{"name":"validator_revert_address","nodeType":"YulIdentifier","src":"7167:24:17"},"nodeType":"YulFunctionCall","src":"7167:31:17"},"nodeType":"YulExpressionStatement","src":"7167:31:17"},{"nodeType":"YulAssignment","src":"7207:15:17","value":{"name":"value","nodeType":"YulIdentifier","src":"7217:5:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"7207:6:17"}]}]},"name":"abi_decode_tuple_t_address_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"7024:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"7035:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"7047:6:17","type":""}],"src":"6977:251:17"},{"body":{"nodeType":"YulBlock","src":"7362:145:17","statements":[{"nodeType":"YulAssignment","src":"7372:26:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7384:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"7395:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7380:3:17"},"nodeType":"YulFunctionCall","src":"7380:18:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"7372:4:17"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7414:9:17"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"7429:6:17"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7445:3:17","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"7450:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"7441:3:17"},"nodeType":"YulFunctionCall","src":"7441:11:17"},{"kind":"number","nodeType":"YulLiteral","src":"7454:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"7437:3:17"},"nodeType":"YulFunctionCall","src":"7437:19:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"7425:3:17"},"nodeType":"YulFunctionCall","src":"7425:32:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7407:6:17"},"nodeType":"YulFunctionCall","src":"7407:51:17"},"nodeType":"YulExpressionStatement","src":"7407:51:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7478:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"7489:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7474:3:17"},"nodeType":"YulFunctionCall","src":"7474:18:17"},{"name":"value1","nodeType":"YulIdentifier","src":"7494:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7467:6:17"},"nodeType":"YulFunctionCall","src":"7467:34:17"},"nodeType":"YulExpressionStatement","src":"7467:34:17"}]},"name":"abi_encode_tuple_t_address_t_uint256__to_t_address_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"7323:9:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"7334:6:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"7342:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"7353:4:17","type":""}],"src":"7233:274:17"},{"body":{"nodeType":"YulBlock","src":"7669:218:17","statements":[{"nodeType":"YulAssignment","src":"7679:26:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7691:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"7702:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7687:3:17"},"nodeType":"YulFunctionCall","src":"7687:18:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"7679:4:17"}]},{"nodeType":"YulVariableDeclaration","src":"7714:29:17","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"7732:3:17","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"7737:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"7728:3:17"},"nodeType":"YulFunctionCall","src":"7728:11:17"},{"kind":"number","nodeType":"YulLiteral","src":"7741:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"7724:3:17"},"nodeType":"YulFunctionCall","src":"7724:19:17"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"7718:2:17","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7759:9:17"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"7774:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"7782:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"7770:3:17"},"nodeType":"YulFunctionCall","src":"7770:15:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7752:6:17"},"nodeType":"YulFunctionCall","src":"7752:34:17"},"nodeType":"YulExpressionStatement","src":"7752:34:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7806:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"7817:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7802:3:17"},"nodeType":"YulFunctionCall","src":"7802:18:17"},{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"7826:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"7834:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"7822:3:17"},"nodeType":"YulFunctionCall","src":"7822:15:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7795:6:17"},"nodeType":"YulFunctionCall","src":"7795:43:17"},"nodeType":"YulExpressionStatement","src":"7795:43:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7858:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"7869:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7854:3:17"},"nodeType":"YulFunctionCall","src":"7854:18:17"},{"name":"value2","nodeType":"YulIdentifier","src":"7874:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7847:6:17"},"nodeType":"YulFunctionCall","src":"7847:34:17"},"nodeType":"YulExpressionStatement","src":"7847:34:17"}]},"name":"abi_encode_tuple_t_address_t_address_t_uint256__to_t_address_t_address_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"7622:9:17","type":""},{"name":"value2","nodeType":"YulTypedName","src":"7633:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"7641:6:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"7649:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"7660:4:17","type":""}],"src":"7512:375:17"},{"body":{"nodeType":"YulBlock","src":"8213:386:17","statements":[{"nodeType":"YulVariableDeclaration","src":"8223:29:17","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"8241:3:17","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"8246:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"8237:3:17"},"nodeType":"YulFunctionCall","src":"8237:11:17"},{"kind":"number","nodeType":"YulLiteral","src":"8250:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"8233:3:17"},"nodeType":"YulFunctionCall","src":"8233:19:17"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"8227:2:17","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8268:9:17"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"8283:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"8291:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"8279:3:17"},"nodeType":"YulFunctionCall","src":"8279:15:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8261:6:17"},"nodeType":"YulFunctionCall","src":"8261:34:17"},"nodeType":"YulExpressionStatement","src":"8261:34:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8315:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8326:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8311:3:17"},"nodeType":"YulFunctionCall","src":"8311:18:17"},{"name":"value1","nodeType":"YulIdentifier","src":"8331:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8304:6:17"},"nodeType":"YulFunctionCall","src":"8304:34:17"},"nodeType":"YulExpressionStatement","src":"8304:34:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8358:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8369:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8354:3:17"},"nodeType":"YulFunctionCall","src":"8354:18:17"},{"arguments":[{"name":"value2","nodeType":"YulIdentifier","src":"8378:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"8386:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"8374:3:17"},"nodeType":"YulFunctionCall","src":"8374:15:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8347:6:17"},"nodeType":"YulFunctionCall","src":"8347:43:17"},"nodeType":"YulExpressionStatement","src":"8347:43:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8410:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8421:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8406:3:17"},"nodeType":"YulFunctionCall","src":"8406:18:17"},{"name":"value3","nodeType":"YulIdentifier","src":"8426:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8399:6:17"},"nodeType":"YulFunctionCall","src":"8399:34:17"},"nodeType":"YulExpressionStatement","src":"8399:34:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8453:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8464:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8449:3:17"},"nodeType":"YulFunctionCall","src":"8449:19:17"},{"name":"value4","nodeType":"YulIdentifier","src":"8470:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8442:6:17"},"nodeType":"YulFunctionCall","src":"8442:35:17"},"nodeType":"YulExpressionStatement","src":"8442:35:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8497:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8508:3:17","type":"","value":"160"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8493:3:17"},"nodeType":"YulFunctionCall","src":"8493:19:17"},{"kind":"number","nodeType":"YulLiteral","src":"8514:3:17","type":"","value":"192"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8486:6:17"},"nodeType":"YulFunctionCall","src":"8486:32:17"},"nodeType":"YulExpressionStatement","src":"8486:32:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8538:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8549:3:17","type":"","value":"192"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8534:3:17"},"nodeType":"YulFunctionCall","src":"8534:19:17"},{"kind":"number","nodeType":"YulLiteral","src":"8555:1:17","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8527:6:17"},"nodeType":"YulFunctionCall","src":"8527:30:17"},"nodeType":"YulExpressionStatement","src":"8527:30:17"},{"nodeType":"YulAssignment","src":"8566:27:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8578:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8589:3:17","type":"","value":"224"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8574:3:17"},"nodeType":"YulFunctionCall","src":"8574:19:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"8566:4:17"}]}]},"name":"abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470__to_t_address_t_uint256_t_address_t_uint256_t_uint256_t_bytes_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"8150:9:17","type":""},{"name":"value4","nodeType":"YulTypedName","src":"8161:6:17","type":""},{"name":"value3","nodeType":"YulTypedName","src":"8169:6:17","type":""},{"name":"value2","nodeType":"YulTypedName","src":"8177:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"8185:6:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"8193:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"8204:4:17","type":""}],"src":"7892:707:17"}]},"contents":"{\n { }\n function abi_encode_tuple_t_address__to_t_address__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, sub(shl(160, 1), 1)))\n }\n function validator_revert_address(value)\n {\n if iszero(eq(value, and(value, sub(shl(160, 1), 1)))) { revert(0, 0) }\n }\n function abi_decode_string_calldata(offset, end) -> arrayPos, length\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n length := calldataload(offset)\n if gt(length, 0xffffffffffffffff) { revert(0, 0) }\n arrayPos := add(offset, 0x20)\n if gt(add(add(offset, length), 0x20), end) { revert(0, 0) }\n }\n function abi_decode_tuple_t_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_address(headStart, dataEnd) -> value0, value1, value2, value3, value4, value5, value6\n {\n if slt(sub(dataEnd, headStart), 192) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n value1 := calldataload(add(headStart, 32))\n let offset := calldataload(add(headStart, 64))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n let value2_1, value3_1 := abi_decode_string_calldata(add(headStart, offset), dataEnd)\n value2 := value2_1\n value3 := value3_1\n let value_1 := calldataload(add(headStart, 96))\n validator_revert_address(value_1)\n value4 := value_1\n value5 := calldataload(add(headStart, 128))\n let value_2 := calldataload(add(headStart, 160))\n validator_revert_address(value_2)\n value6 := value_2\n }\n function abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, value0)\n }\n function abi_decode_tuple_t_addresst_uint256(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n value1 := calldataload(add(headStart, 32))\n }\n function abi_decode_tuple_t_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_uint256(headStart, dataEnd) -> value0, value1, value2, value3, value4, value5, value6\n {\n if slt(sub(dataEnd, headStart), 192) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n value1 := calldataload(add(headStart, 32))\n let offset := calldataload(add(headStart, 64))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n let value2_1, value3_1 := abi_decode_string_calldata(add(headStart, offset), dataEnd)\n value2 := value2_1\n value3 := value3_1\n let value_1 := calldataload(add(headStart, 96))\n validator_revert_address(value_1)\n value4 := value_1\n value5 := calldataload(add(headStart, 128))\n value6 := calldataload(add(headStart, 160))\n }\n function abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, iszero(iszero(value0)))\n }\n function abi_decode_tuple_t_addresst_addresst_uint256t_string_calldata_ptrt_address(headStart, dataEnd) -> value0, value1, value2, value3, value4, value5\n {\n if slt(sub(dataEnd, headStart), 160) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n value2 := calldataload(add(headStart, 64))\n let offset := calldataload(add(headStart, 96))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n let value3_1, value4_1 := abi_decode_string_calldata(add(headStart, offset), dataEnd)\n value3 := value3_1\n value4 := value4_1\n let value_2 := calldataload(add(headStart, 128))\n validator_revert_address(value_2)\n value5 := value_2\n }\n function abi_encode_tuple_t_uint256_t_uint256__to_t_uint256_t_uint256__fromStack_reversed(headStart, value1, value0) -> tail\n {\n tail := add(headStart, 64)\n mstore(headStart, value0)\n mstore(add(headStart, 32), value1)\n }\n function abi_decode_tuple_t_addresst_addresst_uint256t_string_calldata_ptrt_addresst_uint256(headStart, dataEnd) -> value0, value1, value2, value3, value4, value5, value6\n {\n if slt(sub(dataEnd, headStart), 192) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n value2 := calldataload(add(headStart, 64))\n let offset := calldataload(add(headStart, 96))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n let value3_1, value4_1 := abi_decode_string_calldata(add(headStart, offset), dataEnd)\n value3 := value3_1\n value4 := value4_1\n let value_2 := calldataload(add(headStart, 128))\n validator_revert_address(value_2)\n value5 := value_2\n value6 := calldataload(add(headStart, 160))\n }\n function abi_decode_tuple_t_addresst_addresst_uint256t_string_calldata_ptrt_addresst_uint256t_uint256(headStart, dataEnd) -> value0, value1, value2, value3, value4, value5, value6, value7\n {\n if slt(sub(dataEnd, headStart), 224) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_address(value)\n value0 := value\n let value_1 := calldataload(add(headStart, 32))\n validator_revert_address(value_1)\n value1 := value_1\n value2 := calldataload(add(headStart, 64))\n let offset := calldataload(add(headStart, 96))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n let value3_1, value4_1 := abi_decode_string_calldata(add(headStart, offset), dataEnd)\n value3 := value3_1\n value4 := value4_1\n let value_2 := calldataload(add(headStart, 128))\n validator_revert_address(value_2)\n value5 := value_2\n value6 := calldataload(add(headStart, 160))\n value7 := calldataload(add(headStart, 192))\n }\n function abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1__to_t_address_t_uint256_t_address_t_uint256_t_uint256__fromStack_reversed(headStart, value4, value3, value2, value1, value0) -> tail\n {\n tail := add(headStart, 160)\n let _1 := sub(shl(160, 1), 1)\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), value1)\n mstore(add(headStart, 64), and(value2, _1))\n mstore(add(headStart, 96), value3)\n mstore(add(headStart, 128), value4)\n }\n function abi_decode_tuple_t_address_fromMemory(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := mload(headStart)\n validator_revert_address(value)\n value0 := value\n }\n function abi_encode_tuple_t_address_t_uint256__to_t_address_t_uint256__fromStack_reversed(headStart, value1, value0) -> tail\n {\n tail := add(headStart, 64)\n mstore(headStart, and(value0, sub(shl(160, 1), 1)))\n mstore(add(headStart, 32), value1)\n }\n function abi_encode_tuple_t_address_t_address_t_uint256__to_t_address_t_address_t_uint256__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n tail := add(headStart, 96)\n let _1 := sub(shl(160, 1), 1)\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), and(value1, _1))\n mstore(add(headStart, 64), value2)\n }\n function abi_encode_tuple_t_address_t_uint256_t_address_t_uint256_t_rational_0_by_1_t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470__to_t_address_t_uint256_t_address_t_uint256_t_uint256_t_bytes_memory_ptr__fromStack_reversed(headStart, value4, value3, value2, value1, value0) -> tail\n {\n let _1 := sub(shl(160, 1), 1)\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), value1)\n mstore(add(headStart, 64), and(value2, _1))\n mstore(add(headStart, 96), value3)\n mstore(add(headStart, 128), value4)\n mstore(add(headStart, 160), 192)\n mstore(add(headStart, 192), 0)\n tail := add(headStart, 224)\n }\n}","id":17,"language":"Yul","name":"#utility.yul"}],"immutableReferences":{},"linkReferences":{},"object":"608060405234801561001057600080fd5b50600436106100b45760003560e01c806365d20ce21161007157806365d20ce2146101945780636697b359146101a25780637fdfc7b2146101bf578063a8abef47146101a2578063acab923c14610163578063fe02fb00146101da57600080fd5b806306433b1b146100b95780630bdde2ca146100f1578063192df6551461011a5780633ff956cc1461012d5780635fbfb9cf14610150578063621a3b7014610163575b600080fd5b6100d47302101dfb77fde026414827fdc604ddaf224f092181565b6040516001600160a01b0390911681526020015b60405180910390f35b61010c6100ff366004610490565b6000979650505050505050565b6040519081526020016100e8565b6100d4610128366004610520565b6101f6565b61014061013b36600461054c565b6102aa565b60405190151581526020016100e8565b6100d461015e366004610520565b610396565b61017f6101713660046105d2565b600080965096945050505050565b604080519283526020830191909152016100e8565b61010c6100ff366004610657565b61017f6101b0366004610657565b60008097509795505050505050565b6100d4732d25602551487c3f3354dd80d76d54383a24335881565b6101406101e83660046106e7565b600098975050505050505050565b604051632f4de29b60e11b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b038316604482015260648101829052600060848201819052907302101dfb77fde026414827fdc604ddaf224f092190635e9bc5369060a401602060405180830381865afa15801561027f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102a3919061077e565b9392505050565b60405163192df65560e01b81526001600160a01b0388166004820152602481018790526000908190309063192df65590604401602060405180830381865afa1580156102fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061031e919061077e565b604051632142170760e11b81523360048201526001600160a01b03808316602483015260448201879052919250908616906342842e0e90606401600060405180830381600087803b15801561037257600080fd5b505af1158015610386573d6000803e3d6000fd5b5050505050979650505050505050565b60405163da7323b360e01b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b03831660448201526064810182905260006084820181905260c060a483015260c48201819052907302101dfb77fde026414827fdc604ddaf224f09219063da7323b39060e4016020604051808303816000875af115801561027f573d6000803e3d6000fd5b6001600160a01b038116811461044457600080fd5b50565b60008083601f84011261045957600080fd5b50813567ffffffffffffffff81111561047157600080fd5b60208301915083602082850101111561048957600080fd5b9250929050565b600080600080600080600060c0888a0312156104ab57600080fd5b87356104b68161042f565b965060208801359550604088013567ffffffffffffffff8111156104d957600080fd5b6104e58a828b01610447565b90965094505060608801356104f98161042f565b92506080880135915060a08801356105108161042f565b8091505092959891949750929550565b6000806040838503121561053357600080fd5b823561053e8161042f565b946020939093013593505050565b600080600080600080600060c0888a03121561056757600080fd5b87356105728161042f565b965060208801359550604088013567ffffffffffffffff81111561059557600080fd5b6105a18a828b01610447565b90965094505060608801356105b58161042f565b969995985093969295946080840135945060a09093013592915050565b60008060008060008060a087890312156105eb57600080fd5b86356105f68161042f565b955060208701356106068161042f565b945060408701359350606087013567ffffffffffffffff81111561062957600080fd5b61063589828a01610447565b90945092505060808701356106498161042f565b809150509295509295509295565b600080600080600080600060c0888a03121561067257600080fd5b873561067d8161042f565b9650602088013561068d8161042f565b955060408801359450606088013567ffffffffffffffff8111156106b057600080fd5b6106bc8a828b01610447565b90955093505060808801356106d08161042f565b8092505060a0880135905092959891949750929550565b60008060008060008060008060e0898b03121561070357600080fd5b883561070e8161042f565b9750602089013561071e8161042f565b965060408901359550606089013567ffffffffffffffff81111561074157600080fd5b61074d8b828c01610447565b90965094505060808901356107618161042f565b979a969950949793969295929450505060a08201359160c0013590565b60006020828403121561079057600080fd5b81516102a38161042f56fea2646970667358221220374814b7bbfe210c40d5ff478cf67868bd398bb69ad03fd0e65053cade67695d64736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0xB4 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x65D20CE2 GT PUSH2 0x71 JUMPI DUP1 PUSH4 0x65D20CE2 EQ PUSH2 0x194 JUMPI DUP1 PUSH4 0x6697B359 EQ PUSH2 0x1A2 JUMPI DUP1 PUSH4 0x7FDFC7B2 EQ PUSH2 0x1BF JUMPI DUP1 PUSH4 0xA8ABEF47 EQ PUSH2 0x1A2 JUMPI DUP1 PUSH4 0xACAB923C EQ PUSH2 0x163 JUMPI DUP1 PUSH4 0xFE02FB00 EQ PUSH2 0x1DA JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x6433B1B EQ PUSH2 0xB9 JUMPI DUP1 PUSH4 0xBDDE2CA EQ PUSH2 0xF1 JUMPI DUP1 PUSH4 0x192DF655 EQ PUSH2 0x11A JUMPI DUP1 PUSH4 0x3FF956CC EQ PUSH2 0x12D JUMPI DUP1 PUSH4 0x5FBFB9CF EQ PUSH2 0x150 JUMPI DUP1 PUSH4 0x621A3B70 EQ PUSH2 0x163 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xD4 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x10C PUSH2 0xFF CALLDATASIZE PUSH1 0x4 PUSH2 0x490 JUMP JUMPDEST PUSH1 0x0 SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xE8 JUMP JUMPDEST PUSH2 0xD4 PUSH2 0x128 CALLDATASIZE PUSH1 0x4 PUSH2 0x520 JUMP JUMPDEST PUSH2 0x1F6 JUMP JUMPDEST PUSH2 0x140 PUSH2 0x13B CALLDATASIZE PUSH1 0x4 PUSH2 0x54C JUMP JUMPDEST PUSH2 0x2AA JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xE8 JUMP JUMPDEST PUSH2 0xD4 PUSH2 0x15E CALLDATASIZE PUSH1 0x4 PUSH2 0x520 JUMP JUMPDEST PUSH2 0x396 JUMP JUMPDEST PUSH2 0x17F PUSH2 0x171 CALLDATASIZE PUSH1 0x4 PUSH2 0x5D2 JUMP JUMPDEST PUSH1 0x0 DUP1 SWAP7 POP SWAP7 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP3 DUP4 MSTORE PUSH1 0x20 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE ADD PUSH2 0xE8 JUMP JUMPDEST PUSH2 0x10C PUSH2 0xFF CALLDATASIZE PUSH1 0x4 PUSH2 0x657 JUMP JUMPDEST PUSH2 0x17F PUSH2 0x1B0 CALLDATASIZE PUSH1 0x4 PUSH2 0x657 JUMP JUMPDEST PUSH1 0x0 DUP1 SWAP8 POP SWAP8 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH2 0xD4 PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 DUP2 JUMP JUMPDEST PUSH2 0x140 PUSH2 0x1E8 CALLDATASIZE PUSH1 0x4 PUSH2 0x6E7 JUMP JUMPDEST PUSH1 0x0 SWAP9 SWAP8 POP POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x2F4DE29B PUSH1 0xE1 SHL DUP2 MSTORE PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 PUSH1 0x4 DUP3 ADD MSTORE CHAINID PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 PUSH1 0x84 DUP3 ADD DUP2 SWAP1 MSTORE SWAP1 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 SWAP1 PUSH4 0x5E9BC536 SWAP1 PUSH1 0xA4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x27F JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x2A3 SWAP2 SWAP1 PUSH2 0x77E JUMP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x192DF655 PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP9 AND PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x24 DUP2 ADD DUP8 SWAP1 MSTORE PUSH1 0x0 SWAP1 DUP2 SWAP1 ADDRESS SWAP1 PUSH4 0x192DF655 SWAP1 PUSH1 0x44 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x2FA JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x31E SWAP2 SWAP1 PUSH2 0x77E JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0x21421707 PUSH1 0xE1 SHL DUP2 MSTORE CALLER PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP1 DUP4 AND PUSH1 0x24 DUP4 ADD MSTORE PUSH1 0x44 DUP3 ADD DUP8 SWAP1 MSTORE SWAP2 SWAP3 POP SWAP1 DUP7 AND SWAP1 PUSH4 0x42842E0E SWAP1 PUSH1 0x64 ADD PUSH1 0x0 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 DUP1 EXTCODESIZE ISZERO DUP1 ISZERO PUSH2 0x372 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP GAS CALL ISZERO DUP1 ISZERO PUSH2 0x386 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP POP SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH4 0xDA7323B3 PUSH1 0xE0 SHL DUP2 MSTORE PUSH20 0x2D25602551487C3F3354DD80D76D54383A243358 PUSH1 0x4 DUP3 ADD MSTORE CHAINID PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 AND PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 PUSH1 0x84 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0xC0 PUSH1 0xA4 DUP4 ADD MSTORE PUSH1 0xC4 DUP3 ADD DUP2 SWAP1 MSTORE SWAP1 PUSH20 0x2101DFB77FDE026414827FDC604DDAF224F0921 SWAP1 PUSH4 0xDA7323B3 SWAP1 PUSH1 0xE4 ADD PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL ISZERO DUP1 ISZERO PUSH2 0x27F JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0x444 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x459 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x471 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0x489 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xC0 DUP9 DUP11 SUB SLT ISZERO PUSH2 0x4AB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 CALLDATALOAD PUSH2 0x4B6 DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP7 POP PUSH1 0x20 DUP9 ADD CALLDATALOAD SWAP6 POP PUSH1 0x40 DUP9 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x4D9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x4E5 DUP11 DUP3 DUP12 ADD PUSH2 0x447 JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP POP PUSH1 0x60 DUP9 ADD CALLDATALOAD PUSH2 0x4F9 DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP3 POP PUSH1 0x80 DUP9 ADD CALLDATALOAD SWAP2 POP PUSH1 0xA0 DUP9 ADD CALLDATALOAD PUSH2 0x510 DUP2 PUSH2 0x42F JUMP JUMPDEST DUP1 SWAP2 POP POP SWAP3 SWAP6 SWAP9 SWAP2 SWAP5 SWAP8 POP SWAP3 SWAP6 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x533 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH2 0x53E DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP5 PUSH1 0x20 SWAP4 SWAP1 SWAP4 ADD CALLDATALOAD SWAP4 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xC0 DUP9 DUP11 SUB SLT ISZERO PUSH2 0x567 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 CALLDATALOAD PUSH2 0x572 DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP7 POP PUSH1 0x20 DUP9 ADD CALLDATALOAD SWAP6 POP PUSH1 0x40 DUP9 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x595 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x5A1 DUP11 DUP3 DUP12 ADD PUSH2 0x447 JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP POP PUSH1 0x60 DUP9 ADD CALLDATALOAD PUSH2 0x5B5 DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP7 SWAP10 SWAP6 SWAP9 POP SWAP4 SWAP7 SWAP3 SWAP6 SWAP5 PUSH1 0x80 DUP5 ADD CALLDATALOAD SWAP5 POP PUSH1 0xA0 SWAP1 SWAP4 ADD CALLDATALOAD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0xA0 DUP8 DUP10 SUB SLT ISZERO PUSH2 0x5EB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP7 CALLDATALOAD PUSH2 0x5F6 DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP6 POP PUSH1 0x20 DUP8 ADD CALLDATALOAD PUSH2 0x606 DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP5 POP PUSH1 0x40 DUP8 ADD CALLDATALOAD SWAP4 POP PUSH1 0x60 DUP8 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x629 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x635 DUP10 DUP3 DUP11 ADD PUSH2 0x447 JUMP JUMPDEST SWAP1 SWAP5 POP SWAP3 POP POP PUSH1 0x80 DUP8 ADD CALLDATALOAD PUSH2 0x649 DUP2 PUSH2 0x42F JUMP JUMPDEST DUP1 SWAP2 POP POP SWAP3 SWAP6 POP SWAP3 SWAP6 POP SWAP3 SWAP6 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0xC0 DUP9 DUP11 SUB SLT ISZERO PUSH2 0x672 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 CALLDATALOAD PUSH2 0x67D DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP7 POP PUSH1 0x20 DUP9 ADD CALLDATALOAD PUSH2 0x68D DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP6 POP PUSH1 0x40 DUP9 ADD CALLDATALOAD SWAP5 POP PUSH1 0x60 DUP9 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x6B0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x6BC DUP11 DUP3 DUP12 ADD PUSH2 0x447 JUMP JUMPDEST SWAP1 SWAP6 POP SWAP4 POP POP PUSH1 0x80 DUP9 ADD CALLDATALOAD PUSH2 0x6D0 DUP2 PUSH2 0x42F JUMP JUMPDEST DUP1 SWAP3 POP POP PUSH1 0xA0 DUP9 ADD CALLDATALOAD SWAP1 POP SWAP3 SWAP6 SWAP9 SWAP2 SWAP5 SWAP8 POP SWAP3 SWAP6 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0xE0 DUP10 DUP12 SUB SLT ISZERO PUSH2 0x703 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP9 CALLDATALOAD PUSH2 0x70E DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP8 POP PUSH1 0x20 DUP10 ADD CALLDATALOAD PUSH2 0x71E DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP7 POP PUSH1 0x40 DUP10 ADD CALLDATALOAD SWAP6 POP PUSH1 0x60 DUP10 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x741 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x74D DUP12 DUP3 DUP13 ADD PUSH2 0x447 JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP POP PUSH1 0x80 DUP10 ADD CALLDATALOAD PUSH2 0x761 DUP2 PUSH2 0x42F JUMP JUMPDEST SWAP8 SWAP11 SWAP7 SWAP10 POP SWAP5 SWAP8 SWAP4 SWAP7 SWAP3 SWAP6 SWAP3 SWAP5 POP POP POP PUSH1 0xA0 DUP3 ADD CALLDATALOAD SWAP2 PUSH1 0xC0 ADD CALLDATALOAD SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x790 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x2A3 DUP2 PUSH2 0x42F JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 CALLDATACOPY BASEFEE EQ 0xB7 0xBB INVALID 0x21 0xC BLOCKHASH 0xD5 SELFDESTRUCT SELFBALANCE DUP13 0xF6 PUSH25 0x68BD398BB69AD03FD0E65053CADE67695D64736F6C63430008 GT STOP CALLER ","sourceMap":"202:2475:12:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;133:78:11;;169:42;133:78;;;;;-1:-1:-1;;;;;178:32:17;;;160:51;;148:2;133:18;:78:11;;;;;;;;259:275:12;;;;;;:::i;:::-;491:25;259:275;;;;;;;;;;;;;1829:25:17;;;1817:2;1802:18;259:275:12;1683:177:17;626:299:11;;;;;;:::i;:::-;;:::i;1947:430:12:-;;;;;;:::i;:::-;;:::i;:::-;;;3249:14:17;;3242:22;3224:41;;3212:2;3197:18;1947:430:12;3084:187:17;306:314:11;;;;;;:::i;:::-;;:::i;540:259:12:-;;;;;;:::i;:::-;744:21;767:22;540:259;;;;;;;;;;;;;;4353:25:17;;;4409:2;4394:18;;4387:34;;;;4326:18;540:259:12;4179:248:17;1105:275:12;;;;;;:::i;805:294::-;;;;;;:::i;:::-;1044:21;1067:22;805:294;;;;;;;;;;;217:82:11;;257:42;217:82;;2383:291:12;;;;;;:::i;:::-;2652:12;2383:291;;;;;;;;;;;626:299:11;762:156;;-1:-1:-1;;;762:156:11;;257:42;762:156;;;6750:34:17;830:13:11;6800:18:17;;;6793:34;-1:-1:-1;;;;;6863:15:17;;6843:18;;;6836:43;6895:18;;;6888:34;;;732:7:11;6938:19:17;;;6931:35;;;732:7:11;169:42;;762:27;;6684:19:17;;762:156:11;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;755:163;626:299;-1:-1:-1;;;626:299:11:o;1947:430:12:-;2237:38;;-1:-1:-1;;;2237:38:12;;-1:-1:-1;;;;;7425:32:17;;2237:38:12;;;7407:51:17;7474:18;;;7467:34;;;2185:12:12;;;;2237:4;;:12;;7380:18:17;;2237:38:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2286:84;;-1:-1:-1;;;2286:84:12;;2328:10;2286:84;;;7752:34:17;-1:-1:-1;;;;;7822:15:17;;;7802:18;;;7795:43;7854:18;;;7847:34;;;2209:66:12;;-1:-1:-1;2286:41:12;;;;;;7687:18:17;;2286:84:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2199:178;1947:430;;;;;;;;;:::o;306:314:11:-;435:178;;-1:-1:-1;;;435:178:11;;257:42;435:178;;;8261:34:17;509:13:11;8311:18:17;;;8304:34;-1:-1:-1;;;;;8374:15:17;;8354:18;;;8347:43;8406:18;;;8399:34;;;405:7:11;8449:19:17;;;8442:35;;;8514:3;8493:19;;;8486:32;8534:19;;;8527:30;;;405:7:11;169:42;;435:33;;8574:19:17;;435:178:11;;;;;;;;;;;;;;;;;;;;;;;222:131:17;-1:-1:-1;;;;;297:31:17;;287:42;;277:70;;343:1;340;333:12;277:70;222:131;:::o;358:348::-;410:8;420:6;474:3;467:4;459:6;455:17;451:27;441:55;;492:1;489;482:12;441:55;-1:-1:-1;515:20:17;;558:18;547:30;;544:50;;;590:1;587;580:12;544:50;627:4;619:6;615:17;603:29;;679:3;672:4;663:6;655;651:19;647:30;644:39;641:59;;;696:1;693;686:12;641:59;358:348;;;;;:::o;711:967::-;827:6;835;843;851;859;867;875;928:3;916:9;907:7;903:23;899:33;896:53;;;945:1;942;935:12;896:53;984:9;971:23;1003:31;1028:5;1003:31;:::i;:::-;1053:5;-1:-1:-1;1105:2:17;1090:18;;1077:32;;-1:-1:-1;1160:2:17;1145:18;;1132:32;1187:18;1176:30;;1173:50;;;1219:1;1216;1209:12;1173:50;1258:59;1309:7;1300:6;1289:9;1285:22;1258:59;:::i;:::-;1336:8;;-1:-1:-1;1232:85:17;-1:-1:-1;;1423:2:17;1408:18;;1395:32;1436:33;1395:32;1436:33;:::i;:::-;1488:7;-1:-1:-1;1542:3:17;1527:19;;1514:33;;-1:-1:-1;1599:3:17;1584:19;;1571:33;1613;1571;1613;:::i;:::-;1665:7;1655:17;;;711:967;;;;;;;;;;:::o;1865:315::-;1933:6;1941;1994:2;1982:9;1973:7;1969:23;1965:32;1962:52;;;2010:1;2007;2000:12;1962:52;2049:9;2036:23;2068:31;2093:5;2068:31;:::i;:::-;2118:5;2170:2;2155:18;;;;2142:32;;-1:-1:-1;;;1865:315:17:o;2185:894::-;2301:6;2309;2317;2325;2333;2341;2349;2402:3;2390:9;2381:7;2377:23;2373:33;2370:53;;;2419:1;2416;2409:12;2370:53;2458:9;2445:23;2477:31;2502:5;2477:31;:::i;:::-;2527:5;-1:-1:-1;2579:2:17;2564:18;;2551:32;;-1:-1:-1;2634:2:17;2619:18;;2606:32;2661:18;2650:30;;2647:50;;;2693:1;2690;2683:12;2647:50;2732:59;2783:7;2774:6;2763:9;2759:22;2732:59;:::i;:::-;2810:8;;-1:-1:-1;2706:85:17;-1:-1:-1;;2897:2:17;2882:18;;2869:32;2910:33;2869:32;2910:33;:::i;:::-;2185:894;;;;-1:-1:-1;2185:894:17;;;;2962:7;3016:3;3001:19;;2988:33;;-1:-1:-1;3068:3:17;3053:19;;;3040:33;;2185:894;-1:-1:-1;;2185:894:17:o;3276:898::-;3383:6;3391;3399;3407;3415;3423;3476:3;3464:9;3455:7;3451:23;3447:33;3444:53;;;3493:1;3490;3483:12;3444:53;3532:9;3519:23;3551:31;3576:5;3551:31;:::i;:::-;3601:5;-1:-1:-1;3658:2:17;3643:18;;3630:32;3671:33;3630:32;3671:33;:::i;:::-;3723:7;-1:-1:-1;3777:2:17;3762:18;;3749:32;;-1:-1:-1;3832:2:17;3817:18;;3804:32;3859:18;3848:30;;3845:50;;;3891:1;3888;3881:12;3845:50;3930:59;3981:7;3972:6;3961:9;3957:22;3930:59;:::i;:::-;4008:8;;-1:-1:-1;3904:85:17;-1:-1:-1;;4095:3:17;4080:19;;4067:33;4109;4067;4109;:::i;:::-;4161:7;4151:17;;;3276:898;;;;;;;;:::o;4432:967::-;4548:6;4556;4564;4572;4580;4588;4596;4649:3;4637:9;4628:7;4624:23;4620:33;4617:53;;;4666:1;4663;4656:12;4617:53;4705:9;4692:23;4724:31;4749:5;4724:31;:::i;:::-;4774:5;-1:-1:-1;4831:2:17;4816:18;;4803:32;4844:33;4803:32;4844:33;:::i;:::-;4896:7;-1:-1:-1;4950:2:17;4935:18;;4922:32;;-1:-1:-1;5005:2:17;4990:18;;4977:32;5032:18;5021:30;;5018:50;;;5064:1;5061;5054:12;5018:50;5103:59;5154:7;5145:6;5134:9;5130:22;5103:59;:::i;:::-;5181:8;;-1:-1:-1;5077:85:17;-1:-1:-1;;5268:3:17;5253:19;;5240:33;5282;5240;5282;:::i;:::-;5334:7;5324:17;;;5388:3;5377:9;5373:19;5360:33;5350:43;;4432:967;;;;;;;;;;:::o;5404:1036::-;5529:6;5537;5545;5553;5561;5569;5577;5585;5638:3;5626:9;5617:7;5613:23;5609:33;5606:53;;;5655:1;5652;5645:12;5606:53;5694:9;5681:23;5713:31;5738:5;5713:31;:::i;:::-;5763:5;-1:-1:-1;5820:2:17;5805:18;;5792:32;5833:33;5792:32;5833:33;:::i;:::-;5885:7;-1:-1:-1;5939:2:17;5924:18;;5911:32;;-1:-1:-1;5994:2:17;5979:18;;5966:32;6021:18;6010:30;;6007:50;;;6053:1;6050;6043:12;6007:50;6092:59;6143:7;6134:6;6123:9;6119:22;6092:59;:::i;:::-;6170:8;;-1:-1:-1;6066:85:17;-1:-1:-1;;6257:3:17;6242:19;;6229:33;6271;6229;6271;:::i;:::-;5404:1036;;;;-1:-1:-1;5404:1036:17;;;;;;6323:7;;-1:-1:-1;;;6377:3:17;6362:19;;6349:33;;6429:3;6414:19;6401:33;;5404:1036::o;6977:251::-;7047:6;7100:2;7088:9;7079:7;7075:23;7071:32;7068:52;;;7116:1;7113;7106:12;7068:52;7148:9;7142:16;7167:31;7192:5;7167:31;:::i"},"gasEstimates":{"creation":{"codeDepositCost":"400200","executionCost":"436","totalCost":"400636"},"external":{"IMPLMENTATION()":"249","REGISTRY()":"206","account(address,uint256)":"infinite","breakCovalentBond(address,address,uint256,string,address,uint256,uint256)":"infinite","covalentBond(address,uint256,string,address,uint256,uint256)":"infinite","createAccount(address,uint256)":"infinite","dischargeParticle(address,address,uint256,string,address)":"infinite","dischargeParticleAmount(address,address,uint256,string,address,uint256)":"infinite","dischargeParticleForCreator(address,address,uint256,string,address,uint256)":"infinite","energizeParticle(address,uint256,string,address,uint256,address)":"infinite","releaseParticle(address,address,uint256,string,address)":"infinite","releaseParticleAmount(address,address,uint256,string,address,uint256)":"infinite"}},"methodIdentifiers":{"IMPLMENTATION()":"7fdfc7b2","REGISTRY()":"06433b1b","account(address,uint256)":"192df655","breakCovalentBond(address,address,uint256,string,address,uint256,uint256)":"fe02fb00","covalentBond(address,uint256,string,address,uint256,uint256)":"3ff956cc","createAccount(address,uint256)":"5fbfb9cf","dischargeParticle(address,address,uint256,string,address)":"621a3b70","dischargeParticleAmount(address,address,uint256,string,address,uint256)":"6697b359","dischargeParticleForCreator(address,address,uint256,string,address,uint256)":"65d20ce2","energizeParticle(address,uint256,string,address,uint256,address)":"0bdde2ca","releaseParticle(address,address,uint256,string,address)":"acab923c","releaseParticleAmount(address,address,uint256,string,address,uint256)":"a8abef47"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"IMPLMENTATION\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REGISTRY\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"account\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"basketManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"breakCovalentBond\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"basketManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"covalentBond\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"dischargeParticle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"creatorAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"}],\"name\":\"dischargeParticleAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"creatorAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"}],\"name\":\"dischargeParticleForCreator\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receiverAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"referrer\",\"type\":\"address\"}],\"name\":\"energizeParticle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"yieldTokensAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"releaseParticle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"creatorAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"}],\"name\":\"releaseParticleAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"creatorAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ChargedParticles.sol\":\"ChargedParticles\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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`.\\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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\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(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/AccountRegistryBridge.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.13;\\n\\nimport \\\"./interfaces/IRegistry.sol\\\";\\ncontract AccountRegistryBridge {\\n address public constant REGISTRY = \\t0x02101dfB77FDE026414827Fdc604ddAF224F0921;\\n address public constant IMPLMENTATION = 0x2D25602551487C3f3354dD80D76D54383A243358;\\n\\n function createAccount(address contractAddress, uint256 tokenId)\\n external\\n returns (address)\\n {\\n return IRegistry(REGISTRY).createAccount(\\n IMPLMENTATION,\\n block.chainid,\\n contractAddress,\\n tokenId,\\n 0,\\n ''\\n );\\n }\\n\\n function account(address contractAddress, uint256 tokenId)\\n external\\n view\\n returns (address)\\n {\\n return IRegistry(REGISTRY).account(\\n IMPLMENTATION,\\n block.chainid,\\n contractAddress,\\n tokenId,\\n 0\\n );\\n }\\n}\",\"keccak256\":\"0x4536af05c6fa43a3fd532415b4d39c190c35904aee16c48ea453a3b2baf976ea\",\"license\":\"MIT\"},\"contracts/ChargedParticles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.13;\\n\\nimport \\\"./interfaces/IChargedParticles.sol\\\";\\nimport \\\"./AccountRegistryBridge.sol\\\";\\n\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\ncontract ChargedParticles is AccountRegistryBridge {\\n function energizeParticle(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount,\\n address referrer\\n ) external returns (uint256 yieldTokensAmount) {\\n \\n }\\n\\n function dischargeParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount) {\\n\\n }\\n\\n function dischargeParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount) {\\n\\n }\\n\\n function dischargeParticleForCreator(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 receiverAmount) {\\n\\n }\\n\\n function releaseParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount) {\\n\\n }\\n\\n function releaseParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount) {\\n\\n }\\n\\n function covalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success) {\\n address tokenBoundAccount = this.account(contractAddress, tokenId); \\n IERC721(nftTokenAddress).safeTransferFrom(msg.sender, tokenBoundAccount, nftTokenId);\\n }\\n\\n function breakCovalentBond(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success) {\\n\\n }\\n\\n}\\n\",\"keccak256\":\"0xacebddfef042256f5a39f41648a37c98a98d4c1621753a2624cac0549ed7c049\",\"license\":\"MIT\"},\"contracts/interfaces/IChargedParticles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @notice Interface for Charged Particles\\n */\\ninterface IChargedParticles {\\n\\n /***********************************|\\n | Public API |\\n |__________________________________*/\\n\\n function getStateAddress() external view returns (address stateAddress);\\n function getSettingsAddress() external view returns (address settingsAddress);\\n function getManagersAddress() external view returns (address managersAddress);\\n\\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\\n\\n /***********************************|\\n | Particle Mechanics |\\n |__________________________________*/\\n\\n function energizeParticle(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount,\\n address referrer\\n ) external returns (uint256 yieldTokensAmount);\\n\\n function dischargeParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function dischargeParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function dischargeParticleForCreator(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 receiverAmount);\\n\\n function releaseParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function releaseParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function covalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success);\\n\\n function breakCovalentBond(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success);\\n\\n /***********************************|\\n | Particle Events |\\n |__________________________________*/\\n\\n event Initialized(address indexed initiator);\\n event ControllerSet(address indexed controllerAddress, string controllerId);\\n event DepositFeeSet(uint256 depositFee);\\n event ProtocolFeesCollected(address indexed assetToken, uint256 depositAmount, uint256 feesCollected);\\n}\\n\",\"keccak256\":\"0x37104c629e40193ddc8677af8a632adf53754e7915f055a5a14861cd9b417729\",\"license\":\"MIT\"},\"contracts/interfaces/IRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\ninterface IRegistry {\\n function createAccount(\\n address implementation,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId,\\n uint256 salt,\\n bytes calldata initData\\n ) external returns (address);\\n\\n function account(\\n address implementation,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId,\\n uint256 salt\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xd24999d4d474bd349b1e2e5006eff215c5d9a64a481a9ebac3293f98603fbd27\",\"license\":\"UNLICENSED\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/interfaces/IAccount.sol":{"IAccount":{"abi":[{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"executeCall","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"executeCall(address,uint256,bytes)":"9e5d4c49","owner()":"8da5cb5b","token()":"fc0c546a"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"executeCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"tokenContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/interfaces/IAccount.sol\":\"IAccount\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\ninterface IAccount {\\n function owner() external view returns (address);\\n\\n function token()\\n external\\n view\\n returns (address tokenContract, uint256 tokenId);\\n\\n function executeCall(\\n address to,\\n uint256 value,\\n bytes calldata data\\n ) external payable returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x864eddea04e3865e2659848b1f7ac6190e118c26a86a96cf6e68df40896cfa45\",\"license\":\"UNLICENSED\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/interfaces/IChargedParticles.sol":{"IChargedParticles":{"abi":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"controllerAddress","type":"address"},{"indexed":false,"internalType":"string","name":"controllerId","type":"string"}],"name":"ControllerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"depositFee","type":"uint256"}],"name":"DepositFeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"initiator","type":"address"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"assetToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"depositAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feesCollected","type":"uint256"}],"name":"ProtocolFeesCollected","type":"event"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"}],"name":"baseParticleMass","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"basketManagerId","type":"string"},{"internalType":"address","name":"nftTokenAddress","type":"address"},{"internalType":"uint256","name":"nftTokenId","type":"uint256"},{"internalType":"uint256","name":"nftTokenAmount","type":"uint256"}],"name":"breakCovalentBond","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"basketManagerId","type":"string"},{"internalType":"address","name":"nftTokenAddress","type":"address"},{"internalType":"uint256","name":"nftTokenId","type":"uint256"},{"internalType":"uint256","name":"nftTokenAmount","type":"uint256"}],"name":"covalentBond","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"}],"name":"currentParticleCharge","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"basketManagerId","type":"string"}],"name":"currentParticleCovalentBonds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"}],"name":"currentParticleKinetics","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"}],"name":"dischargeParticle","outputs":[{"internalType":"uint256","name":"creatorAmount","type":"uint256"},{"internalType":"uint256","name":"receiverAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"},{"internalType":"uint256","name":"assetAmount","type":"uint256"}],"name":"dischargeParticleAmount","outputs":[{"internalType":"uint256","name":"creatorAmount","type":"uint256"},{"internalType":"uint256","name":"receiverAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"},{"internalType":"uint256","name":"assetAmount","type":"uint256"}],"name":"dischargeParticleForCreator","outputs":[{"internalType":"uint256","name":"receiverAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"},{"internalType":"uint256","name":"assetAmount","type":"uint256"},{"internalType":"address","name":"referrer","type":"address"}],"name":"energizeParticle","outputs":[{"internalType":"uint256","name":"yieldTokensAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assetAmount","type":"uint256"}],"name":"getFeesForDeposit","outputs":[{"internalType":"uint256","name":"protocolFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getManagersAddress","outputs":[{"internalType":"address","name":"managersAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSettingsAddress","outputs":[{"internalType":"address","name":"settingsAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStateAddress","outputs":[{"internalType":"address","name":"stateAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"}],"name":"releaseParticle","outputs":[{"internalType":"uint256","name":"creatorAmount","type":"uint256"},{"internalType":"uint256","name":"receiverAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"walletManagerId","type":"string"},{"internalType":"address","name":"assetToken","type":"address"},{"internalType":"uint256","name":"assetAmount","type":"uint256"}],"name":"releaseParticleAmount","outputs":[{"internalType":"uint256","name":"creatorAmount","type":"uint256"},{"internalType":"uint256","name":"receiverAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"baseParticleMass(address,uint256,string,address)":"e6ea6ce7","breakCovalentBond(address,address,uint256,string,address,uint256,uint256)":"fe02fb00","covalentBond(address,uint256,string,address,uint256,uint256)":"3ff956cc","currentParticleCharge(address,uint256,string,address)":"99fa4c73","currentParticleCovalentBonds(address,uint256,string)":"a13eafd5","currentParticleKinetics(address,uint256,string,address)":"ca92acd0","dischargeParticle(address,address,uint256,string,address)":"621a3b70","dischargeParticleAmount(address,address,uint256,string,address,uint256)":"6697b359","dischargeParticleForCreator(address,address,uint256,string,address,uint256)":"65d20ce2","energizeParticle(address,uint256,string,address,uint256,address)":"0bdde2ca","getFeesForDeposit(uint256)":"ee895623","getManagersAddress()":"8742f168","getSettingsAddress()":"d00999fe","getStateAddress()":"31969e57","releaseParticle(address,address,uint256,string,address)":"acab923c","releaseParticleAmount(address,address,uint256,string,address,uint256)":"a8abef47"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"controllerAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"controllerId\",\"type\":\"string\"}],\"name\":\"ControllerSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"depositFee\",\"type\":\"uint256\"}],\"name\":\"DepositFeeSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"depositAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"feesCollected\",\"type\":\"uint256\"}],\"name\":\"ProtocolFeesCollected\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"baseParticleMass\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"basketManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"breakCovalentBond\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"basketManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"covalentBond\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"currentParticleCharge\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"basketManagerId\",\"type\":\"string\"}],\"name\":\"currentParticleCovalentBonds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"currentParticleKinetics\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"dischargeParticle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"creatorAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"}],\"name\":\"dischargeParticleAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"creatorAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"}],\"name\":\"dischargeParticleForCreator\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"receiverAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"referrer\",\"type\":\"address\"}],\"name\":\"energizeParticle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"yieldTokensAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"}],\"name\":\"getFeesForDeposit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getManagersAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"managersAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSettingsAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"settingsAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStateAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"stateAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"releaseParticle\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"creatorAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"}],\"name\":\"releaseParticleAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"creatorAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Interface for Charged Particles\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/interfaces/IChargedParticles.sol\":\"IChargedParticles\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interfaces/IChargedParticles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @notice Interface for Charged Particles\\n */\\ninterface IChargedParticles {\\n\\n /***********************************|\\n | Public API |\\n |__________________________________*/\\n\\n function getStateAddress() external view returns (address stateAddress);\\n function getSettingsAddress() external view returns (address settingsAddress);\\n function getManagersAddress() external view returns (address managersAddress);\\n\\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\\n\\n /***********************************|\\n | Particle Mechanics |\\n |__________________________________*/\\n\\n function energizeParticle(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount,\\n address referrer\\n ) external returns (uint256 yieldTokensAmount);\\n\\n function dischargeParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function dischargeParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function dischargeParticleForCreator(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 receiverAmount);\\n\\n function releaseParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function releaseParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function covalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success);\\n\\n function breakCovalentBond(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success);\\n\\n /***********************************|\\n | Particle Events |\\n |__________________________________*/\\n\\n event Initialized(address indexed initiator);\\n event ControllerSet(address indexed controllerAddress, string controllerId);\\n event DepositFeeSet(uint256 depositFee);\\n event ProtocolFeesCollected(address indexed assetToken, uint256 depositAmount, uint256 feesCollected);\\n}\\n\",\"keccak256\":\"0x37104c629e40193ddc8677af8a632adf53754e7915f055a5a14861cd9b417729\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"notice":"Interface for Charged Particles","version":1}}},"contracts/interfaces/IRegistry.sol":{"IRegistry":{"abi":[{"inputs":[{"internalType":"address","name":"implementation","type":"address"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"}],"name":"account","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"implementation","type":"address"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"initData","type":"bytes"}],"name":"createAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"evm":{"bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"deployedBytecode":{"functionDebugData":{},"generatedSources":[],"immutableReferences":{},"linkReferences":{},"object":"","opcodes":"","sourceMap":""},"gasEstimates":null,"methodIdentifiers":{"account(address,uint256,address,uint256,uint256)":"5e9bc536","createAccount(address,uint256,address,uint256,uint256,bytes)":"da7323b3"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"salt\",\"type\":\"uint256\"}],\"name\":\"account\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"salt\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initData\",\"type\":\"bytes\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/interfaces/IRegistry.sol\":\"IRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/interfaces/IRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.13;\\n\\ninterface IRegistry {\\n function createAccount(\\n address implementation,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId,\\n uint256 salt,\\n bytes calldata initData\\n ) external returns (address);\\n\\n function account(\\n address implementation,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId,\\n uint256 salt\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0xd24999d4d474bd349b1e2e5006eff215c5d9a64a481a9ebac3293f98603fbd27\",\"license\":\"UNLICENSED\"}},\"version\":1}","storageLayout":{"storage":[],"types":null},"userdoc":{"kind":"user","methods":{},"version":1}}},"contracts/mock/NFTMock.sol":{"NFTMock":{"abi":[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"kind":"dev","methods":{"approve(address,uint256)":{"details":"See {IERC721-approve}."},"balanceOf(address)":{"details":"See {IERC721-balanceOf}."},"getApproved(uint256)":{"details":"See {IERC721-getApproved}."},"isApprovedForAll(address,address)":{"details":"See {IERC721-isApprovedForAll}."},"name()":{"details":"See {IERC721Metadata-name}."},"ownerOf(uint256)":{"details":"See {IERC721-ownerOf}."},"safeTransferFrom(address,address,uint256)":{"details":"See {IERC721-safeTransferFrom}."},"safeTransferFrom(address,address,uint256,bytes)":{"details":"See {IERC721-safeTransferFrom}."},"setApprovalForAll(address,bool)":{"details":"See {IERC721-setApprovalForAll}."},"supportsInterface(bytes4)":{"details":"See {IERC165-supportsInterface}."},"symbol()":{"details":"See {IERC721Metadata-symbol}."},"tokenURI(uint256)":{"details":"See {IERC721Metadata-tokenURI}."},"transferFrom(address,address,uint256)":{"details":"See {IERC721-transferFrom}."}},"version":1},"evm":{"bytecode":{"functionDebugData":{"@_3224":{"entryPoint":null,"id":3224,"parameterSlots":2,"returnSlots":0},"@_62":{"entryPoint":null,"id":62,"parameterSlots":2,"returnSlots":0},"abi_decode_string_fromMemory":{"entryPoint":116,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_string_memory_ptrt_string_memory_ptr_fromMemory":{"entryPoint":291,"id":null,"parameterSlots":2,"returnSlots":2},"array_dataslot_string_storage":{"entryPoint":null,"id":null,"parameterSlots":1,"returnSlots":1},"clean_up_bytearray_end_slots_string_storage":{"entryPoint":457,"id":null,"parameterSlots":3,"returnSlots":0},"copy_byte_array_to_storage_from_t_string_memory_ptr_to_t_string_storage":{"entryPoint":540,"id":null,"parameterSlots":2,"returnSlots":0},"extract_byte_array_length":{"entryPoint":397,"id":null,"parameterSlots":1,"returnSlots":1},"extract_used_part_and_set_length_of_short_byte_array":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"panic_error_0x41":{"entryPoint":94,"id":null,"parameterSlots":0,"returnSlots":0}},"generatedSources":[{"ast":{"nodeType":"YulBlock","src":"0:4144:17","statements":[{"nodeType":"YulBlock","src":"6:3:17","statements":[]},{"body":{"nodeType":"YulBlock","src":"46:95:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"63:1:17","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"70:3:17","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"75:10:17","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"66:3:17"},"nodeType":"YulFunctionCall","src":"66:20:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"56:6:17"},"nodeType":"YulFunctionCall","src":"56:31:17"},"nodeType":"YulExpressionStatement","src":"56:31:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"103:1:17","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"106:4:17","type":"","value":"0x41"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"96:6:17"},"nodeType":"YulFunctionCall","src":"96:15:17"},"nodeType":"YulExpressionStatement","src":"96:15:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"127:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"130:4:17","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"120:6:17"},"nodeType":"YulFunctionCall","src":"120:15:17"},"nodeType":"YulExpressionStatement","src":"120:15:17"}]},"name":"panic_error_0x41","nodeType":"YulFunctionDefinition","src":"14:127:17"},{"body":{"nodeType":"YulBlock","src":"210:776:17","statements":[{"body":{"nodeType":"YulBlock","src":"259:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"268:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"271:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"261:6:17"},"nodeType":"YulFunctionCall","src":"261:12:17"},"nodeType":"YulExpressionStatement","src":"261:12:17"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"238:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"246:4:17","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"234:3:17"},"nodeType":"YulFunctionCall","src":"234:17:17"},{"name":"end","nodeType":"YulIdentifier","src":"253:3:17"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"230:3:17"},"nodeType":"YulFunctionCall","src":"230:27:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"223:6:17"},"nodeType":"YulFunctionCall","src":"223:35:17"},"nodeType":"YulIf","src":"220:55:17"},{"nodeType":"YulVariableDeclaration","src":"284:23:17","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"300:6:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"294:5:17"},"nodeType":"YulFunctionCall","src":"294:13:17"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"288:2:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"316:28:17","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"334:2:17","type":"","value":"64"},{"kind":"number","nodeType":"YulLiteral","src":"338:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"330:3:17"},"nodeType":"YulFunctionCall","src":"330:10:17"},{"kind":"number","nodeType":"YulLiteral","src":"342:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"326:3:17"},"nodeType":"YulFunctionCall","src":"326:18:17"},"variables":[{"name":"_2","nodeType":"YulTypedName","src":"320:2:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"367:22:17","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"369:16:17"},"nodeType":"YulFunctionCall","src":"369:18:17"},"nodeType":"YulExpressionStatement","src":"369:18:17"}]},"condition":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"359:2:17"},{"name":"_2","nodeType":"YulIdentifier","src":"363:2:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"356:2:17"},"nodeType":"YulFunctionCall","src":"356:10:17"},"nodeType":"YulIf","src":"353:36:17"},{"nodeType":"YulVariableDeclaration","src":"398:17:17","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"412:2:17","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"408:3:17"},"nodeType":"YulFunctionCall","src":"408:7:17"},"variables":[{"name":"_3","nodeType":"YulTypedName","src":"402:2:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"424:23:17","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"444:2:17","type":"","value":"64"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"438:5:17"},"nodeType":"YulFunctionCall","src":"438:9:17"},"variables":[{"name":"memPtr","nodeType":"YulTypedName","src":"428:6:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"456:71:17","value":{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"478:6:17"},{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"502:2:17"},{"kind":"number","nodeType":"YulLiteral","src":"506:4:17","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"498:3:17"},"nodeType":"YulFunctionCall","src":"498:13:17"},{"name":"_3","nodeType":"YulIdentifier","src":"513:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"494:3:17"},"nodeType":"YulFunctionCall","src":"494:22:17"},{"kind":"number","nodeType":"YulLiteral","src":"518:2:17","type":"","value":"63"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"490:3:17"},"nodeType":"YulFunctionCall","src":"490:31:17"},{"name":"_3","nodeType":"YulIdentifier","src":"523:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"486:3:17"},"nodeType":"YulFunctionCall","src":"486:40:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"474:3:17"},"nodeType":"YulFunctionCall","src":"474:53:17"},"variables":[{"name":"newFreePtr","nodeType":"YulTypedName","src":"460:10:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"586:22:17","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"588:16:17"},"nodeType":"YulFunctionCall","src":"588:18:17"},"nodeType":"YulExpressionStatement","src":"588:18:17"}]},"condition":{"arguments":[{"arguments":[{"name":"newFreePtr","nodeType":"YulIdentifier","src":"545:10:17"},{"name":"_2","nodeType":"YulIdentifier","src":"557:2:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"542:2:17"},"nodeType":"YulFunctionCall","src":"542:18:17"},{"arguments":[{"name":"newFreePtr","nodeType":"YulIdentifier","src":"565:10:17"},{"name":"memPtr","nodeType":"YulIdentifier","src":"577:6:17"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"562:2:17"},"nodeType":"YulFunctionCall","src":"562:22:17"}],"functionName":{"name":"or","nodeType":"YulIdentifier","src":"539:2:17"},"nodeType":"YulFunctionCall","src":"539:46:17"},"nodeType":"YulIf","src":"536:72:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"624:2:17","type":"","value":"64"},{"name":"newFreePtr","nodeType":"YulIdentifier","src":"628:10:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"617:6:17"},"nodeType":"YulFunctionCall","src":"617:22:17"},"nodeType":"YulExpressionStatement","src":"617:22:17"},{"expression":{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"655:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"663:2:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"648:6:17"},"nodeType":"YulFunctionCall","src":"648:18:17"},"nodeType":"YulExpressionStatement","src":"648:18:17"},{"nodeType":"YulVariableDeclaration","src":"675:14:17","value":{"kind":"number","nodeType":"YulLiteral","src":"685:4:17","type":"","value":"0x20"},"variables":[{"name":"_4","nodeType":"YulTypedName","src":"679:2:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"735:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"744:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"747:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"737:6:17"},"nodeType":"YulFunctionCall","src":"737:12:17"},"nodeType":"YulExpressionStatement","src":"737:12:17"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"712:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"720:2:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"708:3:17"},"nodeType":"YulFunctionCall","src":"708:15:17"},{"name":"_4","nodeType":"YulIdentifier","src":"725:2:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"704:3:17"},"nodeType":"YulFunctionCall","src":"704:24:17"},{"name":"end","nodeType":"YulIdentifier","src":"730:3:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"701:2:17"},"nodeType":"YulFunctionCall","src":"701:33:17"},"nodeType":"YulIf","src":"698:53:17"},{"nodeType":"YulVariableDeclaration","src":"760:10:17","value":{"kind":"number","nodeType":"YulLiteral","src":"769:1:17","type":"","value":"0"},"variables":[{"name":"i","nodeType":"YulTypedName","src":"764:1:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"825:87:17","statements":[{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"854:6:17"},{"name":"i","nodeType":"YulIdentifier","src":"862:1:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"850:3:17"},"nodeType":"YulFunctionCall","src":"850:14:17"},{"name":"_4","nodeType":"YulIdentifier","src":"866:2:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"846:3:17"},"nodeType":"YulFunctionCall","src":"846:23:17"},{"arguments":[{"arguments":[{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"885:6:17"},{"name":"i","nodeType":"YulIdentifier","src":"893:1:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"881:3:17"},"nodeType":"YulFunctionCall","src":"881:14:17"},{"name":"_4","nodeType":"YulIdentifier","src":"897:2:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"877:3:17"},"nodeType":"YulFunctionCall","src":"877:23:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"871:5:17"},"nodeType":"YulFunctionCall","src":"871:30:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"839:6:17"},"nodeType":"YulFunctionCall","src":"839:63:17"},"nodeType":"YulExpressionStatement","src":"839:63:17"}]},"condition":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"790:1:17"},{"name":"_1","nodeType":"YulIdentifier","src":"793:2:17"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"787:2:17"},"nodeType":"YulFunctionCall","src":"787:9:17"},"nodeType":"YulForLoop","post":{"nodeType":"YulBlock","src":"797:19:17","statements":[{"nodeType":"YulAssignment","src":"799:15:17","value":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"808:1:17"},{"name":"_4","nodeType":"YulIdentifier","src":"811:2:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"804:3:17"},"nodeType":"YulFunctionCall","src":"804:10:17"},"variableNames":[{"name":"i","nodeType":"YulIdentifier","src":"799:1:17"}]}]},"pre":{"nodeType":"YulBlock","src":"783:3:17","statements":[]},"src":"779:133:17"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"936:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"944:2:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"932:3:17"},"nodeType":"YulFunctionCall","src":"932:15:17"},{"name":"_4","nodeType":"YulIdentifier","src":"949:2:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"928:3:17"},"nodeType":"YulFunctionCall","src":"928:24:17"},{"kind":"number","nodeType":"YulLiteral","src":"954:1:17","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"921:6:17"},"nodeType":"YulFunctionCall","src":"921:35:17"},"nodeType":"YulExpressionStatement","src":"921:35:17"},{"nodeType":"YulAssignment","src":"965:15:17","value":{"name":"memPtr","nodeType":"YulIdentifier","src":"974:6:17"},"variableNames":[{"name":"array","nodeType":"YulIdentifier","src":"965:5:17"}]}]},"name":"abi_decode_string_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"184:6:17","type":""},{"name":"end","nodeType":"YulTypedName","src":"192:3:17","type":""}],"returnVariables":[{"name":"array","nodeType":"YulTypedName","src":"200:5:17","type":""}],"src":"146:840:17"},{"body":{"nodeType":"YulBlock","src":"1109:444:17","statements":[{"body":{"nodeType":"YulBlock","src":"1155:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1164:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1167:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1157:6:17"},"nodeType":"YulFunctionCall","src":"1157:12:17"},"nodeType":"YulExpressionStatement","src":"1157:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"1130:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"1139:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1126:3:17"},"nodeType":"YulFunctionCall","src":"1126:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"1151:2:17","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"1122:3:17"},"nodeType":"YulFunctionCall","src":"1122:32:17"},"nodeType":"YulIf","src":"1119:52:17"},{"nodeType":"YulVariableDeclaration","src":"1180:30:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1200:9:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"1194:5:17"},"nodeType":"YulFunctionCall","src":"1194:16:17"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"1184:6:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"1219:28:17","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1237:2:17","type":"","value":"64"},{"kind":"number","nodeType":"YulLiteral","src":"1241:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1233:3:17"},"nodeType":"YulFunctionCall","src":"1233:10:17"},{"kind":"number","nodeType":"YulLiteral","src":"1245:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1229:3:17"},"nodeType":"YulFunctionCall","src":"1229:18:17"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"1223:2:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"1274:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1283:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1286:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1276:6:17"},"nodeType":"YulFunctionCall","src":"1276:12:17"},"nodeType":"YulExpressionStatement","src":"1276:12:17"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"1262:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"1270:2:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"1259:2:17"},"nodeType":"YulFunctionCall","src":"1259:14:17"},"nodeType":"YulIf","src":"1256:34:17"},{"nodeType":"YulAssignment","src":"1299:71:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1342:9:17"},{"name":"offset","nodeType":"YulIdentifier","src":"1353:6:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1338:3:17"},"nodeType":"YulFunctionCall","src":"1338:22:17"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"1362:7:17"}],"functionName":{"name":"abi_decode_string_fromMemory","nodeType":"YulIdentifier","src":"1309:28:17"},"nodeType":"YulFunctionCall","src":"1309:61:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"1299:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"1379:41:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1405:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1416:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1401:3:17"},"nodeType":"YulFunctionCall","src":"1401:18:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"1395:5:17"},"nodeType":"YulFunctionCall","src":"1395:25:17"},"variables":[{"name":"offset_1","nodeType":"YulTypedName","src":"1383:8:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"1449:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1458:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1461:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1451:6:17"},"nodeType":"YulFunctionCall","src":"1451:12:17"},"nodeType":"YulExpressionStatement","src":"1451:12:17"}]},"condition":{"arguments":[{"name":"offset_1","nodeType":"YulIdentifier","src":"1435:8:17"},{"name":"_1","nodeType":"YulIdentifier","src":"1445:2:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"1432:2:17"},"nodeType":"YulFunctionCall","src":"1432:16:17"},"nodeType":"YulIf","src":"1429:36:17"},{"nodeType":"YulAssignment","src":"1474:73:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1517:9:17"},{"name":"offset_1","nodeType":"YulIdentifier","src":"1528:8:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1513:3:17"},"nodeType":"YulFunctionCall","src":"1513:24:17"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"1539:7:17"}],"functionName":{"name":"abi_decode_string_fromMemory","nodeType":"YulIdentifier","src":"1484:28:17"},"nodeType":"YulFunctionCall","src":"1484:63:17"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"1474:6:17"}]}]},"name":"abi_decode_tuple_t_string_memory_ptrt_string_memory_ptr_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"1067:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"1078:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"1090:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"1098:6:17","type":""}],"src":"991:562:17"},{"body":{"nodeType":"YulBlock","src":"1613:325:17","statements":[{"nodeType":"YulAssignment","src":"1623:22:17","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1637:1:17","type":"","value":"1"},{"name":"data","nodeType":"YulIdentifier","src":"1640:4:17"}],"functionName":{"name":"shr","nodeType":"YulIdentifier","src":"1633:3:17"},"nodeType":"YulFunctionCall","src":"1633:12:17"},"variableNames":[{"name":"length","nodeType":"YulIdentifier","src":"1623:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"1654:38:17","value":{"arguments":[{"name":"data","nodeType":"YulIdentifier","src":"1684:4:17"},{"kind":"number","nodeType":"YulLiteral","src":"1690:1:17","type":"","value":"1"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1680:3:17"},"nodeType":"YulFunctionCall","src":"1680:12:17"},"variables":[{"name":"outOfPlaceEncoding","nodeType":"YulTypedName","src":"1658:18:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"1731:31:17","statements":[{"nodeType":"YulAssignment","src":"1733:27:17","value":{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"1747:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"1755:4:17","type":"","value":"0x7f"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1743:3:17"},"nodeType":"YulFunctionCall","src":"1743:17:17"},"variableNames":[{"name":"length","nodeType":"YulIdentifier","src":"1733:6:17"}]}]},"condition":{"arguments":[{"name":"outOfPlaceEncoding","nodeType":"YulIdentifier","src":"1711:18:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"1704:6:17"},"nodeType":"YulFunctionCall","src":"1704:26:17"},"nodeType":"YulIf","src":"1701:61:17"},{"body":{"nodeType":"YulBlock","src":"1821:111:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1842:1:17","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1849:3:17","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"1854:10:17","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1845:3:17"},"nodeType":"YulFunctionCall","src":"1845:20:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1835:6:17"},"nodeType":"YulFunctionCall","src":"1835:31:17"},"nodeType":"YulExpressionStatement","src":"1835:31:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1886:1:17","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"1889:4:17","type":"","value":"0x22"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1879:6:17"},"nodeType":"YulFunctionCall","src":"1879:15:17"},"nodeType":"YulExpressionStatement","src":"1879:15:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1914:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1917:4:17","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1907:6:17"},"nodeType":"YulFunctionCall","src":"1907:15:17"},"nodeType":"YulExpressionStatement","src":"1907:15:17"}]},"condition":{"arguments":[{"name":"outOfPlaceEncoding","nodeType":"YulIdentifier","src":"1777:18:17"},{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"1800:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"1808:2:17","type":"","value":"32"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"1797:2:17"},"nodeType":"YulFunctionCall","src":"1797:14:17"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"1774:2:17"},"nodeType":"YulFunctionCall","src":"1774:38:17"},"nodeType":"YulIf","src":"1771:161:17"}]},"name":"extract_byte_array_length","nodeType":"YulFunctionDefinition","parameters":[{"name":"data","nodeType":"YulTypedName","src":"1593:4:17","type":""}],"returnVariables":[{"name":"length","nodeType":"YulTypedName","src":"1602:6:17","type":""}],"src":"1558:380:17"},{"body":{"nodeType":"YulBlock","src":"1999:65:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2016:1:17","type":"","value":"0"},{"name":"ptr","nodeType":"YulIdentifier","src":"2019:3:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2009:6:17"},"nodeType":"YulFunctionCall","src":"2009:14:17"},"nodeType":"YulExpressionStatement","src":"2009:14:17"},{"nodeType":"YulAssignment","src":"2032:26:17","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2050:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2053:4:17","type":"","value":"0x20"}],"functionName":{"name":"keccak256","nodeType":"YulIdentifier","src":"2040:9:17"},"nodeType":"YulFunctionCall","src":"2040:18:17"},"variableNames":[{"name":"data","nodeType":"YulIdentifier","src":"2032:4:17"}]}]},"name":"array_dataslot_string_storage","nodeType":"YulFunctionDefinition","parameters":[{"name":"ptr","nodeType":"YulTypedName","src":"1982:3:17","type":""}],"returnVariables":[{"name":"data","nodeType":"YulTypedName","src":"1990:4:17","type":""}],"src":"1943:121:17"},{"body":{"nodeType":"YulBlock","src":"2150:464:17","statements":[{"body":{"nodeType":"YulBlock","src":"2183:425:17","statements":[{"nodeType":"YulVariableDeclaration","src":"2197:11:17","value":{"kind":"number","nodeType":"YulLiteral","src":"2207:1:17","type":"","value":"0"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"2201:2:17","type":""}]},{"expression":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"2228:2:17"},{"name":"array","nodeType":"YulIdentifier","src":"2232:5:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2221:6:17"},"nodeType":"YulFunctionCall","src":"2221:17:17"},"nodeType":"YulExpressionStatement","src":"2221:17:17"},{"nodeType":"YulVariableDeclaration","src":"2251:31:17","value":{"arguments":[{"name":"_1","nodeType":"YulIdentifier","src":"2273:2:17"},{"kind":"number","nodeType":"YulLiteral","src":"2277:4:17","type":"","value":"0x20"}],"functionName":{"name":"keccak256","nodeType":"YulIdentifier","src":"2263:9:17"},"nodeType":"YulFunctionCall","src":"2263:19:17"},"variables":[{"name":"data","nodeType":"YulTypedName","src":"2255:4:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"2295:57:17","value":{"arguments":[{"name":"data","nodeType":"YulIdentifier","src":"2318:4:17"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2328:1:17","type":"","value":"5"},{"arguments":[{"name":"startIndex","nodeType":"YulIdentifier","src":"2335:10:17"},{"kind":"number","nodeType":"YulLiteral","src":"2347:2:17","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2331:3:17"},"nodeType":"YulFunctionCall","src":"2331:19:17"}],"functionName":{"name":"shr","nodeType":"YulIdentifier","src":"2324:3:17"},"nodeType":"YulFunctionCall","src":"2324:27:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2314:3:17"},"nodeType":"YulFunctionCall","src":"2314:38:17"},"variables":[{"name":"deleteStart","nodeType":"YulTypedName","src":"2299:11:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"2389:23:17","statements":[{"nodeType":"YulAssignment","src":"2391:19:17","value":{"name":"data","nodeType":"YulIdentifier","src":"2406:4:17"},"variableNames":[{"name":"deleteStart","nodeType":"YulIdentifier","src":"2391:11:17"}]}]},"condition":{"arguments":[{"name":"startIndex","nodeType":"YulIdentifier","src":"2371:10:17"},{"kind":"number","nodeType":"YulLiteral","src":"2383:4:17","type":"","value":"0x20"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"2368:2:17"},"nodeType":"YulFunctionCall","src":"2368:20:17"},"nodeType":"YulIf","src":"2365:47:17"},{"nodeType":"YulVariableDeclaration","src":"2425:41:17","value":{"arguments":[{"name":"data","nodeType":"YulIdentifier","src":"2439:4:17"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2449:1:17","type":"","value":"5"},{"arguments":[{"name":"len","nodeType":"YulIdentifier","src":"2456:3:17"},{"kind":"number","nodeType":"YulLiteral","src":"2461:2:17","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2452:3:17"},"nodeType":"YulFunctionCall","src":"2452:12:17"}],"functionName":{"name":"shr","nodeType":"YulIdentifier","src":"2445:3:17"},"nodeType":"YulFunctionCall","src":"2445:20:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2435:3:17"},"nodeType":"YulFunctionCall","src":"2435:31:17"},"variables":[{"name":"_2","nodeType":"YulTypedName","src":"2429:2:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"2479:24:17","value":{"name":"deleteStart","nodeType":"YulIdentifier","src":"2492:11:17"},"variables":[{"name":"start","nodeType":"YulTypedName","src":"2483:5:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"2577:21:17","statements":[{"expression":{"arguments":[{"name":"start","nodeType":"YulIdentifier","src":"2586:5:17"},{"name":"_1","nodeType":"YulIdentifier","src":"2593:2:17"}],"functionName":{"name":"sstore","nodeType":"YulIdentifier","src":"2579:6:17"},"nodeType":"YulFunctionCall","src":"2579:17:17"},"nodeType":"YulExpressionStatement","src":"2579:17:17"}]},"condition":{"arguments":[{"name":"start","nodeType":"YulIdentifier","src":"2527:5:17"},{"name":"_2","nodeType":"YulIdentifier","src":"2534:2:17"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"2524:2:17"},"nodeType":"YulFunctionCall","src":"2524:13:17"},"nodeType":"YulForLoop","post":{"nodeType":"YulBlock","src":"2538:26:17","statements":[{"nodeType":"YulAssignment","src":"2540:22:17","value":{"arguments":[{"name":"start","nodeType":"YulIdentifier","src":"2553:5:17"},{"kind":"number","nodeType":"YulLiteral","src":"2560:1:17","type":"","value":"1"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2549:3:17"},"nodeType":"YulFunctionCall","src":"2549:13:17"},"variableNames":[{"name":"start","nodeType":"YulIdentifier","src":"2540:5:17"}]}]},"pre":{"nodeType":"YulBlock","src":"2520:3:17","statements":[]},"src":"2516:82:17"}]},"condition":{"arguments":[{"name":"len","nodeType":"YulIdentifier","src":"2166:3:17"},{"kind":"number","nodeType":"YulLiteral","src":"2171:2:17","type":"","value":"31"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2163:2:17"},"nodeType":"YulFunctionCall","src":"2163:11:17"},"nodeType":"YulIf","src":"2160:448:17"}]},"name":"clean_up_bytearray_end_slots_string_storage","nodeType":"YulFunctionDefinition","parameters":[{"name":"array","nodeType":"YulTypedName","src":"2122:5:17","type":""},{"name":"len","nodeType":"YulTypedName","src":"2129:3:17","type":""},{"name":"startIndex","nodeType":"YulTypedName","src":"2134:10:17","type":""}],"src":"2069:545:17"},{"body":{"nodeType":"YulBlock","src":"2704:81:17","statements":[{"nodeType":"YulAssignment","src":"2714:65:17","value":{"arguments":[{"arguments":[{"name":"data","nodeType":"YulIdentifier","src":"2729:4:17"},{"arguments":[{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2747:1:17","type":"","value":"3"},{"name":"len","nodeType":"YulIdentifier","src":"2750:3:17"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"2743:3:17"},"nodeType":"YulFunctionCall","src":"2743:11:17"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2760:1:17","type":"","value":"0"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"2756:3:17"},"nodeType":"YulFunctionCall","src":"2756:6:17"}],"functionName":{"name":"shr","nodeType":"YulIdentifier","src":"2739:3:17"},"nodeType":"YulFunctionCall","src":"2739:24:17"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"2735:3:17"},"nodeType":"YulFunctionCall","src":"2735:29:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"2725:3:17"},"nodeType":"YulFunctionCall","src":"2725:40:17"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2771:1:17","type":"","value":"1"},{"name":"len","nodeType":"YulIdentifier","src":"2774:3:17"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"2767:3:17"},"nodeType":"YulFunctionCall","src":"2767:11:17"}],"functionName":{"name":"or","nodeType":"YulIdentifier","src":"2722:2:17"},"nodeType":"YulFunctionCall","src":"2722:57:17"},"variableNames":[{"name":"used","nodeType":"YulIdentifier","src":"2714:4:17"}]}]},"name":"extract_used_part_and_set_length_of_short_byte_array","nodeType":"YulFunctionDefinition","parameters":[{"name":"data","nodeType":"YulTypedName","src":"2681:4:17","type":""},{"name":"len","nodeType":"YulTypedName","src":"2687:3:17","type":""}],"returnVariables":[{"name":"used","nodeType":"YulTypedName","src":"2695:4:17","type":""}],"src":"2619:166:17"},{"body":{"nodeType":"YulBlock","src":"2886:1256:17","statements":[{"nodeType":"YulVariableDeclaration","src":"2896:24:17","value":{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"2916:3:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"2910:5:17"},"nodeType":"YulFunctionCall","src":"2910:10:17"},"variables":[{"name":"newLen","nodeType":"YulTypedName","src":"2900:6:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"2963:22:17","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"2965:16:17"},"nodeType":"YulFunctionCall","src":"2965:18:17"},"nodeType":"YulExpressionStatement","src":"2965:18:17"}]},"condition":{"arguments":[{"name":"newLen","nodeType":"YulIdentifier","src":"2935:6:17"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2951:2:17","type":"","value":"64"},{"kind":"number","nodeType":"YulLiteral","src":"2955:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"2947:3:17"},"nodeType":"YulFunctionCall","src":"2947:10:17"},{"kind":"number","nodeType":"YulLiteral","src":"2959:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"2943:3:17"},"nodeType":"YulFunctionCall","src":"2943:18:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"2932:2:17"},"nodeType":"YulFunctionCall","src":"2932:30:17"},"nodeType":"YulIf","src":"2929:56:17"},{"expression":{"arguments":[{"name":"slot","nodeType":"YulIdentifier","src":"3038:4:17"},{"arguments":[{"arguments":[{"name":"slot","nodeType":"YulIdentifier","src":"3076:4:17"}],"functionName":{"name":"sload","nodeType":"YulIdentifier","src":"3070:5:17"},"nodeType":"YulFunctionCall","src":"3070:11:17"}],"functionName":{"name":"extract_byte_array_length","nodeType":"YulIdentifier","src":"3044:25:17"},"nodeType":"YulFunctionCall","src":"3044:38:17"},{"name":"newLen","nodeType":"YulIdentifier","src":"3084:6:17"}],"functionName":{"name":"clean_up_bytearray_end_slots_string_storage","nodeType":"YulIdentifier","src":"2994:43:17"},"nodeType":"YulFunctionCall","src":"2994:97:17"},"nodeType":"YulExpressionStatement","src":"2994:97:17"},{"nodeType":"YulVariableDeclaration","src":"3100:18:17","value":{"kind":"number","nodeType":"YulLiteral","src":"3117:1:17","type":"","value":"0"},"variables":[{"name":"srcOffset","nodeType":"YulTypedName","src":"3104:9:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"3127:23:17","value":{"kind":"number","nodeType":"YulLiteral","src":"3146:4:17","type":"","value":"0x20"},"variables":[{"name":"srcOffset_1","nodeType":"YulTypedName","src":"3131:11:17","type":""}]},{"nodeType":"YulAssignment","src":"3159:24:17","value":{"name":"srcOffset_1","nodeType":"YulIdentifier","src":"3172:11:17"},"variableNames":[{"name":"srcOffset","nodeType":"YulIdentifier","src":"3159:9:17"}]},{"cases":[{"body":{"nodeType":"YulBlock","src":"3229:656:17","statements":[{"nodeType":"YulVariableDeclaration","src":"3243:35:17","value":{"arguments":[{"name":"newLen","nodeType":"YulIdentifier","src":"3262:6:17"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3274:2:17","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"3270:3:17"},"nodeType":"YulFunctionCall","src":"3270:7:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"3258:3:17"},"nodeType":"YulFunctionCall","src":"3258:20:17"},"variables":[{"name":"loopEnd","nodeType":"YulTypedName","src":"3247:7:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"3291:49:17","value":{"arguments":[{"name":"slot","nodeType":"YulIdentifier","src":"3335:4:17"}],"functionName":{"name":"array_dataslot_string_storage","nodeType":"YulIdentifier","src":"3305:29:17"},"nodeType":"YulFunctionCall","src":"3305:35:17"},"variables":[{"name":"dstPtr","nodeType":"YulTypedName","src":"3295:6:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"3353:10:17","value":{"kind":"number","nodeType":"YulLiteral","src":"3362:1:17","type":"","value":"0"},"variables":[{"name":"i","nodeType":"YulTypedName","src":"3357:1:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"3440:172:17","statements":[{"expression":{"arguments":[{"name":"dstPtr","nodeType":"YulIdentifier","src":"3465:6:17"},{"arguments":[{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"3483:3:17"},{"name":"srcOffset","nodeType":"YulIdentifier","src":"3488:9:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3479:3:17"},"nodeType":"YulFunctionCall","src":"3479:19:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"3473:5:17"},"nodeType":"YulFunctionCall","src":"3473:26:17"}],"functionName":{"name":"sstore","nodeType":"YulIdentifier","src":"3458:6:17"},"nodeType":"YulFunctionCall","src":"3458:42:17"},"nodeType":"YulExpressionStatement","src":"3458:42:17"},{"nodeType":"YulAssignment","src":"3517:24:17","value":{"arguments":[{"name":"dstPtr","nodeType":"YulIdentifier","src":"3531:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"3539:1:17","type":"","value":"1"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3527:3:17"},"nodeType":"YulFunctionCall","src":"3527:14:17"},"variableNames":[{"name":"dstPtr","nodeType":"YulIdentifier","src":"3517:6:17"}]},{"nodeType":"YulAssignment","src":"3558:40:17","value":{"arguments":[{"name":"srcOffset","nodeType":"YulIdentifier","src":"3575:9:17"},{"name":"srcOffset_1","nodeType":"YulIdentifier","src":"3586:11:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3571:3:17"},"nodeType":"YulFunctionCall","src":"3571:27:17"},"variableNames":[{"name":"srcOffset","nodeType":"YulIdentifier","src":"3558:9:17"}]}]},"condition":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"3387:1:17"},{"name":"loopEnd","nodeType":"YulIdentifier","src":"3390:7:17"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"3384:2:17"},"nodeType":"YulFunctionCall","src":"3384:14:17"},"nodeType":"YulForLoop","post":{"nodeType":"YulBlock","src":"3399:28:17","statements":[{"nodeType":"YulAssignment","src":"3401:24:17","value":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"3410:1:17"},{"name":"srcOffset_1","nodeType":"YulIdentifier","src":"3413:11:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3406:3:17"},"nodeType":"YulFunctionCall","src":"3406:19:17"},"variableNames":[{"name":"i","nodeType":"YulIdentifier","src":"3401:1:17"}]}]},"pre":{"nodeType":"YulBlock","src":"3380:3:17","statements":[]},"src":"3376:236:17"},{"body":{"nodeType":"YulBlock","src":"3660:166:17","statements":[{"nodeType":"YulVariableDeclaration","src":"3678:43:17","value":{"arguments":[{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"3705:3:17"},{"name":"srcOffset","nodeType":"YulIdentifier","src":"3710:9:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3701:3:17"},"nodeType":"YulFunctionCall","src":"3701:19:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"3695:5:17"},"nodeType":"YulFunctionCall","src":"3695:26:17"},"variables":[{"name":"lastValue","nodeType":"YulTypedName","src":"3682:9:17","type":""}]},{"expression":{"arguments":[{"name":"dstPtr","nodeType":"YulIdentifier","src":"3745:6:17"},{"arguments":[{"name":"lastValue","nodeType":"YulIdentifier","src":"3757:9:17"},{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3784:1:17","type":"","value":"3"},{"name":"newLen","nodeType":"YulIdentifier","src":"3787:6:17"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"3780:3:17"},"nodeType":"YulFunctionCall","src":"3780:14:17"},{"kind":"number","nodeType":"YulLiteral","src":"3796:3:17","type":"","value":"248"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"3776:3:17"},"nodeType":"YulFunctionCall","src":"3776:24:17"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3806:1:17","type":"","value":"0"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"3802:3:17"},"nodeType":"YulFunctionCall","src":"3802:6:17"}],"functionName":{"name":"shr","nodeType":"YulIdentifier","src":"3772:3:17"},"nodeType":"YulFunctionCall","src":"3772:37:17"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"3768:3:17"},"nodeType":"YulFunctionCall","src":"3768:42:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"3753:3:17"},"nodeType":"YulFunctionCall","src":"3753:58:17"}],"functionName":{"name":"sstore","nodeType":"YulIdentifier","src":"3738:6:17"},"nodeType":"YulFunctionCall","src":"3738:74:17"},"nodeType":"YulExpressionStatement","src":"3738:74:17"}]},"condition":{"arguments":[{"name":"loopEnd","nodeType":"YulIdentifier","src":"3631:7:17"},{"name":"newLen","nodeType":"YulIdentifier","src":"3640:6:17"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"3628:2:17"},"nodeType":"YulFunctionCall","src":"3628:19:17"},"nodeType":"YulIf","src":"3625:201:17"},{"expression":{"arguments":[{"name":"slot","nodeType":"YulIdentifier","src":"3846:4:17"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3860:1:17","type":"","value":"1"},{"name":"newLen","nodeType":"YulIdentifier","src":"3863:6:17"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"3856:3:17"},"nodeType":"YulFunctionCall","src":"3856:14:17"},{"kind":"number","nodeType":"YulLiteral","src":"3872:1:17","type":"","value":"1"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3852:3:17"},"nodeType":"YulFunctionCall","src":"3852:22:17"}],"functionName":{"name":"sstore","nodeType":"YulIdentifier","src":"3839:6:17"},"nodeType":"YulFunctionCall","src":"3839:36:17"},"nodeType":"YulExpressionStatement","src":"3839:36:17"}]},"nodeType":"YulCase","src":"3222:663:17","value":{"kind":"number","nodeType":"YulLiteral","src":"3227:1:17","type":"","value":"1"}},{"body":{"nodeType":"YulBlock","src":"3902:234:17","statements":[{"nodeType":"YulVariableDeclaration","src":"3916:14:17","value":{"kind":"number","nodeType":"YulLiteral","src":"3929:1:17","type":"","value":"0"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"3920:5:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"3965:67:17","statements":[{"nodeType":"YulAssignment","src":"3983:35:17","value":{"arguments":[{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"4002:3:17"},{"name":"srcOffset","nodeType":"YulIdentifier","src":"4007:9:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3998:3:17"},"nodeType":"YulFunctionCall","src":"3998:19:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"3992:5:17"},"nodeType":"YulFunctionCall","src":"3992:26:17"},"variableNames":[{"name":"value","nodeType":"YulIdentifier","src":"3983:5:17"}]}]},"condition":{"name":"newLen","nodeType":"YulIdentifier","src":"3946:6:17"},"nodeType":"YulIf","src":"3943:89:17"},{"expression":{"arguments":[{"name":"slot","nodeType":"YulIdentifier","src":"4052:4:17"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"4111:5:17"},{"name":"newLen","nodeType":"YulIdentifier","src":"4118:6:17"}],"functionName":{"name":"extract_used_part_and_set_length_of_short_byte_array","nodeType":"YulIdentifier","src":"4058:52:17"},"nodeType":"YulFunctionCall","src":"4058:67:17"}],"functionName":{"name":"sstore","nodeType":"YulIdentifier","src":"4045:6:17"},"nodeType":"YulFunctionCall","src":"4045:81:17"},"nodeType":"YulExpressionStatement","src":"4045:81:17"}]},"nodeType":"YulCase","src":"3894:242:17","value":"default"}],"expression":{"arguments":[{"name":"newLen","nodeType":"YulIdentifier","src":"3202:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"3210:2:17","type":"","value":"31"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"3199:2:17"},"nodeType":"YulFunctionCall","src":"3199:14:17"},"nodeType":"YulSwitch","src":"3192:944:17"}]},"name":"copy_byte_array_to_storage_from_t_string_memory_ptr_to_t_string_storage","nodeType":"YulFunctionDefinition","parameters":[{"name":"slot","nodeType":"YulTypedName","src":"2871:4:17","type":""},{"name":"src","nodeType":"YulTypedName","src":"2877:3:17","type":""}],"src":"2790:1352:17"}]},"contents":"{\n { }\n function panic_error_0x41()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x41)\n revert(0, 0x24)\n }\n function abi_decode_string_fromMemory(offset, end) -> array\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n let _1 := mload(offset)\n let _2 := sub(shl(64, 1), 1)\n if gt(_1, _2) { panic_error_0x41() }\n let _3 := not(31)\n let memPtr := mload(64)\n let newFreePtr := add(memPtr, and(add(and(add(_1, 0x1f), _3), 63), _3))\n if or(gt(newFreePtr, _2), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n mstore(64, newFreePtr)\n mstore(memPtr, _1)\n let _4 := 0x20\n if gt(add(add(offset, _1), _4), end) { revert(0, 0) }\n let i := 0\n for { } lt(i, _1) { i := add(i, _4) }\n {\n mstore(add(add(memPtr, i), _4), mload(add(add(offset, i), _4)))\n }\n mstore(add(add(memPtr, _1), _4), 0)\n array := memPtr\n }\n function abi_decode_tuple_t_string_memory_ptrt_string_memory_ptr_fromMemory(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n let offset := mload(headStart)\n let _1 := sub(shl(64, 1), 1)\n if gt(offset, _1) { revert(0, 0) }\n value0 := abi_decode_string_fromMemory(add(headStart, offset), dataEnd)\n let offset_1 := mload(add(headStart, 32))\n if gt(offset_1, _1) { revert(0, 0) }\n value1 := abi_decode_string_fromMemory(add(headStart, offset_1), dataEnd)\n }\n function extract_byte_array_length(data) -> length\n {\n length := shr(1, data)\n let outOfPlaceEncoding := and(data, 1)\n if iszero(outOfPlaceEncoding) { length := and(length, 0x7f) }\n if eq(outOfPlaceEncoding, lt(length, 32))\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x22)\n revert(0, 0x24)\n }\n }\n function array_dataslot_string_storage(ptr) -> data\n {\n mstore(0, ptr)\n data := keccak256(0, 0x20)\n }\n function clean_up_bytearray_end_slots_string_storage(array, len, startIndex)\n {\n if gt(len, 31)\n {\n let _1 := 0\n mstore(_1, array)\n let data := keccak256(_1, 0x20)\n let deleteStart := add(data, shr(5, add(startIndex, 31)))\n if lt(startIndex, 0x20) { deleteStart := data }\n let _2 := add(data, shr(5, add(len, 31)))\n let start := deleteStart\n for { } lt(start, _2) { start := add(start, 1) }\n { sstore(start, _1) }\n }\n }\n function extract_used_part_and_set_length_of_short_byte_array(data, len) -> used\n {\n used := or(and(data, not(shr(shl(3, len), not(0)))), shl(1, len))\n }\n function copy_byte_array_to_storage_from_t_string_memory_ptr_to_t_string_storage(slot, src)\n {\n let newLen := mload(src)\n if gt(newLen, sub(shl(64, 1), 1)) { panic_error_0x41() }\n clean_up_bytearray_end_slots_string_storage(slot, extract_byte_array_length(sload(slot)), newLen)\n let srcOffset := 0\n let srcOffset_1 := 0x20\n srcOffset := srcOffset_1\n switch gt(newLen, 31)\n case 1 {\n let loopEnd := and(newLen, not(31))\n let dstPtr := array_dataslot_string_storage(slot)\n let i := 0\n for { } lt(i, loopEnd) { i := add(i, srcOffset_1) }\n {\n sstore(dstPtr, mload(add(src, srcOffset)))\n dstPtr := add(dstPtr, 1)\n srcOffset := add(srcOffset, srcOffset_1)\n }\n if lt(loopEnd, newLen)\n {\n let lastValue := mload(add(src, srcOffset))\n sstore(dstPtr, and(lastValue, not(shr(and(shl(3, newLen), 248), not(0)))))\n }\n sstore(slot, add(shl(1, newLen), 1))\n }\n default {\n let value := 0\n if newLen\n {\n value := mload(add(src, srcOffset))\n }\n sstore(slot, extract_used_part_and_set_length_of_short_byte_array(value, newLen))\n }\n }\n}","id":17,"language":"Yul","name":"#utility.yul"}],"linkReferences":{},"object":"60806040523480156200001157600080fd5b50604051620015ae380380620015ae833981016040819052620000349162000123565b818160006200004483826200021c565b5060016200005382826200021c565b5050505050620002e8565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200008657600080fd5b81516001600160401b0380821115620000a357620000a36200005e565b604051601f8301601f19908116603f01168101908282118183101715620000ce57620000ce6200005e565b81604052838152602092508683858801011115620000eb57600080fd5b600091505b838210156200010f5785820183015181830184015290820190620000f0565b600093810190920192909252949350505050565b600080604083850312156200013757600080fd5b82516001600160401b03808211156200014f57600080fd5b6200015d8683870162000074565b935060208501519150808211156200017457600080fd5b50620001838582860162000074565b9150509250929050565b600181811c90821680620001a257607f821691505b602082108103620001c357634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200021757600081815260208120601f850160051c81016020861015620001f25750805b601f850160051c820191505b818110156200021357828155600101620001fe565b5050505b505050565b81516001600160401b038111156200023857620002386200005e565b62000250816200024984546200018d565b84620001c9565b602080601f8311600181146200028857600084156200026f5750858301515b600019600386901b1c1916600185901b17855562000213565b600085815260208120601f198616915b82811015620002b95788860151825594840194600190910190840162000298565b5085821015620002d85787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6112b680620002f86000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80636352211e1161008c578063a22cb46511610066578063a22cb465146101e1578063b88d4fde146101f4578063c87b56dd14610207578063e985e9c51461021a57600080fd5b80636352211e146101a557806370a08231146101b857806395d89b41146101d957600080fd5b8063095ea7b3116100c8578063095ea7b31461015757806323b872dd1461016c57806340c10f191461017f57806342842e0e1461019257600080fd5b806301ffc9a7146100ef57806306fdde0314610117578063081812fc1461012c575b600080fd5b6101026100fd366004610e42565b610256565b60405190151581526020015b60405180910390f35b61011f6102a8565b60405161010e9190610eaf565b61013f61013a366004610ec2565b61033a565b6040516001600160a01b03909116815260200161010e565b61016a610165366004610ef7565b610361565b005b61016a61017a366004610f21565b61047b565b61016a61018d366004610ef7565b6104ac565b61016a6101a0366004610f21565b6104ba565b61013f6101b3366004610ec2565b6104d5565b6101cb6101c6366004610f5d565b610535565b60405190815260200161010e565b61011f6105bb565b61016a6101ef366004610f78565b6105ca565b61016a610202366004610fca565b6105d5565b61011f610215366004610ec2565b61060d565b6101026102283660046110a6565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60006001600160e01b031982166380ac58cd60e01b148061028757506001600160e01b03198216635b5e139f60e01b145b806102a257506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600080546102b7906110d9565b80601f01602080910402602001604051908101604052809291908181526020018280546102e3906110d9565b80156103305780601f1061030557610100808354040283529160200191610330565b820191906000526020600020905b81548152906001019060200180831161031357829003601f168201915b5050505050905090565b600061034582610681565b506000908152600460205260409020546001600160a01b031690565b600061036c826104d5565b9050806001600160a01b0316836001600160a01b0316036103de5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806103fa57506103fa8133610228565b61046c5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c00000060648201526084016103d5565b61047683836106e3565b505050565b6104853382610751565b6104a15760405162461bcd60e51b81526004016103d590611113565b6104768383836107d0565b6104b68282610934565b5050565b610476838383604051806020016040528060008152506105d5565b6000818152600260205260408120546001600160a01b0316806102a25760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103d5565b60006001600160a01b03821661059f5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016103d5565b506001600160a01b031660009081526003602052604090205490565b6060600180546102b7906110d9565b6104b6338383610abf565b6105df3383610751565b6105fb5760405162461bcd60e51b81526004016103d590611113565b61060784848484610b8d565b50505050565b606061061882610681565b600061062f60408051602081019091526000815290565b9050600081511161064f576040518060200160405280600081525061067a565b8061065984610bc0565b60405160200161066a929190611160565b6040516020818303038152906040525b9392505050565b6000818152600260205260409020546001600160a01b03166106e05760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103d5565b50565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610718826104d5565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061075d836104d5565b9050806001600160a01b0316846001600160a01b031614806107a457506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b806107c85750836001600160a01b03166107bd8461033a565b6001600160a01b0316145b949350505050565b826001600160a01b03166107e3826104d5565b6001600160a01b0316146108095760405162461bcd60e51b81526004016103d59061118f565b6001600160a01b03821661086b5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016103d5565b826001600160a01b031661087e826104d5565b6001600160a01b0316146108a45760405162461bcd60e51b81526004016103d59061118f565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b03821661098a5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016103d5565b6000818152600260205260409020546001600160a01b0316156109ef5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016103d5565b6000818152600260205260409020546001600160a01b031615610a545760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016103d5565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b816001600160a01b0316836001600160a01b031603610b205760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016103d5565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b610b988484846107d0565b610ba484848484610c53565b6106075760405162461bcd60e51b81526004016103d5906111d4565b60606000610bcd83610d54565b600101905060008167ffffffffffffffff811115610bed57610bed610fb4565b6040519080825280601f01601f191660200182016040528015610c17576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084610c2157509392505050565b60006001600160a01b0384163b15610d4957604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290610c97903390899088908890600401611226565b6020604051808303816000875af1925050508015610cd2575060408051601f3d908101601f19168201909252610ccf91810190611263565b60015b610d2f573d808015610d00576040519150601f19603f3d011682016040523d82523d6000602084013e610d05565b606091505b508051600003610d275760405162461bcd60e51b81526004016103d5906111d4565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506107c8565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310610d935772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310610dbf576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310610ddd57662386f26fc10000830492506010015b6305f5e1008310610df5576305f5e100830492506008015b6127108310610e0957612710830492506004015b60648310610e1b576064830492506002015b600a83106102a25760010192915050565b6001600160e01b0319811681146106e057600080fd5b600060208284031215610e5457600080fd5b813561067a81610e2c565b60005b83811015610e7a578181015183820152602001610e62565b50506000910152565b60008151808452610e9b816020860160208601610e5f565b601f01601f19169290920160200192915050565b60208152600061067a6020830184610e83565b600060208284031215610ed457600080fd5b5035919050565b80356001600160a01b0381168114610ef257600080fd5b919050565b60008060408385031215610f0a57600080fd5b610f1383610edb565b946020939093013593505050565b600080600060608486031215610f3657600080fd5b610f3f84610edb565b9250610f4d60208501610edb565b9150604084013590509250925092565b600060208284031215610f6f57600080fd5b61067a82610edb565b60008060408385031215610f8b57600080fd5b610f9483610edb565b915060208301358015158114610fa957600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215610fe057600080fd5b610fe985610edb565b9350610ff760208601610edb565b925060408501359150606085013567ffffffffffffffff8082111561101b57600080fd5b818701915087601f83011261102f57600080fd5b81358181111561104157611041610fb4565b604051601f8201601f19908116603f0116810190838211818310171561106957611069610fb4565b816040528281528a602084870101111561108257600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b600080604083850312156110b957600080fd5b6110c283610edb565b91506110d060208401610edb565b90509250929050565b600181811c908216806110ed57607f821691505b60208210810361110d57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b60008351611172818460208801610e5f565b835190830190611186818360208801610e5f565b01949350505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061125990830184610e83565b9695505050505050565b60006020828403121561127557600080fd5b815161067a81610e2c56fea26469706673582212203e5c29bc0c6611a8b7a6b12c19a302bc12fee5e380672b063f2b72a4f2ffcd6b64736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH3 0x11 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 MLOAD PUSH3 0x15AE CODESIZE SUB DUP1 PUSH3 0x15AE DUP4 CODECOPY DUP2 ADD PUSH1 0x40 DUP2 SWAP1 MSTORE PUSH3 0x34 SWAP2 PUSH3 0x123 JUMP JUMPDEST DUP2 DUP2 PUSH1 0x0 PUSH3 0x44 DUP4 DUP3 PUSH3 0x21C JUMP JUMPDEST POP PUSH1 0x1 PUSH3 0x53 DUP3 DUP3 PUSH3 0x21C JUMP JUMPDEST POP POP POP POP POP PUSH3 0x2E8 JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 DUP3 PUSH1 0x1F DUP4 ADD SLT PUSH3 0x86 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0x40 SHL SUB DUP1 DUP3 GT ISZERO PUSH3 0xA3 JUMPI PUSH3 0xA3 PUSH3 0x5E JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP4 ADD PUSH1 0x1F NOT SWAP1 DUP2 AND PUSH1 0x3F ADD AND DUP2 ADD SWAP1 DUP3 DUP3 GT DUP2 DUP4 LT OR ISZERO PUSH3 0xCE JUMPI PUSH3 0xCE PUSH3 0x5E JUMP JUMPDEST DUP2 PUSH1 0x40 MSTORE DUP4 DUP2 MSTORE PUSH1 0x20 SWAP3 POP DUP7 DUP4 DUP6 DUP9 ADD ADD GT ISZERO PUSH3 0xEB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 SWAP2 POP JUMPDEST DUP4 DUP3 LT ISZERO PUSH3 0x10F JUMPI DUP6 DUP3 ADD DUP4 ADD MLOAD DUP2 DUP4 ADD DUP5 ADD MSTORE SWAP1 DUP3 ADD SWAP1 PUSH3 0xF0 JUMP JUMPDEST PUSH1 0x0 SWAP4 DUP2 ADD SWAP1 SWAP3 ADD SWAP3 SWAP1 SWAP3 MSTORE SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH3 0x137 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0x40 SHL SUB DUP1 DUP3 GT ISZERO PUSH3 0x14F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH3 0x15D DUP7 DUP4 DUP8 ADD PUSH3 0x74 JUMP JUMPDEST SWAP4 POP PUSH1 0x20 DUP6 ADD MLOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH3 0x174 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH3 0x183 DUP6 DUP3 DUP7 ADD PUSH3 0x74 JUMP JUMPDEST SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x1 DUP2 DUP2 SHR SWAP1 DUP3 AND DUP1 PUSH3 0x1A2 JUMPI PUSH1 0x7F DUP3 AND SWAP2 POP JUMPDEST PUSH1 0x20 DUP3 LT DUP2 SUB PUSH3 0x1C3 JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x22 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x1F DUP3 GT ISZERO PUSH3 0x217 JUMPI PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x20 DUP2 KECCAK256 PUSH1 0x1F DUP6 ADD PUSH1 0x5 SHR DUP2 ADD PUSH1 0x20 DUP7 LT ISZERO PUSH3 0x1F2 JUMPI POP DUP1 JUMPDEST PUSH1 0x1F DUP6 ADD PUSH1 0x5 SHR DUP3 ADD SWAP2 POP JUMPDEST DUP2 DUP2 LT ISZERO PUSH3 0x213 JUMPI DUP3 DUP2 SSTORE PUSH1 0x1 ADD PUSH3 0x1FE JUMP JUMPDEST POP POP POP JUMPDEST POP POP POP JUMP JUMPDEST DUP2 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0x40 SHL SUB DUP2 GT ISZERO PUSH3 0x238 JUMPI PUSH3 0x238 PUSH3 0x5E JUMP JUMPDEST PUSH3 0x250 DUP2 PUSH3 0x249 DUP5 SLOAD PUSH3 0x18D JUMP JUMPDEST DUP5 PUSH3 0x1C9 JUMP JUMPDEST PUSH1 0x20 DUP1 PUSH1 0x1F DUP4 GT PUSH1 0x1 DUP2 EQ PUSH3 0x288 JUMPI PUSH1 0x0 DUP5 ISZERO PUSH3 0x26F JUMPI POP DUP6 DUP4 ADD MLOAD JUMPDEST PUSH1 0x0 NOT PUSH1 0x3 DUP7 SWAP1 SHL SHR NOT AND PUSH1 0x1 DUP6 SWAP1 SHL OR DUP6 SSTORE PUSH3 0x213 JUMP JUMPDEST PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x20 DUP2 KECCAK256 PUSH1 0x1F NOT DUP7 AND SWAP2 JUMPDEST DUP3 DUP2 LT ISZERO PUSH3 0x2B9 JUMPI DUP9 DUP7 ADD MLOAD DUP3 SSTORE SWAP5 DUP5 ADD SWAP5 PUSH1 0x1 SWAP1 SWAP2 ADD SWAP1 DUP5 ADD PUSH3 0x298 JUMP JUMPDEST POP DUP6 DUP3 LT ISZERO PUSH3 0x2D8 JUMPI DUP8 DUP6 ADD MLOAD PUSH1 0x0 NOT PUSH1 0x3 DUP9 SWAP1 SHL PUSH1 0xF8 AND SHR NOT AND DUP2 SSTORE JUMPDEST POP POP POP POP POP PUSH1 0x1 SWAP1 DUP2 SHL ADD SWAP1 SSTORE POP JUMP JUMPDEST PUSH2 0x12B6 DUP1 PUSH3 0x2F8 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0xEA JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x6352211E GT PUSH2 0x8C JUMPI DUP1 PUSH4 0xA22CB465 GT PUSH2 0x66 JUMPI DUP1 PUSH4 0xA22CB465 EQ PUSH2 0x1E1 JUMPI DUP1 PUSH4 0xB88D4FDE EQ PUSH2 0x1F4 JUMPI DUP1 PUSH4 0xC87B56DD EQ PUSH2 0x207 JUMPI DUP1 PUSH4 0xE985E9C5 EQ PUSH2 0x21A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x6352211E EQ PUSH2 0x1A5 JUMPI DUP1 PUSH4 0x70A08231 EQ PUSH2 0x1B8 JUMPI DUP1 PUSH4 0x95D89B41 EQ PUSH2 0x1D9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x95EA7B3 GT PUSH2 0xC8 JUMPI DUP1 PUSH4 0x95EA7B3 EQ PUSH2 0x157 JUMPI DUP1 PUSH4 0x23B872DD EQ PUSH2 0x16C JUMPI DUP1 PUSH4 0x40C10F19 EQ PUSH2 0x17F JUMPI DUP1 PUSH4 0x42842E0E EQ PUSH2 0x192 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1FFC9A7 EQ PUSH2 0xEF JUMPI DUP1 PUSH4 0x6FDDE03 EQ PUSH2 0x117 JUMPI DUP1 PUSH4 0x81812FC EQ PUSH2 0x12C JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x102 PUSH2 0xFD CALLDATASIZE PUSH1 0x4 PUSH2 0xE42 JUMP JUMPDEST PUSH2 0x256 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x11F PUSH2 0x2A8 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x10E SWAP2 SWAP1 PUSH2 0xEAF JUMP JUMPDEST PUSH2 0x13F PUSH2 0x13A CALLDATASIZE PUSH1 0x4 PUSH2 0xEC2 JUMP JUMPDEST PUSH2 0x33A JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x10E JUMP JUMPDEST PUSH2 0x16A PUSH2 0x165 CALLDATASIZE PUSH1 0x4 PUSH2 0xEF7 JUMP JUMPDEST PUSH2 0x361 JUMP JUMPDEST STOP JUMPDEST PUSH2 0x16A PUSH2 0x17A CALLDATASIZE PUSH1 0x4 PUSH2 0xF21 JUMP JUMPDEST PUSH2 0x47B JUMP JUMPDEST PUSH2 0x16A PUSH2 0x18D CALLDATASIZE PUSH1 0x4 PUSH2 0xEF7 JUMP JUMPDEST PUSH2 0x4AC JUMP JUMPDEST PUSH2 0x16A PUSH2 0x1A0 CALLDATASIZE PUSH1 0x4 PUSH2 0xF21 JUMP JUMPDEST PUSH2 0x4BA JUMP JUMPDEST PUSH2 0x13F PUSH2 0x1B3 CALLDATASIZE PUSH1 0x4 PUSH2 0xEC2 JUMP JUMPDEST PUSH2 0x4D5 JUMP JUMPDEST PUSH2 0x1CB PUSH2 0x1C6 CALLDATASIZE PUSH1 0x4 PUSH2 0xF5D JUMP JUMPDEST PUSH2 0x535 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x10E JUMP JUMPDEST PUSH2 0x11F PUSH2 0x5BB JUMP JUMPDEST PUSH2 0x16A PUSH2 0x1EF CALLDATASIZE PUSH1 0x4 PUSH2 0xF78 JUMP JUMPDEST PUSH2 0x5CA JUMP JUMPDEST PUSH2 0x16A PUSH2 0x202 CALLDATASIZE PUSH1 0x4 PUSH2 0xFCA JUMP JUMPDEST PUSH2 0x5D5 JUMP JUMPDEST PUSH2 0x11F PUSH2 0x215 CALLDATASIZE PUSH1 0x4 PUSH2 0xEC2 JUMP JUMPDEST PUSH2 0x60D JUMP JUMPDEST PUSH2 0x102 PUSH2 0x228 CALLDATASIZE PUSH1 0x4 PUSH2 0x10A6 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP2 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 SWAP1 SWAP5 AND DUP3 MSTORE SWAP2 SWAP1 SWAP2 MSTORE KECCAK256 SLOAD PUSH1 0xFF AND SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP3 AND PUSH4 0x80AC58CD PUSH1 0xE0 SHL EQ DUP1 PUSH2 0x287 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP3 AND PUSH4 0x5B5E139F PUSH1 0xE0 SHL EQ JUMPDEST DUP1 PUSH2 0x2A2 JUMPI POP PUSH4 0x1FFC9A7 PUSH1 0xE0 SHL PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND EQ JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 SLOAD PUSH2 0x2B7 SWAP1 PUSH2 0x10D9 JUMP JUMPDEST DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD PUSH2 0x2E3 SWAP1 PUSH2 0x10D9 JUMP JUMPDEST DUP1 ISZERO PUSH2 0x330 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x305 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x330 JUMP JUMPDEST DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD DUP2 MSTORE SWAP1 PUSH1 0x1 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0x313 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x345 DUP3 PUSH2 0x681 JUMP JUMPDEST POP PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x4 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x36C DUP3 PUSH2 0x4D5 JUMP JUMPDEST SWAP1 POP DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP4 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SUB PUSH2 0x3DE JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x21 PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A20617070726F76616C20746F2063757272656E74206F776E65 PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x39 PUSH1 0xF9 SHL PUSH1 0x64 DUP3 ADD MSTORE PUSH1 0x84 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND EQ DUP1 PUSH2 0x3FA JUMPI POP PUSH2 0x3FA DUP2 CALLER PUSH2 0x228 JUMP JUMPDEST PUSH2 0x46C JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x3D PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A20617070726F76652063616C6C6572206973206E6F7420746F PUSH1 0x44 DUP3 ADD MSTORE PUSH32 0x6B656E206F776E6572206F7220617070726F76656420666F7220616C6C000000 PUSH1 0x64 DUP3 ADD MSTORE PUSH1 0x84 ADD PUSH2 0x3D5 JUMP JUMPDEST PUSH2 0x476 DUP4 DUP4 PUSH2 0x6E3 JUMP JUMPDEST POP POP POP JUMP JUMPDEST PUSH2 0x485 CALLER DUP3 PUSH2 0x751 JUMP JUMPDEST PUSH2 0x4A1 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3D5 SWAP1 PUSH2 0x1113 JUMP JUMPDEST PUSH2 0x476 DUP4 DUP4 DUP4 PUSH2 0x7D0 JUMP JUMPDEST PUSH2 0x4B6 DUP3 DUP3 PUSH2 0x934 JUMP JUMPDEST POP POP JUMP JUMPDEST PUSH2 0x476 DUP4 DUP4 DUP4 PUSH1 0x40 MLOAD DUP1 PUSH1 0x20 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 DUP2 MSTORE POP PUSH2 0x5D5 JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP1 PUSH2 0x2A2 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x18 PUSH1 0x24 DUP3 ADD MSTORE PUSH24 0x115490CDCC8C4E881A5B9D985B1A59081D1BDAD95B881251 PUSH1 0x42 SHL PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3D5 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND PUSH2 0x59F JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x29 PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A2061646472657373207A65726F206973206E6F742061207661 PUSH1 0x44 DUP3 ADD MSTORE PUSH9 0x3634B21037BBB732B9 PUSH1 0xB9 SHL PUSH1 0x64 DUP3 ADD MSTORE PUSH1 0x84 ADD PUSH2 0x3D5 JUMP JUMPDEST POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x3 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x1 DUP1 SLOAD PUSH2 0x2B7 SWAP1 PUSH2 0x10D9 JUMP JUMPDEST PUSH2 0x4B6 CALLER DUP4 DUP4 PUSH2 0xABF JUMP JUMPDEST PUSH2 0x5DF CALLER DUP4 PUSH2 0x751 JUMP JUMPDEST PUSH2 0x5FB JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3D5 SWAP1 PUSH2 0x1113 JUMP JUMPDEST PUSH2 0x607 DUP5 DUP5 DUP5 DUP5 PUSH2 0xB8D JUMP JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x60 PUSH2 0x618 DUP3 PUSH2 0x681 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x62F PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 DUP2 ADD SWAP1 SWAP2 MSTORE PUSH1 0x0 DUP2 MSTORE SWAP1 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 DUP2 MLOAD GT PUSH2 0x64F JUMPI PUSH1 0x40 MLOAD DUP1 PUSH1 0x20 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 DUP2 MSTORE POP PUSH2 0x67A JUMP JUMPDEST DUP1 PUSH2 0x659 DUP5 PUSH2 0xBC0 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0x66A SWAP3 SWAP2 SWAP1 PUSH2 0x1160 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH2 0x6E0 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x18 PUSH1 0x24 DUP3 ADD MSTORE PUSH24 0x115490CDCC8C4E881A5B9D985B1A59081D1BDAD95B881251 PUSH1 0x42 SHL PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3D5 JUMP JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x4 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 DUP1 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB NOT AND PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE DUP2 SWAP1 PUSH2 0x718 DUP3 PUSH2 0x4D5 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH32 0x8C5BE1E5EBEC7D5BD14F71427D1E84F3DD0314C0F7B2291E5B200AC8C7C3B925 PUSH1 0x40 MLOAD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG4 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH2 0x75D DUP4 PUSH2 0x4D5 JUMP JUMPDEST SWAP1 POP DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP5 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ DUP1 PUSH2 0x7A4 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP1 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP9 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD PUSH1 0xFF AND JUMPDEST DUP1 PUSH2 0x7C8 JUMPI POP DUP4 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH2 0x7BD DUP5 PUSH2 0x33A JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST DUP3 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH2 0x7E3 DUP3 PUSH2 0x4D5 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ PUSH2 0x809 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3D5 SWAP1 PUSH2 0x118F JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND PUSH2 0x86B JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x24 DUP1 DUP3 ADD MSTORE PUSH32 0x4552433732313A207472616E7366657220746F20746865207A65726F20616464 PUSH1 0x44 DUP3 ADD MSTORE PUSH4 0x72657373 PUSH1 0xE0 SHL PUSH1 0x64 DUP3 ADD MSTORE PUSH1 0x84 ADD PUSH2 0x3D5 JUMP JUMPDEST DUP3 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH2 0x87E DUP3 PUSH2 0x4D5 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ PUSH2 0x8A4 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3D5 SWAP1 PUSH2 0x118F JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x4 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 DUP1 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB NOT SWAP1 DUP2 AND SWAP1 SWAP2 SSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP8 DUP2 AND DUP1 DUP7 MSTORE PUSH1 0x3 DUP6 MSTORE DUP4 DUP7 KECCAK256 DUP1 SLOAD PUSH1 0x0 NOT ADD SWAP1 SSTORE SWAP1 DUP8 AND DUP1 DUP7 MSTORE DUP4 DUP7 KECCAK256 DUP1 SLOAD PUSH1 0x1 ADD SWAP1 SSTORE DUP7 DUP7 MSTORE PUSH1 0x2 SWAP1 SWAP5 MSTORE DUP3 DUP6 KECCAK256 DUP1 SLOAD SWAP1 SWAP3 AND DUP5 OR SWAP1 SWAP2 SSTORE SWAP1 MLOAD DUP5 SWAP4 PUSH32 0xDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF SWAP2 LOG4 POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND PUSH2 0x98A JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A206D696E7420746F20746865207A65726F2061646472657373 PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3D5 JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND ISZERO PUSH2 0x9EF JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x1C PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A20746F6B656E20616C7265616479206D696E74656400000000 PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3D5 JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND ISZERO PUSH2 0xA54 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x1C PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A20746F6B656E20616C7265616479206D696E74656400000000 PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3D5 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x3 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 DUP1 SLOAD PUSH1 0x1 ADD SWAP1 SSTORE DUP5 DUP4 MSTORE PUSH1 0x2 SWAP1 SWAP2 MSTORE DUP1 DUP3 KECCAK256 DUP1 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB NOT AND DUP5 OR SWAP1 SSTORE MLOAD DUP4 SWAP3 SWAP2 SWAP1 PUSH32 0xDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF SWAP1 DUP3 SWAP1 LOG4 POP POP JUMP JUMPDEST DUP2 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP4 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SUB PUSH2 0xB20 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x19 PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A20617070726F766520746F2063616C6C657200000000000000 PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3D5 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 DUP2 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP5 DUP8 AND DUP1 DUP5 MSTORE SWAP5 DUP3 MSTORE SWAP2 DUP3 SWAP1 KECCAK256 DUP1 SLOAD PUSH1 0xFF NOT AND DUP7 ISZERO ISZERO SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE SWAP2 MLOAD SWAP2 DUP3 MSTORE PUSH32 0x17307EAB39AB6107E8899845AD3D59BD9653F200F220920489CA2B5937696C31 SWAP2 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 POP POP POP JUMP JUMPDEST PUSH2 0xB98 DUP5 DUP5 DUP5 PUSH2 0x7D0 JUMP JUMPDEST PUSH2 0xBA4 DUP5 DUP5 DUP5 DUP5 PUSH2 0xC53 JUMP JUMPDEST PUSH2 0x607 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3D5 SWAP1 PUSH2 0x11D4 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 PUSH2 0xBCD DUP4 PUSH2 0xD54 JUMP JUMPDEST PUSH1 0x1 ADD SWAP1 POP PUSH1 0x0 DUP2 PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xBED JUMPI PUSH2 0xBED PUSH2 0xFB4 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x1F ADD PUSH1 0x1F NOT AND PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xC17 JUMPI PUSH1 0x20 DUP3 ADD DUP2 DUP1 CALLDATASIZE DUP4 CALLDATACOPY ADD SWAP1 POP JUMPDEST POP SWAP1 POP DUP2 DUP2 ADD PUSH1 0x20 ADD JUMPDEST PUSH1 0x0 NOT ADD PUSH16 0x181899199A1A9B1B9C1CB0B131B232B3 PUSH1 0x81 SHL PUSH1 0xA DUP7 MOD BYTE DUP2 MSTORE8 PUSH1 0xA DUP6 DIV SWAP5 POP DUP5 PUSH2 0xC21 JUMPI POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND EXTCODESIZE ISZERO PUSH2 0xD49 JUMPI PUSH1 0x40 MLOAD PUSH4 0xA85BD01 PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP6 AND SWAP1 PUSH4 0x150B7A02 SWAP1 PUSH2 0xC97 SWAP1 CALLER SWAP1 DUP10 SWAP1 DUP9 SWAP1 DUP9 SWAP1 PUSH1 0x4 ADD PUSH2 0x1226 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL SWAP3 POP POP POP DUP1 ISZERO PUSH2 0xCD2 JUMPI POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x1F RETURNDATASIZE SWAP1 DUP2 ADD PUSH1 0x1F NOT AND DUP3 ADD SWAP1 SWAP3 MSTORE PUSH2 0xCCF SWAP2 DUP2 ADD SWAP1 PUSH2 0x1263 JUMP JUMPDEST PUSH1 0x1 JUMPDEST PUSH2 0xD2F JUMPI RETURNDATASIZE DUP1 DUP1 ISZERO PUSH2 0xD00 JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0xD05 JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP DUP1 MLOAD PUSH1 0x0 SUB PUSH2 0xD27 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3D5 SWAP1 PUSH2 0x11D4 JUMP JUMPDEST DUP1 MLOAD DUP2 PUSH1 0x20 ADD REVERT JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT AND PUSH4 0xA85BD01 PUSH1 0xE1 SHL EQ SWAP1 POP PUSH2 0x7C8 JUMP JUMPDEST POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH19 0x184F03E93FF9F4DAA797ED6E38ED64BF6A1F01 PUSH1 0x40 SHL DUP4 LT PUSH2 0xD93 JUMPI PUSH19 0x184F03E93FF9F4DAA797ED6E38ED64BF6A1F01 PUSH1 0x40 SHL DUP4 DIV SWAP3 POP PUSH1 0x40 ADD JUMPDEST PUSH14 0x4EE2D6D415B85ACEF8100000000 DUP4 LT PUSH2 0xDBF JUMPI PUSH14 0x4EE2D6D415B85ACEF8100000000 DUP4 DIV SWAP3 POP PUSH1 0x20 ADD JUMPDEST PUSH7 0x2386F26FC10000 DUP4 LT PUSH2 0xDDD JUMPI PUSH7 0x2386F26FC10000 DUP4 DIV SWAP3 POP PUSH1 0x10 ADD JUMPDEST PUSH4 0x5F5E100 DUP4 LT PUSH2 0xDF5 JUMPI PUSH4 0x5F5E100 DUP4 DIV SWAP3 POP PUSH1 0x8 ADD JUMPDEST PUSH2 0x2710 DUP4 LT PUSH2 0xE09 JUMPI PUSH2 0x2710 DUP4 DIV SWAP3 POP PUSH1 0x4 ADD JUMPDEST PUSH1 0x64 DUP4 LT PUSH2 0xE1B JUMPI PUSH1 0x64 DUP4 DIV SWAP3 POP PUSH1 0x2 ADD JUMPDEST PUSH1 0xA DUP4 LT PUSH2 0x2A2 JUMPI PUSH1 0x1 ADD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP2 AND DUP2 EQ PUSH2 0x6E0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xE54 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x67A DUP2 PUSH2 0xE2C JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0xE7A JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0xE62 JUMP JUMPDEST POP POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD DUP1 DUP5 MSTORE PUSH2 0xE9B DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0xE5F JUMP JUMPDEST PUSH1 0x1F ADD PUSH1 0x1F NOT AND SWAP3 SWAP1 SWAP3 ADD PUSH1 0x20 ADD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE PUSH1 0x0 PUSH2 0x67A PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0xE83 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xED4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 CALLDATALOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0xEF2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xF0A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xF13 DUP4 PUSH2 0xEDB JUMP JUMPDEST SWAP5 PUSH1 0x20 SWAP4 SWAP1 SWAP4 ADD CALLDATALOAD SWAP4 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xF36 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xF3F DUP5 PUSH2 0xEDB JUMP JUMPDEST SWAP3 POP PUSH2 0xF4D PUSH1 0x20 DUP6 ADD PUSH2 0xEDB JUMP JUMPDEST SWAP2 POP PUSH1 0x40 DUP5 ADD CALLDATALOAD SWAP1 POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xF6F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x67A DUP3 PUSH2 0xEDB JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xF8B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xF94 DUP4 PUSH2 0xEDB JUMP JUMPDEST SWAP2 POP PUSH1 0x20 DUP4 ADD CALLDATALOAD DUP1 ISZERO ISZERO DUP2 EQ PUSH2 0xFA9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xFE0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xFE9 DUP6 PUSH2 0xEDB JUMP JUMPDEST SWAP4 POP PUSH2 0xFF7 PUSH1 0x20 DUP7 ADD PUSH2 0xEDB JUMP JUMPDEST SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD SWAP2 POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x101B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP8 ADD SWAP2 POP DUP8 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x102F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP2 DUP2 GT ISZERO PUSH2 0x1041 JUMPI PUSH2 0x1041 PUSH2 0xFB4 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT SWAP1 DUP2 AND PUSH1 0x3F ADD AND DUP2 ADD SWAP1 DUP4 DUP3 GT DUP2 DUP4 LT OR ISZERO PUSH2 0x1069 JUMPI PUSH2 0x1069 PUSH2 0xFB4 JUMP JUMPDEST DUP2 PUSH1 0x40 MSTORE DUP3 DUP2 MSTORE DUP11 PUSH1 0x20 DUP5 DUP8 ADD ADD GT ISZERO PUSH2 0x1082 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 PUSH1 0x20 DUP5 DUP4 ADD ADD MSTORE DUP1 SWAP6 POP POP POP POP POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x10B9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x10C2 DUP4 PUSH2 0xEDB JUMP JUMPDEST SWAP2 POP PUSH2 0x10D0 PUSH1 0x20 DUP5 ADD PUSH2 0xEDB JUMP JUMPDEST SWAP1 POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x1 DUP2 DUP2 SHR SWAP1 DUP3 AND DUP1 PUSH2 0x10ED JUMPI PUSH1 0x7F DUP3 AND SWAP2 POP JUMPDEST PUSH1 0x20 DUP3 LT DUP2 SUB PUSH2 0x110D JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x22 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE PUSH1 0x2D SWAP1 DUP3 ADD MSTORE PUSH32 0x4552433732313A2063616C6C6572206973206E6F7420746F6B656E206F776E65 PUSH1 0x40 DUP3 ADD MSTORE PUSH13 0x1C881BDC88185C1C1C9BDD9959 PUSH1 0x9A SHL PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP4 MLOAD PUSH2 0x1172 DUP2 DUP5 PUSH1 0x20 DUP9 ADD PUSH2 0xE5F JUMP JUMPDEST DUP4 MLOAD SWAP1 DUP4 ADD SWAP1 PUSH2 0x1186 DUP2 DUP4 PUSH1 0x20 DUP9 ADD PUSH2 0xE5F JUMP JUMPDEST ADD SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE PUSH1 0x25 SWAP1 DUP3 ADD MSTORE PUSH32 0x4552433732313A207472616E736665722066726F6D20696E636F727265637420 PUSH1 0x40 DUP3 ADD MSTORE PUSH5 0x37BBB732B9 PUSH1 0xD9 SHL PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE PUSH1 0x32 SWAP1 DUP3 ADD MSTORE PUSH32 0x4552433732313A207472616E7366657220746F206E6F6E204552433732315265 PUSH1 0x40 DUP3 ADD MSTORE PUSH18 0x31B2B4BB32B91034B6B83632B6B2B73A32B9 PUSH1 0x71 SHL PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP6 DUP2 AND DUP3 MSTORE DUP5 AND PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 DUP2 ADD DUP4 SWAP1 MSTORE PUSH1 0x80 PUSH1 0x60 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0x0 SWAP1 PUSH2 0x1259 SWAP1 DUP4 ADD DUP5 PUSH2 0xE83 JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1275 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x67A DUP2 PUSH2 0xE2C JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 RETURNDATACOPY 0x5C 0x29 0xBC 0xC PUSH7 0x11A8B7A6B12C19 LOG3 MUL 0xBC SLT INVALID 0xE5 0xE3 DUP1 PUSH8 0x2B063F2B72A4F2FF 0xCD PUSH12 0x64736F6C6343000811003300 ","sourceMap":"117:263:16:-:0;;;199:86;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;262:5;269:7;1456:5:0;:13;262:5:16;1456::0;:13;:::i;:::-;-1:-1:-1;1479:7:0;:17;1489:7;1479;:17;:::i;:::-;;1390:113;;199:86:16;;117:263;;14:127:17;75:10;70:3;66:20;63:1;56:31;106:4;103:1;96:15;130:4;127:1;120:15;146:840;200:5;253:3;246:4;238:6;234:17;230:27;220:55;;271:1;268;261:12;220:55;294:13;;-1:-1:-1;;;;;356:10:17;;;353:36;;;369:18;;:::i;:::-;444:2;438:9;412:2;498:13;;-1:-1:-1;;494:22:17;;;518:2;490:31;486:40;474:53;;;542:18;;;562:22;;;539:46;536:72;;;588:18;;:::i;:::-;628:10;624:2;617:22;663:2;655:6;648:18;685:4;675:14;;730:3;725:2;720;712:6;708:15;704:24;701:33;698:53;;;747:1;744;737:12;698:53;769:1;760:10;;779:133;793:2;790:1;787:9;779:133;;;881:14;;;877:23;;871:30;850:14;;;846:23;;839:63;804:10;;;;779:133;;;954:1;932:15;;;928:24;;;921:35;;;;936:6;146:840;-1:-1:-1;;;;146:840:17:o;991:562::-;1090:6;1098;1151:2;1139:9;1130:7;1126:23;1122:32;1119:52;;;1167:1;1164;1157:12;1119:52;1194:16;;-1:-1:-1;;;;;1259:14:17;;;1256:34;;;1286:1;1283;1276:12;1256:34;1309:61;1362:7;1353:6;1342:9;1338:22;1309:61;:::i;:::-;1299:71;;1416:2;1405:9;1401:18;1395:25;1379:41;;1445:2;1435:8;1432:16;1429:36;;;1461:1;1458;1451:12;1429:36;;1484:63;1539:7;1528:8;1517:9;1513:24;1484:63;:::i;:::-;1474:73;;;991:562;;;;;:::o;1558:380::-;1637:1;1633:12;;;;1680;;;1701:61;;1755:4;1747:6;1743:17;1733:27;;1701:61;1808:2;1800:6;1797:14;1777:18;1774:38;1771:161;;1854:10;1849:3;1845:20;1842:1;1835:31;1889:4;1886:1;1879:15;1917:4;1914:1;1907:15;1771:161;;1558:380;;;:::o;2069:545::-;2171:2;2166:3;2163:11;2160:448;;;2207:1;2232:5;2228:2;2221:17;2277:4;2273:2;2263:19;2347:2;2335:10;2331:19;2328:1;2324:27;2318:4;2314:38;2383:4;2371:10;2368:20;2365:47;;;-1:-1:-1;2406:4:17;2365:47;2461:2;2456:3;2452:12;2449:1;2445:20;2439:4;2435:31;2425:41;;2516:82;2534:2;2527:5;2524:13;2516:82;;;2579:17;;;2560:1;2549:13;2516:82;;;2520:3;;;2160:448;2069:545;;;:::o;2790:1352::-;2910:10;;-1:-1:-1;;;;;2932:30:17;;2929:56;;;2965:18;;:::i;:::-;2994:97;3084:6;3044:38;3076:4;3070:11;3044:38;:::i;:::-;3038:4;2994:97;:::i;:::-;3146:4;;3210:2;3199:14;;3227:1;3222:663;;;;3929:1;3946:6;3943:89;;;-1:-1:-1;3998:19:17;;;3992:26;3943:89;-1:-1:-1;;2747:1:17;2743:11;;;2739:24;2735:29;2725:40;2771:1;2767:11;;;2722:57;4045:81;;3192:944;;3222:663;2016:1;2009:14;;;2053:4;2040:18;;-1:-1:-1;;3258:20:17;;;3376:236;3390:7;3387:1;3384:14;3376:236;;;3479:19;;;3473:26;3458:42;;3571:27;;;;3539:1;3527:14;;;;3406:19;;3376:236;;;3380:3;3640:6;3631:7;3628:19;3625:201;;;3701:19;;;3695:26;-1:-1:-1;;3784:1:17;3780:14;;;3796:3;3776:24;3772:37;3768:42;3753:58;3738:74;;3625:201;-1:-1:-1;;;;;3872:1:17;3856:14;;;3852:22;3839:36;;-1:-1:-1;2790:1352:17:o;:::-;117:263:16;;;;;;"},"deployedBytecode":{"functionDebugData":{"@_afterTokenTransfer_910":{"entryPoint":null,"id":910,"parameterSlots":4,"returnSlots":0},"@_approve_776":{"entryPoint":1763,"id":776,"parameterSlots":2,"returnSlots":0},"@_baseURI_213":{"entryPoint":null,"id":213,"parameterSlots":0,"returnSlots":1},"@_beforeTokenTransfer_897":{"entryPoint":null,"id":897,"parameterSlots":4,"returnSlots":0},"@_checkOnERC721Received_884":{"entryPoint":3155,"id":884,"parameterSlots":4,"returnSlots":1},"@_exists_445":{"entryPoint":null,"id":445,"parameterSlots":1,"returnSlots":1},"@_isApprovedOrOwner_479":{"entryPoint":1873,"id":479,"parameterSlots":2,"returnSlots":1},"@_mint_600":{"entryPoint":2356,"id":600,"parameterSlots":2,"returnSlots":0},"@_msgSender_1429":{"entryPoint":null,"id":1429,"parameterSlots":0,"returnSlots":1},"@_ownerOf_427":{"entryPoint":null,"id":427,"parameterSlots":1,"returnSlots":1},"@_requireMinted_822":{"entryPoint":1665,"id":822,"parameterSlots":1,"returnSlots":0},"@_safeTransfer_414":{"entryPoint":2957,"id":414,"parameterSlots":4,"returnSlots":0},"@_setApprovalForAll_808":{"entryPoint":2751,"id":808,"parameterSlots":3,"returnSlots":0},"@_transfer_752":{"entryPoint":2000,"id":752,"parameterSlots":3,"returnSlots":0},"@approve_256":{"entryPoint":865,"id":256,"parameterSlots":2,"returnSlots":0},"@balanceOf_117":{"entryPoint":1333,"id":117,"parameterSlots":1,"returnSlots":1},"@getApproved_274":{"entryPoint":826,"id":274,"parameterSlots":1,"returnSlots":1},"@isApprovedForAll_309":{"entryPoint":null,"id":309,"parameterSlots":2,"returnSlots":1},"@isContract_1105":{"entryPoint":null,"id":1105,"parameterSlots":1,"returnSlots":1},"@log10_2407":{"entryPoint":3412,"id":2407,"parameterSlots":1,"returnSlots":1},"@mint_3237":{"entryPoint":1196,"id":3237,"parameterSlots":2,"returnSlots":0},"@name_155":{"entryPoint":680,"id":155,"parameterSlots":0,"returnSlots":1},"@ownerOf_145":{"entryPoint":1237,"id":145,"parameterSlots":1,"returnSlots":1},"@safeTransferFrom_355":{"entryPoint":1210,"id":355,"parameterSlots":3,"returnSlots":0},"@safeTransferFrom_385":{"entryPoint":1493,"id":385,"parameterSlots":4,"returnSlots":0},"@setApprovalForAll_291":{"entryPoint":1482,"id":291,"parameterSlots":2,"returnSlots":0},"@supportsInterface_1691":{"entryPoint":null,"id":1691,"parameterSlots":1,"returnSlots":1},"@supportsInterface_93":{"entryPoint":598,"id":93,"parameterSlots":1,"returnSlots":1},"@symbol_165":{"entryPoint":1467,"id":165,"parameterSlots":0,"returnSlots":1},"@toString_1498":{"entryPoint":3008,"id":1498,"parameterSlots":1,"returnSlots":1},"@tokenURI_204":{"entryPoint":1549,"id":204,"parameterSlots":1,"returnSlots":1},"@transferFrom_336":{"entryPoint":1147,"id":336,"parameterSlots":3,"returnSlots":0},"abi_decode_address":{"entryPoint":3803,"id":null,"parameterSlots":1,"returnSlots":1},"abi_decode_tuple_t_address":{"entryPoint":3933,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_addresst_address":{"entryPoint":4262,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_tuple_t_addresst_addresst_uint256":{"entryPoint":3873,"id":null,"parameterSlots":2,"returnSlots":3},"abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr":{"entryPoint":4042,"id":null,"parameterSlots":2,"returnSlots":4},"abi_decode_tuple_t_addresst_bool":{"entryPoint":3960,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_tuple_t_addresst_uint256":{"entryPoint":3831,"id":null,"parameterSlots":2,"returnSlots":2},"abi_decode_tuple_t_bytes4":{"entryPoint":3650,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_bytes4_fromMemory":{"entryPoint":4707,"id":null,"parameterSlots":2,"returnSlots":1},"abi_decode_tuple_t_uint256":{"entryPoint":3778,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_string":{"entryPoint":3715,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_packed_t_string_memory_ptr_t_string_memory_ptr__to_t_string_memory_ptr_t_string_memory_ptr__nonPadded_inplace_fromStack_reversed":{"entryPoint":4448,"id":null,"parameterSlots":3,"returnSlots":1},"abi_encode_tuple_t_address__to_t_address__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_address_t_address_t_uint256_t_bytes_memory_ptr__to_t_address_t_address_t_uint256_t_bytes_memory_ptr__fromStack_reversed":{"entryPoint":4646,"id":null,"parameterSlots":5,"returnSlots":1},"abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":3759,"id":null,"parameterSlots":2,"returnSlots":1},"abi_encode_tuple_t_stringliteral_12a8e5623d251e191fe4a291d9a59bcc01a4db7a1f5c20fc8de44358c18308af__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":4371,"id":null,"parameterSlots":1,"returnSlots":1},"abi_encode_tuple_t_stringliteral_1e766a06da43a53d0f4c380e06e5a342e14d5af1bf8501996c844905530ca84e__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":4564,"id":null,"parameterSlots":1,"returnSlots":1},"abi_encode_tuple_t_stringliteral_277f8ee9d5b4fc3c4149386f24de0fc1bbc63a8210e2197bfd1c0376a2ac5f48__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":4495,"id":null,"parameterSlots":1,"returnSlots":1},"abi_encode_tuple_t_stringliteral_2a63ce106ef95058ed21fd07c42a10f11dc5c32ac13a4e847923f7759f635d57__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":1,"returnSlots":1},"abi_encode_tuple_t_stringliteral_455fea98ea03c32d7dd1a6f1426917d80529bf47b3ccbde74e7206e889e709f4__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":1,"returnSlots":1},"abi_encode_tuple_t_stringliteral_45fe4329685be5ecd250fd0e6a25aea0ea4d0e30fb6a73c118b95749e6d70d05__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":1,"returnSlots":1},"abi_encode_tuple_t_stringliteral_6d05c90094f31cfeb8f0eb86f0a513af3f7f8992991fbde41b08aa7960677159__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":1,"returnSlots":1},"abi_encode_tuple_t_stringliteral_8a66f4bb6512ffbfcc3db9b42318eb65f26ac15163eaa9a1e5cfa7bee9d1c7c6__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":1,"returnSlots":1},"abi_encode_tuple_t_stringliteral_b08d2b0fec7cc108ab049809a8beb42779d969a49299d0c317c907d9db22974f__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":1,"returnSlots":1},"abi_encode_tuple_t_stringliteral_b51b4875eede07862961e8f9365c6749f5fe55c6ee5d7a9e42b6912ad0b15942__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":1,"returnSlots":1},"abi_encode_tuple_t_stringliteral_c6e14a63ffb144eeef7cce6988e5dce07c60a7e0a7b1ef25dbe18c61483e0a83__to_t_string_memory_ptr__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":1,"returnSlots":1},"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed":{"entryPoint":null,"id":null,"parameterSlots":2,"returnSlots":1},"copy_memory_to_memory_with_cleanup":{"entryPoint":3679,"id":null,"parameterSlots":3,"returnSlots":0},"extract_byte_array_length":{"entryPoint":4313,"id":null,"parameterSlots":1,"returnSlots":1},"panic_error_0x12":{"entryPoint":null,"id":null,"parameterSlots":0,"returnSlots":0},"panic_error_0x41":{"entryPoint":4020,"id":null,"parameterSlots":0,"returnSlots":0},"validator_revert_bytes4":{"entryPoint":3628,"id":null,"parameterSlots":1,"returnSlots":0}},"generatedSources":[{"ast":{"nodeType":"YulBlock","src":"0:10850:17","statements":[{"nodeType":"YulBlock","src":"6:3:17","statements":[]},{"body":{"nodeType":"YulBlock","src":"58:87:17","statements":[{"body":{"nodeType":"YulBlock","src":"123:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"132:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"135:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"125:6:17"},"nodeType":"YulFunctionCall","src":"125:12:17"},"nodeType":"YulExpressionStatement","src":"125:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"81:5:17"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"92:5:17"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"103:3:17","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"108:10:17","type":"","value":"0xffffffff"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"99:3:17"},"nodeType":"YulFunctionCall","src":"99:20:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"88:3:17"},"nodeType":"YulFunctionCall","src":"88:32:17"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"78:2:17"},"nodeType":"YulFunctionCall","src":"78:43:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"71:6:17"},"nodeType":"YulFunctionCall","src":"71:51:17"},"nodeType":"YulIf","src":"68:71:17"}]},"name":"validator_revert_bytes4","nodeType":"YulFunctionDefinition","parameters":[{"name":"value","nodeType":"YulTypedName","src":"47:5:17","type":""}],"src":"14:131:17"},{"body":{"nodeType":"YulBlock","src":"219:176:17","statements":[{"body":{"nodeType":"YulBlock","src":"265:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"274:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"277:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"267:6:17"},"nodeType":"YulFunctionCall","src":"267:12:17"},"nodeType":"YulExpressionStatement","src":"267:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"240:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"249:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"236:3:17"},"nodeType":"YulFunctionCall","src":"236:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"261:2:17","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"232:3:17"},"nodeType":"YulFunctionCall","src":"232:32:17"},"nodeType":"YulIf","src":"229:52:17"},{"nodeType":"YulVariableDeclaration","src":"290:36:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"316:9:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"303:12:17"},"nodeType":"YulFunctionCall","src":"303:23:17"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"294:5:17","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"359:5:17"}],"functionName":{"name":"validator_revert_bytes4","nodeType":"YulIdentifier","src":"335:23:17"},"nodeType":"YulFunctionCall","src":"335:30:17"},"nodeType":"YulExpressionStatement","src":"335:30:17"},{"nodeType":"YulAssignment","src":"374:15:17","value":{"name":"value","nodeType":"YulIdentifier","src":"384:5:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"374:6:17"}]}]},"name":"abi_decode_tuple_t_bytes4","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"185:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"196:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"208:6:17","type":""}],"src":"150:245:17"},{"body":{"nodeType":"YulBlock","src":"495:92:17","statements":[{"nodeType":"YulAssignment","src":"505:26:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"517:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"528:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"513:3:17"},"nodeType":"YulFunctionCall","src":"513:18:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"505:4:17"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"547:9:17"},{"arguments":[{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"572:6:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"565:6:17"},"nodeType":"YulFunctionCall","src":"565:14:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"558:6:17"},"nodeType":"YulFunctionCall","src":"558:22:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"540:6:17"},"nodeType":"YulFunctionCall","src":"540:41:17"},"nodeType":"YulExpressionStatement","src":"540:41:17"}]},"name":"abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"464:9:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"475:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"486:4:17","type":""}],"src":"400:187:17"},{"body":{"nodeType":"YulBlock","src":"658:184:17","statements":[{"nodeType":"YulVariableDeclaration","src":"668:10:17","value":{"kind":"number","nodeType":"YulLiteral","src":"677:1:17","type":"","value":"0"},"variables":[{"name":"i","nodeType":"YulTypedName","src":"672:1:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"737:63:17","statements":[{"expression":{"arguments":[{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"762:3:17"},{"name":"i","nodeType":"YulIdentifier","src":"767:1:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"758:3:17"},"nodeType":"YulFunctionCall","src":"758:11:17"},{"arguments":[{"arguments":[{"name":"src","nodeType":"YulIdentifier","src":"781:3:17"},{"name":"i","nodeType":"YulIdentifier","src":"786:1:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"777:3:17"},"nodeType":"YulFunctionCall","src":"777:11:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"771:5:17"},"nodeType":"YulFunctionCall","src":"771:18:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"751:6:17"},"nodeType":"YulFunctionCall","src":"751:39:17"},"nodeType":"YulExpressionStatement","src":"751:39:17"}]},"condition":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"698:1:17"},{"name":"length","nodeType":"YulIdentifier","src":"701:6:17"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"695:2:17"},"nodeType":"YulFunctionCall","src":"695:13:17"},"nodeType":"YulForLoop","post":{"nodeType":"YulBlock","src":"709:19:17","statements":[{"nodeType":"YulAssignment","src":"711:15:17","value":{"arguments":[{"name":"i","nodeType":"YulIdentifier","src":"720:1:17"},{"kind":"number","nodeType":"YulLiteral","src":"723:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"716:3:17"},"nodeType":"YulFunctionCall","src":"716:10:17"},"variableNames":[{"name":"i","nodeType":"YulIdentifier","src":"711:1:17"}]}]},"pre":{"nodeType":"YulBlock","src":"691:3:17","statements":[]},"src":"687:113:17"},{"expression":{"arguments":[{"arguments":[{"name":"dst","nodeType":"YulIdentifier","src":"820:3:17"},{"name":"length","nodeType":"YulIdentifier","src":"825:6:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"816:3:17"},"nodeType":"YulFunctionCall","src":"816:16:17"},{"kind":"number","nodeType":"YulLiteral","src":"834:1:17","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"809:6:17"},"nodeType":"YulFunctionCall","src":"809:27:17"},"nodeType":"YulExpressionStatement","src":"809:27:17"}]},"name":"copy_memory_to_memory_with_cleanup","nodeType":"YulFunctionDefinition","parameters":[{"name":"src","nodeType":"YulTypedName","src":"636:3:17","type":""},{"name":"dst","nodeType":"YulTypedName","src":"641:3:17","type":""},{"name":"length","nodeType":"YulTypedName","src":"646:6:17","type":""}],"src":"592:250:17"},{"body":{"nodeType":"YulBlock","src":"897:221:17","statements":[{"nodeType":"YulVariableDeclaration","src":"907:26:17","value":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"927:5:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"921:5:17"},"nodeType":"YulFunctionCall","src":"921:12:17"},"variables":[{"name":"length","nodeType":"YulTypedName","src":"911:6:17","type":""}]},{"expression":{"arguments":[{"name":"pos","nodeType":"YulIdentifier","src":"949:3:17"},{"name":"length","nodeType":"YulIdentifier","src":"954:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"942:6:17"},"nodeType":"YulFunctionCall","src":"942:19:17"},"nodeType":"YulExpressionStatement","src":"942:19:17"},{"expression":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1009:5:17"},{"kind":"number","nodeType":"YulLiteral","src":"1016:4:17","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1005:3:17"},"nodeType":"YulFunctionCall","src":"1005:16:17"},{"arguments":[{"name":"pos","nodeType":"YulIdentifier","src":"1027:3:17"},{"kind":"number","nodeType":"YulLiteral","src":"1032:4:17","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1023:3:17"},"nodeType":"YulFunctionCall","src":"1023:14:17"},{"name":"length","nodeType":"YulIdentifier","src":"1039:6:17"}],"functionName":{"name":"copy_memory_to_memory_with_cleanup","nodeType":"YulIdentifier","src":"970:34:17"},"nodeType":"YulFunctionCall","src":"970:76:17"},"nodeType":"YulExpressionStatement","src":"970:76:17"},{"nodeType":"YulAssignment","src":"1055:57:17","value":{"arguments":[{"arguments":[{"name":"pos","nodeType":"YulIdentifier","src":"1070:3:17"},{"arguments":[{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"1083:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"1091:2:17","type":"","value":"31"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1079:3:17"},"nodeType":"YulFunctionCall","src":"1079:15:17"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1100:2:17","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"1096:3:17"},"nodeType":"YulFunctionCall","src":"1096:7:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1075:3:17"},"nodeType":"YulFunctionCall","src":"1075:29:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1066:3:17"},"nodeType":"YulFunctionCall","src":"1066:39:17"},{"kind":"number","nodeType":"YulLiteral","src":"1107:4:17","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1062:3:17"},"nodeType":"YulFunctionCall","src":"1062:50:17"},"variableNames":[{"name":"end","nodeType":"YulIdentifier","src":"1055:3:17"}]}]},"name":"abi_encode_string","nodeType":"YulFunctionDefinition","parameters":[{"name":"value","nodeType":"YulTypedName","src":"874:5:17","type":""},{"name":"pos","nodeType":"YulTypedName","src":"881:3:17","type":""}],"returnVariables":[{"name":"end","nodeType":"YulTypedName","src":"889:3:17","type":""}],"src":"847:271:17"},{"body":{"nodeType":"YulBlock","src":"1244:99:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1261:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1272:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1254:6:17"},"nodeType":"YulFunctionCall","src":"1254:21:17"},"nodeType":"YulExpressionStatement","src":"1254:21:17"},{"nodeType":"YulAssignment","src":"1284:53:17","value":{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"1310:6:17"},{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1322:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1333:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1318:3:17"},"nodeType":"YulFunctionCall","src":"1318:18:17"}],"functionName":{"name":"abi_encode_string","nodeType":"YulIdentifier","src":"1292:17:17"},"nodeType":"YulFunctionCall","src":"1292:45:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"1284:4:17"}]}]},"name":"abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"1213:9:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"1224:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"1235:4:17","type":""}],"src":"1123:220:17"},{"body":{"nodeType":"YulBlock","src":"1418:110:17","statements":[{"body":{"nodeType":"YulBlock","src":"1464:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1473:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1476:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1466:6:17"},"nodeType":"YulFunctionCall","src":"1466:12:17"},"nodeType":"YulExpressionStatement","src":"1466:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"1439:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"1448:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1435:3:17"},"nodeType":"YulFunctionCall","src":"1435:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"1460:2:17","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"1431:3:17"},"nodeType":"YulFunctionCall","src":"1431:32:17"},"nodeType":"YulIf","src":"1428:52:17"},{"nodeType":"YulAssignment","src":"1489:33:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1512:9:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1499:12:17"},"nodeType":"YulFunctionCall","src":"1499:23:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"1489:6:17"}]}]},"name":"abi_decode_tuple_t_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"1384:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"1395:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"1407:6:17","type":""}],"src":"1348:180:17"},{"body":{"nodeType":"YulBlock","src":"1634:102:17","statements":[{"nodeType":"YulAssignment","src":"1644:26:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1656:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"1667:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"1652:3:17"},"nodeType":"YulFunctionCall","src":"1652:18:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"1644:4:17"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"1686:9:17"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"1701:6:17"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1717:3:17","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"1722:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1713:3:17"},"nodeType":"YulFunctionCall","src":"1713:11:17"},{"kind":"number","nodeType":"YulLiteral","src":"1726:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1709:3:17"},"nodeType":"YulFunctionCall","src":"1709:19:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1697:3:17"},"nodeType":"YulFunctionCall","src":"1697:32:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"1679:6:17"},"nodeType":"YulFunctionCall","src":"1679:51:17"},"nodeType":"YulExpressionStatement","src":"1679:51:17"}]},"name":"abi_encode_tuple_t_address__to_t_address__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"1603:9:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"1614:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"1625:4:17","type":""}],"src":"1533:203:17"},{"body":{"nodeType":"YulBlock","src":"1790:124:17","statements":[{"nodeType":"YulAssignment","src":"1800:29:17","value":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"1822:6:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"1809:12:17"},"nodeType":"YulFunctionCall","src":"1809:20:17"},"variableNames":[{"name":"value","nodeType":"YulIdentifier","src":"1800:5:17"}]},{"body":{"nodeType":"YulBlock","src":"1892:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1901:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"1904:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"1894:6:17"},"nodeType":"YulFunctionCall","src":"1894:12:17"},"nodeType":"YulExpressionStatement","src":"1894:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1851:5:17"},{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"1862:5:17"},{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"1877:3:17","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"1882:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"1873:3:17"},"nodeType":"YulFunctionCall","src":"1873:11:17"},{"kind":"number","nodeType":"YulLiteral","src":"1886:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"1869:3:17"},"nodeType":"YulFunctionCall","src":"1869:19:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"1858:3:17"},"nodeType":"YulFunctionCall","src":"1858:31:17"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"1848:2:17"},"nodeType":"YulFunctionCall","src":"1848:42:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"1841:6:17"},"nodeType":"YulFunctionCall","src":"1841:50:17"},"nodeType":"YulIf","src":"1838:70:17"}]},"name":"abi_decode_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"offset","nodeType":"YulTypedName","src":"1769:6:17","type":""}],"returnVariables":[{"name":"value","nodeType":"YulTypedName","src":"1780:5:17","type":""}],"src":"1741:173:17"},{"body":{"nodeType":"YulBlock","src":"2006:167:17","statements":[{"body":{"nodeType":"YulBlock","src":"2052:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2061:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2064:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2054:6:17"},"nodeType":"YulFunctionCall","src":"2054:12:17"},"nodeType":"YulExpressionStatement","src":"2054:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"2027:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"2036:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"2023:3:17"},"nodeType":"YulFunctionCall","src":"2023:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"2048:2:17","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"2019:3:17"},"nodeType":"YulFunctionCall","src":"2019:32:17"},"nodeType":"YulIf","src":"2016:52:17"},{"nodeType":"YulAssignment","src":"2077:39:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2106:9:17"}],"functionName":{"name":"abi_decode_address","nodeType":"YulIdentifier","src":"2087:18:17"},"nodeType":"YulFunctionCall","src":"2087:29:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"2077:6:17"}]},{"nodeType":"YulAssignment","src":"2125:42:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2152:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"2163:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2148:3:17"},"nodeType":"YulFunctionCall","src":"2148:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2135:12:17"},"nodeType":"YulFunctionCall","src":"2135:32:17"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"2125:6:17"}]}]},"name":"abi_decode_tuple_t_addresst_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"1964:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"1975:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"1987:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"1995:6:17","type":""}],"src":"1919:254:17"},{"body":{"nodeType":"YulBlock","src":"2282:224:17","statements":[{"body":{"nodeType":"YulBlock","src":"2328:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2337:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2340:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2330:6:17"},"nodeType":"YulFunctionCall","src":"2330:12:17"},"nodeType":"YulExpressionStatement","src":"2330:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"2303:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"2312:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"2299:3:17"},"nodeType":"YulFunctionCall","src":"2299:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"2324:2:17","type":"","value":"96"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"2295:3:17"},"nodeType":"YulFunctionCall","src":"2295:32:17"},"nodeType":"YulIf","src":"2292:52:17"},{"nodeType":"YulAssignment","src":"2353:39:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2382:9:17"}],"functionName":{"name":"abi_decode_address","nodeType":"YulIdentifier","src":"2363:18:17"},"nodeType":"YulFunctionCall","src":"2363:29:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"2353:6:17"}]},{"nodeType":"YulAssignment","src":"2401:48:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2434:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"2445:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2430:3:17"},"nodeType":"YulFunctionCall","src":"2430:18:17"}],"functionName":{"name":"abi_decode_address","nodeType":"YulIdentifier","src":"2411:18:17"},"nodeType":"YulFunctionCall","src":"2411:38:17"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"2401:6:17"}]},{"nodeType":"YulAssignment","src":"2458:42:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2485:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"2496:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2481:3:17"},"nodeType":"YulFunctionCall","src":"2481:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"2468:12:17"},"nodeType":"YulFunctionCall","src":"2468:32:17"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"2458:6:17"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"2232:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"2243:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"2255:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"2263:6:17","type":""},{"name":"value2","nodeType":"YulTypedName","src":"2271:6:17","type":""}],"src":"2178:328:17"},{"body":{"nodeType":"YulBlock","src":"2581:116:17","statements":[{"body":{"nodeType":"YulBlock","src":"2627:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"2636:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"2639:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"2629:6:17"},"nodeType":"YulFunctionCall","src":"2629:12:17"},"nodeType":"YulExpressionStatement","src":"2629:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"2602:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"2611:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"2598:3:17"},"nodeType":"YulFunctionCall","src":"2598:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"2623:2:17","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"2594:3:17"},"nodeType":"YulFunctionCall","src":"2594:32:17"},"nodeType":"YulIf","src":"2591:52:17"},{"nodeType":"YulAssignment","src":"2652:39:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2681:9:17"}],"functionName":{"name":"abi_decode_address","nodeType":"YulIdentifier","src":"2662:18:17"},"nodeType":"YulFunctionCall","src":"2662:29:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"2652:6:17"}]}]},"name":"abi_decode_tuple_t_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"2547:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"2558:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"2570:6:17","type":""}],"src":"2511:186:17"},{"body":{"nodeType":"YulBlock","src":"2803:76:17","statements":[{"nodeType":"YulAssignment","src":"2813:26:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2825:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"2836:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"2821:3:17"},"nodeType":"YulFunctionCall","src":"2821:18:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"2813:4:17"}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"2855:9:17"},{"name":"value0","nodeType":"YulIdentifier","src":"2866:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"2848:6:17"},"nodeType":"YulFunctionCall","src":"2848:25:17"},"nodeType":"YulExpressionStatement","src":"2848:25:17"}]},"name":"abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"2772:9:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"2783:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"2794:4:17","type":""}],"src":"2702:177:17"},{"body":{"nodeType":"YulBlock","src":"2968:263:17","statements":[{"body":{"nodeType":"YulBlock","src":"3014:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3023:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3026:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3016:6:17"},"nodeType":"YulFunctionCall","src":"3016:12:17"},"nodeType":"YulExpressionStatement","src":"3016:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"2989:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"2998:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"2985:3:17"},"nodeType":"YulFunctionCall","src":"2985:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"3010:2:17","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"2981:3:17"},"nodeType":"YulFunctionCall","src":"2981:32:17"},"nodeType":"YulIf","src":"2978:52:17"},{"nodeType":"YulAssignment","src":"3039:39:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3068:9:17"}],"functionName":{"name":"abi_decode_address","nodeType":"YulIdentifier","src":"3049:18:17"},"nodeType":"YulFunctionCall","src":"3049:29:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"3039:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"3087:45:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3117:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"3128:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3113:3:17"},"nodeType":"YulFunctionCall","src":"3113:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3100:12:17"},"nodeType":"YulFunctionCall","src":"3100:32:17"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"3091:5:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"3185:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3194:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3197:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3187:6:17"},"nodeType":"YulFunctionCall","src":"3187:12:17"},"nodeType":"YulExpressionStatement","src":"3187:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"3154:5:17"},{"arguments":[{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"3175:5:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"3168:6:17"},"nodeType":"YulFunctionCall","src":"3168:13:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"3161:6:17"},"nodeType":"YulFunctionCall","src":"3161:21:17"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"3151:2:17"},"nodeType":"YulFunctionCall","src":"3151:32:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"3144:6:17"},"nodeType":"YulFunctionCall","src":"3144:40:17"},"nodeType":"YulIf","src":"3141:60:17"},{"nodeType":"YulAssignment","src":"3210:15:17","value":{"name":"value","nodeType":"YulIdentifier","src":"3220:5:17"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"3210:6:17"}]}]},"name":"abi_decode_tuple_t_addresst_bool","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"2926:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"2937:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"2949:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"2957:6:17","type":""}],"src":"2884:347:17"},{"body":{"nodeType":"YulBlock","src":"3268:95:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3285:1:17","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3292:3:17","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"3297:10:17","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"3288:3:17"},"nodeType":"YulFunctionCall","src":"3288:20:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"3278:6:17"},"nodeType":"YulFunctionCall","src":"3278:31:17"},"nodeType":"YulExpressionStatement","src":"3278:31:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3325:1:17","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"3328:4:17","type":"","value":"0x41"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"3318:6:17"},"nodeType":"YulFunctionCall","src":"3318:15:17"},"nodeType":"YulExpressionStatement","src":"3318:15:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3349:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3352:4:17","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3342:6:17"},"nodeType":"YulFunctionCall","src":"3342:15:17"},"nodeType":"YulExpressionStatement","src":"3342:15:17"}]},"name":"panic_error_0x41","nodeType":"YulFunctionDefinition","src":"3236:127:17"},{"body":{"nodeType":"YulBlock","src":"3498:1008:17","statements":[{"body":{"nodeType":"YulBlock","src":"3545:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3554:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3557:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3547:6:17"},"nodeType":"YulFunctionCall","src":"3547:12:17"},"nodeType":"YulExpressionStatement","src":"3547:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"3519:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"3528:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"3515:3:17"},"nodeType":"YulFunctionCall","src":"3515:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"3540:3:17","type":"","value":"128"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"3511:3:17"},"nodeType":"YulFunctionCall","src":"3511:33:17"},"nodeType":"YulIf","src":"3508:53:17"},{"nodeType":"YulAssignment","src":"3570:39:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3599:9:17"}],"functionName":{"name":"abi_decode_address","nodeType":"YulIdentifier","src":"3580:18:17"},"nodeType":"YulFunctionCall","src":"3580:29:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"3570:6:17"}]},{"nodeType":"YulAssignment","src":"3618:48:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3651:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"3662:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3647:3:17"},"nodeType":"YulFunctionCall","src":"3647:18:17"}],"functionName":{"name":"abi_decode_address","nodeType":"YulIdentifier","src":"3628:18:17"},"nodeType":"YulFunctionCall","src":"3628:38:17"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"3618:6:17"}]},{"nodeType":"YulAssignment","src":"3675:42:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3702:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"3713:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3698:3:17"},"nodeType":"YulFunctionCall","src":"3698:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3685:12:17"},"nodeType":"YulFunctionCall","src":"3685:32:17"},"variableNames":[{"name":"value2","nodeType":"YulIdentifier","src":"3675:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"3726:46:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3757:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"3768:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3753:3:17"},"nodeType":"YulFunctionCall","src":"3753:18:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3740:12:17"},"nodeType":"YulFunctionCall","src":"3740:32:17"},"variables":[{"name":"offset","nodeType":"YulTypedName","src":"3730:6:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"3781:28:17","value":{"kind":"number","nodeType":"YulLiteral","src":"3791:18:17","type":"","value":"0xffffffffffffffff"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"3785:2:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"3836:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3845:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3848:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3838:6:17"},"nodeType":"YulFunctionCall","src":"3838:12:17"},"nodeType":"YulExpressionStatement","src":"3838:12:17"}]},"condition":{"arguments":[{"name":"offset","nodeType":"YulIdentifier","src":"3824:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"3832:2:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"3821:2:17"},"nodeType":"YulFunctionCall","src":"3821:14:17"},"nodeType":"YulIf","src":"3818:34:17"},{"nodeType":"YulVariableDeclaration","src":"3861:32:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"3875:9:17"},{"name":"offset","nodeType":"YulIdentifier","src":"3886:6:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3871:3:17"},"nodeType":"YulFunctionCall","src":"3871:22:17"},"variables":[{"name":"_2","nodeType":"YulTypedName","src":"3865:2:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"3941:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"3950:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"3953:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"3943:6:17"},"nodeType":"YulFunctionCall","src":"3943:12:17"},"nodeType":"YulExpressionStatement","src":"3943:12:17"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"3920:2:17"},{"kind":"number","nodeType":"YulLiteral","src":"3924:4:17","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"3916:3:17"},"nodeType":"YulFunctionCall","src":"3916:13:17"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"3931:7:17"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"3912:3:17"},"nodeType":"YulFunctionCall","src":"3912:27:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"3905:6:17"},"nodeType":"YulFunctionCall","src":"3905:35:17"},"nodeType":"YulIf","src":"3902:55:17"},{"nodeType":"YulVariableDeclaration","src":"3966:26:17","value":{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"3989:2:17"}],"functionName":{"name":"calldataload","nodeType":"YulIdentifier","src":"3976:12:17"},"nodeType":"YulFunctionCall","src":"3976:16:17"},"variables":[{"name":"_3","nodeType":"YulTypedName","src":"3970:2:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"4015:22:17","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"4017:16:17"},"nodeType":"YulFunctionCall","src":"4017:18:17"},"nodeType":"YulExpressionStatement","src":"4017:18:17"}]},"condition":{"arguments":[{"name":"_3","nodeType":"YulIdentifier","src":"4007:2:17"},{"name":"_1","nodeType":"YulIdentifier","src":"4011:2:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"4004:2:17"},"nodeType":"YulFunctionCall","src":"4004:10:17"},"nodeType":"YulIf","src":"4001:36:17"},{"nodeType":"YulVariableDeclaration","src":"4046:17:17","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4060:2:17","type":"","value":"31"}],"functionName":{"name":"not","nodeType":"YulIdentifier","src":"4056:3:17"},"nodeType":"YulFunctionCall","src":"4056:7:17"},"variables":[{"name":"_4","nodeType":"YulTypedName","src":"4050:2:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"4072:23:17","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4092:2:17","type":"","value":"64"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"4086:5:17"},"nodeType":"YulFunctionCall","src":"4086:9:17"},"variables":[{"name":"memPtr","nodeType":"YulTypedName","src":"4076:6:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"4104:71:17","value":{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"4126:6:17"},{"arguments":[{"arguments":[{"arguments":[{"arguments":[{"name":"_3","nodeType":"YulIdentifier","src":"4150:2:17"},{"kind":"number","nodeType":"YulLiteral","src":"4154:4:17","type":"","value":"0x1f"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4146:3:17"},"nodeType":"YulFunctionCall","src":"4146:13:17"},{"name":"_4","nodeType":"YulIdentifier","src":"4161:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"4142:3:17"},"nodeType":"YulFunctionCall","src":"4142:22:17"},{"kind":"number","nodeType":"YulLiteral","src":"4166:2:17","type":"","value":"63"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4138:3:17"},"nodeType":"YulFunctionCall","src":"4138:31:17"},{"name":"_4","nodeType":"YulIdentifier","src":"4171:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"4134:3:17"},"nodeType":"YulFunctionCall","src":"4134:40:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4122:3:17"},"nodeType":"YulFunctionCall","src":"4122:53:17"},"variables":[{"name":"newFreePtr","nodeType":"YulTypedName","src":"4108:10:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"4234:22:17","statements":[{"expression":{"arguments":[],"functionName":{"name":"panic_error_0x41","nodeType":"YulIdentifier","src":"4236:16:17"},"nodeType":"YulFunctionCall","src":"4236:18:17"},"nodeType":"YulExpressionStatement","src":"4236:18:17"}]},"condition":{"arguments":[{"arguments":[{"name":"newFreePtr","nodeType":"YulIdentifier","src":"4193:10:17"},{"name":"_1","nodeType":"YulIdentifier","src":"4205:2:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"4190:2:17"},"nodeType":"YulFunctionCall","src":"4190:18:17"},{"arguments":[{"name":"newFreePtr","nodeType":"YulIdentifier","src":"4213:10:17"},{"name":"memPtr","nodeType":"YulIdentifier","src":"4225:6:17"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"4210:2:17"},"nodeType":"YulFunctionCall","src":"4210:22:17"}],"functionName":{"name":"or","nodeType":"YulIdentifier","src":"4187:2:17"},"nodeType":"YulFunctionCall","src":"4187:46:17"},"nodeType":"YulIf","src":"4184:72:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4272:2:17","type":"","value":"64"},{"name":"newFreePtr","nodeType":"YulIdentifier","src":"4276:10:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"4265:6:17"},"nodeType":"YulFunctionCall","src":"4265:22:17"},"nodeType":"YulExpressionStatement","src":"4265:22:17"},{"expression":{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"4303:6:17"},{"name":"_3","nodeType":"YulIdentifier","src":"4311:2:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"4296:6:17"},"nodeType":"YulFunctionCall","src":"4296:18:17"},"nodeType":"YulExpressionStatement","src":"4296:18:17"},{"body":{"nodeType":"YulBlock","src":"4360:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4369:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4372:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4362:6:17"},"nodeType":"YulFunctionCall","src":"4362:12:17"},"nodeType":"YulExpressionStatement","src":"4362:12:17"}]},"condition":{"arguments":[{"arguments":[{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"4337:2:17"},{"name":"_3","nodeType":"YulIdentifier","src":"4341:2:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4333:3:17"},"nodeType":"YulFunctionCall","src":"4333:11:17"},{"kind":"number","nodeType":"YulLiteral","src":"4346:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4329:3:17"},"nodeType":"YulFunctionCall","src":"4329:20:17"},{"name":"dataEnd","nodeType":"YulIdentifier","src":"4351:7:17"}],"functionName":{"name":"gt","nodeType":"YulIdentifier","src":"4326:2:17"},"nodeType":"YulFunctionCall","src":"4326:33:17"},"nodeType":"YulIf","src":"4323:53:17"},{"expression":{"arguments":[{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"4402:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"4410:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4398:3:17"},"nodeType":"YulFunctionCall","src":"4398:15:17"},{"arguments":[{"name":"_2","nodeType":"YulIdentifier","src":"4419:2:17"},{"kind":"number","nodeType":"YulLiteral","src":"4423:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4415:3:17"},"nodeType":"YulFunctionCall","src":"4415:11:17"},{"name":"_3","nodeType":"YulIdentifier","src":"4428:2:17"}],"functionName":{"name":"calldatacopy","nodeType":"YulIdentifier","src":"4385:12:17"},"nodeType":"YulFunctionCall","src":"4385:46:17"},"nodeType":"YulExpressionStatement","src":"4385:46:17"},{"expression":{"arguments":[{"arguments":[{"arguments":[{"name":"memPtr","nodeType":"YulIdentifier","src":"4455:6:17"},{"name":"_3","nodeType":"YulIdentifier","src":"4463:2:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4451:3:17"},"nodeType":"YulFunctionCall","src":"4451:15:17"},{"kind":"number","nodeType":"YulLiteral","src":"4468:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4447:3:17"},"nodeType":"YulFunctionCall","src":"4447:24:17"},{"kind":"number","nodeType":"YulLiteral","src":"4473:1:17","type":"","value":"0"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"4440:6:17"},"nodeType":"YulFunctionCall","src":"4440:35:17"},"nodeType":"YulExpressionStatement","src":"4440:35:17"},{"nodeType":"YulAssignment","src":"4484:16:17","value":{"name":"memPtr","nodeType":"YulIdentifier","src":"4494:6:17"},"variableNames":[{"name":"value3","nodeType":"YulIdentifier","src":"4484:6:17"}]}]},"name":"abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"3440:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"3451:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"3463:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"3471:6:17","type":""},{"name":"value2","nodeType":"YulTypedName","src":"3479:6:17","type":""},{"name":"value3","nodeType":"YulTypedName","src":"3487:6:17","type":""}],"src":"3368:1138:17"},{"body":{"nodeType":"YulBlock","src":"4598:173:17","statements":[{"body":{"nodeType":"YulBlock","src":"4644:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4653:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"4656:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"4646:6:17"},"nodeType":"YulFunctionCall","src":"4646:12:17"},"nodeType":"YulExpressionStatement","src":"4646:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"4619:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"4628:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"4615:3:17"},"nodeType":"YulFunctionCall","src":"4615:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"4640:2:17","type":"","value":"64"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"4611:3:17"},"nodeType":"YulFunctionCall","src":"4611:32:17"},"nodeType":"YulIf","src":"4608:52:17"},{"nodeType":"YulAssignment","src":"4669:39:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4698:9:17"}],"functionName":{"name":"abi_decode_address","nodeType":"YulIdentifier","src":"4679:18:17"},"nodeType":"YulFunctionCall","src":"4679:29:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"4669:6:17"}]},{"nodeType":"YulAssignment","src":"4717:48:17","value":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"4750:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"4761:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"4746:3:17"},"nodeType":"YulFunctionCall","src":"4746:18:17"}],"functionName":{"name":"abi_decode_address","nodeType":"YulIdentifier","src":"4727:18:17"},"nodeType":"YulFunctionCall","src":"4727:38:17"},"variableNames":[{"name":"value1","nodeType":"YulIdentifier","src":"4717:6:17"}]}]},"name":"abi_decode_tuple_t_addresst_address","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"4556:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"4567:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"4579:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"4587:6:17","type":""}],"src":"4511:260:17"},{"body":{"nodeType":"YulBlock","src":"4831:325:17","statements":[{"nodeType":"YulAssignment","src":"4841:22:17","value":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"4855:1:17","type":"","value":"1"},{"name":"data","nodeType":"YulIdentifier","src":"4858:4:17"}],"functionName":{"name":"shr","nodeType":"YulIdentifier","src":"4851:3:17"},"nodeType":"YulFunctionCall","src":"4851:12:17"},"variableNames":[{"name":"length","nodeType":"YulIdentifier","src":"4841:6:17"}]},{"nodeType":"YulVariableDeclaration","src":"4872:38:17","value":{"arguments":[{"name":"data","nodeType":"YulIdentifier","src":"4902:4:17"},{"kind":"number","nodeType":"YulLiteral","src":"4908:1:17","type":"","value":"1"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"4898:3:17"},"nodeType":"YulFunctionCall","src":"4898:12:17"},"variables":[{"name":"outOfPlaceEncoding","nodeType":"YulTypedName","src":"4876:18:17","type":""}]},{"body":{"nodeType":"YulBlock","src":"4949:31:17","statements":[{"nodeType":"YulAssignment","src":"4951:27:17","value":{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"4965:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"4973:4:17","type":"","value":"0x7f"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"4961:3:17"},"nodeType":"YulFunctionCall","src":"4961:17:17"},"variableNames":[{"name":"length","nodeType":"YulIdentifier","src":"4951:6:17"}]}]},"condition":{"arguments":[{"name":"outOfPlaceEncoding","nodeType":"YulIdentifier","src":"4929:18:17"}],"functionName":{"name":"iszero","nodeType":"YulIdentifier","src":"4922:6:17"},"nodeType":"YulFunctionCall","src":"4922:26:17"},"nodeType":"YulIf","src":"4919:61:17"},{"body":{"nodeType":"YulBlock","src":"5039:111:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5060:1:17","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5067:3:17","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"5072:10:17","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"5063:3:17"},"nodeType":"YulFunctionCall","src":"5063:20:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5053:6:17"},"nodeType":"YulFunctionCall","src":"5053:31:17"},"nodeType":"YulExpressionStatement","src":"5053:31:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5104:1:17","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"5107:4:17","type":"","value":"0x22"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5097:6:17"},"nodeType":"YulFunctionCall","src":"5097:15:17"},"nodeType":"YulExpressionStatement","src":"5097:15:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"5132:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"5135:4:17","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"5125:6:17"},"nodeType":"YulFunctionCall","src":"5125:15:17"},"nodeType":"YulExpressionStatement","src":"5125:15:17"}]},"condition":{"arguments":[{"name":"outOfPlaceEncoding","nodeType":"YulIdentifier","src":"4995:18:17"},{"arguments":[{"name":"length","nodeType":"YulIdentifier","src":"5018:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"5026:2:17","type":"","value":"32"}],"functionName":{"name":"lt","nodeType":"YulIdentifier","src":"5015:2:17"},"nodeType":"YulFunctionCall","src":"5015:14:17"}],"functionName":{"name":"eq","nodeType":"YulIdentifier","src":"4992:2:17"},"nodeType":"YulFunctionCall","src":"4992:38:17"},"nodeType":"YulIf","src":"4989:161:17"}]},"name":"extract_byte_array_length","nodeType":"YulFunctionDefinition","parameters":[{"name":"data","nodeType":"YulTypedName","src":"4811:4:17","type":""}],"returnVariables":[{"name":"length","nodeType":"YulTypedName","src":"4820:6:17","type":""}],"src":"4776:380:17"},{"body":{"nodeType":"YulBlock","src":"5335:223:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5352:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5363:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5345:6:17"},"nodeType":"YulFunctionCall","src":"5345:21:17"},"nodeType":"YulExpressionStatement","src":"5345:21:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5386:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5397:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5382:3:17"},"nodeType":"YulFunctionCall","src":"5382:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"5402:2:17","type":"","value":"33"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5375:6:17"},"nodeType":"YulFunctionCall","src":"5375:30:17"},"nodeType":"YulExpressionStatement","src":"5375:30:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5425:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5436:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5421:3:17"},"nodeType":"YulFunctionCall","src":"5421:18:17"},{"hexValue":"4552433732313a20617070726f76616c20746f2063757272656e74206f776e65","kind":"string","nodeType":"YulLiteral","src":"5441:34:17","type":"","value":"ERC721: approval to current owne"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5414:6:17"},"nodeType":"YulFunctionCall","src":"5414:62:17"},"nodeType":"YulExpressionStatement","src":"5414:62:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5496:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5507:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5492:3:17"},"nodeType":"YulFunctionCall","src":"5492:18:17"},{"hexValue":"72","kind":"string","nodeType":"YulLiteral","src":"5512:3:17","type":"","value":"r"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5485:6:17"},"nodeType":"YulFunctionCall","src":"5485:31:17"},"nodeType":"YulExpressionStatement","src":"5485:31:17"},{"nodeType":"YulAssignment","src":"5525:27:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5537:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5548:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5533:3:17"},"nodeType":"YulFunctionCall","src":"5533:19:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"5525:4:17"}]}]},"name":"abi_encode_tuple_t_stringliteral_b51b4875eede07862961e8f9365c6749f5fe55c6ee5d7a9e42b6912ad0b15942__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"5312:9:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"5326:4:17","type":""}],"src":"5161:397:17"},{"body":{"nodeType":"YulBlock","src":"5737:251:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5754:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5765:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5747:6:17"},"nodeType":"YulFunctionCall","src":"5747:21:17"},"nodeType":"YulExpressionStatement","src":"5747:21:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5788:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5799:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5784:3:17"},"nodeType":"YulFunctionCall","src":"5784:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"5804:2:17","type":"","value":"61"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5777:6:17"},"nodeType":"YulFunctionCall","src":"5777:30:17"},"nodeType":"YulExpressionStatement","src":"5777:30:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5827:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5838:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5823:3:17"},"nodeType":"YulFunctionCall","src":"5823:18:17"},{"hexValue":"4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f","kind":"string","nodeType":"YulLiteral","src":"5843:34:17","type":"","value":"ERC721: approve caller is not to"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5816:6:17"},"nodeType":"YulFunctionCall","src":"5816:62:17"},"nodeType":"YulExpressionStatement","src":"5816:62:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5898:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5909:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5894:3:17"},"nodeType":"YulFunctionCall","src":"5894:18:17"},{"hexValue":"6b656e206f776e6572206f7220617070726f76656420666f7220616c6c","kind":"string","nodeType":"YulLiteral","src":"5914:31:17","type":"","value":"ken owner or approved for all"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"5887:6:17"},"nodeType":"YulFunctionCall","src":"5887:59:17"},"nodeType":"YulExpressionStatement","src":"5887:59:17"},{"nodeType":"YulAssignment","src":"5955:27:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"5967:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"5978:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"5963:3:17"},"nodeType":"YulFunctionCall","src":"5963:19:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"5955:4:17"}]}]},"name":"abi_encode_tuple_t_stringliteral_c6e14a63ffb144eeef7cce6988e5dce07c60a7e0a7b1ef25dbe18c61483e0a83__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"5714:9:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"5728:4:17","type":""}],"src":"5563:425:17"},{"body":{"nodeType":"YulBlock","src":"6167:235:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6184:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6195:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6177:6:17"},"nodeType":"YulFunctionCall","src":"6177:21:17"},"nodeType":"YulExpressionStatement","src":"6177:21:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6218:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6229:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6214:3:17"},"nodeType":"YulFunctionCall","src":"6214:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"6234:2:17","type":"","value":"45"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6207:6:17"},"nodeType":"YulFunctionCall","src":"6207:30:17"},"nodeType":"YulExpressionStatement","src":"6207:30:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6257:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6268:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6253:3:17"},"nodeType":"YulFunctionCall","src":"6253:18:17"},{"hexValue":"4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e65","kind":"string","nodeType":"YulLiteral","src":"6273:34:17","type":"","value":"ERC721: caller is not token owne"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6246:6:17"},"nodeType":"YulFunctionCall","src":"6246:62:17"},"nodeType":"YulExpressionStatement","src":"6246:62:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6328:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6339:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6324:3:17"},"nodeType":"YulFunctionCall","src":"6324:18:17"},{"hexValue":"72206f7220617070726f766564","kind":"string","nodeType":"YulLiteral","src":"6344:15:17","type":"","value":"r or approved"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6317:6:17"},"nodeType":"YulFunctionCall","src":"6317:43:17"},"nodeType":"YulExpressionStatement","src":"6317:43:17"},{"nodeType":"YulAssignment","src":"6369:27:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6381:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6392:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6377:3:17"},"nodeType":"YulFunctionCall","src":"6377:19:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"6369:4:17"}]}]},"name":"abi_encode_tuple_t_stringliteral_12a8e5623d251e191fe4a291d9a59bcc01a4db7a1f5c20fc8de44358c18308af__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"6144:9:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"6158:4:17","type":""}],"src":"5993:409:17"},{"body":{"nodeType":"YulBlock","src":"6581:174:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6598:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6609:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6591:6:17"},"nodeType":"YulFunctionCall","src":"6591:21:17"},"nodeType":"YulExpressionStatement","src":"6591:21:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6632:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6643:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6628:3:17"},"nodeType":"YulFunctionCall","src":"6628:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"6648:2:17","type":"","value":"24"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6621:6:17"},"nodeType":"YulFunctionCall","src":"6621:30:17"},"nodeType":"YulExpressionStatement","src":"6621:30:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6671:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6682:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6667:3:17"},"nodeType":"YulFunctionCall","src":"6667:18:17"},{"hexValue":"4552433732313a20696e76616c696420746f6b656e204944","kind":"string","nodeType":"YulLiteral","src":"6687:26:17","type":"","value":"ERC721: invalid token ID"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6660:6:17"},"nodeType":"YulFunctionCall","src":"6660:54:17"},"nodeType":"YulExpressionStatement","src":"6660:54:17"},{"nodeType":"YulAssignment","src":"6723:26:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6735:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6746:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6731:3:17"},"nodeType":"YulFunctionCall","src":"6731:18:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"6723:4:17"}]}]},"name":"abi_encode_tuple_t_stringliteral_b08d2b0fec7cc108ab049809a8beb42779d969a49299d0c317c907d9db22974f__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"6558:9:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"6572:4:17","type":""}],"src":"6407:348:17"},{"body":{"nodeType":"YulBlock","src":"6934:231:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6951:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6962:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6944:6:17"},"nodeType":"YulFunctionCall","src":"6944:21:17"},"nodeType":"YulExpressionStatement","src":"6944:21:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"6985:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"6996:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"6981:3:17"},"nodeType":"YulFunctionCall","src":"6981:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"7001:2:17","type":"","value":"41"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"6974:6:17"},"nodeType":"YulFunctionCall","src":"6974:30:17"},"nodeType":"YulExpressionStatement","src":"6974:30:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7024:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"7035:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7020:3:17"},"nodeType":"YulFunctionCall","src":"7020:18:17"},{"hexValue":"4552433732313a2061646472657373207a65726f206973206e6f742061207661","kind":"string","nodeType":"YulLiteral","src":"7040:34:17","type":"","value":"ERC721: address zero is not a va"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7013:6:17"},"nodeType":"YulFunctionCall","src":"7013:62:17"},"nodeType":"YulExpressionStatement","src":"7013:62:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7095:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"7106:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7091:3:17"},"nodeType":"YulFunctionCall","src":"7091:18:17"},{"hexValue":"6c6964206f776e6572","kind":"string","nodeType":"YulLiteral","src":"7111:11:17","type":"","value":"lid owner"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7084:6:17"},"nodeType":"YulFunctionCall","src":"7084:39:17"},"nodeType":"YulExpressionStatement","src":"7084:39:17"},{"nodeType":"YulAssignment","src":"7132:27:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7144:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"7155:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7140:3:17"},"nodeType":"YulFunctionCall","src":"7140:19:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"7132:4:17"}]}]},"name":"abi_encode_tuple_t_stringliteral_6d05c90094f31cfeb8f0eb86f0a513af3f7f8992991fbde41b08aa7960677159__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"6911:9:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"6925:4:17","type":""}],"src":"6760:405:17"},{"body":{"nodeType":"YulBlock","src":"7357:309:17","statements":[{"nodeType":"YulVariableDeclaration","src":"7367:27:17","value":{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"7387:6:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"7381:5:17"},"nodeType":"YulFunctionCall","src":"7381:13:17"},"variables":[{"name":"length","nodeType":"YulTypedName","src":"7371:6:17","type":""}]},{"expression":{"arguments":[{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"7442:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"7450:4:17","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7438:3:17"},"nodeType":"YulFunctionCall","src":"7438:17:17"},{"name":"pos","nodeType":"YulIdentifier","src":"7457:3:17"},{"name":"length","nodeType":"YulIdentifier","src":"7462:6:17"}],"functionName":{"name":"copy_memory_to_memory_with_cleanup","nodeType":"YulIdentifier","src":"7403:34:17"},"nodeType":"YulFunctionCall","src":"7403:66:17"},"nodeType":"YulExpressionStatement","src":"7403:66:17"},{"nodeType":"YulVariableDeclaration","src":"7478:29:17","value":{"arguments":[{"name":"pos","nodeType":"YulIdentifier","src":"7495:3:17"},{"name":"length","nodeType":"YulIdentifier","src":"7500:6:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7491:3:17"},"nodeType":"YulFunctionCall","src":"7491:16:17"},"variables":[{"name":"end_1","nodeType":"YulTypedName","src":"7482:5:17","type":""}]},{"nodeType":"YulVariableDeclaration","src":"7516:29:17","value":{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"7538:6:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"7532:5:17"},"nodeType":"YulFunctionCall","src":"7532:13:17"},"variables":[{"name":"length_1","nodeType":"YulTypedName","src":"7520:8:17","type":""}]},{"expression":{"arguments":[{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"7593:6:17"},{"kind":"number","nodeType":"YulLiteral","src":"7601:4:17","type":"","value":"0x20"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7589:3:17"},"nodeType":"YulFunctionCall","src":"7589:17:17"},{"name":"end_1","nodeType":"YulIdentifier","src":"7608:5:17"},{"name":"length_1","nodeType":"YulIdentifier","src":"7615:8:17"}],"functionName":{"name":"copy_memory_to_memory_with_cleanup","nodeType":"YulIdentifier","src":"7554:34:17"},"nodeType":"YulFunctionCall","src":"7554:70:17"},"nodeType":"YulExpressionStatement","src":"7554:70:17"},{"nodeType":"YulAssignment","src":"7633:27:17","value":{"arguments":[{"name":"end_1","nodeType":"YulIdentifier","src":"7644:5:17"},{"name":"length_1","nodeType":"YulIdentifier","src":"7651:8:17"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7640:3:17"},"nodeType":"YulFunctionCall","src":"7640:20:17"},"variableNames":[{"name":"end","nodeType":"YulIdentifier","src":"7633:3:17"}]}]},"name":"abi_encode_tuple_packed_t_string_memory_ptr_t_string_memory_ptr__to_t_string_memory_ptr_t_string_memory_ptr__nonPadded_inplace_fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"pos","nodeType":"YulTypedName","src":"7325:3:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"7330:6:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"7338:6:17","type":""}],"returnVariables":[{"name":"end","nodeType":"YulTypedName","src":"7349:3:17","type":""}],"src":"7170:496:17"},{"body":{"nodeType":"YulBlock","src":"7845:227:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7862:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"7873:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7855:6:17"},"nodeType":"YulFunctionCall","src":"7855:21:17"},"nodeType":"YulExpressionStatement","src":"7855:21:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7896:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"7907:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7892:3:17"},"nodeType":"YulFunctionCall","src":"7892:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"7912:2:17","type":"","value":"37"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7885:6:17"},"nodeType":"YulFunctionCall","src":"7885:30:17"},"nodeType":"YulExpressionStatement","src":"7885:30:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"7935:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"7946:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"7931:3:17"},"nodeType":"YulFunctionCall","src":"7931:18:17"},{"hexValue":"4552433732313a207472616e736665722066726f6d20696e636f727265637420","kind":"string","nodeType":"YulLiteral","src":"7951:34:17","type":"","value":"ERC721: transfer from incorrect "}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7924:6:17"},"nodeType":"YulFunctionCall","src":"7924:62:17"},"nodeType":"YulExpressionStatement","src":"7924:62:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8006:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8017:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8002:3:17"},"nodeType":"YulFunctionCall","src":"8002:18:17"},{"hexValue":"6f776e6572","kind":"string","nodeType":"YulLiteral","src":"8022:7:17","type":"","value":"owner"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"7995:6:17"},"nodeType":"YulFunctionCall","src":"7995:35:17"},"nodeType":"YulExpressionStatement","src":"7995:35:17"},{"nodeType":"YulAssignment","src":"8039:27:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8051:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8062:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8047:3:17"},"nodeType":"YulFunctionCall","src":"8047:19:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"8039:4:17"}]}]},"name":"abi_encode_tuple_t_stringliteral_277f8ee9d5b4fc3c4149386f24de0fc1bbc63a8210e2197bfd1c0376a2ac5f48__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"7822:9:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"7836:4:17","type":""}],"src":"7671:401:17"},{"body":{"nodeType":"YulBlock","src":"8251:226:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8268:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8279:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8261:6:17"},"nodeType":"YulFunctionCall","src":"8261:21:17"},"nodeType":"YulExpressionStatement","src":"8261:21:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8302:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8313:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8298:3:17"},"nodeType":"YulFunctionCall","src":"8298:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"8318:2:17","type":"","value":"36"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8291:6:17"},"nodeType":"YulFunctionCall","src":"8291:30:17"},"nodeType":"YulExpressionStatement","src":"8291:30:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8341:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8352:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8337:3:17"},"nodeType":"YulFunctionCall","src":"8337:18:17"},{"hexValue":"4552433732313a207472616e7366657220746f20746865207a65726f20616464","kind":"string","nodeType":"YulLiteral","src":"8357:34:17","type":"","value":"ERC721: transfer to the zero add"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8330:6:17"},"nodeType":"YulFunctionCall","src":"8330:62:17"},"nodeType":"YulExpressionStatement","src":"8330:62:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8412:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8423:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8408:3:17"},"nodeType":"YulFunctionCall","src":"8408:18:17"},{"hexValue":"72657373","kind":"string","nodeType":"YulLiteral","src":"8428:6:17","type":"","value":"ress"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8401:6:17"},"nodeType":"YulFunctionCall","src":"8401:34:17"},"nodeType":"YulExpressionStatement","src":"8401:34:17"},{"nodeType":"YulAssignment","src":"8444:27:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8456:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8467:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8452:3:17"},"nodeType":"YulFunctionCall","src":"8452:19:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"8444:4:17"}]}]},"name":"abi_encode_tuple_t_stringliteral_455fea98ea03c32d7dd1a6f1426917d80529bf47b3ccbde74e7206e889e709f4__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"8228:9:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"8242:4:17","type":""}],"src":"8077:400:17"},{"body":{"nodeType":"YulBlock","src":"8656:182:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8673:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8684:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8666:6:17"},"nodeType":"YulFunctionCall","src":"8666:21:17"},"nodeType":"YulExpressionStatement","src":"8666:21:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8707:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8718:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8703:3:17"},"nodeType":"YulFunctionCall","src":"8703:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"8723:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8696:6:17"},"nodeType":"YulFunctionCall","src":"8696:30:17"},"nodeType":"YulExpressionStatement","src":"8696:30:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8746:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8757:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8742:3:17"},"nodeType":"YulFunctionCall","src":"8742:18:17"},{"hexValue":"4552433732313a206d696e7420746f20746865207a65726f2061646472657373","kind":"string","nodeType":"YulLiteral","src":"8762:34:17","type":"","value":"ERC721: mint to the zero address"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"8735:6:17"},"nodeType":"YulFunctionCall","src":"8735:62:17"},"nodeType":"YulExpressionStatement","src":"8735:62:17"},{"nodeType":"YulAssignment","src":"8806:26:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"8818:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"8829:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"8814:3:17"},"nodeType":"YulFunctionCall","src":"8814:18:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"8806:4:17"}]}]},"name":"abi_encode_tuple_t_stringliteral_8a66f4bb6512ffbfcc3db9b42318eb65f26ac15163eaa9a1e5cfa7bee9d1c7c6__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"8633:9:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"8647:4:17","type":""}],"src":"8482:356:17"},{"body":{"nodeType":"YulBlock","src":"9017:178:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9034:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9045:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9027:6:17"},"nodeType":"YulFunctionCall","src":"9027:21:17"},"nodeType":"YulExpressionStatement","src":"9027:21:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9068:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9079:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9064:3:17"},"nodeType":"YulFunctionCall","src":"9064:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"9084:2:17","type":"","value":"28"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9057:6:17"},"nodeType":"YulFunctionCall","src":"9057:30:17"},"nodeType":"YulExpressionStatement","src":"9057:30:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9107:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9118:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9103:3:17"},"nodeType":"YulFunctionCall","src":"9103:18:17"},{"hexValue":"4552433732313a20746f6b656e20616c7265616479206d696e746564","kind":"string","nodeType":"YulLiteral","src":"9123:30:17","type":"","value":"ERC721: token already minted"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9096:6:17"},"nodeType":"YulFunctionCall","src":"9096:58:17"},"nodeType":"YulExpressionStatement","src":"9096:58:17"},{"nodeType":"YulAssignment","src":"9163:26:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9175:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9186:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9171:3:17"},"nodeType":"YulFunctionCall","src":"9171:18:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"9163:4:17"}]}]},"name":"abi_encode_tuple_t_stringliteral_2a63ce106ef95058ed21fd07c42a10f11dc5c32ac13a4e847923f7759f635d57__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"8994:9:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"9008:4:17","type":""}],"src":"8843:352:17"},{"body":{"nodeType":"YulBlock","src":"9374:175:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9391:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9402:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9384:6:17"},"nodeType":"YulFunctionCall","src":"9384:21:17"},"nodeType":"YulExpressionStatement","src":"9384:21:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9425:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9436:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9421:3:17"},"nodeType":"YulFunctionCall","src":"9421:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"9441:2:17","type":"","value":"25"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9414:6:17"},"nodeType":"YulFunctionCall","src":"9414:30:17"},"nodeType":"YulExpressionStatement","src":"9414:30:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9464:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9475:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9460:3:17"},"nodeType":"YulFunctionCall","src":"9460:18:17"},{"hexValue":"4552433732313a20617070726f766520746f2063616c6c6572","kind":"string","nodeType":"YulLiteral","src":"9480:27:17","type":"","value":"ERC721: approve to caller"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9453:6:17"},"nodeType":"YulFunctionCall","src":"9453:55:17"},"nodeType":"YulExpressionStatement","src":"9453:55:17"},{"nodeType":"YulAssignment","src":"9517:26:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9529:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9540:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9525:3:17"},"nodeType":"YulFunctionCall","src":"9525:18:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"9517:4:17"}]}]},"name":"abi_encode_tuple_t_stringliteral_45fe4329685be5ecd250fd0e6a25aea0ea4d0e30fb6a73c118b95749e6d70d05__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"9351:9:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"9365:4:17","type":""}],"src":"9200:349:17"},{"body":{"nodeType":"YulBlock","src":"9728:240:17","statements":[{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9745:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9756:2:17","type":"","value":"32"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9738:6:17"},"nodeType":"YulFunctionCall","src":"9738:21:17"},"nodeType":"YulExpressionStatement","src":"9738:21:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9779:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9790:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9775:3:17"},"nodeType":"YulFunctionCall","src":"9775:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"9795:2:17","type":"","value":"50"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9768:6:17"},"nodeType":"YulFunctionCall","src":"9768:30:17"},"nodeType":"YulExpressionStatement","src":"9768:30:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9818:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9829:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9814:3:17"},"nodeType":"YulFunctionCall","src":"9814:18:17"},{"hexValue":"4552433732313a207472616e7366657220746f206e6f6e204552433732315265","kind":"string","nodeType":"YulLiteral","src":"9834:34:17","type":"","value":"ERC721: transfer to non ERC721Re"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9807:6:17"},"nodeType":"YulFunctionCall","src":"9807:62:17"},"nodeType":"YulExpressionStatement","src":"9807:62:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9889:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9900:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9885:3:17"},"nodeType":"YulFunctionCall","src":"9885:18:17"},{"hexValue":"63656976657220696d706c656d656e746572","kind":"string","nodeType":"YulLiteral","src":"9905:20:17","type":"","value":"ceiver implementer"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"9878:6:17"},"nodeType":"YulFunctionCall","src":"9878:48:17"},"nodeType":"YulExpressionStatement","src":"9878:48:17"},{"nodeType":"YulAssignment","src":"9935:27:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"9947:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"9958:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"9943:3:17"},"nodeType":"YulFunctionCall","src":"9943:19:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"9935:4:17"}]}]},"name":"abi_encode_tuple_t_stringliteral_1e766a06da43a53d0f4c380e06e5a342e14d5af1bf8501996c844905530ca84e__to_t_string_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"9705:9:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"9719:4:17","type":""}],"src":"9554:414:17"},{"body":{"nodeType":"YulBlock","src":"10005:95:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10022:1:17","type":"","value":"0"},{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10029:3:17","type":"","value":"224"},{"kind":"number","nodeType":"YulLiteral","src":"10034:10:17","type":"","value":"0x4e487b71"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"10025:3:17"},"nodeType":"YulFunctionCall","src":"10025:20:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10015:6:17"},"nodeType":"YulFunctionCall","src":"10015:31:17"},"nodeType":"YulExpressionStatement","src":"10015:31:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10062:1:17","type":"","value":"4"},{"kind":"number","nodeType":"YulLiteral","src":"10065:4:17","type":"","value":"0x12"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10055:6:17"},"nodeType":"YulFunctionCall","src":"10055:15:17"},"nodeType":"YulExpressionStatement","src":"10055:15:17"},{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10086:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"10089:4:17","type":"","value":"0x24"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"10079:6:17"},"nodeType":"YulFunctionCall","src":"10079:15:17"},"nodeType":"YulExpressionStatement","src":"10079:15:17"}]},"name":"panic_error_0x12","nodeType":"YulFunctionDefinition","src":"9973:127:17"},{"body":{"nodeType":"YulBlock","src":"10308:286:17","statements":[{"nodeType":"YulVariableDeclaration","src":"10318:29:17","value":{"arguments":[{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10336:3:17","type":"","value":"160"},{"kind":"number","nodeType":"YulLiteral","src":"10341:1:17","type":"","value":"1"}],"functionName":{"name":"shl","nodeType":"YulIdentifier","src":"10332:3:17"},"nodeType":"YulFunctionCall","src":"10332:11:17"},{"kind":"number","nodeType":"YulLiteral","src":"10345:1:17","type":"","value":"1"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"10328:3:17"},"nodeType":"YulFunctionCall","src":"10328:19:17"},"variables":[{"name":"_1","nodeType":"YulTypedName","src":"10322:2:17","type":""}]},{"expression":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10363:9:17"},{"arguments":[{"name":"value0","nodeType":"YulIdentifier","src":"10378:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"10386:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"10374:3:17"},"nodeType":"YulFunctionCall","src":"10374:15:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10356:6:17"},"nodeType":"YulFunctionCall","src":"10356:34:17"},"nodeType":"YulExpressionStatement","src":"10356:34:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10410:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"10421:2:17","type":"","value":"32"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10406:3:17"},"nodeType":"YulFunctionCall","src":"10406:18:17"},{"arguments":[{"name":"value1","nodeType":"YulIdentifier","src":"10430:6:17"},{"name":"_1","nodeType":"YulIdentifier","src":"10438:2:17"}],"functionName":{"name":"and","nodeType":"YulIdentifier","src":"10426:3:17"},"nodeType":"YulFunctionCall","src":"10426:15:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10399:6:17"},"nodeType":"YulFunctionCall","src":"10399:43:17"},"nodeType":"YulExpressionStatement","src":"10399:43:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10462:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"10473:2:17","type":"","value":"64"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10458:3:17"},"nodeType":"YulFunctionCall","src":"10458:18:17"},{"name":"value2","nodeType":"YulIdentifier","src":"10478:6:17"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10451:6:17"},"nodeType":"YulFunctionCall","src":"10451:34:17"},"nodeType":"YulExpressionStatement","src":"10451:34:17"},{"expression":{"arguments":[{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10505:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"10516:2:17","type":"","value":"96"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10501:3:17"},"nodeType":"YulFunctionCall","src":"10501:18:17"},{"kind":"number","nodeType":"YulLiteral","src":"10521:3:17","type":"","value":"128"}],"functionName":{"name":"mstore","nodeType":"YulIdentifier","src":"10494:6:17"},"nodeType":"YulFunctionCall","src":"10494:31:17"},"nodeType":"YulExpressionStatement","src":"10494:31:17"},{"nodeType":"YulAssignment","src":"10534:54:17","value":{"arguments":[{"name":"value3","nodeType":"YulIdentifier","src":"10560:6:17"},{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10572:9:17"},{"kind":"number","nodeType":"YulLiteral","src":"10583:3:17","type":"","value":"128"}],"functionName":{"name":"add","nodeType":"YulIdentifier","src":"10568:3:17"},"nodeType":"YulFunctionCall","src":"10568:19:17"}],"functionName":{"name":"abi_encode_string","nodeType":"YulIdentifier","src":"10542:17:17"},"nodeType":"YulFunctionCall","src":"10542:46:17"},"variableNames":[{"name":"tail","nodeType":"YulIdentifier","src":"10534:4:17"}]}]},"name":"abi_encode_tuple_t_address_t_address_t_uint256_t_bytes_memory_ptr__to_t_address_t_address_t_uint256_t_bytes_memory_ptr__fromStack_reversed","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"10253:9:17","type":""},{"name":"value3","nodeType":"YulTypedName","src":"10264:6:17","type":""},{"name":"value2","nodeType":"YulTypedName","src":"10272:6:17","type":""},{"name":"value1","nodeType":"YulTypedName","src":"10280:6:17","type":""},{"name":"value0","nodeType":"YulTypedName","src":"10288:6:17","type":""}],"returnVariables":[{"name":"tail","nodeType":"YulTypedName","src":"10299:4:17","type":""}],"src":"10105:489:17"},{"body":{"nodeType":"YulBlock","src":"10679:169:17","statements":[{"body":{"nodeType":"YulBlock","src":"10725:16:17","statements":[{"expression":{"arguments":[{"kind":"number","nodeType":"YulLiteral","src":"10734:1:17","type":"","value":"0"},{"kind":"number","nodeType":"YulLiteral","src":"10737:1:17","type":"","value":"0"}],"functionName":{"name":"revert","nodeType":"YulIdentifier","src":"10727:6:17"},"nodeType":"YulFunctionCall","src":"10727:12:17"},"nodeType":"YulExpressionStatement","src":"10727:12:17"}]},"condition":{"arguments":[{"arguments":[{"name":"dataEnd","nodeType":"YulIdentifier","src":"10700:7:17"},{"name":"headStart","nodeType":"YulIdentifier","src":"10709:9:17"}],"functionName":{"name":"sub","nodeType":"YulIdentifier","src":"10696:3:17"},"nodeType":"YulFunctionCall","src":"10696:23:17"},{"kind":"number","nodeType":"YulLiteral","src":"10721:2:17","type":"","value":"32"}],"functionName":{"name":"slt","nodeType":"YulIdentifier","src":"10692:3:17"},"nodeType":"YulFunctionCall","src":"10692:32:17"},"nodeType":"YulIf","src":"10689:52:17"},{"nodeType":"YulVariableDeclaration","src":"10750:29:17","value":{"arguments":[{"name":"headStart","nodeType":"YulIdentifier","src":"10769:9:17"}],"functionName":{"name":"mload","nodeType":"YulIdentifier","src":"10763:5:17"},"nodeType":"YulFunctionCall","src":"10763:16:17"},"variables":[{"name":"value","nodeType":"YulTypedName","src":"10754:5:17","type":""}]},{"expression":{"arguments":[{"name":"value","nodeType":"YulIdentifier","src":"10812:5:17"}],"functionName":{"name":"validator_revert_bytes4","nodeType":"YulIdentifier","src":"10788:23:17"},"nodeType":"YulFunctionCall","src":"10788:30:17"},"nodeType":"YulExpressionStatement","src":"10788:30:17"},{"nodeType":"YulAssignment","src":"10827:15:17","value":{"name":"value","nodeType":"YulIdentifier","src":"10837:5:17"},"variableNames":[{"name":"value0","nodeType":"YulIdentifier","src":"10827:6:17"}]}]},"name":"abi_decode_tuple_t_bytes4_fromMemory","nodeType":"YulFunctionDefinition","parameters":[{"name":"headStart","nodeType":"YulTypedName","src":"10645:9:17","type":""},{"name":"dataEnd","nodeType":"YulTypedName","src":"10656:7:17","type":""}],"returnVariables":[{"name":"value0","nodeType":"YulTypedName","src":"10668:6:17","type":""}],"src":"10599:249:17"}]},"contents":"{\n { }\n function validator_revert_bytes4(value)\n {\n if iszero(eq(value, and(value, shl(224, 0xffffffff)))) { revert(0, 0) }\n }\n function abi_decode_tuple_t_bytes4(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_bytes4(value)\n value0 := value\n }\n function abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, iszero(iszero(value0)))\n }\n function copy_memory_to_memory_with_cleanup(src, dst, length)\n {\n let i := 0\n for { } lt(i, length) { i := add(i, 32) }\n {\n mstore(add(dst, i), mload(add(src, i)))\n }\n mstore(add(dst, length), 0)\n }\n function abi_encode_string(value, pos) -> end\n {\n let length := mload(value)\n mstore(pos, length)\n copy_memory_to_memory_with_cleanup(add(value, 0x20), add(pos, 0x20), length)\n end := add(add(pos, and(add(length, 31), not(31))), 0x20)\n }\n function abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr__fromStack_reversed(headStart, value0) -> tail\n {\n mstore(headStart, 32)\n tail := abi_encode_string(value0, add(headStart, 32))\n }\n function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n value0 := calldataload(headStart)\n }\n function abi_encode_tuple_t_address__to_t_address__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, sub(shl(160, 1), 1)))\n }\n function abi_decode_address(offset) -> value\n {\n value := calldataload(offset)\n if iszero(eq(value, and(value, sub(shl(160, 1), 1)))) { revert(0, 0) }\n }\n function abi_decode_tuple_t_addresst_uint256(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n value0 := abi_decode_address(headStart)\n value1 := calldataload(add(headStart, 32))\n }\n function abi_decode_tuple_t_addresst_addresst_uint256(headStart, dataEnd) -> value0, value1, value2\n {\n if slt(sub(dataEnd, headStart), 96) { revert(0, 0) }\n value0 := abi_decode_address(headStart)\n value1 := abi_decode_address(add(headStart, 32))\n value2 := calldataload(add(headStart, 64))\n }\n function abi_decode_tuple_t_address(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n value0 := abi_decode_address(headStart)\n }\n function abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, value0)\n }\n function abi_decode_tuple_t_addresst_bool(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n value0 := abi_decode_address(headStart)\n let value := calldataload(add(headStart, 32))\n if iszero(eq(value, iszero(iszero(value)))) { revert(0, 0) }\n value1 := value\n }\n function panic_error_0x41()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x41)\n revert(0, 0x24)\n }\n function abi_decode_tuple_t_addresst_addresst_uint256t_bytes_memory_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 128) { revert(0, 0) }\n value0 := abi_decode_address(headStart)\n value1 := abi_decode_address(add(headStart, 32))\n value2 := calldataload(add(headStart, 64))\n let offset := calldataload(add(headStart, 96))\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n let _2 := add(headStart, offset)\n if iszero(slt(add(_2, 0x1f), dataEnd)) { revert(0, 0) }\n let _3 := calldataload(_2)\n if gt(_3, _1) { panic_error_0x41() }\n let _4 := not(31)\n let memPtr := mload(64)\n let newFreePtr := add(memPtr, and(add(and(add(_3, 0x1f), _4), 63), _4))\n if or(gt(newFreePtr, _1), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n mstore(64, newFreePtr)\n mstore(memPtr, _3)\n if gt(add(add(_2, _3), 32), dataEnd) { revert(0, 0) }\n calldatacopy(add(memPtr, 32), add(_2, 32), _3)\n mstore(add(add(memPtr, _3), 32), 0)\n value3 := memPtr\n }\n function abi_decode_tuple_t_addresst_address(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n value0 := abi_decode_address(headStart)\n value1 := abi_decode_address(add(headStart, 32))\n }\n function extract_byte_array_length(data) -> length\n {\n length := shr(1, data)\n let outOfPlaceEncoding := and(data, 1)\n if iszero(outOfPlaceEncoding) { length := and(length, 0x7f) }\n if eq(outOfPlaceEncoding, lt(length, 32))\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x22)\n revert(0, 0x24)\n }\n }\n function abi_encode_tuple_t_stringliteral_b51b4875eede07862961e8f9365c6749f5fe55c6ee5d7a9e42b6912ad0b15942__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 33)\n mstore(add(headStart, 64), \"ERC721: approval to current owne\")\n mstore(add(headStart, 96), \"r\")\n tail := add(headStart, 128)\n }\n function abi_encode_tuple_t_stringliteral_c6e14a63ffb144eeef7cce6988e5dce07c60a7e0a7b1ef25dbe18c61483e0a83__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 61)\n mstore(add(headStart, 64), \"ERC721: approve caller is not to\")\n mstore(add(headStart, 96), \"ken owner or approved for all\")\n tail := add(headStart, 128)\n }\n function abi_encode_tuple_t_stringliteral_12a8e5623d251e191fe4a291d9a59bcc01a4db7a1f5c20fc8de44358c18308af__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 45)\n mstore(add(headStart, 64), \"ERC721: caller is not token owne\")\n mstore(add(headStart, 96), \"r or approved\")\n tail := add(headStart, 128)\n }\n function abi_encode_tuple_t_stringliteral_b08d2b0fec7cc108ab049809a8beb42779d969a49299d0c317c907d9db22974f__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 24)\n mstore(add(headStart, 64), \"ERC721: invalid token ID\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_6d05c90094f31cfeb8f0eb86f0a513af3f7f8992991fbde41b08aa7960677159__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 41)\n mstore(add(headStart, 64), \"ERC721: address zero is not a va\")\n mstore(add(headStart, 96), \"lid owner\")\n tail := add(headStart, 128)\n }\n function abi_encode_tuple_packed_t_string_memory_ptr_t_string_memory_ptr__to_t_string_memory_ptr_t_string_memory_ptr__nonPadded_inplace_fromStack_reversed(pos, value1, value0) -> end\n {\n let length := mload(value0)\n copy_memory_to_memory_with_cleanup(add(value0, 0x20), pos, length)\n let end_1 := add(pos, length)\n let length_1 := mload(value1)\n copy_memory_to_memory_with_cleanup(add(value1, 0x20), end_1, length_1)\n end := add(end_1, length_1)\n }\n function abi_encode_tuple_t_stringliteral_277f8ee9d5b4fc3c4149386f24de0fc1bbc63a8210e2197bfd1c0376a2ac5f48__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 37)\n mstore(add(headStart, 64), \"ERC721: transfer from incorrect \")\n mstore(add(headStart, 96), \"owner\")\n tail := add(headStart, 128)\n }\n function abi_encode_tuple_t_stringliteral_455fea98ea03c32d7dd1a6f1426917d80529bf47b3ccbde74e7206e889e709f4__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 36)\n mstore(add(headStart, 64), \"ERC721: transfer to the zero add\")\n mstore(add(headStart, 96), \"ress\")\n tail := add(headStart, 128)\n }\n function abi_encode_tuple_t_stringliteral_8a66f4bb6512ffbfcc3db9b42318eb65f26ac15163eaa9a1e5cfa7bee9d1c7c6__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 32)\n mstore(add(headStart, 64), \"ERC721: mint to the zero address\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_2a63ce106ef95058ed21fd07c42a10f11dc5c32ac13a4e847923f7759f635d57__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 28)\n mstore(add(headStart, 64), \"ERC721: token already minted\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_45fe4329685be5ecd250fd0e6a25aea0ea4d0e30fb6a73c118b95749e6d70d05__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 25)\n mstore(add(headStart, 64), \"ERC721: approve to caller\")\n tail := add(headStart, 96)\n }\n function abi_encode_tuple_t_stringliteral_1e766a06da43a53d0f4c380e06e5a342e14d5af1bf8501996c844905530ca84e__to_t_string_memory_ptr__fromStack_reversed(headStart) -> tail\n {\n mstore(headStart, 32)\n mstore(add(headStart, 32), 50)\n mstore(add(headStart, 64), \"ERC721: transfer to non ERC721Re\")\n mstore(add(headStart, 96), \"ceiver implementer\")\n tail := add(headStart, 128)\n }\n function panic_error_0x12()\n {\n mstore(0, shl(224, 0x4e487b71))\n mstore(4, 0x12)\n revert(0, 0x24)\n }\n function abi_encode_tuple_t_address_t_address_t_uint256_t_bytes_memory_ptr__to_t_address_t_address_t_uint256_t_bytes_memory_ptr__fromStack_reversed(headStart, value3, value2, value1, value0) -> tail\n {\n let _1 := sub(shl(160, 1), 1)\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), and(value1, _1))\n mstore(add(headStart, 64), value2)\n mstore(add(headStart, 96), 128)\n tail := abi_encode_string(value3, add(headStart, 128))\n }\n function abi_decode_tuple_t_bytes4_fromMemory(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := mload(headStart)\n validator_revert_bytes4(value)\n value0 := value\n }\n}","id":17,"language":"Yul","name":"#utility.yul"}],"immutableReferences":{},"linkReferences":{},"object":"608060405234801561001057600080fd5b50600436106100ea5760003560e01c80636352211e1161008c578063a22cb46511610066578063a22cb465146101e1578063b88d4fde146101f4578063c87b56dd14610207578063e985e9c51461021a57600080fd5b80636352211e146101a557806370a08231146101b857806395d89b41146101d957600080fd5b8063095ea7b3116100c8578063095ea7b31461015757806323b872dd1461016c57806340c10f191461017f57806342842e0e1461019257600080fd5b806301ffc9a7146100ef57806306fdde0314610117578063081812fc1461012c575b600080fd5b6101026100fd366004610e42565b610256565b60405190151581526020015b60405180910390f35b61011f6102a8565b60405161010e9190610eaf565b61013f61013a366004610ec2565b61033a565b6040516001600160a01b03909116815260200161010e565b61016a610165366004610ef7565b610361565b005b61016a61017a366004610f21565b61047b565b61016a61018d366004610ef7565b6104ac565b61016a6101a0366004610f21565b6104ba565b61013f6101b3366004610ec2565b6104d5565b6101cb6101c6366004610f5d565b610535565b60405190815260200161010e565b61011f6105bb565b61016a6101ef366004610f78565b6105ca565b61016a610202366004610fca565b6105d5565b61011f610215366004610ec2565b61060d565b6101026102283660046110a6565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60006001600160e01b031982166380ac58cd60e01b148061028757506001600160e01b03198216635b5e139f60e01b145b806102a257506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600080546102b7906110d9565b80601f01602080910402602001604051908101604052809291908181526020018280546102e3906110d9565b80156103305780601f1061030557610100808354040283529160200191610330565b820191906000526020600020905b81548152906001019060200180831161031357829003601f168201915b5050505050905090565b600061034582610681565b506000908152600460205260409020546001600160a01b031690565b600061036c826104d5565b9050806001600160a01b0316836001600160a01b0316036103de5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806103fa57506103fa8133610228565b61046c5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c00000060648201526084016103d5565b61047683836106e3565b505050565b6104853382610751565b6104a15760405162461bcd60e51b81526004016103d590611113565b6104768383836107d0565b6104b68282610934565b5050565b610476838383604051806020016040528060008152506105d5565b6000818152600260205260408120546001600160a01b0316806102a25760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103d5565b60006001600160a01b03821661059f5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016103d5565b506001600160a01b031660009081526003602052604090205490565b6060600180546102b7906110d9565b6104b6338383610abf565b6105df3383610751565b6105fb5760405162461bcd60e51b81526004016103d590611113565b61060784848484610b8d565b50505050565b606061061882610681565b600061062f60408051602081019091526000815290565b9050600081511161064f576040518060200160405280600081525061067a565b8061065984610bc0565b60405160200161066a929190611160565b6040516020818303038152906040525b9392505050565b6000818152600260205260409020546001600160a01b03166106e05760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103d5565b50565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610718826104d5565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061075d836104d5565b9050806001600160a01b0316846001600160a01b031614806107a457506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b806107c85750836001600160a01b03166107bd8461033a565b6001600160a01b0316145b949350505050565b826001600160a01b03166107e3826104d5565b6001600160a01b0316146108095760405162461bcd60e51b81526004016103d59061118f565b6001600160a01b03821661086b5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016103d5565b826001600160a01b031661087e826104d5565b6001600160a01b0316146108a45760405162461bcd60e51b81526004016103d59061118f565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b03821661098a5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016103d5565b6000818152600260205260409020546001600160a01b0316156109ef5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016103d5565b6000818152600260205260409020546001600160a01b031615610a545760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016103d5565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b816001600160a01b0316836001600160a01b031603610b205760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016103d5565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b610b988484846107d0565b610ba484848484610c53565b6106075760405162461bcd60e51b81526004016103d5906111d4565b60606000610bcd83610d54565b600101905060008167ffffffffffffffff811115610bed57610bed610fb4565b6040519080825280601f01601f191660200182016040528015610c17576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084610c2157509392505050565b60006001600160a01b0384163b15610d4957604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290610c97903390899088908890600401611226565b6020604051808303816000875af1925050508015610cd2575060408051601f3d908101601f19168201909252610ccf91810190611263565b60015b610d2f573d808015610d00576040519150601f19603f3d011682016040523d82523d6000602084013e610d05565b606091505b508051600003610d275760405162461bcd60e51b81526004016103d5906111d4565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506107c8565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310610d935772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310610dbf576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310610ddd57662386f26fc10000830492506010015b6305f5e1008310610df5576305f5e100830492506008015b6127108310610e0957612710830492506004015b60648310610e1b576064830492506002015b600a83106102a25760010192915050565b6001600160e01b0319811681146106e057600080fd5b600060208284031215610e5457600080fd5b813561067a81610e2c565b60005b83811015610e7a578181015183820152602001610e62565b50506000910152565b60008151808452610e9b816020860160208601610e5f565b601f01601f19169290920160200192915050565b60208152600061067a6020830184610e83565b600060208284031215610ed457600080fd5b5035919050565b80356001600160a01b0381168114610ef257600080fd5b919050565b60008060408385031215610f0a57600080fd5b610f1383610edb565b946020939093013593505050565b600080600060608486031215610f3657600080fd5b610f3f84610edb565b9250610f4d60208501610edb565b9150604084013590509250925092565b600060208284031215610f6f57600080fd5b61067a82610edb565b60008060408385031215610f8b57600080fd5b610f9483610edb565b915060208301358015158114610fa957600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215610fe057600080fd5b610fe985610edb565b9350610ff760208601610edb565b925060408501359150606085013567ffffffffffffffff8082111561101b57600080fd5b818701915087601f83011261102f57600080fd5b81358181111561104157611041610fb4565b604051601f8201601f19908116603f0116810190838211818310171561106957611069610fb4565b816040528281528a602084870101111561108257600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b600080604083850312156110b957600080fd5b6110c283610edb565b91506110d060208401610edb565b90509250929050565b600181811c908216806110ed57607f821691505b60208210810361110d57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b60008351611172818460208801610e5f565b835190830190611186818360208801610e5f565b01949350505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061125990830184610e83565b9695505050505050565b60006020828403121561127557600080fd5b815161067a81610e2c56fea26469706673582212203e5c29bc0c6611a8b7a6b12c19a302bc12fee5e380672b063f2b72a4f2ffcd6b64736f6c63430008110033","opcodes":"PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0xEA JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x6352211E GT PUSH2 0x8C JUMPI DUP1 PUSH4 0xA22CB465 GT PUSH2 0x66 JUMPI DUP1 PUSH4 0xA22CB465 EQ PUSH2 0x1E1 JUMPI DUP1 PUSH4 0xB88D4FDE EQ PUSH2 0x1F4 JUMPI DUP1 PUSH4 0xC87B56DD EQ PUSH2 0x207 JUMPI DUP1 PUSH4 0xE985E9C5 EQ PUSH2 0x21A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x6352211E EQ PUSH2 0x1A5 JUMPI DUP1 PUSH4 0x70A08231 EQ PUSH2 0x1B8 JUMPI DUP1 PUSH4 0x95D89B41 EQ PUSH2 0x1D9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x95EA7B3 GT PUSH2 0xC8 JUMPI DUP1 PUSH4 0x95EA7B3 EQ PUSH2 0x157 JUMPI DUP1 PUSH4 0x23B872DD EQ PUSH2 0x16C JUMPI DUP1 PUSH4 0x40C10F19 EQ PUSH2 0x17F JUMPI DUP1 PUSH4 0x42842E0E EQ PUSH2 0x192 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1FFC9A7 EQ PUSH2 0xEF JUMPI DUP1 PUSH4 0x6FDDE03 EQ PUSH2 0x117 JUMPI DUP1 PUSH4 0x81812FC EQ PUSH2 0x12C JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x102 PUSH2 0xFD CALLDATASIZE PUSH1 0x4 PUSH2 0xE42 JUMP JUMPDEST PUSH2 0x256 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x11F PUSH2 0x2A8 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x10E SWAP2 SWAP1 PUSH2 0xEAF JUMP JUMPDEST PUSH2 0x13F PUSH2 0x13A CALLDATASIZE PUSH1 0x4 PUSH2 0xEC2 JUMP JUMPDEST PUSH2 0x33A JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x10E JUMP JUMPDEST PUSH2 0x16A PUSH2 0x165 CALLDATASIZE PUSH1 0x4 PUSH2 0xEF7 JUMP JUMPDEST PUSH2 0x361 JUMP JUMPDEST STOP JUMPDEST PUSH2 0x16A PUSH2 0x17A CALLDATASIZE PUSH1 0x4 PUSH2 0xF21 JUMP JUMPDEST PUSH2 0x47B JUMP JUMPDEST PUSH2 0x16A PUSH2 0x18D CALLDATASIZE PUSH1 0x4 PUSH2 0xEF7 JUMP JUMPDEST PUSH2 0x4AC JUMP JUMPDEST PUSH2 0x16A PUSH2 0x1A0 CALLDATASIZE PUSH1 0x4 PUSH2 0xF21 JUMP JUMPDEST PUSH2 0x4BA JUMP JUMPDEST PUSH2 0x13F PUSH2 0x1B3 CALLDATASIZE PUSH1 0x4 PUSH2 0xEC2 JUMP JUMPDEST PUSH2 0x4D5 JUMP JUMPDEST PUSH2 0x1CB PUSH2 0x1C6 CALLDATASIZE PUSH1 0x4 PUSH2 0xF5D JUMP JUMPDEST PUSH2 0x535 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x10E JUMP JUMPDEST PUSH2 0x11F PUSH2 0x5BB JUMP JUMPDEST PUSH2 0x16A PUSH2 0x1EF CALLDATASIZE PUSH1 0x4 PUSH2 0xF78 JUMP JUMPDEST PUSH2 0x5CA JUMP JUMPDEST PUSH2 0x16A PUSH2 0x202 CALLDATASIZE PUSH1 0x4 PUSH2 0xFCA JUMP JUMPDEST PUSH2 0x5D5 JUMP JUMPDEST PUSH2 0x11F PUSH2 0x215 CALLDATASIZE PUSH1 0x4 PUSH2 0xEC2 JUMP JUMPDEST PUSH2 0x60D JUMP JUMPDEST PUSH2 0x102 PUSH2 0x228 CALLDATASIZE PUSH1 0x4 PUSH2 0x10A6 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB SWAP2 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 SWAP1 SWAP5 AND DUP3 MSTORE SWAP2 SWAP1 SWAP2 MSTORE KECCAK256 SLOAD PUSH1 0xFF AND SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP3 AND PUSH4 0x80AC58CD PUSH1 0xE0 SHL EQ DUP1 PUSH2 0x287 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP3 AND PUSH4 0x5B5E139F PUSH1 0xE0 SHL EQ JUMPDEST DUP1 PUSH2 0x2A2 JUMPI POP PUSH4 0x1FFC9A7 PUSH1 0xE0 SHL PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP4 AND EQ JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 DUP1 SLOAD PUSH2 0x2B7 SWAP1 PUSH2 0x10D9 JUMP JUMPDEST DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD PUSH2 0x2E3 SWAP1 PUSH2 0x10D9 JUMP JUMPDEST DUP1 ISZERO PUSH2 0x330 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x305 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x330 JUMP JUMPDEST DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD DUP2 MSTORE SWAP1 PUSH1 0x1 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0x313 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x345 DUP3 PUSH2 0x681 JUMP JUMPDEST POP PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x4 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x36C DUP3 PUSH2 0x4D5 JUMP JUMPDEST SWAP1 POP DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP4 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SUB PUSH2 0x3DE JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x21 PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A20617070726F76616C20746F2063757272656E74206F776E65 PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x39 PUSH1 0xF9 SHL PUSH1 0x64 DUP3 ADD MSTORE PUSH1 0x84 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST CALLER PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND EQ DUP1 PUSH2 0x3FA JUMPI POP PUSH2 0x3FA DUP2 CALLER PUSH2 0x228 JUMP JUMPDEST PUSH2 0x46C JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x3D PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A20617070726F76652063616C6C6572206973206E6F7420746F PUSH1 0x44 DUP3 ADD MSTORE PUSH32 0x6B656E206F776E6572206F7220617070726F76656420666F7220616C6C000000 PUSH1 0x64 DUP3 ADD MSTORE PUSH1 0x84 ADD PUSH2 0x3D5 JUMP JUMPDEST PUSH2 0x476 DUP4 DUP4 PUSH2 0x6E3 JUMP JUMPDEST POP POP POP JUMP JUMPDEST PUSH2 0x485 CALLER DUP3 PUSH2 0x751 JUMP JUMPDEST PUSH2 0x4A1 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3D5 SWAP1 PUSH2 0x1113 JUMP JUMPDEST PUSH2 0x476 DUP4 DUP4 DUP4 PUSH2 0x7D0 JUMP JUMPDEST PUSH2 0x4B6 DUP3 DUP3 PUSH2 0x934 JUMP JUMPDEST POP POP JUMP JUMPDEST PUSH2 0x476 DUP4 DUP4 DUP4 PUSH1 0x40 MLOAD DUP1 PUSH1 0x20 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 DUP2 MSTORE POP PUSH2 0x5D5 JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 DUP2 KECCAK256 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP1 PUSH2 0x2A2 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x18 PUSH1 0x24 DUP3 ADD MSTORE PUSH24 0x115490CDCC8C4E881A5B9D985B1A59081D1BDAD95B881251 PUSH1 0x42 SHL PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3D5 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND PUSH2 0x59F JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x29 PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A2061646472657373207A65726F206973206E6F742061207661 PUSH1 0x44 DUP3 ADD MSTORE PUSH9 0x3634B21037BBB732B9 PUSH1 0xB9 SHL PUSH1 0x64 DUP3 ADD MSTORE PUSH1 0x84 ADD PUSH2 0x3D5 JUMP JUMPDEST POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x3 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD SWAP1 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x1 DUP1 SLOAD PUSH2 0x2B7 SWAP1 PUSH2 0x10D9 JUMP JUMPDEST PUSH2 0x4B6 CALLER DUP4 DUP4 PUSH2 0xABF JUMP JUMPDEST PUSH2 0x5DF CALLER DUP4 PUSH2 0x751 JUMP JUMPDEST PUSH2 0x5FB JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3D5 SWAP1 PUSH2 0x1113 JUMP JUMPDEST PUSH2 0x607 DUP5 DUP5 DUP5 DUP5 PUSH2 0xB8D JUMP JUMPDEST POP POP POP POP JUMP JUMPDEST PUSH1 0x60 PUSH2 0x618 DUP3 PUSH2 0x681 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x62F PUSH1 0x40 DUP1 MLOAD PUSH1 0x20 DUP2 ADD SWAP1 SWAP2 MSTORE PUSH1 0x0 DUP2 MSTORE SWAP1 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 DUP2 MLOAD GT PUSH2 0x64F JUMPI PUSH1 0x40 MLOAD DUP1 PUSH1 0x20 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x0 DUP2 MSTORE POP PUSH2 0x67A JUMP JUMPDEST DUP1 PUSH2 0x659 DUP5 PUSH2 0xBC0 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0x66A SWAP3 SWAP2 SWAP1 PUSH2 0x1160 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH2 0x6E0 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x18 PUSH1 0x24 DUP3 ADD MSTORE PUSH24 0x115490CDCC8C4E881A5B9D985B1A59081D1BDAD95B881251 PUSH1 0x42 SHL PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3D5 JUMP JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x4 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 DUP1 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB NOT AND PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE DUP2 SWAP1 PUSH2 0x718 DUP3 PUSH2 0x4D5 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH32 0x8C5BE1E5EBEC7D5BD14F71427D1E84F3DD0314C0F7B2291E5B200AC8C7C3B925 PUSH1 0x40 MLOAD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG4 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH2 0x75D DUP4 PUSH2 0x4D5 JUMP JUMPDEST SWAP1 POP DUP1 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP5 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ DUP1 PUSH2 0x7A4 JUMPI POP PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP1 DUP3 AND PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP4 DUP9 AND DUP4 MSTORE SWAP3 SWAP1 MSTORE KECCAK256 SLOAD PUSH1 0xFF AND JUMPDEST DUP1 PUSH2 0x7C8 JUMPI POP DUP4 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH2 0x7BD DUP5 PUSH2 0x33A JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST DUP3 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH2 0x7E3 DUP3 PUSH2 0x4D5 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ PUSH2 0x809 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3D5 SWAP1 PUSH2 0x118F JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND PUSH2 0x86B JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x24 DUP1 DUP3 ADD MSTORE PUSH32 0x4552433732313A207472616E7366657220746F20746865207A65726F20616464 PUSH1 0x44 DUP3 ADD MSTORE PUSH4 0x72657373 PUSH1 0xE0 SHL PUSH1 0x64 DUP3 ADD MSTORE PUSH1 0x84 ADD PUSH2 0x3D5 JUMP JUMPDEST DUP3 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND PUSH2 0x87E DUP3 PUSH2 0x4D5 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND EQ PUSH2 0x8A4 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3D5 SWAP1 PUSH2 0x118F JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x4 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 DUP1 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB NOT SWAP1 DUP2 AND SWAP1 SWAP2 SSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP8 DUP2 AND DUP1 DUP7 MSTORE PUSH1 0x3 DUP6 MSTORE DUP4 DUP7 KECCAK256 DUP1 SLOAD PUSH1 0x0 NOT ADD SWAP1 SSTORE SWAP1 DUP8 AND DUP1 DUP7 MSTORE DUP4 DUP7 KECCAK256 DUP1 SLOAD PUSH1 0x1 ADD SWAP1 SSTORE DUP7 DUP7 MSTORE PUSH1 0x2 SWAP1 SWAP5 MSTORE DUP3 DUP6 KECCAK256 DUP1 SLOAD SWAP1 SWAP3 AND DUP5 OR SWAP1 SWAP2 SSTORE SWAP1 MLOAD DUP5 SWAP4 PUSH32 0xDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF SWAP2 LOG4 POP POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND PUSH2 0x98A JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A206D696E7420746F20746865207A65726F2061646472657373 PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3D5 JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND ISZERO PUSH2 0x9EF JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x1C PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A20746F6B656E20616C7265616479206D696E74656400000000 PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3D5 JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x2 PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 KECCAK256 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND ISZERO PUSH2 0xA54 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x1C PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A20746F6B656E20616C7265616479206D696E74656400000000 PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3D5 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP3 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x3 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 DUP1 SLOAD PUSH1 0x1 ADD SWAP1 SSTORE DUP5 DUP4 MSTORE PUSH1 0x2 SWAP1 SWAP2 MSTORE DUP1 DUP3 KECCAK256 DUP1 SLOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB NOT AND DUP5 OR SWAP1 SSTORE MLOAD DUP4 SWAP3 SWAP2 SWAP1 PUSH32 0xDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF SWAP1 DUP3 SWAP1 LOG4 POP POP JUMP JUMPDEST DUP2 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND DUP4 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB AND SUB PUSH2 0xB20 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x20 PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x19 PUSH1 0x24 DUP3 ADD MSTORE PUSH32 0x4552433732313A20617070726F766520746F2063616C6C657200000000000000 PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3D5 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP4 DUP2 AND PUSH1 0x0 DUP2 DUP2 MSTORE PUSH1 0x5 PUSH1 0x20 SWAP1 DUP2 MSTORE PUSH1 0x40 DUP1 DUP4 KECCAK256 SWAP5 DUP8 AND DUP1 DUP5 MSTORE SWAP5 DUP3 MSTORE SWAP2 DUP3 SWAP1 KECCAK256 DUP1 SLOAD PUSH1 0xFF NOT AND DUP7 ISZERO ISZERO SWAP1 DUP2 OR SWAP1 SWAP2 SSTORE SWAP2 MLOAD SWAP2 DUP3 MSTORE PUSH32 0x17307EAB39AB6107E8899845AD3D59BD9653F200F220920489CA2B5937696C31 SWAP2 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 POP POP POP JUMP JUMPDEST PUSH2 0xB98 DUP5 DUP5 DUP5 PUSH2 0x7D0 JUMP JUMPDEST PUSH2 0xBA4 DUP5 DUP5 DUP5 DUP5 PUSH2 0xC53 JUMP JUMPDEST PUSH2 0x607 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3D5 SWAP1 PUSH2 0x11D4 JUMP JUMPDEST PUSH1 0x60 PUSH1 0x0 PUSH2 0xBCD DUP4 PUSH2 0xD54 JUMP JUMPDEST PUSH1 0x1 ADD SWAP1 POP PUSH1 0x0 DUP2 PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0xBED JUMPI PUSH2 0xBED PUSH2 0xFB4 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP1 DUP3 MSTORE DUP1 PUSH1 0x1F ADD PUSH1 0x1F NOT AND PUSH1 0x20 ADD DUP3 ADD PUSH1 0x40 MSTORE DUP1 ISZERO PUSH2 0xC17 JUMPI PUSH1 0x20 DUP3 ADD DUP2 DUP1 CALLDATASIZE DUP4 CALLDATACOPY ADD SWAP1 POP JUMPDEST POP SWAP1 POP DUP2 DUP2 ADD PUSH1 0x20 ADD JUMPDEST PUSH1 0x0 NOT ADD PUSH16 0x181899199A1A9B1B9C1CB0B131B232B3 PUSH1 0x81 SHL PUSH1 0xA DUP7 MOD BYTE DUP2 MSTORE8 PUSH1 0xA DUP6 DIV SWAP5 POP DUP5 PUSH2 0xC21 JUMPI POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP5 AND EXTCODESIZE ISZERO PUSH2 0xD49 JUMPI PUSH1 0x40 MLOAD PUSH4 0xA85BD01 PUSH1 0xE1 SHL DUP2 MSTORE PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP6 AND SWAP1 PUSH4 0x150B7A02 SWAP1 PUSH2 0xC97 SWAP1 CALLER SWAP1 DUP10 SWAP1 DUP9 SWAP1 DUP9 SWAP1 PUSH1 0x4 ADD PUSH2 0x1226 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 PUSH1 0x0 DUP8 GAS CALL SWAP3 POP POP POP DUP1 ISZERO PUSH2 0xCD2 JUMPI POP PUSH1 0x40 DUP1 MLOAD PUSH1 0x1F RETURNDATASIZE SWAP1 DUP2 ADD PUSH1 0x1F NOT AND DUP3 ADD SWAP1 SWAP3 MSTORE PUSH2 0xCCF SWAP2 DUP2 ADD SWAP1 PUSH2 0x1263 JUMP JUMPDEST PUSH1 0x1 JUMPDEST PUSH2 0xD2F JUMPI RETURNDATASIZE DUP1 DUP1 ISZERO PUSH2 0xD00 JUMPI PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x1F NOT PUSH1 0x3F RETURNDATASIZE ADD AND DUP3 ADD PUSH1 0x40 MSTORE RETURNDATASIZE DUP3 MSTORE RETURNDATASIZE PUSH1 0x0 PUSH1 0x20 DUP5 ADD RETURNDATACOPY PUSH2 0xD05 JUMP JUMPDEST PUSH1 0x60 SWAP2 POP JUMPDEST POP DUP1 MLOAD PUSH1 0x0 SUB PUSH2 0xD27 JUMPI PUSH1 0x40 MLOAD PUSH3 0x461BCD PUSH1 0xE5 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3D5 SWAP1 PUSH2 0x11D4 JUMP JUMPDEST DUP1 MLOAD DUP2 PUSH1 0x20 ADD REVERT JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT AND PUSH4 0xA85BD01 PUSH1 0xE1 SHL EQ SWAP1 POP PUSH2 0x7C8 JUMP JUMPDEST POP PUSH1 0x1 SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH19 0x184F03E93FF9F4DAA797ED6E38ED64BF6A1F01 PUSH1 0x40 SHL DUP4 LT PUSH2 0xD93 JUMPI PUSH19 0x184F03E93FF9F4DAA797ED6E38ED64BF6A1F01 PUSH1 0x40 SHL DUP4 DIV SWAP3 POP PUSH1 0x40 ADD JUMPDEST PUSH14 0x4EE2D6D415B85ACEF8100000000 DUP4 LT PUSH2 0xDBF JUMPI PUSH14 0x4EE2D6D415B85ACEF8100000000 DUP4 DIV SWAP3 POP PUSH1 0x20 ADD JUMPDEST PUSH7 0x2386F26FC10000 DUP4 LT PUSH2 0xDDD JUMPI PUSH7 0x2386F26FC10000 DUP4 DIV SWAP3 POP PUSH1 0x10 ADD JUMPDEST PUSH4 0x5F5E100 DUP4 LT PUSH2 0xDF5 JUMPI PUSH4 0x5F5E100 DUP4 DIV SWAP3 POP PUSH1 0x8 ADD JUMPDEST PUSH2 0x2710 DUP4 LT PUSH2 0xE09 JUMPI PUSH2 0x2710 DUP4 DIV SWAP3 POP PUSH1 0x4 ADD JUMPDEST PUSH1 0x64 DUP4 LT PUSH2 0xE1B JUMPI PUSH1 0x64 DUP4 DIV SWAP3 POP PUSH1 0x2 ADD JUMPDEST PUSH1 0xA DUP4 LT PUSH2 0x2A2 JUMPI PUSH1 0x1 ADD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xE0 SHL SUB NOT DUP2 AND DUP2 EQ PUSH2 0x6E0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xE54 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x67A DUP2 PUSH2 0xE2C JUMP JUMPDEST PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0xE7A JUMPI DUP2 DUP2 ADD MLOAD DUP4 DUP3 ADD MSTORE PUSH1 0x20 ADD PUSH2 0xE62 JUMP JUMPDEST POP POP PUSH1 0x0 SWAP2 ADD MSTORE JUMP JUMPDEST PUSH1 0x0 DUP2 MLOAD DUP1 DUP5 MSTORE PUSH2 0xE9B DUP2 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP7 ADD PUSH2 0xE5F JUMP JUMPDEST PUSH1 0x1F ADD PUSH1 0x1F NOT AND SWAP3 SWAP1 SWAP3 ADD PUSH1 0x20 ADD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE PUSH1 0x0 PUSH2 0x67A PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0xE83 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xED4 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 CALLDATALOAD PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP2 AND DUP2 EQ PUSH2 0xEF2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xF0A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xF13 DUP4 PUSH2 0xEDB JUMP JUMPDEST SWAP5 PUSH1 0x20 SWAP4 SWAP1 SWAP4 ADD CALLDATALOAD SWAP4 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP5 DUP7 SUB SLT ISZERO PUSH2 0xF36 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xF3F DUP5 PUSH2 0xEDB JUMP JUMPDEST SWAP3 POP PUSH2 0xF4D PUSH1 0x20 DUP6 ADD PUSH2 0xEDB JUMP JUMPDEST SWAP2 POP PUSH1 0x40 DUP5 ADD CALLDATALOAD SWAP1 POP SWAP3 POP SWAP3 POP SWAP3 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xF6F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x67A DUP3 PUSH2 0xEDB JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0xF8B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xF94 DUP4 PUSH2 0xEDB JUMP JUMPDEST SWAP2 POP PUSH1 0x20 DUP4 ADD CALLDATALOAD DUP1 ISZERO ISZERO DUP2 EQ PUSH2 0xFA9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 SWAP2 POP POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x80 DUP6 DUP8 SUB SLT ISZERO PUSH2 0xFE0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xFE9 DUP6 PUSH2 0xEDB JUMP JUMPDEST SWAP4 POP PUSH2 0xFF7 PUSH1 0x20 DUP7 ADD PUSH2 0xEDB JUMP JUMPDEST SWAP3 POP PUSH1 0x40 DUP6 ADD CALLDATALOAD SWAP2 POP PUSH1 0x60 DUP6 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x101B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP8 ADD SWAP2 POP DUP8 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x102F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP2 DUP2 GT ISZERO PUSH2 0x1041 JUMPI PUSH2 0x1041 PUSH2 0xFB4 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP3 ADD PUSH1 0x1F NOT SWAP1 DUP2 AND PUSH1 0x3F ADD AND DUP2 ADD SWAP1 DUP4 DUP3 GT DUP2 DUP4 LT OR ISZERO PUSH2 0x1069 JUMPI PUSH2 0x1069 PUSH2 0xFB4 JUMP JUMPDEST DUP2 PUSH1 0x40 MSTORE DUP3 DUP2 MSTORE DUP11 PUSH1 0x20 DUP5 DUP8 ADD ADD GT ISZERO PUSH2 0x1082 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 PUSH1 0x20 DUP5 DUP4 ADD ADD MSTORE DUP1 SWAP6 POP POP POP POP POP POP SWAP3 SWAP6 SWAP2 SWAP5 POP SWAP3 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x40 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x10B9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x10C2 DUP4 PUSH2 0xEDB JUMP JUMPDEST SWAP2 POP PUSH2 0x10D0 PUSH1 0x20 DUP5 ADD PUSH2 0xEDB JUMP JUMPDEST SWAP1 POP SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x1 DUP2 DUP2 SHR SWAP1 DUP3 AND DUP1 PUSH2 0x10ED JUMPI PUSH1 0x7F DUP3 AND SWAP2 POP JUMPDEST PUSH1 0x20 DUP3 LT DUP2 SUB PUSH2 0x110D JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x22 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE PUSH1 0x2D SWAP1 DUP3 ADD MSTORE PUSH32 0x4552433732313A2063616C6C6572206973206E6F7420746F6B656E206F776E65 PUSH1 0x40 DUP3 ADD MSTORE PUSH13 0x1C881BDC88185C1C1C9BDD9959 PUSH1 0x9A SHL PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP4 MLOAD PUSH2 0x1172 DUP2 DUP5 PUSH1 0x20 DUP9 ADD PUSH2 0xE5F JUMP JUMPDEST DUP4 MLOAD SWAP1 DUP4 ADD SWAP1 PUSH2 0x1186 DUP2 DUP4 PUSH1 0x20 DUP9 ADD PUSH2 0xE5F JUMP JUMPDEST ADD SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE PUSH1 0x25 SWAP1 DUP3 ADD MSTORE PUSH32 0x4552433732313A207472616E736665722066726F6D20696E636F727265637420 PUSH1 0x40 DUP3 ADD MSTORE PUSH5 0x37BBB732B9 PUSH1 0xD9 SHL PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 ADD SWAP1 JUMP JUMPDEST PUSH1 0x20 DUP1 DUP3 MSTORE PUSH1 0x32 SWAP1 DUP3 ADD MSTORE PUSH32 0x4552433732313A207472616E7366657220746F206E6F6E204552433732315265 PUSH1 0x40 DUP3 ADD MSTORE PUSH18 0x31B2B4BB32B91034B6B83632B6B2B73A32B9 PUSH1 0x71 SHL PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 ADD SWAP1 JUMP JUMPDEST PUSH1 0x1 PUSH1 0x1 PUSH1 0xA0 SHL SUB DUP6 DUP2 AND DUP3 MSTORE DUP5 AND PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 DUP2 ADD DUP4 SWAP1 MSTORE PUSH1 0x80 PUSH1 0x60 DUP3 ADD DUP2 SWAP1 MSTORE PUSH1 0x0 SWAP1 PUSH2 0x1259 SWAP1 DUP4 ADD DUP5 PUSH2 0xE83 JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1275 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x67A DUP2 PUSH2 0xE2C JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 RETURNDATACOPY 0x5C 0x29 0xBC 0xC PUSH7 0x11A8B7A6B12C19 LOG3 MUL 0xBC SLT INVALID 0xE5 0xE3 DUP1 PUSH8 0x2B063F2B72A4F2FF 0xCD PUSH12 0x64736F6C6343000811003300 ","sourceMap":"117:263:16:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1570:300:0;;;;;;:::i;:::-;;:::i;:::-;;;565:14:17;;558:22;540:41;;528:2;513:18;1570:300:0;;;;;;;;2471:98;;;:::i;:::-;;;;;;;:::i;3935:167::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1697:32:17;;;1679:51;;1667:2;1652:18;3935:167:0;1533:203:17;3468:406:0;;;;;;:::i;:::-;;:::i;:::-;;4612:296;;;;;;:::i;:::-;;:::i;291:87:16:-;;;;;;:::i;:::-;;:::i;4974:149:0:-;;;;;;:::i;:::-;;:::i;2190:219::-;;;;;;:::i;:::-;;:::i;1929:204::-;;;;;;:::i;:::-;;:::i;:::-;;;2848:25:17;;;2836:2;2821:18;1929:204:0;2702:177:17;2633:102:0;;;:::i;4169:153::-;;;;;;:::i;:::-;;:::i;5189:276::-;;;;;;:::i;:::-;;:::i;2801:::-;;;;;;:::i;:::-;;:::i;4388:162::-;;;;;;:::i;:::-;-1:-1:-1;;;;;4508:25:0;;;4485:4;4508:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;4388:162;1570:300;1672:4;-1:-1:-1;;;;;;1707:40:0;;-1:-1:-1;;;1707:40:0;;:104;;-1:-1:-1;;;;;;;1763:48:0;;-1:-1:-1;;;1763:48:0;1707:104;:156;;;-1:-1:-1;;;;;;;;;;937:40:7;;;1827:36:0;1688:175;1570:300;-1:-1:-1;;1570:300:0:o;2471:98::-;2525:13;2557:5;2550:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2471:98;:::o;3935:167::-;4011:7;4030:23;4045:7;4030:14;:23::i;:::-;-1:-1:-1;4071:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;4071:24:0;;3935:167::o;3468:406::-;3548:13;3564:23;3579:7;3564:14;:23::i;:::-;3548:39;;3611:5;-1:-1:-1;;;;;3605:11:0;:2;-1:-1:-1;;;;;3605:11:0;;3597:57;;;;-1:-1:-1;;;3597:57:0;;5363:2:17;3597:57:0;;;5345:21:17;5402:2;5382:18;;;5375:30;5441:34;5421:18;;;5414:62;-1:-1:-1;;;5492:18:17;;;5485:31;5533:19;;3597:57:0;;;;;;;;;719:10:5;-1:-1:-1;;;;;3686:21:0;;;;:62;;-1:-1:-1;3711:37:0;3728:5;719:10:5;4388:162:0;:::i;3711:37::-;3665:170;;;;-1:-1:-1;;;3665:170:0;;5765:2:17;3665:170:0;;;5747:21:17;5804:2;5784:18;;;5777:30;5843:34;5823:18;;;5816:62;5914:31;5894:18;;;5887:59;5963:19;;3665:170:0;5563:425:17;3665:170:0;3846:21;3855:2;3859:7;3846:8;:21::i;:::-;3538:336;3468:406;;:::o;4612:296::-;4771:41;719:10:5;4804:7:0;4771:18;:41::i;:::-;4763:99;;;;-1:-1:-1;;;4763:99:0;;;;;;;:::i;:::-;4873:28;4883:4;4889:2;4893:7;4873:9;:28::i;291:87:16:-;353:18;359:2;363:7;353:5;:18::i;:::-;291:87;;:::o;4974:149:0:-;5077:39;5094:4;5100:2;5104:7;5077:39;;;;;;;;;;;;:16;:39::i;2190:219::-;2262:7;6794:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6794:16:0;;2324:56;;;;-1:-1:-1;;;2324:56:0;;6609:2:17;2324:56:0;;;6591:21:17;6648:2;6628:18;;;6621:30;-1:-1:-1;;;6667:18:17;;;6660:54;6731:18;;2324:56:0;6407:348:17;1929:204:0;2001:7;-1:-1:-1;;;;;2028:19:0;;2020:73;;;;-1:-1:-1;;;2020:73:0;;6962:2:17;2020:73:0;;;6944:21:17;7001:2;6981:18;;;6974:30;7040:34;7020:18;;;7013:62;-1:-1:-1;;;7091:18:17;;;7084:39;7140:19;;2020:73:0;6760:405:17;2020:73:0;-1:-1:-1;;;;;;2110:16:0;;;;;:9;:16;;;;;;;1929:204::o;2633:102::-;2689:13;2721:7;2714:14;;;;;:::i;4169:153::-;4263:52;719:10:5;4296:8:0;4306;4263:18;:52::i;5189:276::-;5319:41;719:10:5;5352:7:0;5319:18;:41::i;:::-;5311:99;;;;-1:-1:-1;;;5311:99:0;;;;;;;:::i;:::-;5420:38;5434:4;5440:2;5444:7;5453:4;5420:13;:38::i;:::-;5189:276;;;;:::o;2801:::-;2874:13;2899:23;2914:7;2899:14;:23::i;:::-;2933:21;2957:10;3395:9;;;;;;;;;-1:-1:-1;3395:9:0;;;3319:92;2957:10;2933:34;;3008:1;2990:7;2984:21;:25;:86;;;;;;;;;;;;;;;;;3036:7;3045:18;:7;:16;:18::i;:::-;3019:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;2984:86;2977:93;2801:276;-1:-1:-1;;;2801:276:0:o;13240:133::-;7185:4;6794:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6794:16:0;13313:53;;;;-1:-1:-1;;;13313:53:0;;6609:2:17;13313:53:0;;;6591:21:17;6648:2;6628:18;;;6621:30;-1:-1:-1;;;6667:18:17;;;6660:54;6731:18;;13313:53:0;6407:348:17;13313:53:0;13240:133;:::o;12572:171::-;12646:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;12646:29:0;-1:-1:-1;;;;;12646:29:0;;;;;;;;:24;;12699:23;12646:24;12699:14;:23::i;:::-;-1:-1:-1;;;;;12690:46:0;;;;;;;;;;;12572:171;;:::o;7404:261::-;7497:4;7513:13;7529:23;7544:7;7529:14;:23::i;:::-;7513:39;;7581:5;-1:-1:-1;;;;;7570:16:0;:7;-1:-1:-1;;;;;7570:16:0;;:52;;;-1:-1:-1;;;;;;4508:25:0;;;4485:4;4508:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;7590:32;7570:87;;;;7650:7;-1:-1:-1;;;;;7626:31:0;:20;7638:7;7626:11;:20::i;:::-;-1:-1:-1;;;;;7626:31:0;;7570:87;7562:96;7404:261;-1:-1:-1;;;;7404:261:0:o;11257:1203::-;11381:4;-1:-1:-1;;;;;11354:31:0;:23;11369:7;11354:14;:23::i;:::-;-1:-1:-1;;;;;11354:31:0;;11346:81;;;;-1:-1:-1;;;11346:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;11445:16:0;;11437:65;;;;-1:-1:-1;;;11437:65:0;;8279:2:17;11437:65:0;;;8261:21:17;8318:2;8298:18;;;8291:30;8357:34;8337:18;;;8330:62;-1:-1:-1;;;8408:18:17;;;8401:34;8452:19;;11437:65:0;8077:400:17;11437:65:0;11682:4;-1:-1:-1;;;;;11655:31:0;:23;11670:7;11655:14;:23::i;:::-;-1:-1:-1;;;;;11655:31:0;;11647:81;;;;-1:-1:-1;;;11647:81:0;;;;;;;:::i;:::-;11797:24;;;;:15;:24;;;;;;;;11790:31;;-1:-1:-1;;;;;;11790:31:0;;;;;;-1:-1:-1;;;;;12265:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;12265:20:0;;;12299:13;;;;;;;;;:18;;11790:31;12299:18;;;12337:16;;;:7;:16;;;;;;:21;;;;;;;;;;12374:27;;11813:7;;12374:27;;;3538:336;3468:406;;:::o;8925:920::-;-1:-1:-1;;;;;9004:16:0;;8996:61;;;;-1:-1:-1;;;8996:61:0;;8684:2:17;8996:61:0;;;8666:21:17;;;8703:18;;;8696:30;8762:34;8742:18;;;8735:62;8814:18;;8996:61:0;8482:356:17;8996:61:0;7185:4;6794:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6794:16:0;7208:31;9067:58;;;;-1:-1:-1;;;9067:58:0;;9045:2:17;9067:58:0;;;9027:21:17;9084:2;9064:18;;;9057:30;9123;9103:18;;;9096:58;9171:18;;9067:58:0;8843:352:17;9067:58:0;7185:4;6794:16;;;:7;:16;;;;;;-1:-1:-1;;;;;6794:16:0;7208:31;9271:58;;;;-1:-1:-1;;;9271:58:0;;9045:2:17;9271:58:0;;;9027:21:17;9084:2;9064:18;;;9057:30;9123;9103:18;;;9096:58;9171:18;;9271:58:0;8843:352:17;9271:58:0;-1:-1:-1;;;;;9671:13:0;;;;;;:9;:13;;;;;;;;:18;;9688:1;9671:18;;;9710:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;9710:21:0;;;;;9747:33;9718:7;;9671:13;;9747:33;;9671:13;;9747:33;291:87:16;;:::o;12879:277:0:-;12999:8;-1:-1:-1;;;;;12990:17:0;:5;-1:-1:-1;;;;;12990:17:0;;12982:55;;;;-1:-1:-1;;;12982:55:0;;9402:2:17;12982:55:0;;;9384:21:17;9441:2;9421:18;;;9414:30;9480:27;9460:18;;;9453:55;9525:18;;12982:55:0;9200:349:17;12982:55:0;-1:-1:-1;;;;;13047:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;13047:46:0;;;;;;;;;;13108:41;;540::17;;;13108::0;;513:18:17;13108:41:0;;;;;;;12879:277;;;:::o;6326:267::-;6438:28;6448:4;6454:2;6458:7;6438:9;:28::i;:::-;6484:47;6507:4;6513:2;6517:7;6526:4;6484:22;:47::i;:::-;6476:110;;;;-1:-1:-1;;;6476:110:0;;;;;;;:::i;447:696:6:-;503:13;552:14;569:17;580:5;569:10;:17::i;:::-;589:1;569:21;552:38;;604:20;638:6;627:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;627:18:6;-1:-1:-1;604:41:6;-1:-1:-1;765:28:6;;;781:2;765:28;820:280;-1:-1:-1;;851:5:6;-1:-1:-1;;;985:2:6;974:14;;969:30;851:5;956:44;1044:2;1035:11;;;-1:-1:-1;1064:21:6;820:280;1064:21;-1:-1:-1;1120:6:6;447:696;-1:-1:-1;;;447:696:6:o;13925:831:0:-;14074:4;-1:-1:-1;;;;;14094:13:0;;1702:19:4;:23;14090:660:0;;14129:71;;-1:-1:-1;;;14129:71:0;;-1:-1:-1;;;;;14129:36:0;;;;;:71;;719:10:5;;14180:4:0;;14186:7;;14195:4;;14129:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14129:71:0;;;;;;;;-1:-1:-1;;14129:71:0;;;;;;;;;;;;:::i;:::-;;;14125:573;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14367:6;:13;14384:1;14367:18;14363:321;;14409:60;;-1:-1:-1;;;14409:60:0;;;;;;;:::i;14363:321::-;14636:6;14630:13;14621:6;14617:2;14613:15;14606:38;14125:573;-1:-1:-1;;;;;;14250:51:0;-1:-1:-1;;;14250:51:0;;-1:-1:-1;14243:58:0;;14090:660;-1:-1:-1;14735:4:0;13925:831;;;;;;:::o;10139:916:9:-;10192:7;;-1:-1:-1;;;10267:17:9;;10263:103;;-1:-1:-1;;;10304:17:9;;;-1:-1:-1;10349:2:9;10339:12;10263:103;10392:8;10383:5;:17;10379:103;;10429:8;10420:17;;;-1:-1:-1;10465:2:9;10455:12;10379:103;10508:8;10499:5;:17;10495:103;;10545:8;10536:17;;;-1:-1:-1;10581:2:9;10571:12;10495:103;10624:7;10615:5;:16;10611:100;;10660:7;10651:16;;;-1:-1:-1;10695:1:9;10685:11;10611:100;10737:7;10728:5;:16;10724:100;;10773:7;10764:16;;;-1:-1:-1;10808:1:9;10798:11;10724:100;10850:7;10841:5;:16;10837:100;;10886:7;10877:16;;;-1:-1:-1;10921:1:9;10911:11;10837:100;10963:7;10954:5;:16;10950:66;;11000:1;10990:11;11042:6;10139:916;-1:-1:-1;;10139:916:9:o;14:131:17:-;-1:-1:-1;;;;;;88:32:17;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:250::-;677:1;687:113;701:6;698:1;695:13;687:113;;;777:11;;;771:18;758:11;;;751:39;723:2;716:10;687:113;;;-1:-1:-1;;834:1:17;816:16;;809:27;592:250::o;847:271::-;889:3;927:5;921:12;954:6;949:3;942:19;970:76;1039:6;1032:4;1027:3;1023:14;1016:4;1009:5;1005:16;970:76;:::i;:::-;1100:2;1079:15;-1:-1:-1;;1075:29:17;1066:39;;;;1107:4;1062:50;;847:271;-1:-1:-1;;847:271:17:o;1123:220::-;1272:2;1261:9;1254:21;1235:4;1292:45;1333:2;1322:9;1318:18;1310:6;1292:45;:::i;1348:180::-;1407:6;1460:2;1448:9;1439:7;1435:23;1431:32;1428:52;;;1476:1;1473;1466:12;1428:52;-1:-1:-1;1499:23:17;;1348:180;-1:-1:-1;1348:180:17:o;1741:173::-;1809:20;;-1:-1:-1;;;;;1858:31:17;;1848:42;;1838:70;;1904:1;1901;1894:12;1838:70;1741:173;;;:::o;1919:254::-;1987:6;1995;2048:2;2036:9;2027:7;2023:23;2019:32;2016:52;;;2064:1;2061;2054:12;2016:52;2087:29;2106:9;2087:29;:::i;:::-;2077:39;2163:2;2148:18;;;;2135:32;;-1:-1:-1;;;1919:254:17:o;2178:328::-;2255:6;2263;2271;2324:2;2312:9;2303:7;2299:23;2295:32;2292:52;;;2340:1;2337;2330:12;2292:52;2363:29;2382:9;2363:29;:::i;:::-;2353:39;;2411:38;2445:2;2434:9;2430:18;2411:38;:::i;:::-;2401:48;;2496:2;2485:9;2481:18;2468:32;2458:42;;2178:328;;;;;:::o;2511:186::-;2570:6;2623:2;2611:9;2602:7;2598:23;2594:32;2591:52;;;2639:1;2636;2629:12;2591:52;2662:29;2681:9;2662:29;:::i;2884:347::-;2949:6;2957;3010:2;2998:9;2989:7;2985:23;2981:32;2978:52;;;3026:1;3023;3016:12;2978:52;3049:29;3068:9;3049:29;:::i;:::-;3039:39;;3128:2;3117:9;3113:18;3100:32;3175:5;3168:13;3161:21;3154:5;3151:32;3141:60;;3197:1;3194;3187:12;3141:60;3220:5;3210:15;;;2884:347;;;;;:::o;3236:127::-;3297:10;3292:3;3288:20;3285:1;3278:31;3328:4;3325:1;3318:15;3352:4;3349:1;3342:15;3368:1138;3463:6;3471;3479;3487;3540:3;3528:9;3519:7;3515:23;3511:33;3508:53;;;3557:1;3554;3547:12;3508:53;3580:29;3599:9;3580:29;:::i;:::-;3570:39;;3628:38;3662:2;3651:9;3647:18;3628:38;:::i;:::-;3618:48;;3713:2;3702:9;3698:18;3685:32;3675:42;;3768:2;3757:9;3753:18;3740:32;3791:18;3832:2;3824:6;3821:14;3818:34;;;3848:1;3845;3838:12;3818:34;3886:6;3875:9;3871:22;3861:32;;3931:7;3924:4;3920:2;3916:13;3912:27;3902:55;;3953:1;3950;3943:12;3902:55;3989:2;3976:16;4011:2;4007;4004:10;4001:36;;;4017:18;;:::i;:::-;4092:2;4086:9;4060:2;4146:13;;-1:-1:-1;;4142:22:17;;;4166:2;4138:31;4134:40;4122:53;;;4190:18;;;4210:22;;;4187:46;4184:72;;;4236:18;;:::i;:::-;4276:10;4272:2;4265:22;4311:2;4303:6;4296:18;4351:7;4346:2;4341;4337;4333:11;4329:20;4326:33;4323:53;;;4372:1;4369;4362:12;4323:53;4428:2;4423;4419;4415:11;4410:2;4402:6;4398:15;4385:46;4473:1;4468:2;4463;4455:6;4451:15;4447:24;4440:35;4494:6;4484:16;;;;;;;3368:1138;;;;;;;:::o;4511:260::-;4579:6;4587;4640:2;4628:9;4619:7;4615:23;4611:32;4608:52;;;4656:1;4653;4646:12;4608:52;4679:29;4698:9;4679:29;:::i;:::-;4669:39;;4727:38;4761:2;4750:9;4746:18;4727:38;:::i;:::-;4717:48;;4511:260;;;;;:::o;4776:380::-;4855:1;4851:12;;;;4898;;;4919:61;;4973:4;4965:6;4961:17;4951:27;;4919:61;5026:2;5018:6;5015:14;4995:18;4992:38;4989:161;;5072:10;5067:3;5063:20;5060:1;5053:31;5107:4;5104:1;5097:15;5135:4;5132:1;5125:15;4989:161;;4776:380;;;:::o;5993:409::-;6195:2;6177:21;;;6234:2;6214:18;;;6207:30;6273:34;6268:2;6253:18;;6246:62;-1:-1:-1;;;6339:2:17;6324:18;;6317:43;6392:3;6377:19;;5993:409::o;7170:496::-;7349:3;7387:6;7381:13;7403:66;7462:6;7457:3;7450:4;7442:6;7438:17;7403:66;:::i;:::-;7532:13;;7491:16;;;;7554:70;7532:13;7491:16;7601:4;7589:17;;7554:70;:::i;:::-;7640:20;;7170:496;-1:-1:-1;;;;7170:496:17:o;7671:401::-;7873:2;7855:21;;;7912:2;7892:18;;;7885:30;7951:34;7946:2;7931:18;;7924:62;-1:-1:-1;;;8017:2:17;8002:18;;7995:35;8062:3;8047:19;;7671:401::o;9554:414::-;9756:2;9738:21;;;9795:2;9775:18;;;9768:30;9834:34;9829:2;9814:18;;9807:62;-1:-1:-1;;;9900:2:17;9885:18;;9878:48;9958:3;9943:19;;9554:414::o;10105:489::-;-1:-1:-1;;;;;10374:15:17;;;10356:34;;10426:15;;10421:2;10406:18;;10399:43;10473:2;10458:18;;10451:34;;;10521:3;10516:2;10501:18;;10494:31;;;10299:4;;10542:46;;10568:19;;10560:6;10542:46;:::i;:::-;10534:54;10105:489;-1:-1:-1;;;;;;10105:489:17:o;10599:249::-;10668:6;10721:2;10709:9;10700:7;10696:23;10692:32;10689:52;;;10737:1;10734;10727:12;10689:52;10769:9;10763:16;10788:30;10812:5;10788:30;:::i"},"gasEstimates":{"creation":{"codeDepositCost":"958000","executionCost":"infinite","totalCost":"infinite"},"external":{"approve(address,uint256)":"infinite","balanceOf(address)":"2634","getApproved(uint256)":"4792","isApprovedForAll(address,address)":"infinite","mint(address,uint256)":"55386","name()":"infinite","ownerOf(uint256)":"2561","safeTransferFrom(address,address,uint256)":"infinite","safeTransferFrom(address,address,uint256,bytes)":"infinite","setApprovalForAll(address,bool)":"26705","supportsInterface(bytes4)":"534","symbol()":"infinite","tokenURI(uint256)":"infinite","transferFrom(address,address,uint256)":"infinite"}},"methodIdentifiers":{"approve(address,uint256)":"095ea7b3","balanceOf(address)":"70a08231","getApproved(uint256)":"081812fc","isApprovedForAll(address,address)":"e985e9c5","mint(address,uint256)":"40c10f19","name()":"06fdde03","ownerOf(uint256)":"6352211e","safeTransferFrom(address,address,uint256)":"42842e0e","safeTransferFrom(address,address,uint256,bytes)":"b88d4fde","setApprovalForAll(address,bool)":"a22cb465","supportsInterface(bytes4)":"01ffc9a7","symbol()":"95d89b41","tokenURI(uint256)":"c87b56dd","transferFrom(address,address,uint256)":"23b872dd"}},"metadata":"{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"details\":\"See {IERC721-approve}.\"},\"balanceOf(address)\":{\"details\":\"See {IERC721-balanceOf}.\"},\"getApproved(uint256)\":{\"details\":\"See {IERC721-getApproved}.\"},\"isApprovedForAll(address,address)\":{\"details\":\"See {IERC721-isApprovedForAll}.\"},\"name()\":{\"details\":\"See {IERC721Metadata-name}.\"},\"ownerOf(uint256)\":{\"details\":\"See {IERC721-ownerOf}.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"See {IERC721-setApprovalForAll}.\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"symbol()\":{\"details\":\"See {IERC721Metadata-symbol}.\"},\"tokenURI(uint256)\":{\"details\":\"See {IERC721Metadata-tokenURI}.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-transferFrom}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/mock/NFTMock.sol\":\"NFTMock\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC721/ERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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: address zero is not a valid owner\\\");\\n return _balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\\n address owner = _ownerOf(tokenId);\\n require(owner != address(0), \\\"ERC721: invalid token ID\\\");\\n return owner;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\\n _requireMinted(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = 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 token owner or approved for all\\\"\\n );\\n\\n _approve(to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-getApproved}.\\n */\\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\\n _requireMinted(tokenId);\\n\\n return _tokenApprovals[tokenId];\\n }\\n\\n /**\\n * @dev See {IERC721-setApprovalForAll}.\\n */\\n function setApprovalForAll(address operator, bool approved) public virtual override {\\n _setApprovalForAll(_msgSender(), operator, approved);\\n }\\n\\n /**\\n * @dev See {IERC721-isApprovedForAll}.\\n */\\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\\n return _operatorApprovals[owner][operator];\\n }\\n\\n /**\\n * @dev See {IERC721-transferFrom}.\\n */\\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner or approved\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721: caller is not token owner or 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(address from, address to, uint256 tokenId, bytes memory data) 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 the owner of the `tokenId`. Does NOT revert if token doesn't exist\\n */\\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\\n return _owners[tokenId];\\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 _ownerOf(tokenId) != address(0);\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\\n address owner = ERC721.ownerOf(tokenId);\\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Safely mints `tokenId` and transfers it to `to`.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal virtual {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(address to, uint256 tokenId, bytes memory data) 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, 1);\\n\\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\\n require(!_exists(tokenId), \\\"ERC721: token already minted\\\");\\n\\n unchecked {\\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\\n // Given that tokens are minted one by one, it is impossible in practice that\\n // this ever happens. Might change if we allow batch minting.\\n // The ERC fails to describe this case.\\n _balances[to] += 1;\\n }\\n\\n _owners[tokenId] = to;\\n\\n emit Transfer(address(0), to, tokenId);\\n\\n _afterTokenTransfer(address(0), to, tokenId, 1);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n * This is an internal function that does not check if the sender is authorized to operate on the token.\\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, 1);\\n\\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\\n owner = ERC721.ownerOf(tokenId);\\n\\n // Clear approvals\\n delete _tokenApprovals[tokenId];\\n\\n unchecked {\\n // Cannot overflow, as that would require more tokens to be burned/transferred\\n // out than the owner initially received through minting and transferring in.\\n _balances[owner] -= 1;\\n }\\n delete _owners[tokenId];\\n\\n emit Transfer(owner, address(0), tokenId);\\n\\n _afterTokenTransfer(owner, address(0), tokenId, 1);\\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(address from, address to, uint256 tokenId) internal virtual {\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n require(to != address(0), \\\"ERC721: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, tokenId, 1);\\n\\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\\n require(ERC721.ownerOf(tokenId) == from, \\\"ERC721: transfer from incorrect owner\\\");\\n\\n // Clear approvals from the previous owner\\n delete _tokenApprovals[tokenId];\\n\\n unchecked {\\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\\n // `from`'s balance is the number of token held, which is at least one before the current\\n // transfer.\\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\\n // all 2**256 token ids to be minted, which in practice is impossible.\\n _balances[from] -= 1;\\n _balances[to] += 1;\\n }\\n _owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n _afterTokenTransfer(from, to, tokenId, 1);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * Emits an {Approval} event.\\n */\\n function _approve(address to, uint256 tokenId) internal virtual {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\\n require(owner != operator, \\\"ERC721: approve to caller\\\");\\n _operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` has not been minted yet.\\n */\\n function _requireMinted(uint256 tokenId) internal view virtual {\\n require(_exists(tokenId), \\\"ERC721: invalid token ID\\\");\\n }\\n\\n /**\\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\\n * The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n * @return bool whether the call correctly returned the expected magic value\\n */\\n function _checkOnERC721Received(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes memory data\\n ) private returns (bool) {\\n if (to.isContract()) {\\n try 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 /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n } else {\\n return true;\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\\n * - When `from` is zero, the tokens will be minted for `to`.\\n * - When `to` is zero, ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n * - `batchSize` is non-zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\\n *\\n * Calling conditions:\\n *\\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\\n * - When `from` is zero, the tokens were minted for `to`.\\n * - When `to` is zero, ``from``'s tokens were burned.\\n * - `from` and `to` are never both zero.\\n * - `batchSize` is non-zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\\n\\n /**\\n * @dev Unsafe write access to the balances, used by extensions that \\\"mint\\\" tokens using an {ownerOf} override.\\n *\\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\\n * that `ownerOf(tokenId)` is `a`.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\\n _balances[account] += amount;\\n }\\n}\\n\",\"keccak256\":\"0x2c309e7df9e05e6ce15bedfe74f3c61b467fc37e0fae9eab496acf5ea0bbd7ff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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`.\\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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\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(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x5bce51e11f7d194b79ea59fe00c9e8de9fa2c5530124960f29a24d4c740a3266\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface 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 `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, \\\"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(address target, bytes memory data, uint256 value) 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 (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, 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 (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or 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 _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\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 unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\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] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/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\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (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 enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\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 == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >= 10 ** 64) {\\n value /= 10 ** 64;\\n result += 64;\\n }\\n if (value >= 10 ** 32) {\\n value /= 10 ** 32;\\n result += 32;\\n }\\n if (value >= 10 ** 16) {\\n value /= 10 ** 16;\\n result += 16;\\n }\\n if (value >= 10 ** 8) {\\n value /= 10 ** 8;\\n result += 8;\\n }\\n if (value >= 10 ** 4) {\\n value /= 10 ** 4;\\n result += 4;\\n }\\n if (value >= 10 ** 2) {\\n value /= 10 ** 2;\\n result += 2;\\n }\\n if (value >= 10 ** 1) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log10(value);\\n return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/mock/NFTMock.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.8;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC721/ERC721.sol\\\";\\n\\ncontract NFTMock is ERC721 {\\n // solhint-disable-next-line no-empty-blocks\\n constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {\\n }\\n\\n function mint(address to, uint256 tokenId) external {\\n _mint(to, tokenId);\\n }\\n}\",\"keccak256\":\"0x432a1fde00aeaf5ffaea8788d97a8247dc4a712eeacf22d1c231202a08774eb4\",\"license\":\"MIT\"}},\"version\":1}","storageLayout":{"storage":[{"astId":25,"contract":"contracts/mock/NFTMock.sol:NFTMock","label":"_name","offset":0,"slot":"0","type":"t_string_storage"},{"astId":27,"contract":"contracts/mock/NFTMock.sol:NFTMock","label":"_symbol","offset":0,"slot":"1","type":"t_string_storage"},{"astId":31,"contract":"contracts/mock/NFTMock.sol:NFTMock","label":"_owners","offset":0,"slot":"2","type":"t_mapping(t_uint256,t_address)"},{"astId":35,"contract":"contracts/mock/NFTMock.sol:NFTMock","label":"_balances","offset":0,"slot":"3","type":"t_mapping(t_address,t_uint256)"},{"astId":39,"contract":"contracts/mock/NFTMock.sol:NFTMock","label":"_tokenApprovals","offset":0,"slot":"4","type":"t_mapping(t_uint256,t_address)"},{"astId":45,"contract":"contracts/mock/NFTMock.sol:NFTMock","label":"_operatorApprovals","offset":0,"slot":"5","type":"t_mapping(t_address,t_mapping(t_address,t_bool))"}],"types":{"t_address":{"encoding":"inplace","label":"address","numberOfBytes":"20"},"t_bool":{"encoding":"inplace","label":"bool","numberOfBytes":"1"},"t_mapping(t_address,t_bool)":{"encoding":"mapping","key":"t_address","label":"mapping(address => bool)","numberOfBytes":"32","value":"t_bool"},"t_mapping(t_address,t_mapping(t_address,t_bool))":{"encoding":"mapping","key":"t_address","label":"mapping(address => mapping(address => bool))","numberOfBytes":"32","value":"t_mapping(t_address,t_bool)"},"t_mapping(t_address,t_uint256)":{"encoding":"mapping","key":"t_address","label":"mapping(address => uint256)","numberOfBytes":"32","value":"t_uint256"},"t_mapping(t_uint256,t_address)":{"encoding":"mapping","key":"t_uint256","label":"mapping(uint256 => address)","numberOfBytes":"32","value":"t_address"},"t_string_storage":{"encoding":"bytes","label":"string","numberOfBytes":"32"},"t_uint256":{"encoding":"inplace","label":"uint256","numberOfBytes":"32"}}},"userdoc":{"kind":"user","methods":{},"version":1}}}}}} \ No newline at end of file diff --git a/build/contracts/contracts/AccountRegistryBridge.sol/AccountRegistryBridge.dbg.json b/build/contracts/contracts/AccountRegistryBridge.sol/AccountRegistryBridge.dbg.json deleted file mode 100644 index 4822225..0000000 --- a/build/contracts/contracts/AccountRegistryBridge.sol/AccountRegistryBridge.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../build-info/2976796d46a1fc41934566b3e04b2516.json" -} diff --git a/build/contracts/contracts/AccountRegistryBridge.sol/AccountRegistryBridge.json b/build/contracts/contracts/AccountRegistryBridge.sol/AccountRegistryBridge.json deleted file mode 100644 index b1fc0b2..0000000 --- a/build/contracts/contracts/AccountRegistryBridge.sol/AccountRegistryBridge.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "AccountRegistryBridge", - "sourceName": "contracts/AccountRegistryBridge.sol", - "abi": [ - { - "inputs": [], - "name": "IMPLEMENTATION", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "REGISTRY", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "contractAddress", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "account", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "contractAddress", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "createAccount", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b506102ad806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806306433b1b14610051578063192df655146100885780633a4741bd1461009b5780635fbfb9cf146100b6575b600080fd5b61006c7302101dfb77fde026414827fdc604ddaf224f092181565b6040516001600160a01b03909116815260200160405180910390f35b61006c61009636600461022e565b6100c9565b61006c732d25602551487c3f3354dd80d76d54383a24335881565b61006c6100c436600461022e565b61017d565b604051632f4de29b60e11b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b038316604482015260648101829052600060848201819052907302101dfb77fde026414827fdc604ddaf224f092190635e9bc5369060a401602060405180830381865afa158015610152573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610176919061025a565b9392505050565b60405163da7323b360e01b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b03831660448201526064810182905260006084820181905260c060a483015260c48201819052907302101dfb77fde026414827fdc604ddaf224f09219063da7323b39060e4016020604051808303816000875af1158015610152573d6000803e3d6000fd5b6001600160a01b038116811461022b57600080fd5b50565b6000806040838503121561024157600080fd5b823561024c81610216565b946020939093013593505050565b60006020828403121561026c57600080fd5b81516101768161021656fea26469706673582212200b4836e18ca9294f39a0f67787d9af3a81bbfd3510dceb2abf00f235aa0e1ecf64736f6c63430008110033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806306433b1b14610051578063192df655146100885780633a4741bd1461009b5780635fbfb9cf146100b6575b600080fd5b61006c7302101dfb77fde026414827fdc604ddaf224f092181565b6040516001600160a01b03909116815260200160405180910390f35b61006c61009636600461022e565b6100c9565b61006c732d25602551487c3f3354dd80d76d54383a24335881565b61006c6100c436600461022e565b61017d565b604051632f4de29b60e11b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b038316604482015260648101829052600060848201819052907302101dfb77fde026414827fdc604ddaf224f092190635e9bc5369060a401602060405180830381865afa158015610152573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610176919061025a565b9392505050565b60405163da7323b360e01b8152732d25602551487c3f3354dd80d76d54383a24335860048201524660248201526001600160a01b03831660448201526064810182905260006084820181905260c060a483015260c48201819052907302101dfb77fde026414827fdc604ddaf224f09219063da7323b39060e4016020604051808303816000875af1158015610152573d6000803e3d6000fd5b6001600160a01b038116811461022b57600080fd5b50565b6000806040838503121561024157600080fd5b823561024c81610216565b946020939093013593505050565b60006020828403121561026c57600080fd5b81516101768161021656fea26469706673582212200b4836e18ca9294f39a0f67787d9af3a81bbfd3510dceb2abf00f235aa0e1ecf64736f6c63430008110033", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/contracts/ChargedParticlesAccount.sol/ChargedParticlesAccount.dbg.json b/build/contracts/contracts/ChargedParticlesAccount.sol/ChargedParticlesAccount.dbg.json deleted file mode 100644 index d4b995d..0000000 --- a/build/contracts/contracts/ChargedParticlesAccount.sol/ChargedParticlesAccount.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../build-info/298a06569c51eccf42345b43561716ff.json" -} diff --git a/build/contracts/contracts/ChargedParticlesAccount.sol/ChargedParticlesAccount.json b/build/contracts/contracts/ChargedParticlesAccount.sol/ChargedParticlesAccount.json deleted file mode 100644 index c9d1469..0000000 --- a/build/contracts/contracts/ChargedParticlesAccount.sol/ChargedParticlesAccount.json +++ /dev/null @@ -1,475 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "ChargedParticlesAccount", - "sourceName": "contracts/ChargedParticlesAccount.sol", - "abi": [ - { - "inputs": [], - "name": "AccountLocked", - "type": "error" - }, - { - "inputs": [], - "name": "ExceedsMaxLockTime", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidInput", - "type": "error" - }, - { - "inputs": [], - "name": "NotAuthorized", - "type": "error" - }, - { - "inputs": [], - "name": "OwnershipCycle", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "lockedUntil", - "type": "uint256" - } - ], - "name": "LockUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes4", - "name": "selector", - "type": "bytes4" - }, - { - "indexed": false, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "OverrideUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "caller", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "hasPermission", - "type": "bool" - } - ], - "name": "PermissionUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "TransactionExecuted", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "receiver", - "type": "address" - }, - { - "internalType": "address", - "name": "nftTokenAddress", - "type": "address" - }, - { - "internalType": "uint256", - "name": "nftTokenId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "nftTokenAmount", - "type": "uint256" - } - ], - "name": "breakCovalentBond", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "nftTokenAddress", - "type": "address" - }, - { - "internalType": "uint256", - "name": "nftTokenId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "nftTokenAmount", - "type": "uint256" - } - ], - "name": "covalentBond", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "executeCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "caller", - "type": "address" - } - ], - "name": "isAuthorized", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "isLocked", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_lockedUntil", - "type": "uint256" - } - ], - "name": "lock", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "lockedUntil", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "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": "receivedTokenId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "onERC721Received", - "outputs": [ - { - "internalType": "bytes4", - "name": "", - "type": "bytes4" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "permissions", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address[]", - "name": "callers", - "type": "address[]" - }, - { - "internalType": "bool[]", - "name": "_permissions", - "type": "bool[]" - } - ], - "name": "setPermissions", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "token", - "outputs": [ - { - "internalType": "uint256", - "name": "chainId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "tokenContract", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50611159806100206000396000f3fe6080604052600436106100ec5760003560e01c8063a4e2d6341161008a578063dd46706411610059578063dd467064146102b7578063f23a6e61146102d7578063fc0c546a14610303578063fe9fbb801461033b57600080fd5b8063a4e2d63414610230578063a737a29914610247578063bc197c8114610267578063ce0617ec1461029357600080fd5b80631f9838b5116100c65780631f9838b5146101885780636b764e1b146101c35780638da5cb5b146101e35780639e5d4c491461021057600080fd5b806301ffc9a7146100f8578063039721b11461012d578063150b7a021461014f57600080fd5b366100f357005b600080fd5b34801561010457600080fd5b50610118610113366004610a92565b61035b565b60405190151581526020015b60405180910390f35b34801561013957600080fd5b5061014d610148366004610b0f565b6103c2565b005b34801561015b57600080fd5b5061016f61016a366004610c4a565b61058b565b6040516001600160e01b03199091168152602001610124565b34801561019457600080fd5b506101186101a3366004610cb6565b600160209081526000928352604080842090915290825290205460ff1681565b3480156101cf57600080fd5b5061014d6101de366004610cef565b6105f3565b3480156101ef57600080fd5b506101f8610661565b6040516001600160a01b039091168152602001610124565b61022361021e366004610d35565b6106f7565b6040516101249190610dbe565b34801561023c57600080fd5b506000544210610118565b34801561025357600080fd5b5061014d610262366004610e0c565b61079b565b34801561027357600080fd5b5061016f610282366004610ec1565b63bc197c8160e01b95945050505050565b34801561029f57600080fd5b506102a960005481565b604051908152602001610124565b3480156102c357600080fd5b5061014d6102d2366004610f6f565b6107fd565b3480156102e357600080fd5b5061016f6102f2366004610f88565b63f23a6e6160e01b95945050505050565b34801561030f57600080fd5b506103186108c2565b604080519384526001600160a01b03909216602084015290820152606001610124565b34801561034757600080fd5b50610118610356366004610ff1565b6108da565b6000806001600160e01b031983166301ffc9a760e01b148061038d57506001600160e01b03198316630271189760e51b145b806103a857506001600160e01b03198316631dfe9a6f60e31b145b905080156103b95750600192915050565b50600092915050565b6000544210156103e557604051636315bfbb60e01b815260040160405180910390fd5b60006103ef610661565b9050336001600160a01b0382161461041a5760405163ea8e4eb560e01b815260040160405180910390fd5b8382811461043b5760405163b4fa3fb360e01b815260040160405180910390fd5b60005b81811015610582578484828181106104585761045861100e565b905060200201602081019061046d9190611024565b6001600160a01b0384166000908152600160205260408120908989858181106104985761049861100e565b90506020020160208101906104ad9190610ff1565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f394777a58092892d136a90c4bb7e4350c72ac50fba6a0208128677f36527dcf5838888848181106105095761050961100e565b905060200201602081019061051e9190610ff1565b8787858181106105305761053061100e565b90506020020160208101906105459190611024565b604080516001600160a01b03948516815293909216602084015215159082015260600160405180910390a18061057a8161105c565b91505061043e565b50505050505050565b6000806000806105996109c3565b92509250925046831480156105b657506001600160a01b03821633145b80156105c157508581145b156105df5760405163b79e3f3f60e01b815260040160405180910390fd5b50630a85bd0160e11b979650505050505050565b604051632142170760e11b81523060048201526001600160a01b038581166024830152604482018490528416906342842e0e90606401600060405180830381600087803b15801561064357600080fd5b505af1158015610657573d6000803e3d6000fd5b5050505050505050565b60008060008061066f6109c3565b925092509250468314610686576000935050505090565b6040516331a9108f60e11b8152600481018290526001600160a01b03831690636352211e90602401602060405180830381865afa1580156106cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ef9190611075565b935050505090565b6060610702336108da565b61071f5760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561074257604051636315bfbb60e01b815260040160405180910390fd5b83856001600160a01b03167f47d99ad340f52da66535aff7e10da1ceb85a32bcbd9fa1c42314d194545e14d2858560405161077e929190611092565b60405180910390a361079285858585610a16565b95945050505050565b604051632142170760e11b8152336004820152306024820152604481018390526001600160a01b038416906342842e0e90606401600060405180830381600087803b1580156107e957600080fd5b505af1158015610582573d6000803e3d6000fd5b610805610661565b6001600160a01b0316336001600160a01b0316146108365760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561085957604051636315bfbb60e01b815260040160405180910390fd5b610867426301e133806110c1565b811115610887576040516301814f7d60e31b815260040160405180910390fd5b60008190556040518181527fa7b24c66dd3269a292a60b3facdbb8f3e7557d1e19e64d99e0d6ee7250be63ad9060200160405180910390a150565b60008060006108cf6109c3565b925092509250909192565b60008060006108e76109c3565b6040516331a9108f60e11b8152600481018290529194509250600091506001600160a01b03841690636352211e90602401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109599190611075565b9050806001600160a01b0316856001600160a01b03160361097f57506001949350505050565b6001600160a01b0380821660009081526001602090815260408083209389168352929052205460ff16156109b857506001949350505050565b506000949350505050565b604080516060808252608082019092526000918291829182919060208201818036833701905050905060ad604d60208301303c80806020019051810190610a0a91906110da565b93509350935050909192565b60606000856001600160a01b0316858585604051610a35929190611113565b60006040518083038185875af1925050503d8060008114610a72576040519150601f19603f3d011682016040523d82523d6000602084013e610a77565b606091505b509250905080610a8957815160208301fd5b50949350505050565b600060208284031215610aa457600080fd5b81356001600160e01b031981168114610abc57600080fd5b9392505050565b60008083601f840112610ad557600080fd5b50813567ffffffffffffffff811115610aed57600080fd5b6020830191508360208260051b8501011115610b0857600080fd5b9250929050565b60008060008060408587031215610b2557600080fd5b843567ffffffffffffffff80821115610b3d57600080fd5b610b4988838901610ac3565b90965094506020870135915080821115610b6257600080fd5b50610b6f87828801610ac3565b95989497509550505050565b6001600160a01b0381168114610b9057600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610bd257610bd2610b93565b604052919050565b600082601f830112610beb57600080fd5b813567ffffffffffffffff811115610c0557610c05610b93565b610c18601f8201601f1916602001610ba9565b818152846020838601011115610c2d57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215610c6057600080fd5b8435610c6b81610b7b565b93506020850135610c7b81610b7b565b925060408501359150606085013567ffffffffffffffff811115610c9e57600080fd5b610caa87828801610bda565b91505092959194509250565b60008060408385031215610cc957600080fd5b8235610cd481610b7b565b91506020830135610ce481610b7b565b809150509250929050565b60008060008060808587031215610d0557600080fd5b8435610d1081610b7b565b93506020850135610d2081610b7b565b93969395505050506040820135916060013590565b60008060008060608587031215610d4b57600080fd5b8435610d5681610b7b565b935060208501359250604085013567ffffffffffffffff80821115610d7a57600080fd5b818701915087601f830112610d8e57600080fd5b813581811115610d9d57600080fd5b886020828501011115610daf57600080fd5b95989497505060200194505050565b600060208083528351808285015260005b81811015610deb57858101830151858201604001528201610dcf565b506000604082860101526040601f19601f8301168501019250505092915050565b600080600060608486031215610e2157600080fd5b8335610e2c81610b7b565b95602085013595506040909401359392505050565b600082601f830112610e5257600080fd5b8135602067ffffffffffffffff821115610e6e57610e6e610b93565b8160051b610e7d828201610ba9565b9283528481018201928281019087851115610e9757600080fd5b83870192505b84831015610eb657823582529183019190830190610e9d565b979650505050505050565b600080600080600060a08688031215610ed957600080fd5b8535610ee481610b7b565b94506020860135610ef481610b7b565b9350604086013567ffffffffffffffff80821115610f1157600080fd5b610f1d89838a01610e41565b94506060880135915080821115610f3357600080fd5b610f3f89838a01610e41565b93506080880135915080821115610f5557600080fd5b50610f6288828901610bda565b9150509295509295909350565b600060208284031215610f8157600080fd5b5035919050565b600080600080600060a08688031215610fa057600080fd5b8535610fab81610b7b565b94506020860135610fbb81610b7b565b93506040860135925060608601359150608086013567ffffffffffffffff811115610fe557600080fd5b610f6288828901610bda565b60006020828403121561100357600080fd5b8135610abc81610b7b565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561103657600080fd5b81358015158114610abc57600080fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161106e5761106e611046565b5060010190565b60006020828403121561108757600080fd5b8151610abc81610b7b565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b808201808211156110d4576110d4611046565b92915050565b6000806000606084860312156110ef57600080fd5b83519250602084015161110181610b7b565b80925050604084015190509250925092565b818382376000910190815291905056fea264697066735822122063e6912474b85020b5a9835811ba76231c769e7f9cde34faffb5d227a7ea56e564736f6c63430008110033", - "deployedBytecode": "0x6080604052600436106100ec5760003560e01c8063a4e2d6341161008a578063dd46706411610059578063dd467064146102b7578063f23a6e61146102d7578063fc0c546a14610303578063fe9fbb801461033b57600080fd5b8063a4e2d63414610230578063a737a29914610247578063bc197c8114610267578063ce0617ec1461029357600080fd5b80631f9838b5116100c65780631f9838b5146101885780636b764e1b146101c35780638da5cb5b146101e35780639e5d4c491461021057600080fd5b806301ffc9a7146100f8578063039721b11461012d578063150b7a021461014f57600080fd5b366100f357005b600080fd5b34801561010457600080fd5b50610118610113366004610a92565b61035b565b60405190151581526020015b60405180910390f35b34801561013957600080fd5b5061014d610148366004610b0f565b6103c2565b005b34801561015b57600080fd5b5061016f61016a366004610c4a565b61058b565b6040516001600160e01b03199091168152602001610124565b34801561019457600080fd5b506101186101a3366004610cb6565b600160209081526000928352604080842090915290825290205460ff1681565b3480156101cf57600080fd5b5061014d6101de366004610cef565b6105f3565b3480156101ef57600080fd5b506101f8610661565b6040516001600160a01b039091168152602001610124565b61022361021e366004610d35565b6106f7565b6040516101249190610dbe565b34801561023c57600080fd5b506000544210610118565b34801561025357600080fd5b5061014d610262366004610e0c565b61079b565b34801561027357600080fd5b5061016f610282366004610ec1565b63bc197c8160e01b95945050505050565b34801561029f57600080fd5b506102a960005481565b604051908152602001610124565b3480156102c357600080fd5b5061014d6102d2366004610f6f565b6107fd565b3480156102e357600080fd5b5061016f6102f2366004610f88565b63f23a6e6160e01b95945050505050565b34801561030f57600080fd5b506103186108c2565b604080519384526001600160a01b03909216602084015290820152606001610124565b34801561034757600080fd5b50610118610356366004610ff1565b6108da565b6000806001600160e01b031983166301ffc9a760e01b148061038d57506001600160e01b03198316630271189760e51b145b806103a857506001600160e01b03198316631dfe9a6f60e31b145b905080156103b95750600192915050565b50600092915050565b6000544210156103e557604051636315bfbb60e01b815260040160405180910390fd5b60006103ef610661565b9050336001600160a01b0382161461041a5760405163ea8e4eb560e01b815260040160405180910390fd5b8382811461043b5760405163b4fa3fb360e01b815260040160405180910390fd5b60005b81811015610582578484828181106104585761045861100e565b905060200201602081019061046d9190611024565b6001600160a01b0384166000908152600160205260408120908989858181106104985761049861100e565b90506020020160208101906104ad9190610ff1565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f394777a58092892d136a90c4bb7e4350c72ac50fba6a0208128677f36527dcf5838888848181106105095761050961100e565b905060200201602081019061051e9190610ff1565b8787858181106105305761053061100e565b90506020020160208101906105459190611024565b604080516001600160a01b03948516815293909216602084015215159082015260600160405180910390a18061057a8161105c565b91505061043e565b50505050505050565b6000806000806105996109c3565b92509250925046831480156105b657506001600160a01b03821633145b80156105c157508581145b156105df5760405163b79e3f3f60e01b815260040160405180910390fd5b50630a85bd0160e11b979650505050505050565b604051632142170760e11b81523060048201526001600160a01b038581166024830152604482018490528416906342842e0e90606401600060405180830381600087803b15801561064357600080fd5b505af1158015610657573d6000803e3d6000fd5b5050505050505050565b60008060008061066f6109c3565b925092509250468314610686576000935050505090565b6040516331a9108f60e11b8152600481018290526001600160a01b03831690636352211e90602401602060405180830381865afa1580156106cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ef9190611075565b935050505090565b6060610702336108da565b61071f5760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561074257604051636315bfbb60e01b815260040160405180910390fd5b83856001600160a01b03167f47d99ad340f52da66535aff7e10da1ceb85a32bcbd9fa1c42314d194545e14d2858560405161077e929190611092565b60405180910390a361079285858585610a16565b95945050505050565b604051632142170760e11b8152336004820152306024820152604481018390526001600160a01b038416906342842e0e90606401600060405180830381600087803b1580156107e957600080fd5b505af1158015610582573d6000803e3d6000fd5b610805610661565b6001600160a01b0316336001600160a01b0316146108365760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561085957604051636315bfbb60e01b815260040160405180910390fd5b610867426301e133806110c1565b811115610887576040516301814f7d60e31b815260040160405180910390fd5b60008190556040518181527fa7b24c66dd3269a292a60b3facdbb8f3e7557d1e19e64d99e0d6ee7250be63ad9060200160405180910390a150565b60008060006108cf6109c3565b925092509250909192565b60008060006108e76109c3565b6040516331a9108f60e11b8152600481018290529194509250600091506001600160a01b03841690636352211e90602401602060405180830381865afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109599190611075565b9050806001600160a01b0316856001600160a01b03160361097f57506001949350505050565b6001600160a01b0380821660009081526001602090815260408083209389168352929052205460ff16156109b857506001949350505050565b506000949350505050565b604080516060808252608082019092526000918291829182919060208201818036833701905050905060ad604d60208301303c80806020019051810190610a0a91906110da565b93509350935050909192565b60606000856001600160a01b0316858585604051610a35929190611113565b60006040518083038185875af1925050503d8060008114610a72576040519150601f19603f3d011682016040523d82523d6000602084013e610a77565b606091505b509250905080610a8957815160208301fd5b50949350505050565b600060208284031215610aa457600080fd5b81356001600160e01b031981168114610abc57600080fd5b9392505050565b60008083601f840112610ad557600080fd5b50813567ffffffffffffffff811115610aed57600080fd5b6020830191508360208260051b8501011115610b0857600080fd5b9250929050565b60008060008060408587031215610b2557600080fd5b843567ffffffffffffffff80821115610b3d57600080fd5b610b4988838901610ac3565b90965094506020870135915080821115610b6257600080fd5b50610b6f87828801610ac3565b95989497509550505050565b6001600160a01b0381168114610b9057600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610bd257610bd2610b93565b604052919050565b600082601f830112610beb57600080fd5b813567ffffffffffffffff811115610c0557610c05610b93565b610c18601f8201601f1916602001610ba9565b818152846020838601011115610c2d57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215610c6057600080fd5b8435610c6b81610b7b565b93506020850135610c7b81610b7b565b925060408501359150606085013567ffffffffffffffff811115610c9e57600080fd5b610caa87828801610bda565b91505092959194509250565b60008060408385031215610cc957600080fd5b8235610cd481610b7b565b91506020830135610ce481610b7b565b809150509250929050565b60008060008060808587031215610d0557600080fd5b8435610d1081610b7b565b93506020850135610d2081610b7b565b93969395505050506040820135916060013590565b60008060008060608587031215610d4b57600080fd5b8435610d5681610b7b565b935060208501359250604085013567ffffffffffffffff80821115610d7a57600080fd5b818701915087601f830112610d8e57600080fd5b813581811115610d9d57600080fd5b886020828501011115610daf57600080fd5b95989497505060200194505050565b600060208083528351808285015260005b81811015610deb57858101830151858201604001528201610dcf565b506000604082860101526040601f19601f8301168501019250505092915050565b600080600060608486031215610e2157600080fd5b8335610e2c81610b7b565b95602085013595506040909401359392505050565b600082601f830112610e5257600080fd5b8135602067ffffffffffffffff821115610e6e57610e6e610b93565b8160051b610e7d828201610ba9565b9283528481018201928281019087851115610e9757600080fd5b83870192505b84831015610eb657823582529183019190830190610e9d565b979650505050505050565b600080600080600060a08688031215610ed957600080fd5b8535610ee481610b7b565b94506020860135610ef481610b7b565b9350604086013567ffffffffffffffff80821115610f1157600080fd5b610f1d89838a01610e41565b94506060880135915080821115610f3357600080fd5b610f3f89838a01610e41565b93506080880135915080821115610f5557600080fd5b50610f6288828901610bda565b9150509295509295909350565b600060208284031215610f8157600080fd5b5035919050565b600080600080600060a08688031215610fa057600080fd5b8535610fab81610b7b565b94506020860135610fbb81610b7b565b93506040860135925060608601359150608086013567ffffffffffffffff811115610fe557600080fd5b610f6288828901610bda565b60006020828403121561100357600080fd5b8135610abc81610b7b565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561103657600080fd5b81358015158114610abc57600080fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161106e5761106e611046565b5060010190565b60006020828403121561108757600080fd5b8151610abc81610b7b565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b808201808211156110d4576110d4611046565b92915050565b6000806000606084860312156110ef57600080fd5b83519250602084015161110181610b7b565b80925050604084015190509250925092565b818382376000910190815291905056fea264697066735822122063e6912474b85020b5a9835811ba76231c769e7f9cde34faffb5d227a7ea56e564736f6c63430008110033", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/contracts/MinimalisticAccount.sol/MinimalisticAccount.dbg.json b/build/contracts/contracts/MinimalisticAccount.sol/MinimalisticAccount.dbg.json deleted file mode 100644 index 1244edf..0000000 --- a/build/contracts/contracts/MinimalisticAccount.sol/MinimalisticAccount.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../build-info/00c127ac0f1f040c8525c77a2284410d.json" -} diff --git a/build/contracts/contracts/MinimalisticAccount.sol/MinimalisticAccount.json b/build/contracts/contracts/MinimalisticAccount.sol/MinimalisticAccount.json deleted file mode 100644 index 0072fb6..0000000 --- a/build/contracts/contracts/MinimalisticAccount.sol/MinimalisticAccount.json +++ /dev/null @@ -1,429 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "MinimalisticAccount", - "sourceName": "contracts/MinimalisticAccount.sol", - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "AccountLocked", - "type": "error" - }, - { - "inputs": [], - "name": "ExceedsMaxLockTime", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidInput", - "type": "error" - }, - { - "inputs": [], - "name": "NotAuthorized", - "type": "error" - }, - { - "inputs": [], - "name": "OwnershipCycle", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "lockedUntil", - "type": "uint256" - } - ], - "name": "LockUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes4", - "name": "selector", - "type": "bytes4" - }, - { - "indexed": false, - "internalType": "address", - "name": "implementation", - "type": "address" - } - ], - "name": "OverrideUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "caller", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "hasPermission", - "type": "bool" - } - ], - "name": "PermissionUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "TransactionExecuted", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "executeCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "caller", - "type": "address" - } - ], - "name": "isAuthorized", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "isLocked", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_lockedUntil", - "type": "uint256" - } - ], - "name": "lock", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "lockedUntil", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "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": "receivedTokenId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "name": "onERC721Received", - "outputs": [ - { - "internalType": "bytes4", - "name": "", - "type": "bytes4" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "permissions", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address[]", - "name": "callers", - "type": "address[]" - }, - { - "internalType": "bool[]", - "name": "_permissions", - "type": "bool[]" - } - ], - "name": "setPermissions", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "token", - "outputs": [ - { - "internalType": "uint256", - "name": "chainId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "tokenContract", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610fa8806100206000396000f3fe6080604052600436106100c65760003560e01c8063a4e2d6341161007f578063dd46706411610059578063dd46706414610251578063f23a6e6114610271578063fc0c546a1461029d578063fe9fbb80146102d557600080fd5b8063a4e2d634146101ea578063bc197c8114610201578063ce0617ec1461022d57600080fd5b806301ffc9a7146100d2578063039721b114610107578063150b7a02146101295780631f9838b5146101625780638da5cb5b1461019d5780639e5d4c49146101ca57600080fd5b366100cd57005b600080fd5b3480156100de57600080fd5b506100f26100ed36600461095c565b6102f5565b60405190151581526020015b60405180910390f35b34801561011357600080fd5b506101276101223660046109d9565b61035c565b005b34801561013557600080fd5b50610149610144366004610b14565b610525565b6040516001600160e01b031990911681526020016100fe565b34801561016e57600080fd5b506100f261017d366004610b80565b600160209081526000928352604080842090915290825290205460ff1681565b3480156101a957600080fd5b506101b261058d565b6040516001600160a01b0390911681526020016100fe565b6101dd6101d8366004610bb9565b610623565b6040516100fe9190610c42565b3480156101f657600080fd5b5060005442106100f2565b34801561020d57600080fd5b5061014961021c366004610d10565b63bc197c8160e01b95945050505050565b34801561023957600080fd5b5061024360005481565b6040519081526020016100fe565b34801561025d57600080fd5b5061012761026c366004610dbe565b6106c7565b34801561027d57600080fd5b5061014961028c366004610dd7565b63f23a6e6160e01b95945050505050565b3480156102a957600080fd5b506102b261078c565b604080519384526001600160a01b039092166020840152908201526060016100fe565b3480156102e157600080fd5b506100f26102f0366004610e40565b6107a4565b6000806001600160e01b031983166301ffc9a760e01b148061032757506001600160e01b03198316630271189760e51b145b8061034257506001600160e01b03198316631dfe9a6f60e31b145b905080156103535750600192915050565b50600092915050565b60005442101561037f57604051636315bfbb60e01b815260040160405180910390fd5b600061038961058d565b9050336001600160a01b038216146103b45760405163ea8e4eb560e01b815260040160405180910390fd5b838281146103d55760405163b4fa3fb360e01b815260040160405180910390fd5b60005b8181101561051c578484828181106103f2576103f2610e5d565b90506020020160208101906104079190610e73565b6001600160a01b03841660009081526001602052604081209089898581811061043257610432610e5d565b90506020020160208101906104479190610e40565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f394777a58092892d136a90c4bb7e4350c72ac50fba6a0208128677f36527dcf5838888848181106104a3576104a3610e5d565b90506020020160208101906104b89190610e40565b8787858181106104ca576104ca610e5d565b90506020020160208101906104df9190610e73565b604080516001600160a01b03948516815293909216602084015215159082015260600160405180910390a18061051481610eab565b9150506103d8565b50505050505050565b60008060008061053361088d565b925092509250468314801561055057506001600160a01b03821633145b801561055b57508581145b156105795760405163b79e3f3f60e01b815260040160405180910390fd5b50630a85bd0160e11b979650505050505050565b60008060008061059b61088d565b9250925092504683146105b2576000935050505090565b6040516331a9108f60e11b8152600481018290526001600160a01b03831690636352211e90602401602060405180830381865afa1580156105f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061b9190610ec4565b935050505090565b606061062e336107a4565b61064b5760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561066e57604051636315bfbb60e01b815260040160405180910390fd5b83856001600160a01b03167f47d99ad340f52da66535aff7e10da1ceb85a32bcbd9fa1c42314d194545e14d285856040516106aa929190610ee1565b60405180910390a36106be858585856108e0565b95945050505050565b6106cf61058d565b6001600160a01b0316336001600160a01b0316146107005760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561072357604051636315bfbb60e01b815260040160405180910390fd5b610731426301e13380610f10565b811115610751576040516301814f7d60e31b815260040160405180910390fd5b60008190556040518181527fa7b24c66dd3269a292a60b3facdbb8f3e7557d1e19e64d99e0d6ee7250be63ad9060200160405180910390a150565b600080600061079961088d565b925092509250909192565b60008060006107b161088d565b6040516331a9108f60e11b8152600481018290529194509250600091506001600160a01b03841690636352211e90602401602060405180830381865afa1580156107ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108239190610ec4565b9050806001600160a01b0316856001600160a01b03160361084957506001949350505050565b6001600160a01b0380821660009081526001602090815260408083209389168352929052205460ff161561088257506001949350505050565b506000949350505050565b604080516060808252608082019092526000918291829182919060208201818036833701905050905060ad604d60208301303c808060200190518101906108d49190610f29565b93509350935050909192565b60606000856001600160a01b03168585856040516108ff929190610f62565b60006040518083038185875af1925050503d806000811461093c576040519150601f19603f3d011682016040523d82523d6000602084013e610941565b606091505b50925090508061095357815160208301fd5b50949350505050565b60006020828403121561096e57600080fd5b81356001600160e01b03198116811461098657600080fd5b9392505050565b60008083601f84011261099f57600080fd5b50813567ffffffffffffffff8111156109b757600080fd5b6020830191508360208260051b85010111156109d257600080fd5b9250929050565b600080600080604085870312156109ef57600080fd5b843567ffffffffffffffff80821115610a0757600080fd5b610a138883890161098d565b90965094506020870135915080821115610a2c57600080fd5b50610a398782880161098d565b95989497509550505050565b6001600160a01b0381168114610a5a57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610a9c57610a9c610a5d565b604052919050565b600082601f830112610ab557600080fd5b813567ffffffffffffffff811115610acf57610acf610a5d565b610ae2601f8201601f1916602001610a73565b818152846020838601011115610af757600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215610b2a57600080fd5b8435610b3581610a45565b93506020850135610b4581610a45565b925060408501359150606085013567ffffffffffffffff811115610b6857600080fd5b610b7487828801610aa4565b91505092959194509250565b60008060408385031215610b9357600080fd5b8235610b9e81610a45565b91506020830135610bae81610a45565b809150509250929050565b60008060008060608587031215610bcf57600080fd5b8435610bda81610a45565b935060208501359250604085013567ffffffffffffffff80821115610bfe57600080fd5b818701915087601f830112610c1257600080fd5b813581811115610c2157600080fd5b886020828501011115610c3357600080fd5b95989497505060200194505050565b600060208083528351808285015260005b81811015610c6f57858101830151858201604001528201610c53565b506000604082860101526040601f19601f8301168501019250505092915050565b600082601f830112610ca157600080fd5b8135602067ffffffffffffffff821115610cbd57610cbd610a5d565b8160051b610ccc828201610a73565b9283528481018201928281019087851115610ce657600080fd5b83870192505b84831015610d0557823582529183019190830190610cec565b979650505050505050565b600080600080600060a08688031215610d2857600080fd5b8535610d3381610a45565b94506020860135610d4381610a45565b9350604086013567ffffffffffffffff80821115610d6057600080fd5b610d6c89838a01610c90565b94506060880135915080821115610d8257600080fd5b610d8e89838a01610c90565b93506080880135915080821115610da457600080fd5b50610db188828901610aa4565b9150509295509295909350565b600060208284031215610dd057600080fd5b5035919050565b600080600080600060a08688031215610def57600080fd5b8535610dfa81610a45565b94506020860135610e0a81610a45565b93506040860135925060608601359150608086013567ffffffffffffffff811115610e3457600080fd5b610db188828901610aa4565b600060208284031215610e5257600080fd5b813561098681610a45565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610e8557600080fd5b8135801515811461098657600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610ebd57610ebd610e95565b5060010190565b600060208284031215610ed657600080fd5b815161098681610a45565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b80820180821115610f2357610f23610e95565b92915050565b600080600060608486031215610f3e57600080fd5b835192506020840151610f5081610a45565b80925050604084015190509250925092565b818382376000910190815291905056fea26469706673582212208586a5aa87cff87a1d8e1dc4952c1d3b167ebfafab4c2b56ed97ed8a5ec5921664736f6c63430008110033", - "deployedBytecode": "0x6080604052600436106100c65760003560e01c8063a4e2d6341161007f578063dd46706411610059578063dd46706414610251578063f23a6e6114610271578063fc0c546a1461029d578063fe9fbb80146102d557600080fd5b8063a4e2d634146101ea578063bc197c8114610201578063ce0617ec1461022d57600080fd5b806301ffc9a7146100d2578063039721b114610107578063150b7a02146101295780631f9838b5146101625780638da5cb5b1461019d5780639e5d4c49146101ca57600080fd5b366100cd57005b600080fd5b3480156100de57600080fd5b506100f26100ed36600461095c565b6102f5565b60405190151581526020015b60405180910390f35b34801561011357600080fd5b506101276101223660046109d9565b61035c565b005b34801561013557600080fd5b50610149610144366004610b14565b610525565b6040516001600160e01b031990911681526020016100fe565b34801561016e57600080fd5b506100f261017d366004610b80565b600160209081526000928352604080842090915290825290205460ff1681565b3480156101a957600080fd5b506101b261058d565b6040516001600160a01b0390911681526020016100fe565b6101dd6101d8366004610bb9565b610623565b6040516100fe9190610c42565b3480156101f657600080fd5b5060005442106100f2565b34801561020d57600080fd5b5061014961021c366004610d10565b63bc197c8160e01b95945050505050565b34801561023957600080fd5b5061024360005481565b6040519081526020016100fe565b34801561025d57600080fd5b5061012761026c366004610dbe565b6106c7565b34801561027d57600080fd5b5061014961028c366004610dd7565b63f23a6e6160e01b95945050505050565b3480156102a957600080fd5b506102b261078c565b604080519384526001600160a01b039092166020840152908201526060016100fe565b3480156102e157600080fd5b506100f26102f0366004610e40565b6107a4565b6000806001600160e01b031983166301ffc9a760e01b148061032757506001600160e01b03198316630271189760e51b145b8061034257506001600160e01b03198316631dfe9a6f60e31b145b905080156103535750600192915050565b50600092915050565b60005442101561037f57604051636315bfbb60e01b815260040160405180910390fd5b600061038961058d565b9050336001600160a01b038216146103b45760405163ea8e4eb560e01b815260040160405180910390fd5b838281146103d55760405163b4fa3fb360e01b815260040160405180910390fd5b60005b8181101561051c578484828181106103f2576103f2610e5d565b90506020020160208101906104079190610e73565b6001600160a01b03841660009081526001602052604081209089898581811061043257610432610e5d565b90506020020160208101906104479190610e40565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790557f394777a58092892d136a90c4bb7e4350c72ac50fba6a0208128677f36527dcf5838888848181106104a3576104a3610e5d565b90506020020160208101906104b89190610e40565b8787858181106104ca576104ca610e5d565b90506020020160208101906104df9190610e73565b604080516001600160a01b03948516815293909216602084015215159082015260600160405180910390a18061051481610eab565b9150506103d8565b50505050505050565b60008060008061053361088d565b925092509250468314801561055057506001600160a01b03821633145b801561055b57508581145b156105795760405163b79e3f3f60e01b815260040160405180910390fd5b50630a85bd0160e11b979650505050505050565b60008060008061059b61088d565b9250925092504683146105b2576000935050505090565b6040516331a9108f60e11b8152600481018290526001600160a01b03831690636352211e90602401602060405180830381865afa1580156105f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061b9190610ec4565b935050505090565b606061062e336107a4565b61064b5760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561066e57604051636315bfbb60e01b815260040160405180910390fd5b83856001600160a01b03167f47d99ad340f52da66535aff7e10da1ceb85a32bcbd9fa1c42314d194545e14d285856040516106aa929190610ee1565b60405180910390a36106be858585856108e0565b95945050505050565b6106cf61058d565b6001600160a01b0316336001600160a01b0316146107005760405163ea8e4eb560e01b815260040160405180910390fd5b60005442101561072357604051636315bfbb60e01b815260040160405180910390fd5b610731426301e13380610f10565b811115610751576040516301814f7d60e31b815260040160405180910390fd5b60008190556040518181527fa7b24c66dd3269a292a60b3facdbb8f3e7557d1e19e64d99e0d6ee7250be63ad9060200160405180910390a150565b600080600061079961088d565b925092509250909192565b60008060006107b161088d565b6040516331a9108f60e11b8152600481018290529194509250600091506001600160a01b03841690636352211e90602401602060405180830381865afa1580156107ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108239190610ec4565b9050806001600160a01b0316856001600160a01b03160361084957506001949350505050565b6001600160a01b0380821660009081526001602090815260408083209389168352929052205460ff161561088257506001949350505050565b506000949350505050565b604080516060808252608082019092526000918291829182919060208201818036833701905050905060ad604d60208301303c808060200190518101906108d49190610f29565b93509350935050909192565b60606000856001600160a01b03168585856040516108ff929190610f62565b60006040518083038185875af1925050503d806000811461093c576040519150601f19603f3d011682016040523d82523d6000602084013e610941565b606091505b50925090508061095357815160208301fd5b50949350505050565b60006020828403121561096e57600080fd5b81356001600160e01b03198116811461098657600080fd5b9392505050565b60008083601f84011261099f57600080fd5b50813567ffffffffffffffff8111156109b757600080fd5b6020830191508360208260051b85010111156109d257600080fd5b9250929050565b600080600080604085870312156109ef57600080fd5b843567ffffffffffffffff80821115610a0757600080fd5b610a138883890161098d565b90965094506020870135915080821115610a2c57600080fd5b50610a398782880161098d565b95989497509550505050565b6001600160a01b0381168114610a5a57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610a9c57610a9c610a5d565b604052919050565b600082601f830112610ab557600080fd5b813567ffffffffffffffff811115610acf57610acf610a5d565b610ae2601f8201601f1916602001610a73565b818152846020838601011115610af757600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215610b2a57600080fd5b8435610b3581610a45565b93506020850135610b4581610a45565b925060408501359150606085013567ffffffffffffffff811115610b6857600080fd5b610b7487828801610aa4565b91505092959194509250565b60008060408385031215610b9357600080fd5b8235610b9e81610a45565b91506020830135610bae81610a45565b809150509250929050565b60008060008060608587031215610bcf57600080fd5b8435610bda81610a45565b935060208501359250604085013567ffffffffffffffff80821115610bfe57600080fd5b818701915087601f830112610c1257600080fd5b813581811115610c2157600080fd5b886020828501011115610c3357600080fd5b95989497505060200194505050565b600060208083528351808285015260005b81811015610c6f57858101830151858201604001528201610c53565b506000604082860101526040601f19601f8301168501019250505092915050565b600082601f830112610ca157600080fd5b8135602067ffffffffffffffff821115610cbd57610cbd610a5d565b8160051b610ccc828201610a73565b9283528481018201928281019087851115610ce657600080fd5b83870192505b84831015610d0557823582529183019190830190610cec565b979650505050505050565b600080600080600060a08688031215610d2857600080fd5b8535610d3381610a45565b94506020860135610d4381610a45565b9350604086013567ffffffffffffffff80821115610d6057600080fd5b610d6c89838a01610c90565b94506060880135915080821115610d8257600080fd5b610d8e89838a01610c90565b93506080880135915080821115610da457600080fd5b50610db188828901610aa4565b9150509295509295909350565b600060208284031215610dd057600080fd5b5035919050565b600080600080600060a08688031215610def57600080fd5b8535610dfa81610a45565b94506020860135610e0a81610a45565b93506040860135925060608601359150608086013567ffffffffffffffff811115610e3457600080fd5b610db188828901610aa4565b600060208284031215610e5257600080fd5b813561098681610a45565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610e8557600080fd5b8135801515811461098657600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610ebd57610ebd610e95565b5060010190565b600060208284031215610ed657600080fd5b815161098681610a45565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b80820180821115610f2357610f23610e95565b92915050565b600080600060608486031215610f3e57600080fd5b835192506020840151610f5081610a45565b80925050604084015190509250925092565b818382376000910190815291905056fea26469706673582212208586a5aa87cff87a1d8e1dc4952c1d3b167ebfafab4c2b56ed97ed8a5ec5921664736f6c63430008110033", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/contracts/interfaces/IAccount.sol/IAccount.dbg.json b/build/contracts/contracts/interfaces/IAccount.sol/IAccount.dbg.json deleted file mode 100644 index 112926b..0000000 --- a/build/contracts/contracts/interfaces/IAccount.sol/IAccount.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../../build-info/621b40ccb08e9f77631297486483360b.json" -} diff --git a/build/contracts/contracts/interfaces/IAccount.sol/IAccount.json b/build/contracts/contracts/interfaces/IAccount.sol/IAccount.json deleted file mode 100644 index 91f8386..0000000 --- a/build/contracts/contracts/interfaces/IAccount.sol/IAccount.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "IAccount", - "sourceName": "contracts/interfaces/IAccount.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "executeCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "token", - "outputs": [ - { - "internalType": "address", - "name": "tokenContract", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "bytecode": "0x", - "deployedBytecode": "0x", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/contracts/interfaces/IChargedParticles.sol/IChargedParticles.dbg.json b/build/contracts/contracts/interfaces/IChargedParticles.sol/IChargedParticles.dbg.json deleted file mode 100644 index c686f20..0000000 --- a/build/contracts/contracts/interfaces/IChargedParticles.sol/IChargedParticles.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../../build-info/00c127ac0f1f040c8525c77a2284410d.json" -} diff --git a/build/contracts/contracts/interfaces/IERC6551Account.sol/IERC6551Account.dbg.json b/build/contracts/contracts/interfaces/IERC6551Account.sol/IERC6551Account.dbg.json deleted file mode 100644 index c686f20..0000000 --- a/build/contracts/contracts/interfaces/IERC6551Account.sol/IERC6551Account.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../../build-info/00c127ac0f1f040c8525c77a2284410d.json" -} diff --git a/build/contracts/contracts/interfaces/IERC6551Account.sol/IERC6551Account.json b/build/contracts/contracts/interfaces/IERC6551Account.sol/IERC6551Account.json deleted file mode 100644 index 9c18836..0000000 --- a/build/contracts/contracts/interfaces/IERC6551Account.sol/IERC6551Account.json +++ /dev/null @@ -1,105 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "IERC6551Account", - "sourceName": "contracts/interfaces/IERC6551Account.sol", - "abi": [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "target", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "TransactionExecuted", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "executeCall", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "token", - "outputs": [ - { - "internalType": "uint256", - "name": "chainId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "tokenContract", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - } - ], - "bytecode": "0x", - "deployedBytecode": "0x", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/contracts/interfaces/IERC6551Account.sol/IERC6551AccountProxy.dbg.json b/build/contracts/contracts/interfaces/IERC6551Account.sol/IERC6551AccountProxy.dbg.json deleted file mode 100644 index c686f20..0000000 --- a/build/contracts/contracts/interfaces/IERC6551Account.sol/IERC6551AccountProxy.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../../build-info/00c127ac0f1f040c8525c77a2284410d.json" -} diff --git a/build/contracts/contracts/interfaces/IERC6551Account.sol/IERC6551AccountProxy.json b/build/contracts/contracts/interfaces/IERC6551Account.sol/IERC6551AccountProxy.json deleted file mode 100644 index f1e0baa..0000000 --- a/build/contracts/contracts/interfaces/IERC6551Account.sol/IERC6551AccountProxy.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "IERC6551AccountProxy", - "sourceName": "contracts/interfaces/IERC6551Account.sol", - "abi": [ - { - "inputs": [], - "name": "implementation", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "bytecode": "0x", - "deployedBytecode": "0x", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/contracts/interfaces/IRegistry.sol/IRegistry.dbg.json b/build/contracts/contracts/interfaces/IRegistry.sol/IRegistry.dbg.json deleted file mode 100644 index 112926b..0000000 --- a/build/contracts/contracts/interfaces/IRegistry.sol/IRegistry.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../../build-info/621b40ccb08e9f77631297486483360b.json" -} diff --git a/build/contracts/contracts/interfaces/IRegistry.sol/IRegistry.json b/build/contracts/contracts/interfaces/IRegistry.sol/IRegistry.json deleted file mode 100644 index cc5470c..0000000 --- a/build/contracts/contracts/interfaces/IRegistry.sol/IRegistry.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "IRegistry", - "sourceName": "contracts/interfaces/IRegistry.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "implementation", - "type": "address" - }, - { - "internalType": "uint256", - "name": "chainId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "tokenContract", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "salt", - "type": "uint256" - } - ], - "name": "account", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "implementation", - "type": "address" - }, - { - "internalType": "uint256", - "name": "chainId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "tokenContract", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "salt", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "initData", - "type": "bytes" - } - ], - "name": "createAccount", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x", - "deployedBytecode": "0x", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/contracts/lib/ERC6551AccountLib.sol/ERC6551AccountLib.dbg.json b/build/contracts/contracts/lib/ERC6551AccountLib.sol/ERC6551AccountLib.dbg.json deleted file mode 100644 index c686f20..0000000 --- a/build/contracts/contracts/lib/ERC6551AccountLib.sol/ERC6551AccountLib.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../../build-info/00c127ac0f1f040c8525c77a2284410d.json" -} diff --git a/build/contracts/contracts/lib/ERC6551AccountLib.sol/ERC6551AccountLib.json b/build/contracts/contracts/lib/ERC6551AccountLib.sol/ERC6551AccountLib.json deleted file mode 100644 index 5d66542..0000000 --- a/build/contracts/contracts/lib/ERC6551AccountLib.sol/ERC6551AccountLib.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "ERC6551AccountLib", - "sourceName": "contracts/lib/ERC6551AccountLib.sol", - "abi": [], - "bytecode": "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220507d1af45fff54535180cd2db9c0244503eb6a3f2538827633938e9a22f0be7564736f6c63430008110033", - "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220507d1af45fff54535180cd2db9c0244503eb6a3f2538827633938e9a22f0be7564736f6c63430008110033", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/build/contracts/contracts/mock/NFTMock.sol/NFTMock.dbg.json b/build/contracts/contracts/mock/NFTMock.sol/NFTMock.dbg.json deleted file mode 100644 index 112926b..0000000 --- a/build/contracts/contracts/mock/NFTMock.sol/NFTMock.dbg.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "_format": "hh-sol-dbg-1", - "buildInfo": "../../../build-info/621b40ccb08e9f77631297486483360b.json" -} diff --git a/build/contracts/contracts/mock/NFTMock.sol/NFTMock.json b/build/contracts/contracts/mock/NFTMock.sol/NFTMock.json deleted file mode 100644 index fc50cc3..0000000 --- a/build/contracts/contracts/mock/NFTMock.sol/NFTMock.json +++ /dev/null @@ -1,375 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "NFTMock", - "sourceName": "contracts/mock/NFTMock.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "string", - "name": "name_", - "type": "string" - }, - { - "internalType": "string", - "name": "symbol_", - "type": "string" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "approved", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "ApprovalForAll", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "getApproved", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "name": "isApprovedForAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "mint", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "ownerOf", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "setApprovalForAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "tokenURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x60806040523480156200001157600080fd5b50604051620015ae380380620015ae833981016040819052620000349162000123565b818160006200004483826200021c565b5060016200005382826200021c565b5050505050620002e8565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200008657600080fd5b81516001600160401b0380821115620000a357620000a36200005e565b604051601f8301601f19908116603f01168101908282118183101715620000ce57620000ce6200005e565b81604052838152602092508683858801011115620000eb57600080fd5b600091505b838210156200010f5785820183015181830184015290820190620000f0565b600093810190920192909252949350505050565b600080604083850312156200013757600080fd5b82516001600160401b03808211156200014f57600080fd5b6200015d8683870162000074565b935060208501519150808211156200017457600080fd5b50620001838582860162000074565b9150509250929050565b600181811c90821680620001a257607f821691505b602082108103620001c357634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200021757600081815260208120601f850160051c81016020861015620001f25750805b601f850160051c820191505b818110156200021357828155600101620001fe565b5050505b505050565b81516001600160401b038111156200023857620002386200005e565b62000250816200024984546200018d565b84620001c9565b602080601f8311600181146200028857600084156200026f5750858301515b600019600386901b1c1916600185901b17855562000213565b600085815260208120601f198616915b82811015620002b95788860151825594840194600190910190840162000298565b5085821015620002d85787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6112b680620002f86000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80636352211e1161008c578063a22cb46511610066578063a22cb465146101e1578063b88d4fde146101f4578063c87b56dd14610207578063e985e9c51461021a57600080fd5b80636352211e146101a557806370a08231146101b857806395d89b41146101d957600080fd5b8063095ea7b3116100c8578063095ea7b31461015757806323b872dd1461016c57806340c10f191461017f57806342842e0e1461019257600080fd5b806301ffc9a7146100ef57806306fdde0314610117578063081812fc1461012c575b600080fd5b6101026100fd366004610e42565b610256565b60405190151581526020015b60405180910390f35b61011f6102a8565b60405161010e9190610eaf565b61013f61013a366004610ec2565b61033a565b6040516001600160a01b03909116815260200161010e565b61016a610165366004610ef7565b610361565b005b61016a61017a366004610f21565b61047b565b61016a61018d366004610ef7565b6104ac565b61016a6101a0366004610f21565b6104ba565b61013f6101b3366004610ec2565b6104d5565b6101cb6101c6366004610f5d565b610535565b60405190815260200161010e565b61011f6105bb565b61016a6101ef366004610f78565b6105ca565b61016a610202366004610fca565b6105d5565b61011f610215366004610ec2565b61060d565b6101026102283660046110a6565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60006001600160e01b031982166380ac58cd60e01b148061028757506001600160e01b03198216635b5e139f60e01b145b806102a257506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600080546102b7906110d9565b80601f01602080910402602001604051908101604052809291908181526020018280546102e3906110d9565b80156103305780601f1061030557610100808354040283529160200191610330565b820191906000526020600020905b81548152906001019060200180831161031357829003601f168201915b5050505050905090565b600061034582610681565b506000908152600460205260409020546001600160a01b031690565b600061036c826104d5565b9050806001600160a01b0316836001600160a01b0316036103de5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806103fa57506103fa8133610228565b61046c5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c00000060648201526084016103d5565b61047683836106e3565b505050565b6104853382610751565b6104a15760405162461bcd60e51b81526004016103d590611113565b6104768383836107d0565b6104b68282610934565b5050565b610476838383604051806020016040528060008152506105d5565b6000818152600260205260408120546001600160a01b0316806102a25760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103d5565b60006001600160a01b03821661059f5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016103d5565b506001600160a01b031660009081526003602052604090205490565b6060600180546102b7906110d9565b6104b6338383610abf565b6105df3383610751565b6105fb5760405162461bcd60e51b81526004016103d590611113565b61060784848484610b8d565b50505050565b606061061882610681565b600061062f60408051602081019091526000815290565b9050600081511161064f576040518060200160405280600081525061067a565b8061065984610bc0565b60405160200161066a929190611160565b6040516020818303038152906040525b9392505050565b6000818152600260205260409020546001600160a01b03166106e05760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103d5565b50565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610718826104d5565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061075d836104d5565b9050806001600160a01b0316846001600160a01b031614806107a457506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b806107c85750836001600160a01b03166107bd8461033a565b6001600160a01b0316145b949350505050565b826001600160a01b03166107e3826104d5565b6001600160a01b0316146108095760405162461bcd60e51b81526004016103d59061118f565b6001600160a01b03821661086b5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016103d5565b826001600160a01b031661087e826104d5565b6001600160a01b0316146108a45760405162461bcd60e51b81526004016103d59061118f565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b03821661098a5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016103d5565b6000818152600260205260409020546001600160a01b0316156109ef5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016103d5565b6000818152600260205260409020546001600160a01b031615610a545760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016103d5565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b816001600160a01b0316836001600160a01b031603610b205760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016103d5565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b610b988484846107d0565b610ba484848484610c53565b6106075760405162461bcd60e51b81526004016103d5906111d4565b60606000610bcd83610d54565b600101905060008167ffffffffffffffff811115610bed57610bed610fb4565b6040519080825280601f01601f191660200182016040528015610c17576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084610c2157509392505050565b60006001600160a01b0384163b15610d4957604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290610c97903390899088908890600401611226565b6020604051808303816000875af1925050508015610cd2575060408051601f3d908101601f19168201909252610ccf91810190611263565b60015b610d2f573d808015610d00576040519150601f19603f3d011682016040523d82523d6000602084013e610d05565b606091505b508051600003610d275760405162461bcd60e51b81526004016103d5906111d4565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506107c8565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310610d935772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310610dbf576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310610ddd57662386f26fc10000830492506010015b6305f5e1008310610df5576305f5e100830492506008015b6127108310610e0957612710830492506004015b60648310610e1b576064830492506002015b600a83106102a25760010192915050565b6001600160e01b0319811681146106e057600080fd5b600060208284031215610e5457600080fd5b813561067a81610e2c565b60005b83811015610e7a578181015183820152602001610e62565b50506000910152565b60008151808452610e9b816020860160208601610e5f565b601f01601f19169290920160200192915050565b60208152600061067a6020830184610e83565b600060208284031215610ed457600080fd5b5035919050565b80356001600160a01b0381168114610ef257600080fd5b919050565b60008060408385031215610f0a57600080fd5b610f1383610edb565b946020939093013593505050565b600080600060608486031215610f3657600080fd5b610f3f84610edb565b9250610f4d60208501610edb565b9150604084013590509250925092565b600060208284031215610f6f57600080fd5b61067a82610edb565b60008060408385031215610f8b57600080fd5b610f9483610edb565b915060208301358015158114610fa957600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215610fe057600080fd5b610fe985610edb565b9350610ff760208601610edb565b925060408501359150606085013567ffffffffffffffff8082111561101b57600080fd5b818701915087601f83011261102f57600080fd5b81358181111561104157611041610fb4565b604051601f8201601f19908116603f0116810190838211818310171561106957611069610fb4565b816040528281528a602084870101111561108257600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b600080604083850312156110b957600080fd5b6110c283610edb565b91506110d060208401610edb565b90509250929050565b600181811c908216806110ed57607f821691505b60208210810361110d57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b60008351611172818460208801610e5f565b835190830190611186818360208801610e5f565b01949350505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061125990830184610e83565b9695505050505050565b60006020828403121561127557600080fd5b815161067a81610e2c56fea26469706673582212203e5c29bc0c6611a8b7a6b12c19a302bc12fee5e380672b063f2b72a4f2ffcd6b64736f6c63430008110033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c80636352211e1161008c578063a22cb46511610066578063a22cb465146101e1578063b88d4fde146101f4578063c87b56dd14610207578063e985e9c51461021a57600080fd5b80636352211e146101a557806370a08231146101b857806395d89b41146101d957600080fd5b8063095ea7b3116100c8578063095ea7b31461015757806323b872dd1461016c57806340c10f191461017f57806342842e0e1461019257600080fd5b806301ffc9a7146100ef57806306fdde0314610117578063081812fc1461012c575b600080fd5b6101026100fd366004610e42565b610256565b60405190151581526020015b60405180910390f35b61011f6102a8565b60405161010e9190610eaf565b61013f61013a366004610ec2565b61033a565b6040516001600160a01b03909116815260200161010e565b61016a610165366004610ef7565b610361565b005b61016a61017a366004610f21565b61047b565b61016a61018d366004610ef7565b6104ac565b61016a6101a0366004610f21565b6104ba565b61013f6101b3366004610ec2565b6104d5565b6101cb6101c6366004610f5d565b610535565b60405190815260200161010e565b61011f6105bb565b61016a6101ef366004610f78565b6105ca565b61016a610202366004610fca565b6105d5565b61011f610215366004610ec2565b61060d565b6101026102283660046110a6565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60006001600160e01b031982166380ac58cd60e01b148061028757506001600160e01b03198216635b5e139f60e01b145b806102a257506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600080546102b7906110d9565b80601f01602080910402602001604051908101604052809291908181526020018280546102e3906110d9565b80156103305780601f1061030557610100808354040283529160200191610330565b820191906000526020600020905b81548152906001019060200180831161031357829003601f168201915b5050505050905090565b600061034582610681565b506000908152600460205260409020546001600160a01b031690565b600061036c826104d5565b9050806001600160a01b0316836001600160a01b0316036103de5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806103fa57506103fa8133610228565b61046c5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c00000060648201526084016103d5565b61047683836106e3565b505050565b6104853382610751565b6104a15760405162461bcd60e51b81526004016103d590611113565b6104768383836107d0565b6104b68282610934565b5050565b610476838383604051806020016040528060008152506105d5565b6000818152600260205260408120546001600160a01b0316806102a25760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103d5565b60006001600160a01b03821661059f5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016103d5565b506001600160a01b031660009081526003602052604090205490565b6060600180546102b7906110d9565b6104b6338383610abf565b6105df3383610751565b6105fb5760405162461bcd60e51b81526004016103d590611113565b61060784848484610b8d565b50505050565b606061061882610681565b600061062f60408051602081019091526000815290565b9050600081511161064f576040518060200160405280600081525061067a565b8061065984610bc0565b60405160200161066a929190611160565b6040516020818303038152906040525b9392505050565b6000818152600260205260409020546001600160a01b03166106e05760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103d5565b50565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610718826104d5565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061075d836104d5565b9050806001600160a01b0316846001600160a01b031614806107a457506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b806107c85750836001600160a01b03166107bd8461033a565b6001600160a01b0316145b949350505050565b826001600160a01b03166107e3826104d5565b6001600160a01b0316146108095760405162461bcd60e51b81526004016103d59061118f565b6001600160a01b03821661086b5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016103d5565b826001600160a01b031661087e826104d5565b6001600160a01b0316146108a45760405162461bcd60e51b81526004016103d59061118f565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b03821661098a5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016103d5565b6000818152600260205260409020546001600160a01b0316156109ef5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016103d5565b6000818152600260205260409020546001600160a01b031615610a545760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016103d5565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b816001600160a01b0316836001600160a01b031603610b205760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016103d5565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b610b988484846107d0565b610ba484848484610c53565b6106075760405162461bcd60e51b81526004016103d5906111d4565b60606000610bcd83610d54565b600101905060008167ffffffffffffffff811115610bed57610bed610fb4565b6040519080825280601f01601f191660200182016040528015610c17576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084610c2157509392505050565b60006001600160a01b0384163b15610d4957604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290610c97903390899088908890600401611226565b6020604051808303816000875af1925050508015610cd2575060408051601f3d908101601f19168201909252610ccf91810190611263565b60015b610d2f573d808015610d00576040519150601f19603f3d011682016040523d82523d6000602084013e610d05565b606091505b508051600003610d275760405162461bcd60e51b81526004016103d5906111d4565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506107c8565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310610d935772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310610dbf576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310610ddd57662386f26fc10000830492506010015b6305f5e1008310610df5576305f5e100830492506008015b6127108310610e0957612710830492506004015b60648310610e1b576064830492506002015b600a83106102a25760010192915050565b6001600160e01b0319811681146106e057600080fd5b600060208284031215610e5457600080fd5b813561067a81610e2c565b60005b83811015610e7a578181015183820152602001610e62565b50506000910152565b60008151808452610e9b816020860160208601610e5f565b601f01601f19169290920160200192915050565b60208152600061067a6020830184610e83565b600060208284031215610ed457600080fd5b5035919050565b80356001600160a01b0381168114610ef257600080fd5b919050565b60008060408385031215610f0a57600080fd5b610f1383610edb565b946020939093013593505050565b600080600060608486031215610f3657600080fd5b610f3f84610edb565b9250610f4d60208501610edb565b9150604084013590509250925092565b600060208284031215610f6f57600080fd5b61067a82610edb565b60008060408385031215610f8b57600080fd5b610f9483610edb565b915060208301358015158114610fa957600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215610fe057600080fd5b610fe985610edb565b9350610ff760208601610edb565b925060408501359150606085013567ffffffffffffffff8082111561101b57600080fd5b818701915087601f83011261102f57600080fd5b81358181111561104157611041610fb4565b604051601f8201601f19908116603f0116810190838211818310171561106957611069610fb4565b816040528281528a602084870101111561108257600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b600080604083850312156110b957600080fd5b6110c283610edb565b91506110d060208401610edb565b90509250929050565b600181811c908216806110ed57607f821691505b60208210810361110d57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b60008351611172818460208801610e5f565b835190830190611186818360208801610e5f565b01949350505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061125990830184610e83565b9695505050505050565b60006020828403121561127557600080fd5b815161067a81610e2c56fea26469706673582212203e5c29bc0c6611a8b7a6b12c19a302bc12fee5e380672b063f2b72a4f2ffcd6b64736f6c63430008110033", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/contracts/AccountRegistryBridge.sol b/contracts/AccountRegistryBridge.sol deleted file mode 100644 index 94abca1..0000000 --- a/contracts/AccountRegistryBridge.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.13; - -import "./interfaces/IRegistry.sol"; -import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; - -contract AccountRegistryBridge { - address public constant REGISTRY = 0x02101dfB77FDE026414827Fdc604ddAF224F0921; - address public constant IMPLEMENTATION = 0x2D25602551487C3f3354dD80D76D54383A243358; - - function createAccount( - address contractAddress, - uint256 tokenId - ) external returns (address) { - return IRegistry(REGISTRY).createAccount( - IMPLEMENTATION, - block.chainid, - contractAddress, - tokenId, - 0, - '' - ); - } - - function account( - address contractAddress, - uint256 tokenId - ) external view returns (address) { - return IRegistry(REGISTRY).account( - IMPLEMENTATION, - block.chainid, - contractAddress, - tokenId, - 0 - ); - } -} \ No newline at end of file diff --git a/contracts/ChargedParticlesAccount.sol b/contracts/ChargedParticlesAccount.sol deleted file mode 100644 index 8f8692d..0000000 --- a/contracts/ChargedParticlesAccount.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -import "./MinimalisticAccount.sol"; -import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; - -contract ChargedParticlesAccount is MinimalisticAccount { - function covalentBond( - address nftTokenAddress, - uint256 nftTokenId, - uint256 nftTokenAmount - ) external { - // Transfer to self - IERC721(nftTokenAddress).safeTransferFrom( - msg.sender, - address(this), - nftTokenId - ); - } - - function breakCovalentBond( - address receiver, - address nftTokenAddress, - uint256 nftTokenId, - uint256 nftTokenAmount - ) external { - IERC721(nftTokenAddress).safeTransferFrom(address(this), receiver, nftTokenId); - } -} diff --git a/contracts/MinimalisticAccount.sol b/contracts/MinimalisticAccount.sol deleted file mode 100644 index 657a342..0000000 --- a/contracts/MinimalisticAccount.sol +++ /dev/null @@ -1,252 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -import "./interfaces/IERC6551Account.sol"; -import "./lib/ERC6551AccountLib.sol"; - -import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; -import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; -import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; -import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol"; -import "@openzeppelin/contracts/interfaces/IERC1271.sol"; - -error NotAuthorized(); -error InvalidInput(); -error AccountLocked(); -error ExceedsMaxLockTime(); -error UntrustedImplementation(); -error OwnershipCycle(); - -/** - * @title A smart contract account owned by a single ERC721 token - */ -contract MinimalisticAccount is - IERC165, - IERC6551Account, - IERC721Receiver, - IERC1155Receiver -{ - /// @dev timestamp at which this account will be unlocked - uint256 public lockedUntil; - - /// @dev mapping from owner => caller => has permissions - mapping(address => mapping(address => bool)) public permissions; - - event OverrideUpdated( - address owner, - bytes4 selector, - address implementation - ); - - event PermissionUpdated(address owner, address caller, bool hasPermission); - - event LockUpdated(uint256 lockedUntil); - - /// @dev reverts if caller is not the owner of the account - modifier onlyOwner() { - if (msg.sender != owner()) revert NotAuthorized(); - _; - } - - /// @dev reverts if caller is not authorized to execute on this account - modifier onlyAuthorized() { - if (!isAuthorized(msg.sender)) revert NotAuthorized(); - _; - } - - /// @dev reverts if this account is currently locked - modifier onlyUnlocked() { - if (isLocked()) revert AccountLocked(); - _; - } - - constructor() {} - - /// @dev allows eth transfers by default, but allows account owner to override - receive() external payable { - } - - /// @dev executes a low-level call against an account if the caller is authorized to make calls - function executeCall( - address to, - uint256 value, - bytes calldata data - ) external payable onlyAuthorized onlyUnlocked returns (bytes memory) { - emit TransactionExecuted(to, value, data); - - return _call(to, value, data); - } - - /// @dev grants a given caller execution permissions - function setPermissions( - address[] calldata callers, - bool[] calldata _permissions - ) external onlyUnlocked { - address _owner = owner(); - if (msg.sender != _owner) revert NotAuthorized(); - - uint256 length = callers.length; - - if (_permissions.length != length) revert InvalidInput(); - - for (uint256 i = 0; i < length; i++) { - permissions[_owner][callers[i]] = _permissions[i]; - emit PermissionUpdated(_owner, callers[i], _permissions[i]); - } - } - - /// @dev locks the account until a certain timestamp - function lock(uint256 _lockedUntil) external onlyOwner onlyUnlocked { - if (_lockedUntil > block.timestamp + 365 days) - revert ExceedsMaxLockTime(); - - lockedUntil = _lockedUntil; - - emit LockUpdated(_lockedUntil); - } - - /// @dev returns the current lock status of the account as a boolean - function isLocked() public view returns (bool) { - return lockedUntil > block.timestamp; - } - - /// @dev Returns the EIP-155 chain ID, token contract address, and token ID for the token that - /// owns this account. - function token() - external - view - returns ( - uint256 chainId, - address tokenContract, - uint256 tokenId - ) - { - return ERC6551AccountLib.token(); - } - - /// @dev Returns the owner of the ERC-721 token which owns this account. By default, the owner - /// of the token has full permissions on the account. - function owner() public view returns (address) { - ( - uint256 chainId, - address tokenContract, - uint256 tokenId - ) = ERC6551AccountLib.token(); - - if (chainId != block.chainid) return address(0); - - return IERC721(tokenContract).ownerOf(tokenId); - } - - /// @dev Returns the authorization status for a given caller - function isAuthorized(address caller) public view returns (bool) { - ( - , - address tokenContract, - uint256 tokenId - ) = ERC6551AccountLib.token(); - address _owner = IERC721(tokenContract).ownerOf(tokenId); - - // authorize token owner - if (caller == _owner) return true; - - // authorize caller if owner has granted permissions - if (permissions[_owner][caller]) return true; - - return false; - } - - /// @dev Returns true if a given interfaceId is supported by this account. This method can be - /// extended by an override. - function supportsInterface(bytes4 interfaceId) - public - pure - override - returns (bool) - { - bool defaultSupport = interfaceId == type(IERC165).interfaceId || - interfaceId == type(IERC1155Receiver).interfaceId || - interfaceId == type(IERC6551Account).interfaceId; - - if (defaultSupport) return true; - - return false; - } - - /// @dev Allows ERC-721 tokens to be received so long as they do not cause an ownership cycle. - /// This function can be overriden. - function onERC721Received( - address, - address, - uint256 receivedTokenId, - bytes memory - ) public view override returns (bytes4) { - ( - uint256 chainId, - address tokenContract, - uint256 tokenId - ) = ERC6551AccountLib.token(); - - if ( - chainId == block.chainid && - tokenContract == msg.sender && - tokenId == receivedTokenId - ) revert OwnershipCycle(); - - return this.onERC721Received.selector; - } - - /// @dev Allows ERC-1155 tokens to be received. This function can be overriden. - function onERC1155Received( - address, - address, - uint256, - uint256, - bytes memory - ) public pure override returns (bytes4) { - return this.onERC1155Received.selector; - } - - /// @dev Allows ERC-1155 token batches to be received. This function can be overriden. - function onERC1155BatchReceived( - address, - address, - uint256[] memory, - uint256[] memory, - bytes memory - ) public pure override returns (bytes4) { - return this.onERC1155BatchReceived.selector; - } - - /// @dev Executes a low-level call - function _call( - address to, - uint256 value, - bytes calldata data - ) internal returns (bytes memory result) { - bool success; - (success, result) = to.call{value: value}(data); - - if (!success) { - assembly { - revert(add(result, 32), mload(result)) - } - } - } - - /// @dev Executes a low-level static call - function _callStatic(address to, bytes calldata data) - internal - view - returns (bytes memory result) - { - bool success; - (success, result) = to.staticcall(data); - - if (!success) { - assembly { - revert(add(result, 32), mload(result)) - } - } - } -} diff --git a/contracts/interfaces/IAccount.sol b/contracts/interfaces/IAccount.sol deleted file mode 100644 index da027ae..0000000 --- a/contracts/interfaces/IAccount.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -interface IAccount { - function owner() external view returns (address); - - function token() - external - view - returns (address tokenContract, uint256 tokenId); - - function executeCall( - address to, - uint256 value, - bytes calldata data - ) external payable returns (bytes memory); -} diff --git a/contracts/interfaces/IERC6551Account.sol b/contracts/interfaces/IERC6551Account.sol deleted file mode 100644 index 2f28589..0000000 --- a/contracts/interfaces/IERC6551Account.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -interface IERC6551AccountProxy { - function implementation() external view returns (address); -} - -/// @dev the ERC-165 identifier for this interface is `0xeff4d378` -interface IERC6551Account { - event TransactionExecuted(address indexed target, uint256 indexed value, bytes data); - - receive() external payable; - - function executeCall( - address to, - uint256 value, - bytes calldata data - ) external payable returns (bytes memory); - - function token() - external - view - returns (uint256 chainId, address tokenContract, uint256 tokenId); - - function owner() external view returns (address); -} diff --git a/contracts/interfaces/IRegistry.sol b/contracts/interfaces/IRegistry.sol deleted file mode 100644 index 664dab2..0000000 --- a/contracts/interfaces/IRegistry.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -interface IRegistry { - function createAccount( - address implementation, - uint256 chainId, - address tokenContract, - uint256 tokenId, - uint256 salt, - bytes calldata initData - ) external returns (address); - - function account( - address implementation, - uint256 chainId, - address tokenContract, - uint256 tokenId, - uint256 salt - ) external view returns (address); -} diff --git a/contracts/lib/ERC6551AccountLib.sol b/contracts/lib/ERC6551AccountLib.sol deleted file mode 100644 index 21c12ab..0000000 --- a/contracts/lib/ERC6551AccountLib.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -library ERC6551AccountLib { - function token() - internal - view - returns ( - uint256, - address, - uint256 - ) - { - bytes memory footer = new bytes(0x60); - - assembly { - // copy 0x60 bytes from end of footer - extcodecopy(address(), add(footer, 0x20), 0x4d, 0xad) - } - - return abi.decode(footer, (uint256, address, uint256)); - } - - function salt() internal view returns (uint256) { - bytes memory footer = new bytes(0x20); - - assembly { - // copy 0x20 bytes from beginning of footer - extcodecopy(address(), add(footer, 0x20), 0x2d, 0x4d) - } - - return abi.decode(footer, (uint256)); - } -} diff --git a/contracts/mock/NFTMock.sol b/contracts/mock/NFTMock.sol deleted file mode 100644 index b76875c..0000000 --- a/contracts/mock/NFTMock.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.8; - -import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; - -contract NFTMock is ERC721 { - // solhint-disable-next-line no-empty-blocks - constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) { - } - - function mint(address to, uint256 tokenId) external { - _mint(to, tokenId); - } -} \ No newline at end of file diff --git a/contracts/v1/ChargedManagers.sol b/contracts/v1/ChargedManagers.sol new file mode 100644 index 0000000..d3d79f6 --- /dev/null +++ b/contracts/v1/ChargedManagers.sol @@ -0,0 +1,414 @@ +// SPDX-License-Identifier: MIT + +// ChargedSettings.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol"; +import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; + +import "./interfaces/IChargedManagers.sol"; +import "./interfaces/IChargedSettings.sol"; +import "./interfaces/IChargedState.sol"; +import "./interfaces/ITokenInfoProxy.sol"; + +import "./lib/TokenInfo.sol"; +import "./lib/BlackholePrevention.sol"; + +/** + * @notice Charged Particles Wallet-Managers Contract + */ +contract ChargedManagers is + IChargedManagers, + Initializable, + OwnableUpgradeable, + BlackholePrevention +{ + using SafeMathUpgradeable for uint256; + using TokenInfo for address; + + IChargedSettings internal _chargedSettings; + IChargedState internal _chargedState; + ITokenInfoProxy internal _tokenInfoProxy; + + // Wallet/Basket Managers (by Unique Manager ID) + mapping (string => IWalletManager) internal _ftWalletManager; + mapping (string => IBasketManager) internal _nftBasketManager; + + + /***********************************| + | Initialization | + |__________________________________*/ + + function initialize(address initiator) public initializer { + __Ownable_init(); + emit Initialized(initiator); + } + + + /***********************************| + | Public | + |__________________________________*/ + + /// @notice Checks if an Account is the Owner of an NFT Contract + /// When Custom Contracts are registered, only the "owner" or operator of the Contract + /// is allowed to register them and define custom rules for how their tokens are "Charged". + /// Otherwise, any token can be "Charged" according to the default rules of Charged Particles. + /// @param contractAddress The Address to the External NFT Contract to check + /// @param account The Account to check if it is the Owner of the specified Contract + /// @return True if the account is the Owner of the _contract + function isContractOwner(address contractAddress, address account) external view override virtual returns (bool) { + return contractAddress.isContractOwner(account); + } + + function isWalletManagerEnabled(string calldata walletManagerId) external virtual override view returns (bool) { + return _isWalletManagerEnabled(walletManagerId); + } + + function getWalletManager(string calldata walletManagerId) external virtual override view returns (IWalletManager) { + return _ftWalletManager[walletManagerId]; + } + + function isNftBasketEnabled(string calldata basketId) external virtual override view returns (bool) { + return _isNftBasketEnabled(basketId); + } + + function getBasketManager(string calldata basketId) external virtual override view returns (IBasketManager) { + return _nftBasketManager[basketId]; + } + + /// @dev Validates a Deposit according to the rules set by the Token Contract + /// @param sender The sender address to validate against + /// @param contractAddress The Address to the Contract of the External NFT to check + /// @param tokenId The Token ID of the External NFT to check + /// @param walletManagerId The Wallet Manager of the Assets to Deposit + /// @param assetToken The Address of the Asset Token to Deposit + /// @param assetAmount The specific amount of Asset Token to Deposit + function validateDeposit( + address sender, + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken, + uint256 assetAmount + ) external virtual override { + _validateDeposit(sender, contractAddress, tokenId, walletManagerId, assetToken, assetAmount); + } + + /// @dev Validates an NFT Deposit according to the rules set by the Token Contract + /// @param sender The sender address to validate against + /// @param contractAddress The Address to the Contract of the External NFT to check + /// @param tokenId The Token ID of the External NFT to check + /// @param basketManagerId The Basket to Deposit the NFT into + /// @param nftTokenAddress The Address of the NFT Token being deposited + /// @param nftTokenId The ID of the NFT Token being deposited + /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific) + function validateNftDeposit( + address sender, + address contractAddress, + uint256 tokenId, + string calldata basketManagerId, + address nftTokenAddress, + uint256 nftTokenId, + uint256 nftTokenAmount + ) external virtual override { + _validateNftDeposit(sender, contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount); + } + + function validateDischarge(address sender, address contractAddress, uint256 tokenId) external virtual override { + _validateDischarge(sender, contractAddress, tokenId); + } + + function validateRelease(address sender, address contractAddress, uint256 tokenId) external virtual override { + _validateRelease(sender, contractAddress, tokenId); + } + + function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external virtual override { + _validateBreakBond(sender, contractAddress, tokenId); + } + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + /// @dev Setup the various Charged-Controllers + function setController(address controller, string calldata controllerId) external virtual onlyOwner { + bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId)); + + if (controllerIdStr == keccak256(abi.encodePacked("settings"))) { + _chargedSettings = IChargedSettings(controller); + } + else if (controllerIdStr == keccak256(abi.encodePacked("state"))) { + _chargedState = IChargedState(controller); + } + else if (controllerIdStr == keccak256(abi.encodePacked("tokeninfo"))) { + _tokenInfoProxy = ITokenInfoProxy(controller); + } + + emit ControllerSet(controller, controllerId); + } + + /// @dev Register Contracts as wallet managers with a unique liquidity provider ID + function registerWalletManager(string calldata walletManagerId, address walletManager) external virtual onlyOwner { + // Validate wallet manager + IWalletManager newWalletMgr = IWalletManager(walletManager); + require(newWalletMgr.isPaused() != true, "CP:E-418"); + + // Register LP ID + _ftWalletManager[walletManagerId] = newWalletMgr; + emit WalletManagerRegistered(walletManagerId, walletManager); + } + + /// @dev Register Contracts as basket managers with a unique basket ID + function registerBasketManager(string calldata basketId, address basketManager) external virtual onlyOwner { + // Validate basket manager + IBasketManager newBasketMgr = IBasketManager(basketManager); + require(newBasketMgr.isPaused() != true, "CP:E-418"); + + // Register Basket ID + _nftBasketManager[basketId] = newBasketMgr; + emit BasketManagerRegistered(basketId, basketManager); + } + + /***********************************| + | Only Admin/DAO | + | (blackhole prevention) | + |__________________________________*/ + + function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner { + _withdrawEther(receiver, amount); + } + + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner { + _withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner { + _withdrawERC1155(receiver, tokenAddress, tokenId, amount); + } + + /***********************************| + | Private Functions | + |__________________________________*/ + + /// @dev See {ChargedParticles-isWalletManagerEnabled}. + function _isWalletManagerEnabled(string calldata walletManagerId) internal view virtual returns (bool) { + return (address(_ftWalletManager[walletManagerId]) != address(0x0) && !_ftWalletManager[walletManagerId].isPaused()); + } + + /// @dev See {ChargedParticles-isNftBasketEnabled}. + function _isNftBasketEnabled(string calldata basketId) internal view virtual returns (bool) { + return (address(_nftBasketManager[basketId]) != address(0x0) && !_nftBasketManager[basketId].isPaused()); + } + + /// @dev Validates a Deposit according to the rules set by the Token Contract + /// @param contractAddress The Address to the Contract of the External NFT to check + /// @param tokenId The Token ID of the External NFT to check + /// @param walletManagerId The Wallet Manager of the Assets to Deposit + /// @param assetToken The Address of the Asset Token to Deposit + /// @param assetAmount The specific amount of Asset Token to Deposit + function _validateDeposit( + address sender, + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken, + uint256 assetAmount + ) + internal + virtual + { + if (_chargedState.isEnergizeRestricted(contractAddress, tokenId)) { + bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender); + require(isNFTOwnerOrOperator, "CP:E-105"); + } + + ( string memory requiredWalletManager, + bool energizeEnabled, + bool restrictedAssets, + bool validAsset, + uint256 depositCap, + uint256 depositMin, + uint256 depositMax, + bool invalidAsset + ) = _chargedSettings.getAssetRequirements(contractAddress, assetToken); + + require(energizeEnabled, "CP:E-417"); + + require(!invalidAsset, "CP:E-424"); + + // Valid Wallet Manager? + if (bytes(requiredWalletManager).length > 0) { + require(keccak256(abi.encodePacked(requiredWalletManager)) == keccak256(abi.encodePacked(walletManagerId)), "CP:E-419"); + } + + // Valid Asset? + if (restrictedAssets) { + require(validAsset, "CP:E-424"); + } + + _validateDepositAmount( + contractAddress, + tokenId, + walletManagerId, + assetToken, + assetAmount, + depositCap, + depositMin, + depositMax + ); + } + + /// @dev Validates a Deposit-Amount according to the rules set by the Token Contract + /// @param contractAddress The Address to the Contract of the External NFT to check + /// @param tokenId The Token ID of the External NFT to check + /// @param walletManagerId The Wallet Manager of the Assets to Deposit + /// @param assetToken The Address of the Asset Token to Deposit + /// @param assetAmount The specific amount of Asset Token to Deposit + function _validateDepositAmount( + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken, + uint256 assetAmount, + uint256 depositCap, + uint256 depositMin, + uint256 depositMax + ) + internal + virtual + { + uint256 existingBalance = _ftWalletManager[walletManagerId].getPrincipal(contractAddress, tokenId, assetToken); + uint256 newBalance = assetAmount.add(existingBalance); + + // Validate Deposit Cap + if (depositCap > 0) { + require(newBalance <= depositCap, "CP:E-408"); + } + + // Valid Amount for Deposit? + if (depositMin > 0) { + require(newBalance >= depositMin, "CP:E-410"); + } + if (depositMax > 0) { + require(newBalance <= depositMax, "CP:E-410"); + } + } + + /// @dev Validates an NFT Deposit according to the rules set by the Token Contract + /// @param contractAddress The Address to the Contract of the External NFT to check + /// @param tokenId The Token ID of the External NFT to check + /// @param basketManagerId The Basket to Deposit the NFT into + /// @param nftTokenAddress The Address of the NFT Token being deposited + /// @param nftTokenId The ID of the NFT Token being deposited + /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific) + function _validateNftDeposit( + address sender, + address contractAddress, + uint256 tokenId, + string calldata basketManagerId, + address nftTokenAddress, + uint256 nftTokenId, + uint256 nftTokenAmount + ) + internal + virtual + { + // Prevent Ouroboros NFTs + require(contractAddress.getTokenUUID(tokenId) != nftTokenAddress.getTokenUUID(nftTokenId), "CP:E-433"); + + if (_chargedState.isCovalentBondRestricted(contractAddress, tokenId)) { + bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender); + require(isNFTOwnerOrOperator, "CP:E-105"); + } + + ( string memory requiredBasketManager, + bool basketEnabled, + uint256 maxNfts + ) = _chargedSettings.getNftAssetRequirements(contractAddress, nftTokenAddress); + + require(basketEnabled, "CP:E-417"); + + // Valid Basket Manager? + if (bytes(requiredBasketManager).length > 0) { + require(keccak256(abi.encodePacked(requiredBasketManager)) == keccak256(abi.encodePacked(basketManagerId)), "CP:E-419"); + } + + if (maxNfts > 0) { + uint256 tokenCount = _nftBasketManager[basketManagerId].getTokenTotalCount(contractAddress, tokenId); + require(maxNfts >= (tokenCount + nftTokenAmount), "CP:E-427"); + } + } + + function _validateDischarge(address sender, address contractAddress, uint256 tokenId) internal virtual { + ( bool allowFromAll, + bool isApproved, + uint256 timelock, + uint256 tempLockExpiry + ) = _chargedState.getDischargeState(contractAddress, tokenId, sender); + _validateState(allowFromAll, isApproved, timelock, tempLockExpiry); + } + + function _validateRelease(address sender, address contractAddress, uint256 tokenId) internal virtual { + ( bool allowFromAll, + bool isApproved, + uint256 timelock, + uint256 tempLockExpiry + ) = _chargedState.getReleaseState(contractAddress, tokenId, sender); + _validateState(allowFromAll, isApproved, timelock, tempLockExpiry); + } + + function _validateBreakBond(address sender, address contractAddress, uint256 tokenId) internal virtual { + ( bool allowFromAll, + bool isApproved, + uint256 timelock, + uint256 tempLockExpiry + ) = _chargedState.getBreakBondState(contractAddress, tokenId, sender); + _validateState(allowFromAll, isApproved, timelock, tempLockExpiry); + } + + function _validateState( + bool allowFromAll, + bool isApproved, + uint256 timelock, + uint256 tempLockExpiry + ) + internal + view + virtual + { + if (!allowFromAll) { + require(isApproved, "CP:E-105"); + } + if (timelock > 0) { + require(block.number >= timelock, "CP:E-302"); + } + if (tempLockExpiry > 0) { + require(block.number >= tempLockExpiry, "CP:E-303"); + } + } +} diff --git a/contracts/v1/ChargedParticles.sol b/contracts/v1/ChargedParticles.sol new file mode 100755 index 0000000..8e04d48 --- /dev/null +++ b/contracts/v1/ChargedParticles.sol @@ -0,0 +1,946 @@ +// SPDX-License-Identifier: MIT + +// ChargedParticles.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol"; +import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol"; + +import "./interfaces/IUniverse.sol"; +import "./interfaces/IChargedState.sol"; +import "./interfaces/IChargedSettings.sol"; +import "./interfaces/IChargedManagers.sol"; +import "./interfaces/IChargedParticles.sol"; +import "./interfaces/IWalletManager.sol"; +import "./interfaces/IBasketManager.sol"; +import "./interfaces/ITokenInfoProxy.sol"; + +import "./lib/Bitwise.sol"; +import "./lib/RelayRecipient.sol"; + +import "./lib/BlackholePrevention.sol"; + +/** + * @notice Charged Particles V2 Contract + * @dev Upgradeable Contract + */ +contract ChargedParticles is + IChargedParticles, + Initializable, + OwnableUpgradeable, + ReentrancyGuardUpgradeable, + RelayRecipient, + IERC721ReceiverUpgradeable, + BlackholePrevention, + IERC1155ReceiverUpgradeable +{ + using SafeMathUpgradeable for uint256; + using SafeERC20Upgradeable for IERC20Upgradeable; + using Bitwise for uint32; + using AddressUpgradeable for address; + + uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%) + + // + // Particle Terminology + // + // Particle - Non-fungible Token (NFT) + // Mass - Underlying Asset of a Token (ex; DAI) + // Charge - Accrued Interest on the Underlying Asset of a Token + // Charged Particle - Any NFT that has a Mass and a Positive Charge + // Neutral Particle - Any NFT that has a Mass and No Charge + // Energize / Recharge - Deposit of an Underlying Asset into an NFT + // Discharge - Withdraw the Accrued Interest of an NFT leaving the Particle with its initial Mass + // Release - Withdraw the Underlying Asset & Accrued Interest of an NFT leaving the Particle with No Mass or Charge + // + // Proton - NFTs minted from the Charged Particle Accelerator + // - A proton is a subatomic particle, symbol p or p⁺, with a positive electric charge of +1e elementary + // charge and a mass slightly less than that of a neutron. + // Ion - Platform Governance Token + // - A charged subatomic particle. An atom or group of atoms that carries a positive or negative electric charge + // as a result of having lost or gained one or more electrons. + // + + // Linked Contracts + IUniverse internal _universe; + IChargedState internal _chargedState; + IChargedSettings internal _chargedSettings; + address internal _lepton; + uint256 internal depositFee; + ITokenInfoProxy internal _tokenInfoProxy; + IChargedManagers internal _chargedManagers; + + + /***********************************| + | Initialization | + |__________________________________*/ + + function initialize(address initiator) public initializer { + __Ownable_init(); + __ReentrancyGuard_init(); + emit Initialized(initiator); + } + + + /***********************************| + | Public Functions | + |__________________________________*/ + + function getStateAddress() external view virtual override returns (address stateAddress) { + return address(_chargedState); + } + + function getSettingsAddress() external view virtual override returns (address settingsAddress) { + return address(_chargedSettings); + } + + function getManagersAddress() external view virtual override returns (address managersAddress) { + return address(_chargedManagers); + } + + function onERC721Received(address, address, uint256, bytes calldata) external virtual override returns (bytes4) { + return IERC721ReceiverUpgradeable(0).onERC721Received.selector; + } + + function onERC1155Received(address, address, uint256, uint256, bytes calldata) external virtual override returns (bytes4) { + return IERC1155ReceiverUpgradeable(0).onERC1155Received.selector; + } + + // Unimplemented + function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external virtual override returns (bytes4) { + return ""; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector; + } + + function supportsInterface(bytes4 /* interfaceId */) external view virtual override returns (bool) { + return false; + } + + /// @notice Calculates the amount of Fees to be paid for a specific deposit amount + /// @param assetAmount The Amount of Assets to calculate Fees on + /// @return protocolFee The amount of deposit fees for the protocol + function getFeesForDeposit( + uint256 assetAmount + ) + external + override + view + returns (uint256 protocolFee) + { + protocolFee = _getFeesForDeposit(assetAmount); + } + + /// @notice Gets the Amount of Asset Tokens that have been Deposited into the Particle + /// representing the Mass of the Particle. + /// @param contractAddress The Address to the Contract of the Token + /// @param tokenId The ID of the Token + /// @param walletManagerId The Liquidity-Provider ID to check the Asset balance of + /// @param assetToken The Address of the Asset Token to check + /// @return The Amount of underlying Assets held within the Token + function baseParticleMass( + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken + ) + external + virtual + override + managerEnabled(walletManagerId) + returns (uint256) + { + return _baseParticleMass(contractAddress, tokenId, walletManagerId, assetToken); + } + + /// @notice Gets the amount of Interest that the Particle has generated representing + /// the Charge of the Particle + /// @param contractAddress The Address to the Contract of the Token + /// @param tokenId The ID of the Token + /// @param walletManagerId The Liquidity-Provider ID to check the Interest balance of + /// @param assetToken The Address of the Asset Token to check + /// @return The amount of interest the Token has generated (in Asset Token) + function currentParticleCharge( + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken + ) + external + virtual + override + managerEnabled(walletManagerId) + returns (uint256) + { + return _currentParticleCharge(contractAddress, tokenId, walletManagerId, assetToken); + } + + /// @notice Gets the amount of LP Tokens that the Particle has generated representing + /// the Kinetics of the Particle + /// @param contractAddress The Address to the Contract of the Token + /// @param tokenId The ID of the Token + /// @param walletManagerId The Liquidity-Provider ID to check the Kinetics balance of + /// @param assetToken The Address of the Asset Token to check + /// @return The amount of LP tokens that have been generated + function currentParticleKinetics( + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken + ) + external + virtual + override + managerEnabled(walletManagerId) + returns (uint256) + { + return _currentParticleKinetics(contractAddress, tokenId, walletManagerId, assetToken); + } + + /// @notice Gets the total amount of ERC721 Tokens that the Particle holds + /// @param contractAddress The Address to the Contract of the Token + /// @param tokenId The ID of the Token + /// @param basketManagerId The ID of the BasketManager to check the token balance of + /// @return The total amount of ERC721 tokens that are held within the Particle + function currentParticleCovalentBonds( + address contractAddress, + uint256 tokenId, + string calldata basketManagerId + ) + external + view + virtual + override + basketEnabled(basketManagerId) + returns (uint256) + { + return _currentParticleCovalentBonds(contractAddress, tokenId, basketManagerId); + } + + + /***********************************| + | Energize Particles | + |__________________________________*/ + + /// @notice Fund Particle with Asset Token + /// Must be called by the account providing the Asset + /// Account must Approve THIS contract as Operator of Asset + /// + /// NOTE: DO NOT Energize an ERC20 Token, as anyone who holds any amount + /// of the same ERC20 token could discharge or release the funds. + /// All holders of the ERC20 token would essentially be owners of the Charged Particle. + /// + /// @param contractAddress The Address to the Contract of the Token to Energize + /// @param tokenId The ID of the Token to Energize + /// @param walletManagerId The Asset-Pair to Energize the Token with + /// @param assetToken The Address of the Asset Token being used + /// @param assetAmount The Amount of Asset Token to Energize the Token with + /// @return yieldTokensAmount The amount of Yield-bearing Tokens added to the escrow for the Token + function energizeParticle( + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken, + uint256 assetAmount, + address referrer + ) + external + virtual + override + managerEnabled(walletManagerId) + nonReentrant + returns (uint256 yieldTokensAmount) + { + _validateDeposit(contractAddress, tokenId, walletManagerId, assetToken, assetAmount); + + // Transfer ERC20 Token from Caller to Contract (reverts on fail) + uint256 feeAmount = _collectAssetToken(_msgSender(), assetToken, assetAmount); + + // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager + yieldTokensAmount = _depositIntoWalletManager(contractAddress, tokenId, walletManagerId, assetToken, assetAmount, feeAmount); + + // Signal to Universe Controller + if (address(_universe) != address(0)) { + _universe.onEnergize(_msgSender(), referrer, contractAddress, tokenId, walletManagerId, assetToken, assetAmount); + } + } + + + /***********************************| + | Discharge Particles | + |__________________________________*/ + + /// @notice Allows the owner or operator of the Token to collect or transfer the interest generated + /// from the token without removing the underlying Asset that is held within the token. + /// @param receiver The Address to Receive the Discharged Asset Tokens + /// @param contractAddress The Address to the Contract of the Token to Discharge + /// @param tokenId The ID of the Token to Discharge + /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token + /// @param assetToken The Address of the Asset Token being discharged + /// @return creatorAmount Amount of Asset Token discharged to the Creator + /// @return receiverAmount Amount of Asset Token discharged to the Receiver + function dischargeParticle( + address receiver, + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken + ) + external + virtual + override + managerEnabled(walletManagerId) + nonReentrant + returns (uint256 creatorAmount, uint256 receiverAmount) + { + _validateDischarge(contractAddress, tokenId); + + address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId); + (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).discharge( + receiver, + contractAddress, + tokenId, + assetToken, + creatorRedirect + ); + + // Signal to Universe Controller + if (address(_universe) != address(0)) { + _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount); + } + } + + /// @notice Allows the owner or operator of the Token to collect or transfer a specific amount of the interest + /// generated from the token without removing the underlying Asset that is held within the token. + /// @param receiver The Address to Receive the Discharged Asset Tokens + /// @param contractAddress The Address to the Contract of the Token to Discharge + /// @param tokenId The ID of the Token to Discharge + /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token + /// @param assetToken The Address of the Asset Token being discharged + /// @param assetAmount The specific amount of Asset Token to Discharge from the Token + /// @return creatorAmount Amount of Asset Token discharged to the Creator + /// @return receiverAmount Amount of Asset Token discharged to the Receiver + function dischargeParticleAmount( + address receiver, + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken, + uint256 assetAmount + ) + external + virtual + override + managerEnabled(walletManagerId) + nonReentrant + returns (uint256 creatorAmount, uint256 receiverAmount) + { + _validateDischarge(contractAddress, tokenId); + + address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId); + (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).dischargeAmount( + receiver, + contractAddress, + tokenId, + assetToken, + assetAmount, + creatorRedirect + ); + + // Signal to Universe Controller + if (address(_universe) != address(0)) { + _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount); + } + } + + /// @notice Allows the Creator of the Token to collect or transfer a their portion of the interest (if any) + /// generated from the token without removing the underlying Asset that is held within the token. + /// @param receiver The Address to Receive the Discharged Asset Tokens + /// @param contractAddress The Address to the Contract of the Token to Discharge + /// @param tokenId The ID of the Token to Discharge + /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token + /// @param assetToken The Address of the Asset Token being discharged + /// @param assetAmount The specific amount of Asset Token to Discharge from the Particle + /// @return receiverAmount Amount of Asset Token discharged to the Receiver + function dischargeParticleForCreator( + address receiver, + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken, + uint256 assetAmount + ) + external + virtual + override + managerEnabled(walletManagerId) + nonReentrant + returns (uint256 receiverAmount) + { + address sender = _msgSender(); + address tokenCreator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId); + require(sender == tokenCreator, "CP:E-104"); + + receiverAmount = _chargedManagers.getWalletManager(walletManagerId).dischargeAmountForCreator( + receiver, + contractAddress, + tokenId, + sender, + assetToken, + assetAmount + ); + + // Signal to Universe Controller + if (address(_universe) != address(0)) { + _universe.onDischargeForCreator(contractAddress, tokenId, walletManagerId, sender, assetToken, receiverAmount); + } + } + + + /***********************************| + | Release Particles | + |__________________________________*/ + + /// @notice Releases the Full amount of Asset + Interest held within the Particle by LP of the Assets + /// @param receiver The Address to Receive the Released Asset Tokens + /// @param contractAddress The Address to the Contract of the Token to Release + /// @param tokenId The ID of the Token to Release + /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token + /// @param assetToken The Address of the Asset Token being released + /// @return creatorAmount Amount of Asset Token released to the Creator + /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount) + function releaseParticle( + address receiver, + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken + ) + external + virtual + override + managerEnabled(walletManagerId) + nonReentrant + returns (uint256 creatorAmount, uint256 receiverAmount) + { + _validateRelease(contractAddress, tokenId); + + // Release Particle to Receiver + uint256 principalAmount; + address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId); + (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).release( + receiver, + contractAddress, + tokenId, + assetToken, + creatorRedirect + ); + + // Signal to Universe Controller + if (address(_universe) != address(0)) { + _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount); + } + } + + + /// @notice Releases a partial amount of Asset + Interest held within the Particle by LP of the Assets + /// @param receiver The Address to Receive the Released Asset Tokens + /// @param contractAddress The Address to the Contract of the Token to Release + /// @param tokenId The ID of the Token to Release + /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token + /// @param assetToken The Address of the Asset Token being released + /// @param assetAmount The specific amount of Asset Token to Release from the Particle + /// @return creatorAmount Amount of Asset Token released to the Creator + /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount) + function releaseParticleAmount( + address receiver, + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken, + uint256 assetAmount + ) + external + virtual + override + managerEnabled(walletManagerId) + nonReentrant + returns (uint256 creatorAmount, uint256 receiverAmount) + { + _validateRelease(contractAddress, tokenId); + + // Release Particle to Receiver + uint256 principalAmount; + address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId); + (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).releaseAmount( + receiver, + contractAddress, + tokenId, + assetToken, + assetAmount, + creatorRedirect + ); + + // Signal to Universe Controller + if (address(_universe) != address(0)) { + _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount); + } + } + + + /***********************************| + | Covalent Bonding | + |__________________________________*/ + + /// @notice Deposit other NFT Assets into the Particle + /// Must be called by the account providing the Asset + /// Account must Approve THIS contract as Operator of Asset + /// + /// @param contractAddress The Address to the Contract of the Token to Energize + /// @param tokenId The ID of the Token to Energize + /// @param basketManagerId The Basket to Deposit the NFT into + /// @param nftTokenAddress The Address of the NFT Token being deposited + /// @param nftTokenId The ID of the NFT Token being deposited + /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific) + function covalentBond( + address contractAddress, + uint256 tokenId, + string calldata basketManagerId, + address nftTokenAddress, + uint256 nftTokenId, + uint256 nftTokenAmount + ) + external + virtual + override + basketEnabled(basketManagerId) + nonReentrant + returns (bool success) + { + _validateNftDeposit(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount); + + // Transfer ERC721 Token from Caller to Contract (reverts on fail) + _collectNftToken(_msgSender(), nftTokenAddress, nftTokenId, nftTokenAmount); + + // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager + success = _depositIntoBasketManager(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount); + + // Signal to Universe Controller + if (address(_universe) != address(0)) { + _universe.onCovalentBond(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount); + } + } + + /// @notice Release NFT Assets from the Particle + /// @param receiver The Address to Receive the Released Asset Tokens + /// @param contractAddress The Address to the Contract of the Token to Energize + /// @param tokenId The ID of the Token to Energize + /// @param basketManagerId The Basket to Deposit the NFT into + /// @param nftTokenAddress The Address of the NFT Token being deposited + /// @param nftTokenId The ID of the NFT Token being deposited + /// @param nftTokenAmount The amount of Tokens to Withdraw (ERC1155-specific) + function breakCovalentBond( + address receiver, + address contractAddress, + uint256 tokenId, + string calldata basketManagerId, + address nftTokenAddress, + uint256 nftTokenId, + uint256 nftTokenAmount + ) + external + virtual + override + basketEnabled(basketManagerId) + nonReentrant + returns (bool success) + { + _validateBreakBond(contractAddress, tokenId); + + IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId); + if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked("generic"))) { + basketMgr.prepareTransferAmount(nftTokenAmount); + } + + // Release Particle to Receiver + success = basketMgr.removeFromBasket( + receiver, + contractAddress, + tokenId, + nftTokenAddress, + nftTokenId + ); + + // Signal to Universe Controller + if (address(_universe) != address(0)) { + _universe.onCovalentBreak(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount); + } + } + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + /// @dev Setup the various Charged-Controllers + function setController(address controller, string calldata controllerId) external virtual onlyOwner { + bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId)); + + if (controllerIdStr == keccak256(abi.encodePacked("universe"))) { + _universe = IUniverse(controller); + } + else if (controllerIdStr == keccak256(abi.encodePacked("settings"))) { + _chargedSettings = IChargedSettings(controller); + } + else if (controllerIdStr == keccak256(abi.encodePacked("state"))) { + _chargedState = IChargedState(controller); + } + else if (controllerIdStr == keccak256(abi.encodePacked("managers"))) { + _chargedManagers = IChargedManagers(controller); + } + else if (controllerIdStr == keccak256(abi.encodePacked("leptons"))) { + _lepton = controller; + } + else if (controllerIdStr == keccak256(abi.encodePacked("forwarder"))) { + trustedForwarder = controller; + } + else if (controllerIdStr == keccak256(abi.encodePacked("tokeninfo"))) { + _tokenInfoProxy = ITokenInfoProxy(controller); + } + + emit ControllerSet(controller, controllerId); + } + + + /***********************************| + | Protocol Fees | + |__________________________________*/ + + /// @dev Setup the Base Deposit Fee for the Protocol + function setDepositFee(uint256 fee) external onlyOwner { + require(fee < PERCENTAGE_SCALE, "CP:E-421"); + depositFee = fee; + emit DepositFeeSet(fee); + } + + /***********************************| + | Only Admin/DAO | + | (blackhole prevention) | + |__________________________________*/ + + function withdrawEther(address payable receiver, uint256 amount) external onlyOwner { + _withdrawEther(receiver, amount); + } + + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner { + _withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner { + _withdrawERC1155(receiver, tokenAddress, tokenId, amount); + } + + + /***********************************| + | Private Functions | + |__________________________________*/ + + /// @dev Validates a Deposit according to the rules set by the Token Contract + /// @param contractAddress The Address to the Contract of the External NFT to check + /// @param tokenId The Token ID of the External NFT to check + /// @param walletManagerId The Wallet Manager of the Assets to Deposit + /// @param assetToken The Address of the Asset Token to Deposit + /// @param assetAmount The specific amount of Asset Token to Deposit + function _validateDeposit( + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken, + uint256 assetAmount + ) + internal + virtual + { + _chargedManagers.validateDeposit(_msgSender(), contractAddress, tokenId, walletManagerId, assetToken, assetAmount); + } + + /// @dev Validates an NFT Deposit according to the rules set by the Token Contract + /// @param contractAddress The Address to the Contract of the External NFT to check + /// @param tokenId The Token ID of the External NFT to check + /// @param basketManagerId The Basket to Deposit the NFT into + /// @param nftTokenAddress The Address of the NFT Token being deposited + /// @param nftTokenId The ID of the NFT Token being deposited + /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific) + function _validateNftDeposit( + address contractAddress, + uint256 tokenId, + string calldata basketManagerId, + address nftTokenAddress, + uint256 nftTokenId, + uint256 nftTokenAmount + ) + internal + virtual + { + _chargedManagers.validateNftDeposit(_msgSender(), contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount); + } + + function _validateDischarge(address contractAddress, uint256 tokenId) internal virtual { + _chargedManagers.validateDischarge(_msgSender(), contractAddress, tokenId); + } + + function _validateRelease(address contractAddress, uint256 tokenId) internal virtual { + _chargedManagers.validateRelease(_msgSender(), contractAddress, tokenId); + } + + function _validateBreakBond(address contractAddress, uint256 tokenId) internal virtual { + _chargedManagers.validateBreakBond(_msgSender(), contractAddress, tokenId); + } + + /// @dev Deposit Asset Tokens into an NFT via the Wallet Manager + /// @param contractAddress The Address to the Contract of the NFT + /// @param tokenId The Token ID of the NFT + /// @param walletManagerId The Wallet Manager of the Assets to Deposit + /// @param assetToken The Address of the Asset Token to Deposit + /// @param assetAmount The specific amount of Asset Token to Deposit + /// @param feeAmount The Amount of Protocol Fees charged + function _depositIntoWalletManager( + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken, + uint256 assetAmount, + uint256 feeAmount + ) + internal + virtual + returns (uint256) + { + // Get Wallet-Manager for LP + IWalletManager lpWalletMgr = _chargedManagers.getWalletManager(walletManagerId); + + (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId); + + // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager + address wallet = lpWalletMgr.getWalletAddressById(contractAddress, tokenId, creator, annuityPct); + IERC20Upgradeable(assetToken).transfer(wallet, assetAmount); + + emit ProtocolFeesCollected(assetToken, assetAmount, feeAmount); + + return lpWalletMgr.energize(contractAddress, tokenId, assetToken, assetAmount); + } + + /// @dev Deposit NFT Tokens into the Basket Manager + /// @param contractAddress The Address to the Contract of the NFT + /// @param tokenId The Token ID of the NFT + /// @param basketManagerId The Wallet Manager of the Assets to Deposit + /// @param nftTokenAddress The Address of the Asset Token to Deposit + /// @param nftTokenId The specific amount of Asset Token to Deposit + /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific) + function _depositIntoBasketManager( + address contractAddress, + uint256 tokenId, + string calldata basketManagerId, + address nftTokenAddress, + uint256 nftTokenId, + uint256 nftTokenAmount + ) + internal + virtual + returns (bool) + { + // Deposit NFT Token directly into Smart Wallet (reverts on fail) and Update BasketManager + IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId); + address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId); + + if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked("generic"))) { + basketMgr.prepareTransferAmount(nftTokenAmount); + } + + if (_isERC1155(nftTokenAddress)) { + if (nftTokenAmount == 0) { nftTokenAmount = 1; } + IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(address(this), wallet, nftTokenId, nftTokenAmount, ""); + } else { + IERC721Upgradeable(nftTokenAddress).transferFrom(address(this), wallet, nftTokenId); + } + return basketMgr.addToBasket(contractAddress, tokenId, nftTokenAddress, nftTokenId); + } + + /** + * @dev Calculates the amount of Fees to be paid for a specific deposit amount + * Fees are calculated in Interest-Token as they are the type collected for Fees + * @param assetAmount The Amount of Assets to calculate Fees on + * @return protocolFee The amount of fees reserved for the protocol + */ + function _getFeesForDeposit( + uint256 assetAmount + ) + internal + view + returns (uint256 protocolFee) + { + if (depositFee > 0) { + protocolFee = assetAmount.mul(depositFee).div(PERCENTAGE_SCALE); + } + } + + /// @dev Collects the Required ERC20 Token(s) from the users wallet + /// Be sure to Approve this Contract to transfer your Token(s) + /// @param from The owner address to collect the tokens from + /// @param tokenAddress The addres of the token to transfer + /// @param tokenAmount The amount of tokens to collect + function _collectAssetToken(address from, address tokenAddress, uint256 tokenAmount) internal virtual returns (uint256 protocolFee) { + protocolFee = _getFeesForDeposit(tokenAmount); + IERC20Upgradeable(tokenAddress).safeTransferFrom(from, address(this), tokenAmount.add(protocolFee)); + } + + /// @dev Collects the Required ERC721 Token(s) from the users wallet + /// Be sure to Approve this Contract to transfer your Token(s) + /// @param from The owner address to collect the tokens from + /// @param nftTokenAddress The address of the NFT token to transfer + /// @param nftTokenId The ID of the NFT token to transfer + /// @param nftTokenAmount The amount of Tokens to Transfer (ERC1155-specific) + function _collectNftToken(address from, address nftTokenAddress, uint256 nftTokenId, uint256 nftTokenAmount) internal virtual { + if (_isERC1155(nftTokenAddress)) { + IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId, nftTokenAmount, ""); + } else { + IERC721Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId); + } + } + + /// @dev Checks if an NFT token contract supports the ERC1155 standard interface + function _isERC1155(address nftTokenAddress) internal view virtual returns (bool) { + bytes4 _INTERFACE_ID_ERC1155 = 0xd9b67a26; + return IERC165Upgradeable(nftTokenAddress).supportsInterface(_INTERFACE_ID_ERC1155); + } + + /// @dev See {ChargedParticles-baseParticleMass}. + function _baseParticleMass( + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken + ) + internal + virtual + returns (uint256) + { + return _chargedManagers.getWalletManager(walletManagerId).getPrincipal(contractAddress, tokenId, assetToken); + } + + /// @dev See {ChargedParticles-currentParticleCharge}. + function _currentParticleCharge( + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken + ) + internal + virtual + returns (uint256) + { + (, uint256 ownerInterest) = _chargedManagers.getWalletManager(walletManagerId).getInterest(contractAddress, tokenId, assetToken); + return ownerInterest; + } + + /// @dev See {ChargedParticles-currentParticleKinetics}. + function _currentParticleKinetics( + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken + ) + internal + virtual + returns (uint256) + { + return _chargedManagers.getWalletManager(walletManagerId).getRewards(contractAddress, tokenId, assetToken); + } + + /// @dev See {ChargedParticles-currentParticleCovalentBonds}. + function _currentParticleCovalentBonds( + address contractAddress, + uint256 tokenId, + string calldata basketManagerId + ) + internal + view + virtual + returns (uint256) + { + return _chargedManagers.getBasketManager(basketManagerId).getTokenTotalCount(contractAddress, tokenId); + } + + + /***********************************| + | GSN/MetaTx Relay | + |__________________________________*/ + + /// @dev See {BaseRelayRecipient-_msgSender}. + function _msgSender() + internal + view + virtual + override(BaseRelayRecipient, ContextUpgradeable) + returns (address payable) + { + return BaseRelayRecipient._msgSender(); + } + + /// @dev See {BaseRelayRecipient-_msgData}. + function _msgData() + internal + view + virtual + override(BaseRelayRecipient, ContextUpgradeable) + returns (bytes memory) + { + return BaseRelayRecipient._msgData(); + } + + + /***********************************| + | Modifiers | + |__________________________________*/ + + modifier managerEnabled(string calldata walletManagerId) { + require(_chargedManagers.isWalletManagerEnabled(walletManagerId), "CP:E-419"); + _; + } + + modifier basketEnabled(string calldata basketManagerId) { + require(_chargedManagers.isNftBasketEnabled(basketManagerId), "CP:E-419"); + _; + } +} diff --git a/contracts/v1/ChargedSettings.sol b/contracts/v1/ChargedSettings.sol new file mode 100644 index 0000000..d47d91d --- /dev/null +++ b/contracts/v1/ChargedSettings.sol @@ -0,0 +1,641 @@ +// SPDX-License-Identifier: MIT + +// ChargedSettings.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol"; +import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; + +import "./interfaces/IChargedSettings.sol"; +import "./interfaces/ITokenInfoProxy.sol"; + +import "./lib/Bitwise.sol"; +import "./lib/TokenInfo.sol"; +import "./lib/RelayRecipient.sol"; +import "./lib/BlackholePrevention.sol"; + +import "./lib/TokenInfoProxy.sol"; + +/** + * @notice Charged Particles Settings Contract + */ +contract ChargedSettings is + IChargedSettings, + Initializable, + OwnableUpgradeable, + RelayRecipient, + BlackholePrevention +{ + using SafeMathUpgradeable for uint256; + using TokenInfo for address; + using Bitwise for uint32; + + uint256 constant internal MAX_ANNUITIES = 1e4; // 10000 (100%) + + // NftSettings - actionPerms + uint32 constant internal PERM_CHARGE_NFT = 1; // NFT Contracts that can have assets Deposited into them (Charged) + uint32 constant internal PERM_BASKET_NFT = 2; // NFT Contracts that can have other NFTs Deposited into them + uint32 constant internal PERM_TIMELOCK_ANY_NFT = 4; // NFT Contracts that can timelock any NFT on behalf of users (primarily used for Front-run Protection) + uint32 constant internal PERM_TIMELOCK_OWN_NFT = 8; // NFT Contracts that can timelock their own NFTs on behalf of their users + uint32 constant internal PERM_RESTRICTED_ASSETS = 16; // NFT Contracts that have restricted deposits to specific assets + + ITokenInfoProxy internal _tokenInfoProxy; + + // Current Settings for External NFT Token Contracts; + // - Any user can add any ERC721 or ERC1155 token as a Charged Particle without Limits, + // unless the Owner of the ERC721 or ERC1155 token contract registers the token + // and sets the Custom Settings for their token(s) + mapping (address => uint32) internal _nftActionPerms; + + mapping (address => string) internal _nftRequiredWalletManager; + mapping (address => string) internal _nftRequiredBasketManager; + + // ERC20 + mapping (address => mapping(address => bool)) internal _nftAllowedAssetTokens; + mapping (address => mapping (address => uint256)) internal _nftDepositMin; + mapping (address => mapping (address => uint256)) internal _nftDepositMax; + + // ERC721 / ERC1155 + mapping (address => mapping (address => uint256)) internal _nftMaxNfts; // NFT Token Address => Max + + // Optional Configs for individual NFTs set by NFT Creator (by Token UUID) + mapping (uint256 => uint256) internal _creatorAnnuityPercent; + mapping (uint256 => address) internal _creatorAnnuityRedirect; + + mapping (address => uint256) internal _depositCap; + uint256 internal _tempLockExpiryBlocks; + + // Blacklist for non-compliant tokens + mapping (address => bool) internal _invalidAssets; + + + /***********************************| + | Initialization | + |__________________________________*/ + + function initialize(address initiator) public initializer { + __Ownable_init(); + emit Initialized(initiator); + } + + + /***********************************| + | Public | + |__________________________________*/ + + /// @dev Gets the amount of creator annuities reserved for the creator for the specified NFT + /// @param contractAddress The Address to the Contract of the NFT + /// @param tokenId The Token ID of the NFT + /// @return creator The address of the creator + /// @return annuityPct The percentage amount of annuities reserved for the creator + function getCreatorAnnuities( + address contractAddress, + uint256 tokenId + ) + external + override + virtual + returns (address creator, uint256 annuityPct) + { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + creator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId); + annuityPct = _creatorAnnuityPercent[tokenUuid]; + } + + function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId) + external + view + override + virtual + returns (address) + { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + return _creatorAnnuityRedirect[tokenUuid]; + } + + function getTempLockExpiryBlocks() external view override virtual returns (uint256) { + return _tempLockExpiryBlocks; + } + + function getTimelockApprovals(address operator) + external + view + override + virtual + returns (bool timelockAny, bool timelockOwn) + { + timelockAny = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_ANY_NFT); + timelockOwn = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_OWN_NFT); + } + + function getAssetRequirements(address contractAddress, address assetToken) + external + view + override + virtual + returns ( + string memory requiredWalletManager, + bool energizeEnabled, + bool restrictedAssets, + bool validAsset, + uint256 depositCap, + uint256 depositMin, + uint256 depositMax, + bool invalidAsset + ) + { + requiredWalletManager = _nftRequiredWalletManager[contractAddress]; + energizeEnabled = _nftActionPerms[contractAddress].hasBit(PERM_CHARGE_NFT); + restrictedAssets = _nftActionPerms[contractAddress].hasBit(PERM_RESTRICTED_ASSETS); + validAsset = _nftAllowedAssetTokens[contractAddress][assetToken]; + depositCap = _depositCap[assetToken]; + depositMin = _nftDepositMin[contractAddress][assetToken]; + depositMax = _nftDepositMax[contractAddress][assetToken]; + invalidAsset = _invalidAssets[assetToken]; + } + + function getNftAssetRequirements(address contractAddress, address nftTokenAddress) + external + view + override + virtual + returns (string memory requiredBasketManager, bool basketEnabled, uint256 maxNfts) + { + requiredBasketManager = _nftRequiredBasketManager[contractAddress]; + basketEnabled = _nftActionPerms[contractAddress].hasBit(PERM_BASKET_NFT); + maxNfts = _nftMaxNfts[contractAddress][nftTokenAddress]; + } + + + /***********************************| + | Only NFT Creator | + |__________________________________*/ + + /// @notice Sets the Custom Configuration for Creators of Proton-based NFTs + /// @param contractAddress The Address to the Proton-based NFT to configure + /// @param tokenId The token ID of the Proton-based NFT to configure + /// @param creator The creator of the Proton-based NFT + /// @param annuityPercent The percentage of interest-annuities to reserve for the creator + function setCreatorAnnuities( + address contractAddress, + uint256 tokenId, + address creator, + uint256 annuityPercent + ) + external + virtual + override + { + require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), "CP:E-104"); + _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent); + } + + /// @notice Sets a Custom Receiver Address for the Creator Annuities + /// @param contractAddress The Address to the Proton-based NFT to configure + /// @param tokenId The token ID of the Proton-based NFT to configure + /// @param receiver The receiver of the Creator interest-annuities + function setCreatorAnnuitiesRedirect( + address contractAddress, + uint256 tokenId, + address receiver + ) + external + virtual + override + { + require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), "CP:E-104"); + _setCreatorAnnuitiesRedirect(contractAddress, tokenId, receiver); + } + + + /***********************************| + | Register Contract Settings | + |(For External Contract Integration)| + |__________________________________*/ + + /// @notice Sets a Required Wallet-Manager for External NFT Contracts (otherwise set to "none" to allow any Wallet-Manager) + /// @param contractAddress The Address to the External NFT Contract to configure + /// @param walletManager If set, will only allow deposits from this specific Wallet-Manager + function setRequiredWalletManager( + address contractAddress, + string calldata walletManager + ) + external + virtual + override + onlyValidExternalContract(contractAddress) + onlyContractOwnerOrAdmin(contractAddress, msg.sender) + { + // Update Configs for External Token Contract + if (keccak256(bytes(walletManager)) == keccak256(bytes("none"))) { + _nftRequiredWalletManager[contractAddress] = ""; + } else { + _nftRequiredWalletManager[contractAddress] = walletManager; + } + + emit RequiredWalletManagerSet( + contractAddress, + walletManager + ); + } + + /// @notice Sets a Required Basket-Manager for External NFT Contracts (otherwise set to "none" to allow any Basket-Manager) + /// @param contractAddress The Address to the External Contract to configure + /// @param basketManager If set, will only allow deposits from this specific Basket-Manager + function setRequiredBasketManager( + address contractAddress, + string calldata basketManager + ) + external + virtual + override + onlyValidExternalContract(contractAddress) + onlyContractOwnerOrAdmin(contractAddress, msg.sender) + { + // Update Configs for External Token Contract + if (keccak256(bytes(basketManager)) == keccak256(bytes("none"))) { + _nftRequiredBasketManager[contractAddress] = ""; + } else { + _nftRequiredBasketManager[contractAddress] = basketManager; + } + + emit RequiredBasketManagerSet( + contractAddress, + basketManager + ); + } + + /// @notice Enables or Disables Asset-Token Restrictions for External NFT Contracts + /// @param contractAddress The Address to the External NFT Contract to configure + /// @param restrictionsEnabled If set, will only allow deposits from Allowed Asset Tokens + function setAssetTokenRestrictions( + address contractAddress, + bool restrictionsEnabled + ) + external + virtual + override + onlyValidExternalContract(contractAddress) + onlyContractOwnerOrAdmin(contractAddress, msg.sender) + { + // Update Configs for External Token Contract + if (restrictionsEnabled) { + _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_RESTRICTED_ASSETS); + } else { + _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_RESTRICTED_ASSETS); + } + + emit AssetTokenRestrictionsSet( + contractAddress, + restrictionsEnabled + ); + } + + /// @notice Enables or Disables Allowed Asset Tokens for External NFT Contracts + /// @param contractAddress The Address to the External NFT Contract to configure + /// @param assetToken The Address of the Asset Token to Allow or Disallow + /// @param isAllowed True if the Asset Token is allowed + function setAllowedAssetToken( + address contractAddress, + address assetToken, + bool isAllowed + ) + external + virtual + override + onlyValidExternalContract(contractAddress) + onlyContractOwnerOrAdmin(contractAddress, msg.sender) + { + // Update Configs for External Token Contract + _nftAllowedAssetTokens[contractAddress][assetToken] = isAllowed; + + emit AllowedAssetTokenSet( + contractAddress, + assetToken, + isAllowed + ); + } + + /// @notice Sets the Custom Configuration for External Contracts + /// @param contractAddress The Address to the External Contract to configure + /// @param assetToken The address of the Asset Token to set Limits for + /// @param depositMin If set, will define the minimum amount of Asset tokens the NFT may hold, otherwise any amount + /// @param depositMax If set, will define the maximum amount of Asset tokens the NFT may hold, otherwise any amount + function setAssetTokenLimits( + address contractAddress, + address assetToken, + uint256 depositMin, + uint256 depositMax + ) + external + virtual + override + onlyValidExternalContract(contractAddress) + onlyContractOwnerOrAdmin(contractAddress, msg.sender) + { + // Update Configs for External Token Contract + _nftDepositMin[contractAddress][assetToken] = depositMin; + _nftDepositMax[contractAddress][assetToken] = depositMax; + + emit AssetTokenLimitsSet( + contractAddress, + assetToken, + depositMin, + depositMax + ); + } + + /// @notice Sets the Max Number of NFTs that can be held by a Charged Particle NFT + /// @param contractAddress The Address to the External Contract to configure + /// @param nftTokenAddress The address of the NFT Token to set a Max for + /// @param maxNfts The maximum numbers of NFTs that can be held by a given NFT (0 = unlimited) + function setMaxNfts( + address contractAddress, + address nftTokenAddress, + uint256 maxNfts + ) + external + virtual + override + onlyValidExternalContract(contractAddress) + onlyContractOwnerOrAdmin(contractAddress, msg.sender) + { + // Update Configs for External Token Contract + _nftMaxNfts[contractAddress][nftTokenAddress] = maxNfts; + + emit MaxNftsSet( + contractAddress, + nftTokenAddress, + maxNfts + ); + } + + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + /// @dev Setup the various Charged-Controllers + function setController(address controller, string calldata controllerId) external virtual onlyOwner { + bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId)); + + if (controllerIdStr == keccak256(abi.encodePacked("tokeninfo"))) { + _tokenInfoProxy = ITokenInfoProxy(controller); + } + + emit ControllerSet(controller, controllerId); + } + + function setTrustedForwarder(address _trustedForwarder) external onlyOwner { + trustedForwarder = _trustedForwarder; + } + + function setAssetInvalidity(address assetToken, bool invalidity) external virtual override onlyOwner { + _invalidAssets[assetToken] = invalidity; + emit AssetInvaliditySet(assetToken, invalidity); + } + + function setDepositCap(address assetToken, uint256 cap) external virtual onlyOwner { + _depositCap[assetToken] = cap; + emit DepositCapSet(assetToken, cap); + } + + function setTempLockExpiryBlocks(uint256 numBlocks) external virtual onlyOwner { + _tempLockExpiryBlocks = numBlocks; + emit TempLockExpirySet(numBlocks); + } + + function enableNftContracts(address[] calldata contracts) external override virtual onlyOwner { + uint count = contracts.length; + for (uint i = 0; i < count; i++) { + address tokenContract = contracts[i]; + _setPermsForCharge(tokenContract, true); + _setPermsForBasket(tokenContract, true); + _setPermsForTimelockSelf(tokenContract, true); + } + } + + function migrateToken( + address contractAddress, + uint256 tokenId, + address creator, + uint256 annuityPercent, + address annuityReceiver + ) + external + onlyOwner + { + _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent); + if (annuityReceiver != address(0)) { + _setCreatorAnnuitiesRedirect(contractAddress, tokenId, annuityReceiver); + } + } + + /// @dev Update the list of NFT contracts that can be Charged + function setPermsForCharge(address contractAddress, bool state) + external + override + virtual + onlyOwner + { + _setPermsForCharge(contractAddress, state); + } + + /// @dev Update the list of NFT contracts that can hold other NFTs + function setPermsForBasket(address contractAddress, bool state) + external + override + virtual + onlyOwner + { + _setPermsForBasket(contractAddress, state); + } + + /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection + function setPermsForTimelockAny(address contractAddress, bool state) + external + override + virtual + onlyOwner + { + _setPermsForTimelockAny(contractAddress, state); + } + + /// @dev Update the list of NFT contracts that can Timelock their own tokens + function setPermsForTimelockSelf(address contractAddress, bool state) + external + override + virtual + onlyOwner + { + _setPermsForTimelockSelf(contractAddress, state); + } + + + /***********************************| + | Only Admin/DAO | + | (blackhole prevention) | + |__________________________________*/ + + function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner { + _withdrawEther(receiver, amount); + } + + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner { + _withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner { + _withdrawERC1155(receiver, tokenAddress, tokenId, amount); + } + + + /***********************************| + | Private Functions | + |__________________________________*/ + + /// @dev Update the list of NFT contracts that can be Charged + function _setPermsForCharge(address contractAddress, bool state) internal virtual { + if (state) { + _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_CHARGE_NFT); + } else { + _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_CHARGE_NFT); + } + emit PermsSetForCharge(contractAddress, state); + } + + /// @dev Update the list of NFT contracts that can hold other NFTs + function _setPermsForBasket(address contractAddress, bool state) internal virtual { + if (state) { + _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_BASKET_NFT); + } else { + _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_BASKET_NFT); + } + emit PermsSetForBasket(contractAddress, state); + } + + /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection + function _setPermsForTimelockAny(address contractAddress, bool state) internal virtual { + if (state) { + _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_ANY_NFT); + } else { + _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_ANY_NFT); + } + emit PermsSetForTimelockAny(contractAddress, state); + } + + /// @dev Update the list of NFT contracts that can Timelock their own tokens + function _setPermsForTimelockSelf(address contractAddress, bool state) internal virtual { + if (state) { + _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_OWN_NFT); + } else { + _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_OWN_NFT); + } + emit PermsSetForTimelockSelf(contractAddress, state); + } + + /// @dev see setCreatorAnnuities() + function _setCreatorAnnuities( + address contractAddress, + uint256 tokenId, + address creator, + uint256 annuityPercent + ) + internal + virtual + { + require(annuityPercent <= MAX_ANNUITIES, "CP:E-421"); + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + + // Update Configs for External Token Creator + _creatorAnnuityPercent[tokenUuid] = annuityPercent; + + emit TokenCreatorConfigsSet( + contractAddress, + tokenId, + creator, + annuityPercent + ); + } + + /// @dev see setCreatorAnnuitiesRedirect() + function _setCreatorAnnuitiesRedirect( + address contractAddress, + uint256 tokenId, + address receiver + ) + internal + virtual + { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + _creatorAnnuityRedirect[tokenUuid] = receiver; + emit TokenCreatorAnnuitiesRedirected(contractAddress, tokenId, receiver); + } + + + /***********************************| + | GSN/MetaTx Relay | + |__________________________________*/ + + /// @dev See {BaseRelayRecipient-_msgSender}. + function _msgSender() + internal + view + virtual + override(BaseRelayRecipient, ContextUpgradeable) + returns (address payable) + { + return BaseRelayRecipient._msgSender(); + } + + /// @dev See {BaseRelayRecipient-_msgData}. + function _msgData() + internal + view + virtual + override(BaseRelayRecipient, ContextUpgradeable) + returns (bytes memory) + { + return BaseRelayRecipient._msgData(); + } + + + /***********************************| + | Modifiers | + |__________________________________*/ + + modifier onlyValidExternalContract(address contractAddress) { + require(contractAddress.isContract(), "CP:E-420"); + _; + } + + modifier onlyContractOwnerOrAdmin(address contractAddress, address sender) { + require(sender == owner() || contractAddress.isContractOwner(sender), "CP:E-103"); + _; + } +} diff --git a/contracts/v1/ChargedState.sol b/contracts/v1/ChargedState.sol new file mode 100644 index 0000000..3d9eb4a --- /dev/null +++ b/contracts/v1/ChargedState.sol @@ -0,0 +1,808 @@ +// SPDX-License-Identifier: MIT + +// ChargedState.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol"; +import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; + +import "./interfaces/IChargedState.sol"; +import "./interfaces/ITokenInfoProxy.sol"; + +import "./lib/Bitwise.sol"; +import "./lib/TokenInfo.sol"; +import "./lib/RelayRecipient.sol"; +import "./lib/BlackholePrevention.sol"; + +/** + * @notice Charged Particles Settings Contract + */ +contract ChargedState is + IChargedState, + Initializable, + OwnableUpgradeable, + RelayRecipient, + BlackholePrevention +{ + using SafeMathUpgradeable for uint256; + using TokenInfo for address; + using Bitwise for uint32; + + // NftState - actionPerms + uint32 constant internal PERM_RESTRICT_ENERGIZE_FROM_ALL = 1; // NFTs that have Restrictions on Energize + uint32 constant internal PERM_ALLOW_DISCHARGE_FROM_ALL = 2; // NFTs that allow Discharge by anyone + uint32 constant internal PERM_ALLOW_RELEASE_FROM_ALL = 4; // NFTs that allow Release by anyone + uint32 constant internal PERM_RESTRICT_BOND_FROM_ALL = 8; // NFTs that have Restrictions on Covalent Bonds + uint32 constant internal PERM_ALLOW_BREAK_BOND_FROM_ALL = 16; // NFTs that allow Breaking Covalent Bonds by anyone + + IChargedSettings internal _chargedSettings; + ITokenInfoProxy internal _tokenInfoProxy; + + // NftTimelocks + /// @dev discharge unlockBlock and lockedBy + mapping (uint256 => uint256) internal _nftDischargeTimelockUnlockBlock; + mapping (uint256 => address) internal _nftDischargeTimelockLockedBy; + + /// @dev release unlockBlock and lockedBy + mapping (uint256 => uint256) internal _nftReleaseTimelockUnlockBlock; + mapping (uint256 => address) internal _nftReleaseTimelockLockedBy; + + /// @dev release unlockBlock and lockedBy + mapping (uint256 => uint256) internal _nftBreakBondTimelockUnlockBlock; + mapping (uint256 => address) internal _nftBreakBondTimelockLockedBy; + + // NftState + /// @dev maps nft by tokenId to actionPermissions uint32 which is a composite of all possible NftState - actionPerms + mapping (uint256 => uint32) internal _nftActionPerms; + + /// @dev maps nft by tokenId to its tempLockExpiry + mapping (uint256 => uint256) internal _nftTempLockExpiry; + + /// @dev maps tokenId to user address to operator address for approving various actions + mapping (uint256 => mapping(address => address)) internal _nftDischargeApproval; + mapping (uint256 => mapping(address => address)) internal _nftReleaseApproval; + mapping (uint256 => mapping(address => address)) internal _nftBreakBondApproval; + mapping (uint256 => mapping(address => address)) internal _nftTimelockApproval; + + + /***********************************| + | Initialization | + |__________________________________*/ + + function initialize(address initiator) public initializer { + __Ownable_init(); + emit Initialized(initiator); + } + + /***********************************| + | Public | + |__________________________________*/ + + function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + + if (_nftDischargeTimelockUnlockBlock[tokenUuid] > block.number) { + lockExpiry = _nftDischargeTimelockUnlockBlock[tokenUuid]; + } + if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) { + lockExpiry = _nftTempLockExpiry[tokenUuid]; + } + } + + function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + + if (_nftReleaseTimelockUnlockBlock[tokenUuid] > block.number) { + lockExpiry = _nftReleaseTimelockUnlockBlock[tokenUuid]; + } + if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) { + lockExpiry = _nftTempLockExpiry[tokenUuid]; + } + } + + function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + + if (_nftBreakBondTimelockUnlockBlock[tokenUuid] > block.number) { + lockExpiry = _nftBreakBondTimelockUnlockBlock[tokenUuid]; + } + if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) { + lockExpiry = _nftTempLockExpiry[tokenUuid]; + } + } + + + /// @notice Checks if an operator is allowed to Discharge a specific Token + /// @param contractAddress The Address to the Contract of the Token + /// @param tokenId The ID of the Token + /// @param operator The Address of the operator to check + /// @return True if the operator is Approved + function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) { + return _isApprovedForDischarge(contractAddress, tokenId, operator); + } + + /// @notice Checks if an operator is allowed to Release a specific Token + /// @param contractAddress The Address to the Contract of the Token + /// @param tokenId The ID of the Token + /// @param operator The Address of the operator to check + /// @return True if the operator is Approved + function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) { + return _isApprovedForRelease(contractAddress, tokenId, operator); + } + + /// @notice Checks if an operator is allowed to Break Covalent Bonds on a specific Token + /// @param contractAddress The Address to the Contract of the Token + /// @param tokenId The ID of the Token + /// @param operator The Address of the operator to check + /// @return True if the operator is Approved + function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) { + return _isApprovedForBreakBond(contractAddress, tokenId, operator); + } + + /// @notice Checks if an operator is allowed to Timelock a specific Token + /// @param contractAddress The Address to the Contract of the Token + /// @param tokenId The ID of the Token + /// @param operator The Address of the operator to check + /// @return True if the operator is Approved + function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) { + return _isApprovedForTimelock(contractAddress, tokenId, operator); + } + + + function isEnergizeRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_ENERGIZE_FROM_ALL); + } + + + function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_BOND_FROM_ALL); + } + + + function getDischargeState(address contractAddress, uint256 tokenId, address sender) + external + virtual + override + returns ( + bool allowFromAll, + bool isApproved, + uint256 timelock, + uint256 tempLockExpiry + ) + { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_DISCHARGE_FROM_ALL); + isApproved = _isApprovedForDischarge(contractAddress, tokenId, sender); + timelock = _nftDischargeTimelockUnlockBlock[tokenUuid]; + tempLockExpiry = _nftTempLockExpiry[tokenUuid]; + } + + + + function getReleaseState(address contractAddress, uint256 tokenId, address sender) + external + virtual + override + returns ( + bool allowFromAll, + bool isApproved, + uint256 timelock, + uint256 tempLockExpiry + ) + { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_RELEASE_FROM_ALL); + isApproved = _isApprovedForRelease(contractAddress, tokenId, sender); + timelock = _nftReleaseTimelockUnlockBlock[tokenUuid]; + tempLockExpiry = _nftTempLockExpiry[tokenUuid]; + } + + + + function getBreakBondState(address contractAddress, uint256 tokenId, address sender) + external + virtual + override + returns ( + bool allowFromAll, + bool isApproved, + uint256 timelock, + uint256 tempLockExpiry + ) + { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_BREAK_BOND_FROM_ALL); + isApproved = _isApprovedForBreakBond(contractAddress, tokenId, sender); + timelock = _nftBreakBondTimelockUnlockBlock[tokenUuid]; + tempLockExpiry = _nftTempLockExpiry[tokenUuid]; + } + + + + + /***********************************| + | Only NFT Owner/Operator | + |__________________________________*/ + + /// @notice Sets an Operator as Approved to Discharge a specific Token + /// This allows an operator to withdraw the interest-portion only + /// @param contractAddress The Address to the Contract of the Token + /// @param tokenId The ID of the Token + /// @param operator The Address of the Operator to Approve + function setDischargeApproval( + address contractAddress, + uint256 tokenId, + address operator + ) + external + virtual + override + onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender()) + { + address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId); + require(operator != tokenOwner, "CP:E-106"); + _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator); + } + + /// @notice Sets an Operator as Approved to Release a specific Token + /// This allows an operator to withdraw the principal + interest + /// @param contractAddress The Address to the Contract of the Token + /// @param tokenId The ID of the Token + /// @param operator The Address of the Operator to Approve + function setReleaseApproval( + address contractAddress, + uint256 tokenId, + address operator + ) + external + virtual + override + onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender()) + { + address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId); + require(operator != tokenOwner, "CP:E-106"); + _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator); + } + + /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token + /// This allows an operator to withdraw Basket NFTs + /// @param contractAddress The Address to the Contract of the Token + /// @param tokenId The ID of the Token + /// @param operator The Address of the Operator to Approve + function setBreakBondApproval( + address contractAddress, + uint256 tokenId, + address operator + ) + external + virtual + override + onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender()) + { + address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId); + require(operator != tokenOwner, "CP:E-106"); + _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator); + } + + /// @notice Sets an Operator as Approved to Timelock a specific Token + /// This allows an operator to timelock the principal or interest + /// @param contractAddress The Address to the Contract of the Token + /// @param tokenId The ID of the Token + /// @param operator The Address of the Operator to Approve + function setTimelockApproval( + address contractAddress, + uint256 tokenId, + address operator + ) + external + virtual + override + onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender()) + { + address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId); + require(operator != tokenOwner, "CP:E-106"); + _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator); + } + + /// @notice Sets an Operator as Approved to Discharge/Release/Timelock a specific Token + /// @param contractAddress The Address to the Contract of the Token + /// @param tokenId The ID of the Token + /// @param operator The Address of the Operator to Approve + function setApprovalForAll( + address contractAddress, + uint256 tokenId, + address operator + ) + external + virtual + override + onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender()) + { + address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId); + require(operator != tokenOwner, "CP:E-106"); + _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator); + _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator); + _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator); + _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator); + } + + /// @dev Updates Restrictions on Energizing an NFT + function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) + external + virtual + override + onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender()) + { + _setPermsForRestrictCharge(contractAddress, tokenId, state); + } + + /// @dev Updates Allowance on Discharging an NFT by Anyone + function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) + external + virtual + override + onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender()) + { + _setPermsForAllowDischarge(contractAddress, tokenId, state); + } + + /// @dev Updates Allowance on Discharging an NFT by Anyone + function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) + external + virtual + override + onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender()) + { + _setPermsForAllowRelease(contractAddress, tokenId, state); + } + + /// @dev Updates Restrictions on Covalent Bonds on an NFT + function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) + external + virtual + override + onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender()) + { + _setPermsForRestrictBond(contractAddress, tokenId, state); + } + + /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone + function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) + external + virtual + override + onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender()) + { + _setPermsForAllowBreakBond(contractAddress, tokenId, state); + } + + /// @notice Sets a Timelock on the ability to Discharge the Interest of a Particle + /// @param contractAddress The Address to the NFT to Timelock + /// @param tokenId The token ID of the NFT to Timelock + /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block) + function setDischargeTimelock( + address contractAddress, + uint256 tokenId, + uint256 unlockBlock + ) + external + override + virtual + { + address sender = _msgSender(); + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + + // Clear Timelock + if (unlockBlock == 0 && _nftDischargeTimelockLockedBy[tokenUuid] == sender) { + delete _nftDischargeTimelockUnlockBlock[tokenUuid]; + delete _nftDischargeTimelockLockedBy[tokenUuid]; + } + + // Set Timelock + else { + require(_isApprovedForTimelock(contractAddress, tokenId, sender), "CP:E-105"); + require(block.number >= _nftDischargeTimelockUnlockBlock[tokenUuid], "CP:E-302"); + + _nftDischargeTimelockUnlockBlock[tokenUuid] = unlockBlock; + _nftDischargeTimelockLockedBy[tokenUuid] = sender; + } + + emit TokenDischargeTimelock(contractAddress, tokenId, sender, unlockBlock); + } + + /// @notice Sets a Timelock on the ability to Release the Assets of a Particle + /// @param contractAddress The Address to the NFT to Timelock + /// @param tokenId The token ID of the NFT to Timelock + /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block) + function setReleaseTimelock( + address contractAddress, + uint256 tokenId, + uint256 unlockBlock + ) + external + override + virtual + { + address sender = _msgSender(); + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + + // Clear Timelock + if (unlockBlock == 0 && _nftReleaseTimelockLockedBy[tokenUuid] == sender) { + delete _nftReleaseTimelockUnlockBlock[tokenUuid]; + delete _nftReleaseTimelockLockedBy[tokenUuid]; + } + + // Set Timelock + else { + require(_isApprovedForTimelock(contractAddress, tokenId, sender), "CP:E-105"); + require(block.number >= _nftReleaseTimelockUnlockBlock[tokenUuid], "CP:E-302"); + + _nftReleaseTimelockUnlockBlock[tokenUuid] = unlockBlock; + _nftReleaseTimelockLockedBy[tokenUuid] = sender; + } + + emit TokenReleaseTimelock(contractAddress, tokenId, sender, unlockBlock); + } + + /// @notice Sets a Timelock on the ability to Break the Covalent Bond of a Particle + /// @param contractAddress The Address to the NFT to Timelock + /// @param tokenId The token ID of the NFT to Timelock + /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block) + function setBreakBondTimelock( + address contractAddress, + uint256 tokenId, + uint256 unlockBlock + ) + external + override + virtual + { + address sender = _msgSender(); + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + + // Clear Timelock + if (unlockBlock == 0 && _nftBreakBondTimelockLockedBy[tokenUuid] == sender) { + delete _nftBreakBondTimelockUnlockBlock[tokenUuid]; + delete _nftBreakBondTimelockLockedBy[tokenUuid]; + } + + // Set Timelock + else { + require(_isApprovedForTimelock(contractAddress, tokenId, sender), "CP:E-105"); + require(block.number >= _nftBreakBondTimelockUnlockBlock[tokenUuid], "CP:E-302"); + + _nftBreakBondTimelockUnlockBlock[tokenUuid] = unlockBlock; + _nftBreakBondTimelockLockedBy[tokenUuid] = sender; + } + + emit TokenBreakBondTimelock(contractAddress, tokenId, sender, unlockBlock); + } + + + /***********************************| + | Only NFT Contract | + |__________________________________*/ + + /// @notice Sets a Temporary-Lock on the ability to Release/Discharge the Assets of a Particle + /// @param contractAddress The Address to the NFT to Timelock + /// @param tokenId The token ID of the NFT to Timelock + /// @param isLocked The locked state; contracts are expected to disable this lock before expiry + function setTemporaryLock( + address contractAddress, + uint256 tokenId, + bool isLocked + ) + external + override + virtual + { + require(msg.sender == contractAddress, "CP:E-112"); + + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + uint256 unlockBlock; + if (isLocked && _nftTempLockExpiry[tokenUuid] == 0) { + unlockBlock = block.number.add(_chargedSettings.getTempLockExpiryBlocks()); + _nftTempLockExpiry[tokenUuid] = unlockBlock; + } + if (!isLocked) { + _nftTempLockExpiry[tokenUuid] = 0; + } + + emit TokenTempLock(contractAddress, tokenId, unlockBlock); + } + + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + /// @dev Setup the various Charged-Controllers + function setController(address controller, string calldata controllerId) external virtual onlyOwner { + bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId)); + + if (controllerIdStr == keccak256(abi.encodePacked("settings"))) { + _chargedSettings = IChargedSettings(controller); + } + else if (controllerIdStr == keccak256(abi.encodePacked("tokeninfo"))) { + _tokenInfoProxy = ITokenInfoProxy(controller); + } + + emit ControllerSet(controller, controllerId); + } + + function migrateToken( + address contractAddress, + uint256 tokenId, + uint256 releaseTimelockExpiry, + address releaseTimelockLockedBy, + uint256 tempLockExpiry + ) + external + onlyOwner + { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + + if (releaseTimelockExpiry > block.number && releaseTimelockLockedBy != address(0)) { + _nftReleaseTimelockUnlockBlock[tokenUuid] = releaseTimelockExpiry; + _nftReleaseTimelockLockedBy[tokenUuid] = releaseTimelockLockedBy; + emit TokenReleaseTimelock(contractAddress, tokenId, releaseTimelockLockedBy, releaseTimelockExpiry); + } + + if (tempLockExpiry > 0) { + _nftTempLockExpiry[tokenUuid] = tempLockExpiry; + emit TokenTempLock(contractAddress, tokenId, tempLockExpiry); + } + } + + /***********************************| + | Only Admin/DAO | + | (blackhole prevention) | + |__________________________________*/ + + function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner { + _withdrawEther(receiver, amount); + } + + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner { + _withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner { + _withdrawERC1155(receiver, tokenAddress, tokenId, amount); + } + + + /***********************************| + | Private Functions | + |__________________________________*/ + + /// @dev See {ChargedParticles-isApprovedForDischarge}. + function _isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) { + address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId); + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + return contractAddress == operator || tokenOwner == operator || _nftDischargeApproval[tokenUuid][tokenOwner] == operator; + } + + /// @dev See {ChargedParticles-isApprovedForRelease}. + function _isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) { + address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId); + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + return contractAddress == operator || tokenOwner == operator || _nftReleaseApproval[tokenUuid][tokenOwner] == operator; + } + + /// @dev See {ChargedParticles-isApprovedForBreakBond}. + function _isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) { + address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId); + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + return contractAddress == operator || tokenOwner == operator || _nftBreakBondApproval[tokenUuid][tokenOwner] == operator; + } + + /// @dev See {ChargedParticles-isApprovedForTimelock}. + function _isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) { + (bool timelockAny, bool timelockOwn) = _chargedSettings.getTimelockApprovals(operator); + if (timelockAny || (timelockOwn && contractAddress == operator)) { return true; } + + address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId); + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + return tokenOwner == operator || _nftTimelockApproval[tokenUuid][tokenOwner] == operator; + } + + /// @notice Sets an Operator as Approved to Discharge a specific Token + /// This allows an operator to withdraw the interest-portion only + /// @param contractAddress The Address to the Contract of the Token + /// @param tokenId The ID of the Token + /// @param tokenOwner The Owner Address of the Token + /// @param operator The Address of the Operator to Approve + function _setDischargeApproval( + address contractAddress, + uint256 tokenId, + address tokenOwner, + address operator + ) + internal + virtual + { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + _nftDischargeApproval[tokenUuid][tokenOwner] = operator; + emit DischargeApproval(contractAddress, tokenId, tokenOwner, operator); + } + + /// @notice Sets an Operator as Approved to Release a specific Token + /// This allows an operator to withdraw the principal + interest + /// @param contractAddress The Address to the Contract of the Token + /// @param tokenId The ID of the Token + /// @param tokenOwner The Owner Address of the Token + /// @param operator The Address of the Operator to Approve + function _setReleaseApproval( + address contractAddress, + uint256 tokenId, + address tokenOwner, + address operator + ) + internal + virtual + { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + _nftReleaseApproval[tokenUuid][tokenOwner] = operator; + emit ReleaseApproval(contractAddress, tokenId, tokenOwner, operator); + } + + /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token + /// This allows an operator to withdraw Basket NFTs + /// @param contractAddress The Address to the Contract of the Token + /// @param tokenId The ID of the Token + /// @param tokenOwner The Owner Address of the Token + /// @param operator The Address of the Operator to Approve + function _setBreakBondApproval( + address contractAddress, + uint256 tokenId, + address tokenOwner, + address operator + ) + internal + virtual + { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + _nftBreakBondApproval[tokenUuid][tokenOwner] = operator; + emit BreakBondApproval(contractAddress, tokenId, tokenOwner, operator); + } + + /// @notice Sets an Operator as Approved to Timelock a specific Token + /// This allows an operator to timelock the principal or interest + /// @param contractAddress The Address to the Contract of the Token + /// @param tokenId The ID of the Token + /// @param tokenOwner The Owner Address of the Token + /// @param operator The Address of the Operator to Approve + function _setTimelockApproval( + address contractAddress, + uint256 tokenId, + address tokenOwner, + address operator + ) + internal + virtual + { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + _nftTimelockApproval[tokenUuid][tokenOwner] = operator; + emit TimelockApproval(contractAddress, tokenId, tokenOwner, operator); + } + + /// @dev Updates Restrictions on Energizing an NFT + function _setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) internal virtual { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + if (state) { + _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_ENERGIZE_FROM_ALL); + } else { + _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_ENERGIZE_FROM_ALL); + } + emit PermsSetForRestrictCharge(contractAddress, tokenId, state); + } + + /// @dev Updates Allowance on Discharging an NFT by Anyone + function _setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) internal virtual { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + if (state) { + _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_DISCHARGE_FROM_ALL); + } else { + _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_DISCHARGE_FROM_ALL); + } + emit PermsSetForAllowDischarge(contractAddress, tokenId, state); + } + + /// @dev Updates Allowance on Discharging an NFT by Anyone + function _setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) internal virtual { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + if (state) { + _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_RELEASE_FROM_ALL); + } else { + _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_RELEASE_FROM_ALL); + } + emit PermsSetForAllowRelease(contractAddress, tokenId, state); + } + + /// @dev Updates Restrictions on Covalent Bonds on an NFT + function _setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) internal virtual { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + if (state) { + _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_BOND_FROM_ALL); + } else { + _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_BOND_FROM_ALL); + } + emit PermsSetForRestrictBond(contractAddress, tokenId, state); + } + + /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone + function _setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) internal virtual { + uint256 tokenUuid = contractAddress.getTokenUUID(tokenId); + if (state) { + _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_BREAK_BOND_FROM_ALL); + } else { + _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_BREAK_BOND_FROM_ALL); + } + emit PermsSetForAllowBreakBond(contractAddress, tokenId, state); + } + + + /***********************************| + | GSN/MetaTx Relay | + |__________________________________*/ + + /// @dev See {BaseRelayRecipient-_msgSender}. + function _msgSender() + internal + view + virtual + override(BaseRelayRecipient, ContextUpgradeable) + returns (address payable) + { + return BaseRelayRecipient._msgSender(); + } + + /// @dev See {BaseRelayRecipient-_msgData}. + function _msgData() + internal + view + virtual + override(BaseRelayRecipient, ContextUpgradeable) + returns (bytes memory) + { + return BaseRelayRecipient._msgData(); + } + + + /***********************************| + | Modifiers | + |__________________________________*/ + + modifier onlyNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) { + require(_tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender), "CP:E-105"); + _; + } +} diff --git a/contracts/v1/ParticleSplitter.sol b/contracts/v1/ParticleSplitter.sol new file mode 100755 index 0000000..193bce2 --- /dev/null +++ b/contracts/v1/ParticleSplitter.sol @@ -0,0 +1,268 @@ +// SPDX-License-Identifier: MIT + +// ParticleSplitter.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; +import "./interfaces/IParticleSplitter.sol"; +import "./interfaces/IChargedManagers.sol"; +import "./interfaces/IWalletManager.sol"; +import "./interfaces/IBasketManager.sol"; +import "./interfaces/ITokenInfoProxy.sol"; +import "./lib/BlackholePrevention.sol"; + +/** + * @notice Charged Particles Contract + * @dev Upgradeable Contract + */ +contract ParticleSplitter is IParticleSplitter, Ownable, ReentrancyGuard, BlackholePrevention +{ + IChargedManagers internal _chargedManagers; + ITokenInfoProxy internal _tokenInfoProxy; + + mapping (address => bool) internal _externalAddressesAllowed; + + + /***********************************| + | Execute for Account | + |__________________________________*/ + + /// @notice Executes an arbitrary command on an NFT Wallet + /// @param contractAddress The Address to the Contract of the Token + /// @param tokenId The ID of the Token + /// @param walletManagerId The Wallet Manager controlling the NFT Wallet to execute on + /// @param externalAddress The Address of the External Contract to execute on + /// @param encodedParams The encoded function call to execute + function executeForWallet( + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address externalAddress, + bytes memory encodedParams + ) + external + payable + virtual + override + onlyTokenOwner(contractAddress, tokenId) + nonReentrant + returns (bytes memory) + { + require(_chargedManagers.isWalletManagerEnabled(walletManagerId), "PS:E-419"); + require(_externalAddressesAllowed[externalAddress], "PS:E-117"); + + // Validate Owner/Operator & Timelocks + _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId); + + // Get appropriate Wallet Manager + IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId); + + // Get Address of Wallet to send any ETH into + if (msg.value > 0) { + address wallet = walletMgr.getWalletAddressById(contractAddress, tokenId, address(0), 0); + payable(wallet).sendValue(msg.value); + } + + emit ExecuteForWallet(contractAddress, tokenId, walletManagerId, externalAddress, encodedParams, msg.value); + + // Execute command for NFT Wallet + return walletMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams); + } + + /// @notice Executes an arbitrary command on an NFT Basket + /// @param contractAddress The Address to the Contract of the Token + /// @param tokenId The ID of the Token + /// @param basketManagerId The Basket Manager controlling the NFT Wallet to execute on + /// @param externalAddress The Address of the External Contract to execute on + /// @param encodedParams The encoded function call to execute + function executeForBasket( + address contractAddress, + uint256 tokenId, + string calldata basketManagerId, + address externalAddress, + bytes memory encodedParams + ) + external + payable + virtual + override + onlyTokenOwner(contractAddress, tokenId) + nonReentrant + returns (bytes memory) + { + require(_chargedManagers.isNftBasketEnabled(basketManagerId), "PS:E-419"); + require(_externalAddressesAllowed[externalAddress], "PS:E-117"); + + // Validate Owner/Operator & Timelocks + _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId); + + // Get appropriate Basket Manager + IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId); + + // Get Address of Wallet to send any ETH into + if (msg.value > 0) { + address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId); + payable(wallet).sendValue(msg.value); + } + + emit ExecuteForBasket(contractAddress, tokenId, basketManagerId, externalAddress, encodedParams, msg.value); + + // Execute command for NFT Wallet + return basketMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams); + } + + function withdrawWalletRewards( + address receiver, + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address rewardsToken, + uint256 rewardsAmount + ) + external + virtual + override + onlyTokenOwner(contractAddress, tokenId) + nonReentrant + returns (uint256 amountWithdrawn) + { + require(_chargedManagers.isWalletManagerEnabled(walletManagerId), "PS:E-419"); + + // Validate Owner/Operator & Timelocks + _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId); + + // Get appropriate Wallet Manager + IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId); + + // Withdraw Rewards for NFT Wallet + return walletMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount); + } + + function withdrawBasketRewards( + address receiver, + address contractAddress, + uint256 tokenId, + string calldata basketManagerId, + address rewardsToken, + uint256 rewardsAmount + ) + external + virtual + override + onlyTokenOwner(contractAddress, tokenId) + nonReentrant + returns (uint256 amountWithdrawn) + { + require(_chargedManagers.isNftBasketEnabled(basketManagerId), "PS:E-419"); + + // Validate Owner/Operator & Timelocks + _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId); + + // Get appropriate Basket Manager + IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId); + + // Withdraw Rewards for NFT Basket + return basketMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount); + } + + function refreshWalletPrincipal( + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken + ) + external + virtual + override + { + require(_chargedManagers.isWalletManagerEnabled(walletManagerId), "PS:E-419"); + + IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId); + walletMgr.refreshPrincipal(contractAddress, tokenId, assetToken); + + emit PrincipalRefreshed(contractAddress, tokenId, walletManagerId, assetToken); + } + + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + /** + * @dev Setup the ChargedManagers Interface + */ + function setChargedManagers(address chargedManagers) external virtual onlyOwner { + _chargedManagers = IChargedManagers(chargedManagers); + emit ChargedManagersSet(chargedManagers); + } + + /** + * @dev Setup the ChargedManagers Interface + */ + function setTokenInfoProxy(address tokenInfoProxy) external virtual onlyOwner { + _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy); + emit TokenInfoProxySet(tokenInfoProxy); + } + + /** + * @dev Allows/Disallows execute from on specific contracts + */ + function setExternalContracts(address[] calldata contracts, bool state) external onlyOwner { + uint count = contracts.length; + for (uint i; i < count; i++) { + address externalContract = contracts[i]; + _externalAddressesAllowed[externalContract] = state; + emit PermsSetForExternal(externalContract, state); + } + } + + + function withdrawEther(address payable receiver, uint256 amount) external onlyOwner { + _withdrawEther(receiver, amount); + } + + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner { + _withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner { + _withdrawERC1155(receiver, tokenAddress, tokenId, amount); + } + + + + /***********************************| + | Modifiers | + |__________________________________*/ + + modifier onlyTokenOwner(address contractAddress, uint256 tokenId) { + address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId); + require(msg.sender == tokenOwner, "PS:E-102"); + _; + } +} diff --git a/contracts/v1/Universe.sol b/contracts/v1/Universe.sol new file mode 100644 index 0000000..741c90c --- /dev/null +++ b/contracts/v1/Universe.sol @@ -0,0 +1,358 @@ +// SPDX-License-Identifier: MIT + +// Universe.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol"; +import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol"; + +import "./interfaces/IUniverse.sol"; +import "./interfaces/IChargedParticles.sol"; +import "./interfaces/ILepton.sol"; +import "./lib/TokenInfo.sol"; +import "./lib/BlackholePrevention.sol"; + + +/** + * @notice Charged Particles Universe Contract + * @dev Upgradeable Contract + */ +contract Universe is IUniverse, Initializable, OwnableUpgradeable, BlackholePrevention { + using SafeMathUpgradeable for uint256; + using TokenInfo for address; + using SafeERC20Upgradeable for IERC20Upgradeable; + + // The ChargedParticles Contract Address + address public chargedParticles; + address public proton; + address public lepton; + address public quark; + address public boson; + + uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%) + + // Positive Charge + uint256 internal photonMaxSupply; + uint256 internal totalPhotonDischarged; + + // Source of Positive Charge + IERC20Upgradeable public photonSource; + + // Asset Token => Electrostatic Attraction Multiplier + mapping (address => uint256) internal esaMultiplier; + + // Account => Electrostatic Attraction Levels + mapping (address => uint256) internal esaLevel; + + // Energizing Account => Referral Source + mapping (address => address) internal referralSource; + + // NFT Token UUID => Bonded Lepton Mass + mapping (uint256 => uint256) internal bondedLeptonMass; + + + /***********************************| + | Initialization | + |__________________________________*/ + + function initialize() public initializer { + __Ownable_init(); + } + + + /***********************************| + | Public Functions | + |__________________________________*/ + + function getStaticCharge(address /* account */) external pure virtual returns (uint256 positiveEnergy) { + return 0; + } + + function conductElectrostaticDischarge(address /* account */, uint256 /* amount */) external pure virtual returns (uint256 positiveEnergy) { + return 0; + } + + /***********************************| + | Only Charged Particles | + |__________________________________*/ + + function onEnergize( + address /* sender */, + address /* referrer */, + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken, + uint256 assetAmount + ) + external + virtual + override + onlyChargedParticles + { + // no-op + } + + function onDischarge( + address contractAddress, + uint256 tokenId, + string calldata /* walletManagerId */, + address assetToken, + uint256 creatorEnergy, + uint256 receiverEnergy + ) + external + virtual + override + onlyChargedParticles + { + // no-op + } + + function onDischargeForCreator( + address contractAddress, + uint256 tokenId, + string calldata /* walletManagerId */, + address /* creator */, + address assetToken, + uint256 receiverEnergy + ) + external + virtual + override + onlyChargedParticles + { + // no-op + } + + function onRelease( + address contractAddress, + uint256 tokenId, + string calldata /* walletManagerId */, + address assetToken, + uint256 principalAmount, + uint256 creatorEnergy, + uint256 receiverEnergy + ) + external + virtual + override + onlyChargedParticles + { + // no-op + } + + function onCovalentBond( + address contractAddress, + uint256 tokenId, + string calldata /* managerId */, + address nftTokenAddress, + uint256 nftTokenId, + uint256 nftTokenAmount + ) + external + virtual + override + onlyChargedParticles + { + // no-op + } + + function onCovalentBreak( + address contractAddress, + uint256 tokenId, + string calldata /* managerId */, + address nftTokenAddress, + uint256 nftTokenId, + uint256 nftTokenAmount + ) + external + virtual + override + onlyChargedParticles + { + // no-op + } + + function onProtonSale( + address contractAddress, + uint256 tokenId, + address oldOwner, + address newOwner, + uint256 salePrice, + address creator, + uint256 creatorRoyalties + ) + external + virtual + override + onlyProton + { + // no-op + } + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + function setChargedParticles( + address controller + ) + external + virtual + onlyOwner + onlyValidContractAddress(controller) + { + chargedParticles = controller; + emit ChargedParticlesSet(controller); + } + + function setPhoton( + address token, + uint256 maxSupply + ) + external + virtual + onlyOwner + onlyValidContractAddress(token) + { + photonSource = IERC20Upgradeable(token); + photonMaxSupply = maxSupply; + emit PhotonSet(token, maxSupply); + } + + function setProtonToken( + address token + ) + external + virtual + onlyOwner + onlyValidContractAddress(token) + { + proton = token; + emit ProtonTokenSet(token); + } + + function setLeptonToken( + address token + ) + external + virtual + onlyOwner + onlyValidContractAddress(token) + { + lepton = token; + emit LeptonTokenSet(token); + } + + function setQuarkToken( + address token + ) + external + virtual + onlyOwner + onlyValidContractAddress(token) + { + quark = token; + emit QuarkTokenSet(token); + } + + function setBosonToken( + address token + ) + external + virtual + onlyOwner + onlyValidContractAddress(token) + { + boson = token; + emit BosonTokenSet(token); + } + + function setEsaMultiplier( + address assetToken, + uint256 multiplier + ) + external + virtual + onlyOwner + { + esaMultiplier[assetToken] = multiplier; + emit EsaMultiplierSet(assetToken, multiplier); + } + + function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner { + _withdrawEther(receiver, amount); + } + + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner { + _withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner { + _withdrawERC1155(receiver, tokenAddress, tokenId, amount); + } + + + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _electrostaticAttraction(uint256 tokenUuid, address receiver, address assetToken, uint256 baseAmount) internal virtual { + } + + function _conductElectrostaticDischarge(address /* account */, uint256 /* energy */) internal virtual pure returns (uint256) { + return 0; + } + + /***********************************| + | Modifiers | + |__________________________________*/ + + /// @dev Throws if called by any non-account + modifier onlyValidContractAddress(address account) { + require(account != address(0x0) && account.isContract(), "UNI:E-417"); + _; + } + + /// @dev Throws if called by any account other than the Charged Particles contract + modifier onlyChargedParticles() { + require(chargedParticles == msg.sender, "UNI:E-108"); + _; + } + + /// @dev Throws if called by any account other than the Proton NFT contract + modifier onlyProton() { + require(proton == msg.sender, "UNI:E-110"); + _; + } +} diff --git a/contracts/v1/UniverseRP.sol b/contracts/v1/UniverseRP.sol new file mode 100644 index 0000000..1bc3faa --- /dev/null +++ b/contracts/v1/UniverseRP.sol @@ -0,0 +1,395 @@ +// SPDX-License-Identifier: MIT + +// Universe.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; +pragma experimental ABIEncoderV2; + +import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol"; +import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol"; +import "@openzeppelin/contracts/utils/EnumerableSet.sol"; + +import "./interfaces/IUniverseRP.sol"; +import "./interfaces/IChargedParticles.sol"; +import "./interfaces/ILepton.sol"; +import "./interfaces/IRewardNft.sol"; +import "./lib/TokenInfo.sol"; +import "./lib/BlackholePrevention.sol"; +import "./interfaces/IRewardProgram.sol"; + +/** + * @notice Charged Particles Universe Contract with Rewards Program + * @dev Upgradeable Contract + */ +contract UniverseRP is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention { + using SafeMathUpgradeable for uint256; + using TokenInfo for address; + using SafeERC20Upgradeable for IERC20Upgradeable; + using EnumerableSet for EnumerableSet.UintSet; + + uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2; + uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%) + + // The ChargedParticles Contract Address + address public _chargedParticles; + + // The Lepton NFT Contract Address + address public _multiplierNft; + + // Asset Token => Reward Program + mapping (address => address) internal _assetRewardPrograms; + mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet; + + // Token UUID => NFT Staking Data + mapping (uint256 => NftStake) private _nftStake; + + + /***********************************| + | Initialization | + |__________________________________*/ + + function initialize() public initializer { + __Ownable_init(); + } + + function getRewardProgram(address asset) external view override returns (address) { + return _getRewardProgram(asset); + } + + function getNftStake(uint256 uuid) external view override returns (NftStake memory) { + return _nftStake[uuid]; + } + + /***********************************| + | Only Charged Particles | + |__________________________________*/ + + function onEnergize( + address /* sender */, + address /* referrer */, + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken, + uint256 assetAmount + ) + external + virtual + override + onlyChargedParticles + { + address rewardProgram = _getRewardProgram(assetToken); + if (rewardProgram != address(0)) { + IRewardProgram(rewardProgram).registerAssetDeposit( + contractAddress, + tokenId, + walletManagerId, + assetAmount + ); + } + } + + function onDischarge( + address contractAddress, + uint256 tokenId, + string calldata /* walletManagerId */, + address assetToken, + uint256 creatorEnergy, + uint256 receiverEnergy + ) + external + virtual + override + onlyChargedParticles + { + address rewardProgram = _getRewardProgram(assetToken); + if (rewardProgram != address(0)) { + uint256 totalInterest = receiverEnergy.add(creatorEnergy); + IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest); + } + } + + function onDischargeForCreator( + address contractAddress, + uint256 tokenId, + string calldata /* walletManagerId */, + address /* creator */, + address assetToken, + uint256 receiverEnergy + ) + external + virtual + override + onlyChargedParticles + { + address rewardProgram = _getRewardProgram(assetToken); + if (rewardProgram != address(0)) { + IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy); + } + } + + function onRelease( + address contractAddress, + uint256 tokenId, + string calldata /* walletManagerId */, + address assetToken, + uint256 principalAmount, + uint256 creatorEnergy, + uint256 receiverEnergy + ) + external + virtual + override + onlyChargedParticles + { + address rewardProgram = _getRewardProgram(assetToken); + if (rewardProgram != address(0)) { + // "receiverEnergy" includes the "principalAmount" + uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy); + IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest); + } + } + + function onCovalentBond( + address contractAddress, + uint256 tokenId, + string calldata /* managerId */, + address nftTokenAddress, + uint256 nftTokenId, + uint256 nftTokenAmount + ) + external + virtual + override + onlyChargedParticles + { + _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount); + } + + function onCovalentBreak( + address contractAddress, + uint256 tokenId, + string calldata /* managerId */, + address nftTokenAddress, + uint256 nftTokenId, + uint256 nftTokenAmount + ) + external + virtual + override + onlyChargedParticles + { + _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount); + } + + function onProtonSale( + address contractAddress, + uint256 tokenId, + address oldOwner, + address newOwner, + uint256 salePrice, + address creator, + uint256 creatorRoyalties + ) + external + virtual + override + { + // no-op + } + + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + function setChargedParticles( + address controller + ) + external + onlyOwner + onlyValidContractAddress(controller) + { + _chargedParticles = controller; + emit ChargedParticlesSet(controller); + } + + function setMultiplierNft(address nftTokenAddress) + external + onlyOwner + onlyValidContractAddress(nftTokenAddress) + { + _multiplierNft = nftTokenAddress; + } + + function setRewardProgram( + address rewardProgam, + address assetToken + ) + external + onlyOwner + onlyValidContractAddress(rewardProgam) + { + require(assetToken != address(0x0), "UNI:E-403"); + _assetRewardPrograms[assetToken] = rewardProgam; + emit RewardProgramSet(assetToken, rewardProgam); + } + + function removeRewardProgram(address assetToken) external onlyOwner { + delete _assetRewardPrograms[assetToken]; + emit RewardProgramRemoved(assetToken); + } + + + /***********************************| + | Only Admin/DAO | + | (blackhole prevention) | + |__________________________________*/ + + function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner { + _withdrawEther(receiver, amount); + } + + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner { + _withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner { + _withdrawERC1155(receiver, tokenAddress, tokenId, amount); + } + + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _getRewardProgram(address assetToken) internal view returns (address) { + return _assetRewardPrograms[assetToken]; + } + + function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */) + internal + { + // We only care about the Multiplier NFT + if (_multiplierNft != depositNftAddress) { return; } + + uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId); + uint256 multiplier = _getNftMultiplier(depositNftAddress, depositNftTokenId); + + if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) { + // Add to Multipliers Set + _multiplierNftsSet[parentNftUuid].add(multiplier); + + // Update NFT Stake + uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid); + if (_nftStake[parentNftUuid].depositBlockNumber == 0) { + _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0); + } else { + uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber; + _nftStake[parentNftUuid].multiplier = combinedMultiplier; + _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2)); + } + } + + emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId); + } + + function _registerNftRelease( + address contractAddress, + uint256 tokenId, + address releaseNftAddress, + uint256 releaseNftTokenId, + uint256 /* nftTokenAmount */ + ) + internal + { + // We only care about the Multiplier NFT + if (_multiplierNft != releaseNftAddress) { return; } + + uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId); + NftStake storage nftStake = _nftStake[parentNftUuid]; + + // Remove from Multipliers Set + uint256 multiplier = _getNftMultiplier(releaseNftAddress, releaseNftTokenId); + _multiplierNftsSet[parentNftUuid].remove(multiplier); + + // Determine New Multiplier or Mark as Released + if (_multiplierNftsSet[parentNftUuid].length() > 0) { + nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid); + } else { + nftStake.releaseBlockNumber = block.number; + } + + emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId); + } + + function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) { + uint256 len = _multiplierNftsSet[parentNftUuid].length(); + uint256 multiplier = 0; + uint256 loss = 50; + uint256 i = 0; + + for (; i < len; i++) { + multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i)); + } + if (len > 1) { + multiplier = multiplier.sub(loss.mul(len)); + } + return multiplier; + } + + function _getNftMultiplier(address contractAddress, uint256 tokenId) internal returns (uint256) { + bytes4 fnSig = IRewardNft.getMultiplier.selector; + (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId)); + + if (success) { + return abi.decode(returnData, (uint256)); + } else { + return 0; + } + } + + + /***********************************| + | Modifiers | + |__________________________________*/ + + /// @dev Throws if called by any non-account + modifier onlyValidContractAddress(address account) { + require(account != address(0x0) && account.isContract(), "UNI:E-417"); + _; + } + + /// @dev Throws if called by any account other than the Charged Particles contract + modifier onlyChargedParticles() { + require(_chargedParticles == msg.sender, "UNI:E-108"); + _; + } +} diff --git a/contracts/v1/UniveserRPPolygon.sol b/contracts/v1/UniveserRPPolygon.sol new file mode 100644 index 0000000..cb8fd77 --- /dev/null +++ b/contracts/v1/UniveserRPPolygon.sol @@ -0,0 +1,402 @@ +// SPDX-License-Identifier: MIT + +// Universe.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; +pragma experimental ABIEncoderV2; + +import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol"; +import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol"; +import "@openzeppelin/contracts/utils/EnumerableSet.sol"; + +import "./interfaces/IUniverseRP.sol"; +import "./interfaces/IChargedParticles.sol"; +import "./interfaces/ILepton.sol"; +import "./interfaces/IRewardNft.sol"; +import "./lib/TokenInfo.sol"; +import "./lib/BlackholePrevention.sol"; +import "./interfaces/IRewardProgram.sol"; + +/** + * @notice Charged Particles Universe Contract with Rewards Program + * @dev Upgradeable Contract + */ +contract UniverseRPPolygon is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention { + using SafeMathUpgradeable for uint256; + using TokenInfo for address; + using SafeERC20Upgradeable for IERC20Upgradeable; + using EnumerableSet for EnumerableSet.UintSet; + + uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2; + uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%) + + // The ChargedParticles Contract Address + address public _chargedParticles; + + // The Lepton NFT Contract Address + address public _multiplierNft; + + // Asset Token => Reward Program + mapping (address => address) internal _assetRewardPrograms; + mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet; + + // Token UUID => NFT Staking Data + mapping (uint256 => NftStake) private _nftStake; + + + /***********************************| + | Initialization | + |__________________________________*/ + + function initialize() public initializer { + __Ownable_init(); + } + + function getRewardProgram(address asset) external view override returns (address) { + return _getRewardProgram(asset); + } + + function getNftStake(uint256 uuid) external view override returns (NftStake memory) { + return _nftStake[uuid]; + } + + /***********************************| + | Only Charged Particles | + |__________________________________*/ + + function onEnergize( + address /* sender */, + address /* referrer */, + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken, + uint256 assetAmount + ) + external + virtual + override + onlyChargedParticles + { + address rewardProgram = _getRewardProgram(assetToken); + if (rewardProgram != address(0)) { + IRewardProgram(rewardProgram).registerAssetDeposit( + contractAddress, + tokenId, + walletManagerId, + assetAmount + ); + } + } + + function onDischarge( + address contractAddress, + uint256 tokenId, + string calldata /* walletManagerId */, + address assetToken, + uint256 creatorEnergy, + uint256 receiverEnergy + ) + external + virtual + override + onlyChargedParticles + { + address rewardProgram = _getRewardProgram(assetToken); + if (rewardProgram != address(0)) { + uint256 totalInterest = receiverEnergy.add(creatorEnergy); + IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest); + } + } + + function onDischargeForCreator( + address contractAddress, + uint256 tokenId, + string calldata /* walletManagerId */, + address /* creator */, + address assetToken, + uint256 receiverEnergy + ) + external + virtual + override + onlyChargedParticles + { + address rewardProgram = _getRewardProgram(assetToken); + if (rewardProgram != address(0)) { + IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy); + } + } + + function onRelease( + address contractAddress, + uint256 tokenId, + string calldata /* walletManagerId */, + address assetToken, + uint256 principalAmount, + uint256 creatorEnergy, + uint256 receiverEnergy + ) + external + virtual + override + onlyChargedParticles + { + address rewardProgram = _getRewardProgram(assetToken); + if (rewardProgram != address(0)) { + // "receiverEnergy" includes the "principalAmount" + uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy); + IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest); + } + } + + function onCovalentBond( + address contractAddress, + uint256 tokenId, + string calldata /* managerId */, + address nftTokenAddress, + uint256 nftTokenId, + uint256 nftTokenAmount + ) + external + virtual + override + onlyChargedParticles + { + _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount); + } + + function onCovalentBreak( + address contractAddress, + uint256 tokenId, + string calldata /* managerId */, + address nftTokenAddress, + uint256 nftTokenId, + uint256 nftTokenAmount + ) + external + virtual + override + onlyChargedParticles + { + _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount); + } + + function onProtonSale( + address contractAddress, + uint256 tokenId, + address oldOwner, + address newOwner, + uint256 salePrice, + address creator, + uint256 creatorRoyalties + ) + external + virtual + override + { + // no-op + } + + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + function setChargedParticles( + address controller + ) + external + onlyOwner + onlyValidContractAddress(controller) + { + _chargedParticles = controller; + emit ChargedParticlesSet(controller); + } + + function setMultiplierNft(address nftTokenAddress) + external + onlyOwner + onlyValidContractAddress(nftTokenAddress) + { + _multiplierNft = nftTokenAddress; + } + + function setRewardProgram( + address rewardProgam, + address assetToken + ) + external + onlyOwner + onlyValidContractAddress(rewardProgam) + { + require(assetToken != address(0x0), "UNI:E-403"); + _assetRewardPrograms[assetToken] = rewardProgam; + emit RewardProgramSet(assetToken, rewardProgam); + } + + function removeRewardProgram(address assetToken) external onlyOwner { + delete _assetRewardPrograms[assetToken]; + emit RewardProgramRemoved(assetToken); + } + + + /***********************************| + | Only Admin/DAO | + | (blackhole prevention) | + |__________________________________*/ + + function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner { + _withdrawEther(receiver, amount); + } + + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner { + _withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner { + _withdrawERC1155(receiver, tokenAddress, tokenId, amount); + } + + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _getRewardProgram(address assetToken) internal view returns (address) { + return _assetRewardPrograms[assetToken]; + } + + function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */) + internal + { + // We only care about the Multiplier NFT + if (_multiplierNft != depositNftAddress) { return; } + + uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId); + uint256 multiplier = _getNftMultiplier(depositNftTokenId); + + if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) { + // Add to Multipliers Set + _multiplierNftsSet[parentNftUuid].add(multiplier); + + // Update NFT Stake + uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid); + if (_nftStake[parentNftUuid].depositBlockNumber == 0) { + _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0); + } else { + uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber; + _nftStake[parentNftUuid].multiplier = combinedMultiplier; + _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2)); + } + } + + emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId); + } + + function _registerNftRelease( + address contractAddress, + uint256 tokenId, + address releaseNftAddress, + uint256 releaseNftTokenId, + uint256 /* nftTokenAmount */ + ) + internal + { + // We only care about the Multiplier NFT + if (_multiplierNft != releaseNftAddress) { return; } + + uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId); + NftStake storage nftStake = _nftStake[parentNftUuid]; + + // Remove from Multipliers Set + uint256 multiplier = _getNftMultiplier(releaseNftTokenId); + _multiplierNftsSet[parentNftUuid].remove(multiplier); + + // Determine New Multiplier or Mark as Released + if (_multiplierNftsSet[parentNftUuid].length() > 0) { + nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid); + } else { + nftStake.releaseBlockNumber = block.number; + } + + emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId); + } + + function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) { + uint256 len = _multiplierNftsSet[parentNftUuid].length(); + uint256 multiplier = 0; + uint256 loss = 50; + uint256 i = 0; + + for (; i < len; i++) { + multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i)); + } + if (len > 1) { + multiplier = multiplier.sub(loss.mul(len)); + } + return multiplier; + } + + function _getNftMultiplier(uint256 tokenId) internal pure returns (uint256) { + if (tokenId >= 1 && tokenId <= 721) { + return 110; + } else if (tokenId > 721 && tokenId <= 1122) { + return 130; + } else if (tokenId > 1122 && tokenId <= 1423) { + return 150; + } else if (tokenId > 1423 && tokenId <= 1624) { + return 180; + } else if (tokenId > 1624 && tokenId <= 1712) { + return 230; + } else if (tokenId > 1712 && tokenId <= 1733) { + return 510; + } else { + return 1; + } + } + + + /***********************************| + | Modifiers | + |__________________________________*/ + + /// @dev Throws if called by any non-account + modifier onlyValidContractAddress(address account) { + require(account != address(0x0) && account.isContract(), "UNI:E-417"); + _; + } + + /// @dev Throws if called by any account other than the Charged Particles contract + modifier onlyChargedParticles() { + require(_chargedParticles == msg.sender, "UNI:E-108"); + _; + } +} diff --git a/contracts/v1/incentives/CommunityVault.sol b/contracts/v1/incentives/CommunityVault.sol new file mode 100644 index 0000000..9c73250 --- /dev/null +++ b/contracts/v1/incentives/CommunityVault.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.6.11; + +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "../lib/BlackholePrevention.sol"; + +contract CommunityVault is Ownable, BlackholePrevention { + + IERC20 private immutable _ionx; + + constructor (address ionx) public { + _ionx = IERC20(ionx); + } + + event SetAllowance(address indexed caller, address indexed spender, uint256 amount); + + function setAllowance(address spender, uint amount) public onlyOwner { + _ionx.approve(spender, amount); + + emit SetAllowance(msg.sender, spender, amount); + } + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it + function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner { + _withdrawEther(receiver, amount); + } + + // Note: This contract should never hold any tokens other than IONX, if any are accidentally sent in then the DAO can return them + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner { + require(tokenAddress != address(_ionx), "CommunityVault: cannot withdraw IONX"); + _withdrawERC20(receiver, tokenAddress, amount); + } + + // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } +} \ No newline at end of file diff --git a/contracts/v1/incentives/ErrorCodes.txt b/contracts/v1/incentives/ErrorCodes.txt new file mode 100644 index 0000000..e62b36b --- /dev/null +++ b/contracts/v1/incentives/ErrorCodes.txt @@ -0,0 +1,37 @@ + +Categories: + 0. General + 1. Permission & Control + 2. Find, Inequalities & Range + 3. Availability & Time + 4. Tokens, Funds & Finance + + + + +Codes: + + + 0. General + E-002 - ALREADY_INIT + + + 1. Permission & Control + E-101 - PAUSED + + + 2. Find, Inequalities & Range + E-204 - invalid chronological order + E-205 - amount must be positive + + + 3. Availability & Time + E-304 - emergency withdraw too soon + E-305 - previous epoch not initialized + E-306 - epoch is in the future + + + 4. Tokens, Funds & Finance + E-408 - cap exceeded + E-432 - balance too small + diff --git a/contracts/v1/incentives/MerkleDistributor.sol b/contracts/v1/incentives/MerkleDistributor.sol new file mode 100644 index 0000000..c119e04 --- /dev/null +++ b/contracts/v1/incentives/MerkleDistributor.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/cryptography/MerkleProof.sol"; +import "../interfaces/IMerkleDistributor.sol"; + +contract MerkleDistributor is IMerkleDistributor { + address public immutable override token; + bytes32 public immutable override merkleRoot; + + // This is a packed array of booleans. + mapping(uint256 => uint256) private claimedBitMap; + + constructor(address token_, bytes32 merkleRoot_) public { + token = token_; + merkleRoot = merkleRoot_; + } + + function isClaimed(uint256 index) public view override returns (bool) { + uint256 claimedWordIndex = index / 256; + uint256 claimedBitIndex = index % 256; + uint256 claimedWord = claimedBitMap[claimedWordIndex]; + uint256 mask = (1 << claimedBitIndex); + return claimedWord & mask == mask; + } + + function _setClaimed(uint256 index) private { + uint256 claimedWordIndex = index / 256; + uint256 claimedBitIndex = index % 256; + claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex); + } + + function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override { + require(!isClaimed(index), 'MerkleDistributor: Drop already claimed.'); + + // Verify the merkle proof. + bytes32 node = keccak256(abi.encodePacked(index, account, amount)); + require(MerkleProof.verify(merkleProof, merkleRoot, node), 'MerkleDistributor: Invalid proof.'); + + // Mark it claimed and send the token. + _setClaimed(index); + require(IERC20(token).transfer(account, amount), 'MerkleDistributor: Transfer failed.'); + + emit Claimed(index, account, amount); + } +} diff --git a/contracts/v1/incentives/MerkleDistributor2.sol b/contracts/v1/incentives/MerkleDistributor2.sol new file mode 100644 index 0000000..c890e05 --- /dev/null +++ b/contracts/v1/incentives/MerkleDistributor2.sol @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/cryptography/MerkleProof.sol"; +import "../interfaces/IMerkleDistributor.sol"; + +contract MerkleDistributor2 is IMerkleDistributor { + address public immutable override token; + bytes32 public immutable override merkleRoot; + + address public owner; + uint256 public immutable expiryDate; + + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + // This is a packed array of booleans. + mapping(uint256 => uint256) private claimedBitMap; + + constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public { + owner = msg.sender; + token = token_; + merkleRoot = merkleRoot_; + expiryDate = expiryDate_; + } + + function isClaimed(uint256 index) public view override returns (bool) { + uint256 claimedWordIndex = index / 256; + uint256 claimedBitIndex = index % 256; + uint256 claimedWord = claimedBitMap[claimedWordIndex]; + uint256 mask = (1 << claimedBitIndex); + return claimedWord & mask == mask; + } + + function _setClaimed(uint256 index) private { + uint256 claimedWordIndex = index / 256; + uint256 claimedBitIndex = index % 256; + claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex); + } + + function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override { + require(!isClaimed(index), "MerkleDistributor2: Drop already claimed."); + + // Verify the merkle proof. + bytes32 node = keccak256(abi.encodePacked(index, account, amount)); + require(MerkleProof.verify(merkleProof, merkleRoot, node), "MerkleDistributor2: Invalid proof."); + + // Mark it claimed and send the token. + _setClaimed(index); + require(IERC20(token).transfer(account, amount), "MerkleDistributor2: Transfer failed."); + + emit Claimed(index, account, amount); + } + + function expire(address exitAddress) external onlyOwner { + require(block.timestamp >= expiryDate, "MerkleDistributor2: expiry date not reached"); + uint256 remainingBalance = IERC20(token).balanceOf(address(this)); + IERC20(token).transfer(exitAddress, remainingBalance); + } + + function transferOwnership(address newOwner) external onlyOwner { + require(newOwner != address(0), "MerkleDistributor2: new owner is the zero address"); + emit OwnershipTransferred(owner, newOwner); + owner = newOwner; + } + + modifier onlyOwner() { + require(msg.sender == owner, "MerkleDistributor2: not owner"); + _; + } +} diff --git a/contracts/v1/incentives/MerkleDistributor3.sol b/contracts/v1/incentives/MerkleDistributor3.sol new file mode 100644 index 0000000..331819b --- /dev/null +++ b/contracts/v1/incentives/MerkleDistributor3.sol @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/cryptography/MerkleProof.sol"; +import "../interfaces/IMerkleDistributor.sol"; + +contract MerkleDistributor3 is IMerkleDistributor { + address public immutable override token; + bytes32 public immutable override merkleRoot; + + address public owner; + uint256 public immutable expiryDate; + + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + // This is a packed array of booleans. + mapping(uint256 => uint256) private claimedBitMap; + + constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public { + owner = msg.sender; + token = token_; + merkleRoot = merkleRoot_; + expiryDate = expiryDate_; + } + + function isClaimed(uint256 index) public view override returns (bool) { + uint256 claimedWordIndex = index / 256; + uint256 claimedBitIndex = index % 256; + uint256 claimedWord = claimedBitMap[claimedWordIndex]; + uint256 mask = (1 << claimedBitIndex); + return claimedWord & mask == mask; + } + + function _setClaimed(uint256 index) private { + uint256 claimedWordIndex = index / 256; + uint256 claimedBitIndex = index % 256; + claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex); + } + + function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override { + require(!isClaimed(index), "MerkleDistributor3: Drop already claimed."); + + // Verify the merkle proof. + bytes32 node = keccak256(abi.encodePacked(index, account, amount)); + require(MerkleProof.verify(merkleProof, merkleRoot, node), "MerkleDistributor3: Invalid proof."); + + // Mark it claimed and send the token. + _setClaimed(index); + require(IERC20(token).transfer(account, amount), "MerkleDistributor3: Transfer failed."); + + emit Claimed(index, account, amount); + } + + function expire(address exitAddress) external onlyOwner { + require(block.timestamp >= expiryDate, "MerkleDistributor3: expiry date not reached"); + uint256 remainingBalance = IERC20(token).balanceOf(address(this)); + IERC20(token).transfer(exitAddress, remainingBalance); + } + + function transferOwnership(address newOwner) external onlyOwner { + require(newOwner != address(0), "MerkleDistributor3: new owner is the zero address"); + emit OwnershipTransferred(owner, newOwner); + owner = newOwner; + } + + modifier onlyOwner() { + require(msg.sender == owner, "MerkleDistributor3: not owner"); + _; + } +} diff --git a/contracts/v1/incentives/RewardProgram.sol b/contracts/v1/incentives/RewardProgram.sol new file mode 100644 index 0000000..cdaae65 --- /dev/null +++ b/contracts/v1/incentives/RewardProgram.sol @@ -0,0 +1,390 @@ +// SPDX-License-Identifier: MIT + +// RewardProgram.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2023 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; +pragma experimental ABIEncoderV2; + +import "../interfaces/IRewardProgram.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/introspection/IERC165.sol"; +import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; +import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol"; +import "@openzeppelin/contracts/utils/EnumerableSet.sol"; + +import "../interfaces/IUniverseRP.sol"; +import "../interfaces/IChargedManagers.sol"; +import "../interfaces/IWalletManager.sol"; +import "../lib/TokenInfo.sol"; +import "../lib/ReentrancyGuard.sol"; +import "../lib/BlackholePrevention.sol"; +import "../interfaces/IERC20Detailed.sol"; + +contract RewardProgram is + IRewardProgram, + BlackholePrevention, + IERC165, + ReentrancyGuard, + IERC721Receiver, + IERC1155Receiver +{ + using SafeMath for uint256; + using TokenInfo for address; + using SafeERC20 for IERC20; + using EnumerableSet for EnumerableSet.UintSet; + + uint256 constant private PERCENTAGE_SCALE = 1e4; // 10000 (100%) + uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2; + + address private _owner; + IUniverseRP private _universe; + IChargedManagers private _chargedManagers; + ProgramRewardData private _programData; + mapping(uint256 => AssetStake) private _assetStake; + + + /***********************************| + | Initialization | + |__________________________________*/ + + constructor() public {} + + function initialize( + address stakingToken, + address rewardToken, + uint256 baseMultiplier, + address chargedManagers, + address universe, + address owner + ) external override { + require(_owner == address(0x0), "Already initialized"); + _owner = owner; + + // Prepare Reward Program + _programData.stakingToken = stakingToken; + _programData.rewardToken = rewardToken; + _programData.baseMultiplier = baseMultiplier; // Basis Points + + // Connect to Charged Particles + _chargedManagers = IChargedManagers(chargedManagers); + _universe = IUniverseRP(universe); + } + + + /***********************************| + | Public Functions | + |__________________________________*/ + + function getProgramData() external view override returns (ProgramRewardData memory) { + return _programData; + } + + function getAssetStake(uint256 parentNftUuid) external view override returns (AssetStake memory) { + return _assetStake[parentNftUuid]; + } + + function getFundBalance() external view override returns (uint256) { + return _getFundBalance(); + } + + function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) public view override returns (uint256) { + return _calculateRewardsEarned(parentNftUuid, interestAmount); + } + + function getClaimableRewards(address contractAddress, uint256 tokenId) external view override returns (uint256) { + uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId); + return _assetStake[parentNftUuid].claimableRewards; + } + + function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) { + return IERC721Receiver.onERC721Received.selector; + } + + function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) { + return IERC1155Receiver.onERC1155BatchReceived.selector; + } + + function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) { + return ""; + } + + function supportsInterface(bytes4 interfaceId) + public + view + virtual + override(IERC165) + returns (bool) + { + // default interface support + if ( + interfaceId == type(IERC721Receiver).interfaceId || + interfaceId == type(IERC1155Receiver).interfaceId || + interfaceId == type(IERC165).interfaceId + ) { + return true; + } + } + + function owner() public view returns (address) { + return _owner; + } + + + /***********************************| + | Only Universe | + |__________________________________*/ + + function registerAssetDeposit( + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + uint256 principalAmount + ) + external + override + onlyUniverse + { + uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId); + AssetStake storage assetStake = _assetStake[parentNftUuid]; + + if (assetStake.start == 0) { + assetStake.start = block.number; + assetStake.walletManagerId = walletManagerId; + } + emit AssetDeposit(contractAddress, tokenId, walletManagerId, principalAmount); + } + + function registerAssetRelease( + address contractAddress, + uint256 tokenId, + uint256 interestAmount + ) + external + override + onlyUniverse + nonReentrant + returns (uint256 rewards) + { + uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId); + AssetStake storage assetStake = _assetStake[parentNftUuid]; + + if (assetStake.start > 0) { + // Update Claimable Rewards + uint256 newRewards = _calculateRewardsEarned(parentNftUuid, interestAmount); + assetStake.claimableRewards = assetStake.claimableRewards.add(newRewards); + + // Reset Stake if Principal Balance falls to Zero + IWalletManager walletMgr = _chargedManagers.getWalletManager(assetStake.walletManagerId); + uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken); + if (principal == 0) { + assetStake.start = 0; + } + + // Issue Rewards to NFT Owner + rewards = _claimRewards(contractAddress, tokenId); + + emit AssetRelease(contractAddress, tokenId, interestAmount); + } + } + + + /***********************************| + | Reward Calculation | + |__________________________________*/ + + function _calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) internal view returns (uint256 totalReward) { + uint256 baseReward = _calculateBaseReward(interestAmount); + uint256 leptonMultipliedReward = _calculateMultipliedReward(parentNftUuid, baseReward); + totalReward = _convertDecimals(leptonMultipliedReward); + } + + function _calculateBaseReward(uint256 amount) internal view returns(uint256 baseReward) { + baseReward = amount.mul(_programData.baseMultiplier).div(PERCENTAGE_SCALE); + } + + function _calculateMultipliedReward(uint256 parentNftUuid, uint256 baseReward) internal view returns(uint256) { + AssetStake storage assetStake = _assetStake[parentNftUuid]; + if (assetStake.start == 0) { return baseReward; } + + IUniverseRP.NftStake memory nftStake = _universe.getNftStake(parentNftUuid); + uint256 multiplierBP = nftStake.multiplier; + + uint256 assetDepositLength = block.number.sub(assetStake.start); + uint256 nftDepositLength = 0; + if (nftStake.releaseBlockNumber > 0) { + nftDepositLength = nftStake.releaseBlockNumber.sub(nftStake.depositBlockNumber); + } else { + nftDepositLength = block.number.sub(nftStake.depositBlockNumber); + } + + if (multiplierBP == 0 || nftDepositLength == 0 || assetDepositLength == 0) { + return baseReward; + } + + if (nftDepositLength > assetDepositLength) { + nftDepositLength = assetDepositLength; + } + + // Percentage of the total program that the Multiplier Nft was deposited for + uint256 nftRewardRatioBP = nftDepositLength.mul(PERCENTAGE_SCALE).div(assetDepositLength); + + // Amount of reward that the Multiplier Nft is responsible for + uint256 amountGeneratedDuringNftDeposit = baseReward.mul(nftRewardRatioBP).div(PERCENTAGE_SCALE); + + // Amount of Multiplied Reward from NFT + uint256 multipliedReward = amountGeneratedDuringNftDeposit.mul(multiplierBP.mul(LEPTON_MULTIPLIER_SCALE)).div(PERCENTAGE_SCALE); + + // Amount of Base Reward without Multiplied NFT Rewards + uint256 amountGeneratedWithoutNftDeposit = baseReward.sub(amountGeneratedDuringNftDeposit); + + // Amount of Base Rewards + Multiplied NFT Rewards + return amountGeneratedWithoutNftDeposit.add(multipliedReward); + } + + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + function fundProgram(uint256 amount) external onlyOwner { + require(_programData.rewardToken != address(0), "RP:E-405"); + IERC20(_programData.rewardToken).safeTransferFrom(msg.sender, address(this), amount); + emit RewardProgramFunded(amount); + } + + function setStakingToken(address newStakingToken) external onlyOwner { + _programData.stakingToken = newStakingToken; + } + + function setRewardToken(address newRewardToken) external onlyOwner { + _programData.rewardToken = newRewardToken; + } + + function setBaseMultiplier(uint256 newMultiplier) external onlyOwner { + _programData.baseMultiplier = newMultiplier; // Basis Points + } + + function setChargedManagers(address manager) external onlyOwner { + _chargedManagers = IChargedManagers(manager); + } + + function setUniverse(address universe) external onlyOwner { + _universe = IUniverseRP(universe); + } + + function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external override onlyOwner { + uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId); + + // Initiate Asset Stake + IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId); + uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken); + if (principal > 0) { + _assetStake[parentNftUuid] = AssetStake(block.number, 0, walletManagerId); + emit AssetRegistered(contractAddress, tokenId, walletManagerId, principal); + } + } + + + /***********************************| + | Only Admin/DAO | + | (blackhole prevention) | + |__________________________________*/ + + function withdrawEther(address payable receiver, uint256 amount) external onlyOwner { + _withdrawEther(receiver, amount); + } + + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner { + _withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner { + _withdrawERC1155(receiver, tokenAddress, tokenId, amount); + } + + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _claimRewards( + address contractAddress, + uint256 tokenId + ) + internal + returns (uint256 totalReward) + { + uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId); + AssetStake storage assetStake = _assetStake[parentNftUuid]; + + // Rewards Receiver + address receiver = IERC721(contractAddress).ownerOf(tokenId); + + // Ensure Reward Pool has Sufficient Balance + totalReward = assetStake.claimableRewards; + uint256 fundBalance = _getFundBalance(); + uint256 unavailReward = totalReward > fundBalance ? totalReward.sub(fundBalance) : 0; + + // Determine amount of Rewards to Transfer + if (unavailReward > 0) { + totalReward = totalReward.sub(unavailReward); + emit RewardProgramOutOfFunds(); + } + + // Update Asset Stake + assetStake.claimableRewards = unavailReward; + + if (totalReward > 0) { + // Transfer Available Rewards to Receiver + IERC20(_programData.rewardToken).safeTransfer(receiver, totalReward); + } + + emit RewardsClaimed(contractAddress, tokenId, receiver, totalReward, unavailReward); + } + + function _convertDecimals(uint256 reward) internal view returns (uint256) { + uint8 stakingTokenDecimals = IERC20Detailed(_programData.stakingToken).decimals(); + return reward.mul(10**(18 - uint256(stakingTokenDecimals))); + } + + function _getFundBalance() internal view returns (uint256) { + return IERC20Detailed(_programData.rewardToken).balanceOf(address(this)); + } + + + modifier onlyOwner() { + require(_owner == msg.sender, "Caller is not the owner"); + _; + } + + modifier onlyUniverse() { + require(msg.sender == address(_universe), "RP:E-108"); + _; + } +} diff --git a/contracts/v1/incentives/RewardProgramFactory.sol b/contracts/v1/incentives/RewardProgramFactory.sol new file mode 100644 index 0000000..9bd1698 --- /dev/null +++ b/contracts/v1/incentives/RewardProgramFactory.sol @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: MIT + +// RewardProgramFactory.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2023 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; +pragma experimental ABIEncoderV2; + +import "@openzeppelin/contracts/access/Ownable.sol"; + +import "./RewardProgram.sol"; +import "../lib/BlackholePrevention.sol"; + +contract RewardProgramFactory is BlackholePrevention, Ownable { + event RewardProgramCreated(address indexed rewardProgram); + + address public _template; + + constructor () public { + _template = address(new RewardProgram()); + } + + // function _msgSender() internal view override returns (address payable) { + // return msg.sender; + // } + + function createRewardProgram( + address stakingToken, + address rewardToken, + uint256 baseMultiplier, + address chargedManagers, + address universe + ) + external + onlyOwner + returns (address) + { + address newRewardProgram = _createClone(_template); + RewardProgram rewardProgram = RewardProgram(newRewardProgram); + rewardProgram.initialize(stakingToken, rewardToken, baseMultiplier, chargedManagers, universe, _msgSender()); + emit RewardProgramCreated(newRewardProgram); + return newRewardProgram; + } + + /** + * @dev Creates Contracts from a Template via Cloning + * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md + */ + function _createClone(address target) internal returns (address result) { + bytes20 targetBytes = bytes20(target); + assembly { + let clone := mload(0x40) + mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) + mstore(add(clone, 0x14), targetBytes) + mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) + result := create(0, clone, 0x37) + } + } + + + /***********************************| + | Only Admin/DAO | + | (blackhole prevention) | + |__________________________________*/ + + function withdrawEther(address payable receiver, uint256 amount) external onlyOwner { + _withdrawEther(receiver, amount); + } + + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner { + _withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner { + _withdrawERC1155(receiver, tokenAddress, tokenId, amount); + } +} diff --git a/contracts/v1/incentives/Staking.sol b/contracts/v1/incentives/Staking.sol new file mode 100644 index 0000000..4f06325 --- /dev/null +++ b/contracts/v1/incentives/Staking.sol @@ -0,0 +1,412 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.6.11; + +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; +import "../lib/BlackholePrevention.sol"; + +contract Staking is + Ownable, + ReentrancyGuard, + BlackholePrevention +{ + using SafeMath for uint256; + + uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18); + + bool internal _paused; + + // timestamp for the epoch 1 + // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake + uint256 public immutable epoch1Start; + + // duration of each epoch + uint256 public immutable epochDuration; + + // holds the current balance of the user for each token + mapping(address => mapping(address => uint256)) private balances; + + struct Pool { + uint256 size; + bool set; + } + + // for each token, we store the total pool size + mapping(address => mapping(uint256 => Pool)) private poolSize; + + // a checkpoint of the valid balance of a user for an epoch + struct Checkpoint { + uint128 epochId; + uint128 multiplier; + uint256 startBalance; + uint256 newDeposits; + } + + // balanceCheckpoints[user][token][] + mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints; + + mapping(address => uint128) private lastWithdrawEpochId; + + event PausedStateSet(bool isPaused); + event Deposit(address indexed user, address indexed tokenAddress, uint256 amount); + event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount); + event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens); + event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount); + + constructor (uint256 _epoch1Start, uint256 _epochDuration) public { + _paused = false; + epoch1Start = _epoch1Start; + epochDuration = _epochDuration; + } + + function isPaused() external view returns (bool) { + return _paused; + } + + /* + * Stores `amount` of `tokenAddress` tokens for the `user` into the vault + */ + function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused { + require(amount > 0, "STK:E-205"); + + IERC20 token = IERC20(tokenAddress); + + balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount); + + token.transferFrom(msg.sender, address(this), amount); + + // epoch logic + uint128 currentEpoch = getCurrentEpoch(); + uint128 currentMultiplier = currentEpochMultiplier(); + uint256 balance = balances[msg.sender][tokenAddress]; + + if (!epochIsInitialized(tokenAddress, currentEpoch)) { + address[] memory tokens = new address[](1); + tokens[0] = tokenAddress; + manualEpochInit(tokens, currentEpoch); + } + + // update the next epoch pool size + Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1]; + pNextEpoch.size = token.balanceOf(address(this)); + pNextEpoch.set = true; + + Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress]; + + uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch); + + // if there's no checkpoint yet, it means the user didn't have any activity + // we want to store checkpoints both for the current epoch and next epoch because + // if a user does a withdraw, the current epoch can also be modified and + // we don't want to insert another checkpoint in the middle of the array as that could be expensive + if (checkpoints.length == 0) { + checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount)); + + // next epoch => multiplier is 1, epoch deposits is 0 + checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0)); + } else { + uint256 last = checkpoints.length - 1; + + // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5) + if (checkpoints[last].epochId < currentEpoch) { + uint128 multiplier = computeNewMultiplier( + getCheckpointBalance(checkpoints[last]), + BASE_MULTIPLIER, + amount, + currentMultiplier + ); + checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount)); + checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0)); + } + // the last action happened in the previous epoch + else if (checkpoints[last].epochId == currentEpoch) { + checkpoints[last].multiplier = computeNewMultiplier( + getCheckpointBalance(checkpoints[last]), + checkpoints[last].multiplier, + amount, + currentMultiplier + ); + checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount); + + checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0)); + } + // the last action happened in the current epoch + else { + if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) { + checkpoints[last - 1].multiplier = computeNewMultiplier( + getCheckpointBalance(checkpoints[last - 1]), + checkpoints[last - 1].multiplier, + amount, + currentMultiplier + ); + checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount); + } + + checkpoints[last].startBalance = balance; + } + } + + uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch); + + poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore)); + + emit Deposit(msg.sender, tokenAddress, amount); + } + + /* + * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user` + */ + function withdraw(address tokenAddress, uint256 amount) public nonReentrant { + require(balances[msg.sender][tokenAddress] >= amount, "STK:E-432"); + + balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount); + + IERC20 token = IERC20(tokenAddress); + token.transfer(msg.sender, amount); + + // epoch logic + uint128 currentEpoch = getCurrentEpoch(); + + lastWithdrawEpochId[tokenAddress] = currentEpoch; + + if (!epochIsInitialized(tokenAddress, currentEpoch)) { + address[] memory tokens = new address[](1); + tokens[0] = tokenAddress; + manualEpochInit(tokens, currentEpoch); + } + + // update the pool size of the next epoch to its current balance + Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1]; + pNextEpoch.size = token.balanceOf(address(this)); + pNextEpoch.set = true; + + Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress]; + uint256 last = checkpoints.length - 1; + + // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert + + // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then + if (checkpoints[last].epochId < currentEpoch) { + checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0)); + + poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount); + } + // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch + else if (checkpoints[last].epochId == currentEpoch) { + checkpoints[last].startBalance = balances[msg.sender][tokenAddress]; + checkpoints[last].newDeposits = 0; + checkpoints[last].multiplier = BASE_MULTIPLIER; + + poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount); + } + // there was a deposit in the current epoch + else { + Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1]; + + uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint); + + // in case of withdraw, we have 2 branches: + // 1. the user withdraws less than he added in the current epoch + // 2. the user withdraws more than he added in the current epoch (including 0) + if (amount < currentEpochCheckpoint.newDeposits) { + uint128 avgDepositMultiplier = uint128( + balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits) + ); + + currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount); + + currentEpochCheckpoint.multiplier = computeNewMultiplier( + currentEpochCheckpoint.startBalance, + BASE_MULTIPLIER, + currentEpochCheckpoint.newDeposits, + avgDepositMultiplier + ); + } else { + currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub( + amount.sub(currentEpochCheckpoint.newDeposits) + ); + currentEpochCheckpoint.newDeposits = 0; + currentEpochCheckpoint.multiplier = BASE_MULTIPLIER; + } + + uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint); + + poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter)); + + checkpoints[last].startBalance = balances[msg.sender][tokenAddress]; + } + + emit Withdraw(msg.sender, tokenAddress, amount); + } + + /* + * manualEpochInit can be used by anyone to initialize an epoch based on the previous one + * This is only applicable if there was no action (deposit/withdraw) in the current epoch. + * Any deposit and withdraw will automatically initialize the current and next epoch. + */ + function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused { + require(epochId <= getCurrentEpoch(), "STK:E-306"); + + + for (uint i = 0; i < tokens.length; i++) { + Pool storage p = poolSize[tokens[i]][epochId]; + if (epochId == 0) { + p.size = uint256(0); + p.set = true; + } else { + require(!epochIsInitialized(tokens[i], epochId), "STK:E-002"); + require(epochIsInitialized(tokens[i], epochId - 1), "STK:E-305"); + p.size = poolSize[tokens[i]][epochId - 1].size; + p.set = true; + } + } + + emit ManualEpochInit(msg.sender, epochId, tokens); + } + + function emergencyWithdraw(address tokenAddress) public { + require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, "STK:E-304"); + + uint256 totalUserBalance = balances[msg.sender][tokenAddress]; + require(totalUserBalance > 0, "STK:E-205"); + + balances[msg.sender][tokenAddress] = 0; + + IERC20 token = IERC20(tokenAddress); + token.transfer(msg.sender, totalUserBalance); + + emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance); + } + + /* + * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch + * A deposit will only change the next epoch balance. + * A withdraw will decrease the current epoch (and subsequent) balance. + */ + function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) { + Checkpoint[] storage checkpoints = balanceCheckpoints[user][token]; + + // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0 + if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) { + return 0; + } + + uint min = 0; + uint max = checkpoints.length - 1; + + // shortcut for blocks newer than the latest checkpoint == current balance + if (epochId >= checkpoints[max].epochId) { + return getCheckpointEffectiveBalance(checkpoints[max]); + } + + // binary search of the value in the array + while (max > min) { + uint mid = (max + min + 1) / 2; + if (checkpoints[mid].epochId <= epochId) { + min = mid; + } else { + max = mid - 1; + } + } + + return getCheckpointEffectiveBalance(checkpoints[min]); + } + + /* + * Returns the amount of `token` that the `user` has currently staked + */ + function balanceOf(address user, address token) public view returns (uint256) { + return balances[user][token]; + } + + /* + * Returns the id of the current epoch derived from block.timestamp + */ + function getCurrentEpoch() public view returns (uint128) { + if (block.timestamp < epoch1Start) { + return 0; + } + + return uint128((block.timestamp - epoch1Start) / epochDuration + 1); + } + + /* + * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId` + */ + function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) { + // Premises: + // 1. it's impossible to have gaps of uninitialized epochs + // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized + if (epochIsInitialized(tokenAddress, epochId)) { + return poolSize[tokenAddress][epochId].size; + } + + // epochId not initialized and epoch 0 not initialized => there was never any action on this pool + if (!epochIsInitialized(tokenAddress, 0)) { + return 0; + } + + // epoch 0 is initialized => there was an action at some point but none that initialized the epochId + // which means the current pool size is equal to the current balance of token held by the staking contract + IERC20 token = IERC20(tokenAddress); + return token.balanceOf(address(this)); + } + + /* + * Returns the percentage of time left in the current epoch + */ + function currentEpochMultiplier() public view returns (uint128) { + uint128 currentEpoch = getCurrentEpoch(); + uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration; + uint256 timeLeft = currentEpochEnd - block.timestamp; + uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration); + + return multiplier; + } + + function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) { + uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER); + uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER); + uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount))); + + return newMultiplier; + } + + /* + * Checks if an epoch is initialized, meaning we have a pool size set for it + */ + function epochIsInitialized(address token, uint128 epochId) public view returns (bool) { + return poolSize[token][epochId].set; + } + + function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) { + return c.startBalance.add(c.newDeposits); + } + + function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) { + return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER); + } + + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + function setPausedState(bool paused) external onlyOwner { + _paused = paused; + emit PausedStateSet(paused); + } + + // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it + function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner { + _withdrawEther(receiver, amount); + } + + modifier whenNotPaused() { + require(_paused != true, "STK:E-101"); + _; + } + +} diff --git a/contracts/v1/incentives/Staking2.sol b/contracts/v1/incentives/Staking2.sol new file mode 100644 index 0000000..8c513fb --- /dev/null +++ b/contracts/v1/incentives/Staking2.sol @@ -0,0 +1,412 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.6.11; + +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; +import "../lib/BlackholePrevention.sol"; + +contract Staking2 is + Ownable, + ReentrancyGuard, + BlackholePrevention +{ + using SafeMath for uint256; + + uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18); + + bool internal _paused; + + // timestamp for the epoch 1 + // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake + uint256 public immutable epoch1Start; + + // duration of each epoch + uint256 public immutable epochDuration; + + // holds the current balance of the user for each token + mapping(address => mapping(address => uint256)) private balances; + + struct Pool { + uint256 size; + bool set; + } + + // for each token, we store the total pool size + mapping(address => mapping(uint256 => Pool)) private poolSize; + + // a checkpoint of the valid balance of a user for an epoch + struct Checkpoint { + uint128 epochId; + uint128 multiplier; + uint256 startBalance; + uint256 newDeposits; + } + + // balanceCheckpoints[user][token][] + mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints; + + mapping(address => uint128) private lastWithdrawEpochId; + + event PausedStateSet(bool isPaused); + event Deposit(address indexed user, address indexed tokenAddress, uint256 amount); + event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount); + event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens); + event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount); + + constructor (uint256 _epoch1Start, uint256 _epochDuration) public { + _paused = false; + epoch1Start = _epoch1Start; + epochDuration = _epochDuration; + } + + function isPaused() external view returns (bool) { + return _paused; + } + + /* + * Stores `amount` of `tokenAddress` tokens for the `user` into the vault + */ + function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused { + require(amount > 0, "STK:E-205"); + + IERC20 token = IERC20(tokenAddress); + + balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount); + + token.transferFrom(msg.sender, address(this), amount); + + // epoch logic + uint128 currentEpoch = getCurrentEpoch(); + uint128 currentMultiplier = currentEpochMultiplier(); + uint256 balance = balances[msg.sender][tokenAddress]; + + if (!epochIsInitialized(tokenAddress, currentEpoch)) { + address[] memory tokens = new address[](1); + tokens[0] = tokenAddress; + manualEpochInit(tokens, currentEpoch); + } + + // update the next epoch pool size + Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1]; + pNextEpoch.size = token.balanceOf(address(this)); + pNextEpoch.set = true; + + Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress]; + + uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch); + + // if there's no checkpoint yet, it means the user didn't have any activity + // we want to store checkpoints both for the current epoch and next epoch because + // if a user does a withdraw, the current epoch can also be modified and + // we don't want to insert another checkpoint in the middle of the array as that could be expensive + if (checkpoints.length == 0) { + checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount)); + + // next epoch => multiplier is 1, epoch deposits is 0 + checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0)); + } else { + uint256 last = checkpoints.length - 1; + + // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5) + if (checkpoints[last].epochId < currentEpoch) { + uint128 multiplier = computeNewMultiplier( + getCheckpointBalance(checkpoints[last]), + BASE_MULTIPLIER, + amount, + currentMultiplier + ); + checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount)); + checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0)); + } + // the last action happened in the previous epoch + else if (checkpoints[last].epochId == currentEpoch) { + checkpoints[last].multiplier = computeNewMultiplier( + getCheckpointBalance(checkpoints[last]), + checkpoints[last].multiplier, + amount, + currentMultiplier + ); + checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount); + + checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0)); + } + // the last action happened in the current epoch + else { + if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) { + checkpoints[last - 1].multiplier = computeNewMultiplier( + getCheckpointBalance(checkpoints[last - 1]), + checkpoints[last - 1].multiplier, + amount, + currentMultiplier + ); + checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount); + } + + checkpoints[last].startBalance = balance; + } + } + + uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch); + + poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore)); + + emit Deposit(msg.sender, tokenAddress, amount); + } + + /* + * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user` + */ + function withdraw(address tokenAddress, uint256 amount) public nonReentrant { + require(balances[msg.sender][tokenAddress] >= amount, "STK:E-432"); + + balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount); + + IERC20 token = IERC20(tokenAddress); + token.transfer(msg.sender, amount); + + // epoch logic + uint128 currentEpoch = getCurrentEpoch(); + + lastWithdrawEpochId[tokenAddress] = currentEpoch; + + if (!epochIsInitialized(tokenAddress, currentEpoch)) { + address[] memory tokens = new address[](1); + tokens[0] = tokenAddress; + manualEpochInit(tokens, currentEpoch); + } + + // update the pool size of the next epoch to its current balance + Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1]; + pNextEpoch.size = token.balanceOf(address(this)); + pNextEpoch.set = true; + + Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress]; + uint256 last = checkpoints.length - 1; + + // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert + + // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then + if (checkpoints[last].epochId < currentEpoch) { + checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0)); + + poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount); + } + // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch + else if (checkpoints[last].epochId == currentEpoch) { + checkpoints[last].startBalance = balances[msg.sender][tokenAddress]; + checkpoints[last].newDeposits = 0; + checkpoints[last].multiplier = BASE_MULTIPLIER; + + poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount); + } + // there was a deposit in the current epoch + else { + Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1]; + + uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint); + + // in case of withdraw, we have 2 branches: + // 1. the user withdraws less than he added in the current epoch + // 2. the user withdraws more than he added in the current epoch (including 0) + if (amount < currentEpochCheckpoint.newDeposits) { + uint128 avgDepositMultiplier = uint128( + balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits) + ); + + currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount); + + currentEpochCheckpoint.multiplier = computeNewMultiplier( + currentEpochCheckpoint.startBalance, + BASE_MULTIPLIER, + currentEpochCheckpoint.newDeposits, + avgDepositMultiplier + ); + } else { + currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub( + amount.sub(currentEpochCheckpoint.newDeposits) + ); + currentEpochCheckpoint.newDeposits = 0; + currentEpochCheckpoint.multiplier = BASE_MULTIPLIER; + } + + uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint); + + poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter)); + + checkpoints[last].startBalance = balances[msg.sender][tokenAddress]; + } + + emit Withdraw(msg.sender, tokenAddress, amount); + } + + /* + * manualEpochInit can be used by anyone to initialize an epoch based on the previous one + * This is only applicable if there was no action (deposit/withdraw) in the current epoch. + * Any deposit and withdraw will automatically initialize the current and next epoch. + */ + function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused { + require(epochId <= getCurrentEpoch(), "STK:E-306"); + + + for (uint i = 0; i < tokens.length; i++) { + Pool storage p = poolSize[tokens[i]][epochId]; + if (epochId == 0) { + p.size = uint256(0); + p.set = true; + } else { + require(!epochIsInitialized(tokens[i], epochId), "STK:E-002"); + require(epochIsInitialized(tokens[i], epochId - 1), "STK:E-305"); + p.size = poolSize[tokens[i]][epochId - 1].size; + p.set = true; + } + } + + emit ManualEpochInit(msg.sender, epochId, tokens); + } + + function emergencyWithdraw(address tokenAddress) public { + require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, "STK:E-304"); + + uint256 totalUserBalance = balances[msg.sender][tokenAddress]; + require(totalUserBalance > 0, "STK:E-205"); + + balances[msg.sender][tokenAddress] = 0; + + IERC20 token = IERC20(tokenAddress); + token.transfer(msg.sender, totalUserBalance); + + emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance); + } + + /* + * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch + * A deposit will only change the next epoch balance. + * A withdraw will decrease the current epoch (and subsequent) balance. + */ + function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) { + Checkpoint[] storage checkpoints = balanceCheckpoints[user][token]; + + // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0 + if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) { + return 0; + } + + uint min = 0; + uint max = checkpoints.length - 1; + + // shortcut for blocks newer than the latest checkpoint == current balance + if (epochId >= checkpoints[max].epochId) { + return getCheckpointEffectiveBalance(checkpoints[max]); + } + + // binary search of the value in the array + while (max > min) { + uint mid = (max + min + 1) / 2; + if (checkpoints[mid].epochId <= epochId) { + min = mid; + } else { + max = mid - 1; + } + } + + return getCheckpointEffectiveBalance(checkpoints[min]); + } + + /* + * Returns the amount of `token` that the `user` has currently staked + */ + function balanceOf(address user, address token) public view returns (uint256) { + return balances[user][token]; + } + + /* + * Returns the id of the current epoch derived from block.timestamp + */ + function getCurrentEpoch() public view returns (uint128) { + if (block.timestamp < epoch1Start) { + return 0; + } + + return uint128((block.timestamp - epoch1Start) / epochDuration + 1); + } + + /* + * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId` + */ + function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) { + // Premises: + // 1. it's impossible to have gaps of uninitialized epochs + // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized + if (epochIsInitialized(tokenAddress, epochId)) { + return poolSize[tokenAddress][epochId].size; + } + + // epochId not initialized and epoch 0 not initialized => there was never any action on this pool + if (!epochIsInitialized(tokenAddress, 0)) { + return 0; + } + + // epoch 0 is initialized => there was an action at some point but none that initialized the epochId + // which means the current pool size is equal to the current balance of token held by the staking contract + IERC20 token = IERC20(tokenAddress); + return token.balanceOf(address(this)); + } + + /* + * Returns the percentage of time left in the current epoch + */ + function currentEpochMultiplier() public view returns (uint128) { + uint128 currentEpoch = getCurrentEpoch(); + uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration; + uint256 timeLeft = currentEpochEnd - block.timestamp; + uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration); + + return multiplier; + } + + function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) { + uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER); + uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER); + uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount))); + + return newMultiplier; + } + + /* + * Checks if an epoch is initialized, meaning we have a pool size set for it + */ + function epochIsInitialized(address token, uint128 epochId) public view returns (bool) { + return poolSize[token][epochId].set; + } + + function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) { + return c.startBalance.add(c.newDeposits); + } + + function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) { + return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER); + } + + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + function setPausedState(bool paused) external onlyOwner { + _paused = paused; + emit PausedStateSet(paused); + } + + // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it + function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner { + _withdrawEther(receiver, amount); + } + + modifier whenNotPaused() { + require(_paused != true, "STK:E-101"); + _; + } + +} diff --git a/contracts/v1/incentives/Staking3.sol b/contracts/v1/incentives/Staking3.sol new file mode 100644 index 0000000..ea5a761 --- /dev/null +++ b/contracts/v1/incentives/Staking3.sol @@ -0,0 +1,412 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.6.11; + +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; +import "../lib/BlackholePrevention.sol"; + +contract Staking3 is + Ownable, + ReentrancyGuard, + BlackholePrevention +{ + using SafeMath for uint256; + + uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18); + + bool internal _paused; + + // timestamp for the epoch 1 + // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake + uint256 public immutable epoch1Start; + + // duration of each epoch + uint256 public immutable epochDuration; + + // holds the current balance of the user for each token + mapping(address => mapping(address => uint256)) private balances; + + struct Pool { + uint256 size; + bool set; + } + + // for each token, we store the total pool size + mapping(address => mapping(uint256 => Pool)) private poolSize; + + // a checkpoint of the valid balance of a user for an epoch + struct Checkpoint { + uint128 epochId; + uint128 multiplier; + uint256 startBalance; + uint256 newDeposits; + } + + // balanceCheckpoints[user][token][] + mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints; + + mapping(address => uint128) private lastWithdrawEpochId; + + event PausedStateSet(bool isPaused); + event Deposit(address indexed user, address indexed tokenAddress, uint256 amount); + event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount); + event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens); + event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount); + + constructor (uint256 _epoch1Start, uint256 _epochDuration) public { + _paused = false; + epoch1Start = _epoch1Start; + epochDuration = _epochDuration; + } + + function isPaused() external view returns (bool) { + return _paused; + } + + /* + * Stores `amount` of `tokenAddress` tokens for the `user` into the vault + */ + function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused { + require(amount > 0, "STK:E-205"); + + IERC20 token = IERC20(tokenAddress); + + balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount); + + token.transferFrom(msg.sender, address(this), amount); + + // epoch logic + uint128 currentEpoch = getCurrentEpoch(); + uint128 currentMultiplier = currentEpochMultiplier(); + uint256 balance = balances[msg.sender][tokenAddress]; + + if (!epochIsInitialized(tokenAddress, currentEpoch)) { + address[] memory tokens = new address[](1); + tokens[0] = tokenAddress; + manualEpochInit(tokens, currentEpoch); + } + + // update the next epoch pool size + Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1]; + pNextEpoch.size = token.balanceOf(address(this)); + pNextEpoch.set = true; + + Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress]; + + uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch); + + // if there's no checkpoint yet, it means the user didn't have any activity + // we want to store checkpoints both for the current epoch and next epoch because + // if a user does a withdraw, the current epoch can also be modified and + // we don't want to insert another checkpoint in the middle of the array as that could be expensive + if (checkpoints.length == 0) { + checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount)); + + // next epoch => multiplier is 1, epoch deposits is 0 + checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0)); + } else { + uint256 last = checkpoints.length - 1; + + // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5) + if (checkpoints[last].epochId < currentEpoch) { + uint128 multiplier = computeNewMultiplier( + getCheckpointBalance(checkpoints[last]), + BASE_MULTIPLIER, + amount, + currentMultiplier + ); + checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount)); + checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0)); + } + // the last action happened in the previous epoch + else if (checkpoints[last].epochId == currentEpoch) { + checkpoints[last].multiplier = computeNewMultiplier( + getCheckpointBalance(checkpoints[last]), + checkpoints[last].multiplier, + amount, + currentMultiplier + ); + checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount); + + checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0)); + } + // the last action happened in the current epoch + else { + if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) { + checkpoints[last - 1].multiplier = computeNewMultiplier( + getCheckpointBalance(checkpoints[last - 1]), + checkpoints[last - 1].multiplier, + amount, + currentMultiplier + ); + checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount); + } + + checkpoints[last].startBalance = balance; + } + } + + uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch); + + poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore)); + + emit Deposit(msg.sender, tokenAddress, amount); + } + + /* + * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user` + */ + function withdraw(address tokenAddress, uint256 amount) public nonReentrant { + require(balances[msg.sender][tokenAddress] >= amount, "STK:E-432"); + + balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount); + + IERC20 token = IERC20(tokenAddress); + token.transfer(msg.sender, amount); + + // epoch logic + uint128 currentEpoch = getCurrentEpoch(); + + lastWithdrawEpochId[tokenAddress] = currentEpoch; + + if (!epochIsInitialized(tokenAddress, currentEpoch)) { + address[] memory tokens = new address[](1); + tokens[0] = tokenAddress; + manualEpochInit(tokens, currentEpoch); + } + + // update the pool size of the next epoch to its current balance + Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1]; + pNextEpoch.size = token.balanceOf(address(this)); + pNextEpoch.set = true; + + Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress]; + uint256 last = checkpoints.length - 1; + + // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert + + // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then + if (checkpoints[last].epochId < currentEpoch) { + checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0)); + + poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount); + } + // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch + else if (checkpoints[last].epochId == currentEpoch) { + checkpoints[last].startBalance = balances[msg.sender][tokenAddress]; + checkpoints[last].newDeposits = 0; + checkpoints[last].multiplier = BASE_MULTIPLIER; + + poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount); + } + // there was a deposit in the current epoch + else { + Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1]; + + uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint); + + // in case of withdraw, we have 2 branches: + // 1. the user withdraws less than he added in the current epoch + // 2. the user withdraws more than he added in the current epoch (including 0) + if (amount < currentEpochCheckpoint.newDeposits) { + uint128 avgDepositMultiplier = uint128( + balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits) + ); + + currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount); + + currentEpochCheckpoint.multiplier = computeNewMultiplier( + currentEpochCheckpoint.startBalance, + BASE_MULTIPLIER, + currentEpochCheckpoint.newDeposits, + avgDepositMultiplier + ); + } else { + currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub( + amount.sub(currentEpochCheckpoint.newDeposits) + ); + currentEpochCheckpoint.newDeposits = 0; + currentEpochCheckpoint.multiplier = BASE_MULTIPLIER; + } + + uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint); + + poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter)); + + checkpoints[last].startBalance = balances[msg.sender][tokenAddress]; + } + + emit Withdraw(msg.sender, tokenAddress, amount); + } + + /* + * manualEpochInit can be used by anyone to initialize an epoch based on the previous one + * This is only applicable if there was no action (deposit/withdraw) in the current epoch. + * Any deposit and withdraw will automatically initialize the current and next epoch. + */ + function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused { + require(epochId <= getCurrentEpoch(), "STK:E-306"); + + + for (uint i = 0; i < tokens.length; i++) { + Pool storage p = poolSize[tokens[i]][epochId]; + if (epochId == 0) { + p.size = uint256(0); + p.set = true; + } else { + require(!epochIsInitialized(tokens[i], epochId), "STK:E-002"); + require(epochIsInitialized(tokens[i], epochId - 1), "STK:E-305"); + p.size = poolSize[tokens[i]][epochId - 1].size; + p.set = true; + } + } + + emit ManualEpochInit(msg.sender, epochId, tokens); + } + + function emergencyWithdraw(address tokenAddress) public { + require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, "STK:E-304"); + + uint256 totalUserBalance = balances[msg.sender][tokenAddress]; + require(totalUserBalance > 0, "STK:E-205"); + + balances[msg.sender][tokenAddress] = 0; + + IERC20 token = IERC20(tokenAddress); + token.transfer(msg.sender, totalUserBalance); + + emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance); + } + + /* + * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch + * A deposit will only change the next epoch balance. + * A withdraw will decrease the current epoch (and subsequent) balance. + */ + function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) { + Checkpoint[] storage checkpoints = balanceCheckpoints[user][token]; + + // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0 + if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) { + return 0; + } + + uint min = 0; + uint max = checkpoints.length - 1; + + // shortcut for blocks newer than the latest checkpoint == current balance + if (epochId >= checkpoints[max].epochId) { + return getCheckpointEffectiveBalance(checkpoints[max]); + } + + // binary search of the value in the array + while (max > min) { + uint mid = (max + min + 1) / 2; + if (checkpoints[mid].epochId <= epochId) { + min = mid; + } else { + max = mid - 1; + } + } + + return getCheckpointEffectiveBalance(checkpoints[min]); + } + + /* + * Returns the amount of `token` that the `user` has currently staked + */ + function balanceOf(address user, address token) public view returns (uint256) { + return balances[user][token]; + } + + /* + * Returns the id of the current epoch derived from block.timestamp + */ + function getCurrentEpoch() public view returns (uint128) { + if (block.timestamp < epoch1Start) { + return 0; + } + + return uint128((block.timestamp - epoch1Start) / epochDuration + 1); + } + + /* + * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId` + */ + function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) { + // Premises: + // 1. it's impossible to have gaps of uninitialized epochs + // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized + if (epochIsInitialized(tokenAddress, epochId)) { + return poolSize[tokenAddress][epochId].size; + } + + // epochId not initialized and epoch 0 not initialized => there was never any action on this pool + if (!epochIsInitialized(tokenAddress, 0)) { + return 0; + } + + // epoch 0 is initialized => there was an action at some point but none that initialized the epochId + // which means the current pool size is equal to the current balance of token held by the staking contract + IERC20 token = IERC20(tokenAddress); + return token.balanceOf(address(this)); + } + + /* + * Returns the percentage of time left in the current epoch + */ + function currentEpochMultiplier() public view returns (uint128) { + uint128 currentEpoch = getCurrentEpoch(); + uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration; + uint256 timeLeft = currentEpochEnd - block.timestamp; + uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration); + + return multiplier; + } + + function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) { + uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER); + uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER); + uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount))); + + return newMultiplier; + } + + /* + * Checks if an epoch is initialized, meaning we have a pool size set for it + */ + function epochIsInitialized(address token, uint128 epochId) public view returns (bool) { + return poolSize[token][epochId].set; + } + + function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) { + return c.startBalance.add(c.newDeposits); + } + + function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) { + return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER); + } + + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + function setPausedState(bool paused) external onlyOwner { + _paused = paused; + emit PausedStateSet(paused); + } + + // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it + function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner { + _withdrawEther(receiver, amount); + } + + modifier whenNotPaused() { + require(_paused != true, "STK:E-101"); + _; + } + +} diff --git a/contracts/v1/incentives/YieldFarm.sol b/contracts/v1/incentives/YieldFarm.sol new file mode 100644 index 0000000..f29e212 --- /dev/null +++ b/contracts/v1/incentives/YieldFarm.sol @@ -0,0 +1,229 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.6.11; + +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "../lib/BlackholePrevention.sol"; +import "../interfaces/IStaking.sol"; + +contract YieldFarm is Ownable, BlackholePrevention { + + // lib + using SafeMath for uint; + using SafeMath for uint128; + + // constants + uint public immutable TOTAL_DISTRIBUTED_AMOUNT; + uint public immutable NR_OF_EPOCHS; + + // state variables + + // addreses + address private immutable _token; + address private immutable _communityVault; + // contracts + IERC20 private immutable _ionx; + IStaking private _staking; + + + uint[] private epochs; + uint private immutable _genesisEpochAmount; + uint private _deprecationPerEpoch; + uint128 public lastInitializedEpoch; + bool internal _paused; + mapping(address => uint128) public lastEpochIdHarvested; + uint public epochDuration; // init from staking contract + uint public immutable epochStart; // init from staking contract + + // events + event PausedStateSet(bool isPaused); + event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue); + event Harvest(address indexed user, uint128 indexed epochId, uint256 amount); + + // constructor + constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public { + _paused = false; + _ionx = IERC20(ionxTokenAddress); + _token = token; + _staking = IStaking(stakeContract); + _communityVault = communityVault; + epochDuration = _staking.epochDuration(); + epochStart = _staking.epoch1Start() + epochDuration; + _deprecationPerEpoch = deprecationPerEpoch; + uint n = nrOfEpochs; + uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch)); + TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2)); + NR_OF_EPOCHS = nrOfEpochs; + epochs = new uint[](nrOfEpochs + 1); + _genesisEpochAmount = genesisEpochAmount; + + } + + function isPaused() external view returns (bool) { + return _paused; + } + + function getAmountClaimable() external view returns (uint) { + uint totalClaimable; + uint epochId = _getEpochId().sub(1); // fails in epoch 0 + + // force max number of epochs + if (epochId > NR_OF_EPOCHS) { + epochId = NR_OF_EPOCHS; + } + + for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) { + totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i); + } + + return totalClaimable; + } + + // public method to harvest all the unharvested epochs until current epoch - 1 + function massHarvest() external whenNotPaused returns (uint){ + uint totalDistributedValue; + uint epochId = _getEpochId().sub(1); // fails in epoch 0 + uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender]; + + // force max number of epochs + if (epochId > NR_OF_EPOCHS) { + epochId = NR_OF_EPOCHS; + } + + for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) { + // i = epochId + // compute distributed Value and do one single transfer at the end + totalDistributedValue += _harvest(i); + } + + emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue); + + if (totalDistributedValue > 0) { + _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue); + } + + return totalDistributedValue; + } + function harvest (uint128 epochId) external whenNotPaused returns (uint){ + // checks for requested epoch + require (_getEpochId() > epochId, "YLD:E-306"); + require(epochId <= NR_OF_EPOCHS, "YLD:E-408"); + require (lastEpochIdHarvested[msg.sender].add(1) == epochId, "YLD:E-204"); + uint userReward = _harvest(epochId); + if (userReward > 0) { + _ionx.transferFrom(_communityVault, msg.sender, userReward); + } + emit Harvest(msg.sender, epochId, userReward); + return userReward; + } + + // views + // calls to the staking smart contract to retrieve the epoch total pool size + function getPoolSize(uint128 epochId) external view returns (uint) { + return _getPoolSize(epochId); + } + + function getCurrentEpoch() external view returns (uint) { + return _getEpochId(); + } + + // calls to the staking smart contract to retrieve user balance for an epoch + function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) { + return _getUserBalancePerEpoch(userAddress, epochId); + } + + function getGenesisEpochAmount() external view returns (uint){ + return _genesisEpochAmount; + } + + function getDeprecationPerEpoch() external view returns (uint){ + return _deprecationPerEpoch; + } + + function userLastEpochIdHarvested() external view returns (uint){ + return lastEpochIdHarvested[msg.sender]; + } + + // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it + function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner { + _withdrawEther(receiver, amount); + } + + // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner { + _withdrawERC20(receiver, tokenAddress, amount); + } + + // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + // internal methods + + function _initEpoch(uint128 epochId) internal { + require(lastInitializedEpoch.add(1) == epochId, "YLD:E-204"); + lastInitializedEpoch = epochId; + // call the staking smart contract to init the epoch + epochs[epochId] = _getPoolSize(epochId); + } + + function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) { + if (epochs[epochId] == 0) { return 0; } + return _calcTotalAmountPerEpoch(epochId) + .mul(_getUserBalancePerEpoch(account, epochId)) + .div(epochs[epochId]); + } + + function _harvest (uint128 epochId) internal returns (uint) { + // try to initialize an epoch. if it can't it fails + // if it fails either user either a BarnBridge account will init not init epochs + if (lastInitializedEpoch < epochId) { + _initEpoch(epochId); + } + // Set user state for last harvested + lastEpochIdHarvested[msg.sender] = epochId; + // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer) + + // exit if there is no stake on the epoch + if (epochs[epochId] == 0) { + return 0; + } + return _calcTotalAmountPerEpoch(epochId) + .mul(_getUserBalancePerEpoch(msg.sender, epochId)) + .div(epochs[epochId]); + } + + function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) { + return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ? + } + + function _getPoolSize(uint128 epochId) internal view returns (uint) { + // retrieve token token balance + return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId)); + } + + function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){ + // retrieve token token balance per user per epoch + return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId)); + } + + // compute epoch id from blocktimestamp and epochstart date + function _getEpochId() internal view returns (uint128 epochId) { + if (block.timestamp < epochStart) { + return 0; + } + epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1)); + } + + // get the staking epoch which is 1 epoch more + function _stakingEpochId(uint128 epochId) pure internal returns (uint128) { + return epochId + 1; + } + + modifier whenNotPaused() { + require(_paused != true, "YLD:E-101"); + _; + } +} \ No newline at end of file diff --git a/contracts/v1/incentives/YieldFarm2.sol b/contracts/v1/incentives/YieldFarm2.sol new file mode 100644 index 0000000..d14465f --- /dev/null +++ b/contracts/v1/incentives/YieldFarm2.sol @@ -0,0 +1,229 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.6.11; + +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "../lib/BlackholePrevention.sol"; +import "../interfaces/IStaking.sol"; + +contract YieldFarm2 is Ownable, BlackholePrevention { + + // lib + using SafeMath for uint; + using SafeMath for uint128; + + // constants + uint public immutable TOTAL_DISTRIBUTED_AMOUNT; + uint public immutable NR_OF_EPOCHS; + + // state variables + + // addreses + address private immutable _token; + address private immutable _communityVault; + // contracts + IERC20 private immutable _ionx; + IStaking private _staking; + + + uint[] private epochs; + uint private immutable _genesisEpochAmount; + uint private _deprecationPerEpoch; + uint128 public lastInitializedEpoch; + bool internal _paused; + mapping(address => uint128) public lastEpochIdHarvested; + uint public epochDuration; // init from staking contract + uint public immutable epochStart; // init from staking contract + + // events + event PausedStateSet(bool isPaused); + event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue); + event Harvest(address indexed user, uint128 indexed epochId, uint256 amount); + + // constructor + constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public { + _paused = false; + _ionx = IERC20(ionxTokenAddress); + _token = token; + _staking = IStaking(stakeContract); + _communityVault = communityVault; + epochDuration = _staking.epochDuration(); + epochStart = _staking.epoch1Start() + epochDuration; + _deprecationPerEpoch = deprecationPerEpoch; + uint n = nrOfEpochs; + uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch)); + TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2)); + NR_OF_EPOCHS = nrOfEpochs; + epochs = new uint[](nrOfEpochs + 1); + _genesisEpochAmount = genesisEpochAmount; + + } + + function isPaused() external view returns (bool) { + return _paused; + } + + function getAmountClaimable() external view returns (uint) { + uint totalClaimable; + uint epochId = _getEpochId().sub(1); // fails in epoch 0 + + // force max number of epochs + if (epochId > NR_OF_EPOCHS) { + epochId = NR_OF_EPOCHS; + } + + for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) { + totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i); + } + + return totalClaimable; + } + + // public method to harvest all the unharvested epochs until current epoch - 1 + function massHarvest() external whenNotPaused returns (uint){ + uint totalDistributedValue; + uint epochId = _getEpochId().sub(1); // fails in epoch 0 + uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender]; + + // force max number of epochs + if (epochId > NR_OF_EPOCHS) { + epochId = NR_OF_EPOCHS; + } + + for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) { + // i = epochId + // compute distributed Value and do one single transfer at the end + totalDistributedValue += _harvest(i); + } + + emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue); + + if (totalDistributedValue > 0) { + _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue); + } + + return totalDistributedValue; + } + function harvest (uint128 epochId) external whenNotPaused returns (uint){ + // checks for requested epoch + require (_getEpochId() > epochId, "YLD:E-306"); + require(epochId <= NR_OF_EPOCHS, "YLD:E-408"); + require (lastEpochIdHarvested[msg.sender].add(1) == epochId, "YLD:E-204"); + uint userReward = _harvest(epochId); + if (userReward > 0) { + _ionx.transferFrom(_communityVault, msg.sender, userReward); + } + emit Harvest(msg.sender, epochId, userReward); + return userReward; + } + + // views + // calls to the staking smart contract to retrieve the epoch total pool size + function getPoolSize(uint128 epochId) external view returns (uint) { + return _getPoolSize(epochId); + } + + function getCurrentEpoch() external view returns (uint) { + return _getEpochId(); + } + + // calls to the staking smart contract to retrieve user balance for an epoch + function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) { + return _getUserBalancePerEpoch(userAddress, epochId); + } + + function getGenesisEpochAmount() external view returns (uint){ + return _genesisEpochAmount; + } + + function getDeprecationPerEpoch() external view returns (uint){ + return _deprecationPerEpoch; + } + + function userLastEpochIdHarvested() external view returns (uint){ + return lastEpochIdHarvested[msg.sender]; + } + + // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it + function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner { + _withdrawEther(receiver, amount); + } + + // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner { + _withdrawERC20(receiver, tokenAddress, amount); + } + + // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + // internal methods + + function _initEpoch(uint128 epochId) internal { + require(lastInitializedEpoch.add(1) == epochId, "YLD:E-204"); + lastInitializedEpoch = epochId; + // call the staking smart contract to init the epoch + epochs[epochId] = _getPoolSize(epochId); + } + + function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) { + if (epochs[epochId] == 0) { return 0; } + return _calcTotalAmountPerEpoch(epochId) + .mul(_getUserBalancePerEpoch(account, epochId)) + .div(epochs[epochId]); + } + + function _harvest (uint128 epochId) internal returns (uint) { + // try to initialize an epoch. if it can't it fails + // if it fails either user either a BarnBridge account will init not init epochs + if (lastInitializedEpoch < epochId) { + _initEpoch(epochId); + } + // Set user state for last harvested + lastEpochIdHarvested[msg.sender] = epochId; + // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer) + + // exit if there is no stake on the epoch + if (epochs[epochId] == 0) { + return 0; + } + return _calcTotalAmountPerEpoch(epochId) + .mul(_getUserBalancePerEpoch(msg.sender, epochId)) + .div(epochs[epochId]); + } + + function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) { + return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ? + } + + function _getPoolSize(uint128 epochId) internal view returns (uint) { + // retrieve token token balance + return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId)); + } + + function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){ + // retrieve token token balance per user per epoch + return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId)); + } + + // compute epoch id from blocktimestamp and epochstart date + function _getEpochId() internal view returns (uint128 epochId) { + if (block.timestamp < epochStart) { + return 0; + } + epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1)); + } + + // get the staking epoch which is 1 epoch more + function _stakingEpochId(uint128 epochId) pure internal returns (uint128) { + return epochId + 1; + } + + modifier whenNotPaused() { + require(_paused != true, "YLD:E-101"); + _; + } +} \ No newline at end of file diff --git a/contracts/v1/incentives/YieldFarm3.sol b/contracts/v1/incentives/YieldFarm3.sol new file mode 100644 index 0000000..f6177de --- /dev/null +++ b/contracts/v1/incentives/YieldFarm3.sol @@ -0,0 +1,229 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.6.11; + +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "../lib/BlackholePrevention.sol"; +import "../interfaces/IStaking.sol"; + +contract YieldFarm3 is Ownable, BlackholePrevention { + + // lib + using SafeMath for uint; + using SafeMath for uint128; + + // constants + uint public immutable TOTAL_DISTRIBUTED_AMOUNT; + uint public immutable NR_OF_EPOCHS; + + // state variables + + // addreses + address private immutable _token; + address private immutable _communityVault; + // contracts + IERC20 private immutable _ionx; + IStaking private _staking; + + + uint[] private epochs; + uint private immutable _genesisEpochAmount; + uint private _deprecationPerEpoch; + uint128 public lastInitializedEpoch; + bool internal _paused; + mapping(address => uint128) public lastEpochIdHarvested; + uint public epochDuration; // init from staking contract + uint public immutable epochStart; // init from staking contract + + // events + event PausedStateSet(bool isPaused); + event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue); + event Harvest(address indexed user, uint128 indexed epochId, uint256 amount); + + // constructor + constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public { + _paused = false; + _ionx = IERC20(ionxTokenAddress); + _token = token; + _staking = IStaking(stakeContract); + _communityVault = communityVault; + epochDuration = _staking.epochDuration(); + epochStart = _staking.epoch1Start() + epochDuration; + _deprecationPerEpoch = deprecationPerEpoch; + uint n = nrOfEpochs; + uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch)); + TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2)); + NR_OF_EPOCHS = nrOfEpochs; + epochs = new uint[](nrOfEpochs + 1); + _genesisEpochAmount = genesisEpochAmount; + + } + + function isPaused() external view returns (bool) { + return _paused; + } + + function getAmountClaimable() external view returns (uint) { + uint totalClaimable; + uint epochId = _getEpochId().sub(1); // fails in epoch 0 + + // force max number of epochs + if (epochId > NR_OF_EPOCHS) { + epochId = NR_OF_EPOCHS; + } + + for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) { + totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i); + } + + return totalClaimable; + } + + // public method to harvest all the unharvested epochs until current epoch - 1 + function massHarvest() external whenNotPaused returns (uint){ + uint totalDistributedValue; + uint epochId = _getEpochId().sub(1); // fails in epoch 0 + uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender]; + + // force max number of epochs + if (epochId > NR_OF_EPOCHS) { + epochId = NR_OF_EPOCHS; + } + + for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) { + // i = epochId + // compute distributed Value and do one single transfer at the end + totalDistributedValue += _harvest(i); + } + + emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue); + + if (totalDistributedValue > 0) { + _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue); + } + + return totalDistributedValue; + } + function harvest (uint128 epochId) external whenNotPaused returns (uint){ + // checks for requested epoch + require (_getEpochId() > epochId, "YLD:E-306"); + require(epochId <= NR_OF_EPOCHS, "YLD:E-408"); + require (lastEpochIdHarvested[msg.sender].add(1) == epochId, "YLD:E-204"); + uint userReward = _harvest(epochId); + if (userReward > 0) { + _ionx.transferFrom(_communityVault, msg.sender, userReward); + } + emit Harvest(msg.sender, epochId, userReward); + return userReward; + } + + // views + // calls to the staking smart contract to retrieve the epoch total pool size + function getPoolSize(uint128 epochId) external view returns (uint) { + return _getPoolSize(epochId); + } + + function getCurrentEpoch() external view returns (uint) { + return _getEpochId(); + } + + // calls to the staking smart contract to retrieve user balance for an epoch + function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) { + return _getUserBalancePerEpoch(userAddress, epochId); + } + + function getGenesisEpochAmount() external view returns (uint){ + return _genesisEpochAmount; + } + + function getDeprecationPerEpoch() external view returns (uint){ + return _deprecationPerEpoch; + } + + function userLastEpochIdHarvested() external view returns (uint){ + return lastEpochIdHarvested[msg.sender]; + } + + // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it + function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner { + _withdrawEther(receiver, amount); + } + + // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner { + _withdrawERC20(receiver, tokenAddress, amount); + } + + // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + // internal methods + + function _initEpoch(uint128 epochId) internal { + require(lastInitializedEpoch.add(1) == epochId, "YLD:E-204"); + lastInitializedEpoch = epochId; + // call the staking smart contract to init the epoch + epochs[epochId] = _getPoolSize(epochId); + } + + function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) { + if (epochs[epochId] == 0) { return 0; } + return _calcTotalAmountPerEpoch(epochId) + .mul(_getUserBalancePerEpoch(account, epochId)) + .div(epochs[epochId]); + } + + function _harvest (uint128 epochId) internal returns (uint) { + // try to initialize an epoch. if it can't it fails + // if it fails either user either a BarnBridge account will init not init epochs + if (lastInitializedEpoch < epochId) { + _initEpoch(epochId); + } + // Set user state for last harvested + lastEpochIdHarvested[msg.sender] = epochId; + // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer) + + // exit if there is no stake on the epoch + if (epochs[epochId] == 0) { + return 0; + } + return _calcTotalAmountPerEpoch(epochId) + .mul(_getUserBalancePerEpoch(msg.sender, epochId)) + .div(epochs[epochId]); + } + + function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) { + return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ? + } + + function _getPoolSize(uint128 epochId) internal view returns (uint) { + // retrieve token token balance + return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId)); + } + + function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){ + // retrieve token token balance per user per epoch + return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId)); + } + + // compute epoch id from blocktimestamp and epochstart date + function _getEpochId() internal view returns (uint128 epochId) { + if (block.timestamp < epochStart) { + return 0; + } + epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1)); + } + + // get the staking epoch which is 1 epoch more + function _stakingEpochId(uint128 epochId) pure internal returns (uint128) { + return epochId + 1; + } + + modifier whenNotPaused() { + require(_paused != true, "YLD:E-101"); + _; + } +} \ No newline at end of file diff --git a/contracts/v1/interfaces/IAaveBridge.sol b/contracts/v1/interfaces/IAaveBridge.sol new file mode 100644 index 0000000..288407a --- /dev/null +++ b/contracts/v1/interfaces/IAaveBridge.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: MIT + +// IAaveBridge.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; + + +interface IAaveBridge { + function getReserveInterestToken(address assetToken) external view returns (address aTokenAddress); + function isReserveActive(address assetToken) external view returns (bool); + + function getTotalBalance(address account, address assetToken) external view returns (uint256); + function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256); + function withdraw(address receiver, address assetToken, uint256 assetAmount) external; +} diff --git a/contracts/v1/interfaces/IBaseProton.sol b/contracts/v1/interfaces/IBaseProton.sol new file mode 100644 index 0000000..1ec21a5 --- /dev/null +++ b/contracts/v1/interfaces/IBaseProton.sol @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: MIT + +// Proton.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; +pragma experimental ABIEncoderV2; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/utils/Counters.sol"; +import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; + +import "../lib/BlackholePrevention.sol"; +import "../lib/RelayRecipient.sol"; + + +interface IBaseProton is IERC721 { + event PausedStateSet(bool isPaused); + event SalePriceSet(uint256 indexed tokenId, uint256 salePrice); + event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct); + event FeesWithdrawn(address indexed receiver, uint256 amount); + event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties); + event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed); + + /***********************************| + | Public | + |__________________________________*/ + + function creatorOf(uint256 tokenId) external view returns (address); + function getSalePrice(uint256 tokenId) external view returns (uint256); + function getLastSellPrice(uint256 tokenId) external view returns (uint256); + function getCreatorRoyalties(address account) external view returns (uint256); + function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256); + function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address); + + function buyProton(uint256 tokenId, uint256 gasLimit) external payable returns (bool); + function claimCreatorRoyalties() external returns (uint256); + + function createProton( + address creator, + address receiver, + string memory tokenMetaUri + ) external returns (uint256 newTokenId); + + function createProtons( + address creator, + address receiver, + string[] calldata tokenMetaUris + ) external returns (bool); + + function createProtonsForSale( + address creator, + address receiver, + uint256 royaltiesPercent, + string[] calldata tokenMetaUris, + uint256[] calldata salePrices + ) external returns (bool); + + /***********************************| + | Only Token Creator/Owner | + |__________________________________*/ + + function setSalePrice(uint256 tokenId, uint256 salePrice) external; + function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external; + function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external; +} \ No newline at end of file diff --git a/contracts/v1/interfaces/IBasketManager.sol b/contracts/v1/interfaces/IBasketManager.sol new file mode 100755 index 0000000..398e81d --- /dev/null +++ b/contracts/v1/interfaces/IBasketManager.sol @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: MIT + +// IBasketManager.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; + +/** + * @title Particle Basket Manager interface + * @dev The basket-manager for underlying assets attached to Charged Particles + * @dev Manages the link between NFTs and their respective Smart-Baskets + */ +interface IBasketManager { + + event ControllerSet(address indexed controller); + event ExecutorSet(address indexed executor); + event PausedStateSet(bool isPaused); + event NewSmartBasket(address indexed contractAddress, uint256 indexed tokenId, address indexed smartBasket); + event BasketAdd(address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount); + event BasketRemove(address indexed receiver, address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount); + event BasketRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount); + event RewardProgramSet(address indexed rewardProgram); + + function isPaused() external view returns (bool); + + function getTokenTotalCount(address contractAddress, uint256 tokenId) external view returns (uint256); + function getTokenCountByType(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (uint256); + + function prepareTransferAmount(uint256 nftTokenAmount) external; + function addToBasket(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool); + function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool); + function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount); + function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory); + function getBasketAddressById(address contractAddress, uint256 tokenId) external returns (address); + + function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external; + function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external; + function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external; + function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount) external; +} diff --git a/contracts/v1/interfaces/IChargedManagers.sol b/contracts/v1/interfaces/IChargedManagers.sol new file mode 100755 index 0000000..e64a498 --- /dev/null +++ b/contracts/v1/interfaces/IChargedManagers.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: MIT + +// IChargedSettings.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; + +import "./IWalletManager.sol"; +import "./IBasketManager.sol"; + +/** + * @notice Interface for Charged Wallet-Managers + */ +interface IChargedManagers { + + /***********************************| + | Public API | + |__________________________________*/ + + function isContractOwner(address contractAddress, address account) external view returns (bool); + + // ERC20 + function isWalletManagerEnabled(string calldata walletManagerId) external view returns (bool); + function getWalletManager(string calldata walletManagerId) external view returns (IWalletManager); + + // ERC721 + function isNftBasketEnabled(string calldata basketId) external view returns (bool); + function getBasketManager(string calldata basketId) external view returns (IBasketManager); + + // Validation + function validateDeposit( + address sender, + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken, + uint256 assetAmount + ) external; + function validateNftDeposit( + address sender, + address contractAddress, + uint256 tokenId, + string calldata basketManagerId, + address nftTokenAddress, + uint256 nftTokenId, + uint256 nftTokenAmount + ) external; + function validateDischarge(address sender, address contractAddress, uint256 tokenId) external; + function validateRelease(address sender, address contractAddress, uint256 tokenId) external; + function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external; + + /***********************************| + | Particle Events | + |__________________________________*/ + + event Initialized(address indexed initiator); + event ControllerSet(address indexed controllerAddress, string controllerId); + event WalletManagerRegistered(string indexed walletManagerId, address indexed walletManager); + event BasketManagerRegistered(string indexed basketId, address indexed basketManager); +} diff --git a/contracts/interfaces/IChargedParticles.sol b/contracts/v1/interfaces/IChargedParticles.sol old mode 100644 new mode 100755 similarity index 91% rename from contracts/interfaces/IChargedParticles.sol rename to contracts/v1/interfaces/IChargedParticles.sol index b3bddf4..b65c8f1 --- a/contracts/interfaces/IChargedParticles.sol +++ b/contracts/v1/interfaces/IChargedParticles.sol @@ -116,4 +116,13 @@ interface IChargedParticles { uint256 nftTokenId, uint256 nftTokenAmount ) external returns (bool success); + + /***********************************| + | Particle Events | + |__________________________________*/ + + event Initialized(address indexed initiator); + event ControllerSet(address indexed controllerAddress, string controllerId); + event DepositFeeSet(uint256 depositFee); + event ProtocolFeesCollected(address indexed assetToken, uint256 depositAmount, uint256 feesCollected); } diff --git a/contracts/v1/interfaces/IChargedSettings.sol b/contracts/v1/interfaces/IChargedSettings.sol new file mode 100755 index 0000000..6843010 --- /dev/null +++ b/contracts/v1/interfaces/IChargedSettings.sol @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: MIT + +// IChargedSettings.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; + +import "./IWalletManager.sol"; +import "./IBasketManager.sol"; + +/** + * @notice Interface for Charged Settings + */ +interface IChargedSettings { + + /***********************************| + | Public API | + |__________________________________*/ + + // function isContractOwner(address contractAddress, address account) external view returns (bool); + function getCreatorAnnuities(address contractAddress, uint256 tokenId) external returns (address creator, uint256 annuityPct); + function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId) external view returns (address); + function getTempLockExpiryBlocks() external view returns (uint256); + function getTimelockApprovals(address operator) external view returns (bool timelockAny, bool timelockOwn); + function getAssetRequirements( + address contractAddress, + address assetToken + ) external view returns ( + string memory requiredWalletManager, + bool energizeEnabled, + bool restrictedAssets, + bool validAsset, + uint256 depositCap, + uint256 depositMin, + uint256 depositMax, + bool invalidAsset + ); + function getNftAssetRequirements( + address contractAddress, + address nftTokenAddress + ) external view returns ( + string memory requiredBasketManager, + bool basketEnabled, + uint256 maxNfts + ); + + /***********************************| + | Only NFT Creator | + |__________________________________*/ + + function setCreatorAnnuities(address contractAddress, uint256 tokenId, address creator, uint256 annuityPercent) external; + function setCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId, address receiver) external; + + + /***********************************| + | Only NFT Contract Owner | + |__________________________________*/ + + function setRequiredWalletManager(address contractAddress, string calldata walletManager) external; + function setRequiredBasketManager(address contractAddress, string calldata basketManager) external; + function setAssetTokenRestrictions(address contractAddress, bool restrictionsEnabled) external; + function setAllowedAssetToken(address contractAddress, address assetToken, bool isAllowed) external; + function setAssetTokenLimits(address contractAddress, address assetToken, uint256 depositMin, uint256 depositMax) external; + function setMaxNfts(address contractAddress, address nftTokenAddress, uint256 maxNfts) external; + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + function setAssetInvalidity(address assetToken, bool invalidity) external; + function enableNftContracts(address[] calldata contracts) external; + function setPermsForCharge(address contractAddress, bool state) external; + function setPermsForBasket(address contractAddress, bool state) external; + function setPermsForTimelockAny(address contractAddress, bool state) external; + function setPermsForTimelockSelf(address contractAddress, bool state) external; + + /***********************************| + | Particle Events | + |__________________________________*/ + + event Initialized(address indexed initiator); + event ControllerSet(address indexed controllerAddress, string controllerId); + event DepositCapSet(address assetToken, uint256 depositCap); + event TempLockExpirySet(uint256 expiryBlocks); + + event RequiredWalletManagerSet(address indexed contractAddress, string walletManager); + event RequiredBasketManagerSet(address indexed contractAddress, string basketManager); + event AssetTokenRestrictionsSet(address indexed contractAddress, bool restrictionsEnabled); + event AllowedAssetTokenSet(address indexed contractAddress, address assetToken, bool isAllowed); + event AssetTokenLimitsSet(address indexed contractAddress, address assetToken, uint256 assetDepositMin, uint256 assetDepositMax); + event MaxNftsSet(address indexed contractAddress, address indexed nftTokenAddress, uint256 maxNfts); + event AssetInvaliditySet(address indexed assetToken, bool invalidity); + + event TokenCreatorConfigsSet(address indexed contractAddress, uint256 indexed tokenId, address indexed creatorAddress, uint256 annuityPercent); + event TokenCreatorAnnuitiesRedirected(address indexed contractAddress, uint256 indexed tokenId, address indexed redirectAddress); + + event PermsSetForCharge(address indexed contractAddress, bool state); + event PermsSetForBasket(address indexed contractAddress, bool state); + event PermsSetForTimelockAny(address indexed contractAddress, bool state); + event PermsSetForTimelockSelf(address indexed contractAddress, bool state); +} diff --git a/contracts/v1/interfaces/IChargedState.sol b/contracts/v1/interfaces/IChargedState.sol new file mode 100755 index 0000000..83de630 --- /dev/null +++ b/contracts/v1/interfaces/IChargedState.sol @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: MIT + +// IChargedSettings.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; + +import "./IChargedSettings.sol"; + +/** + * @notice Interface for Charged State + */ +interface IChargedState { + + /***********************************| + | Public API | + |__________________________________*/ + + function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry); + function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry); + function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry); + + function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external returns (bool); + function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external returns (bool); + function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external returns (bool); + function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external returns (bool); + + function isEnergizeRestricted(address contractAddress, uint256 tokenId) external view returns (bool); + function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external view returns (bool); + + function getDischargeState(address contractAddress, uint256 tokenId, address sender) external + returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry); + function getReleaseState(address contractAddress, uint256 tokenId, address sender) external + returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry); + function getBreakBondState(address contractAddress, uint256 tokenId, address sender) external + returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry); + + /***********************************| + | Only NFT Owner/Operator | + |__________________________________*/ + + function setDischargeApproval(address contractAddress, uint256 tokenId, address operator) external; + function setReleaseApproval(address contractAddress, uint256 tokenId, address operator) external; + function setBreakBondApproval(address contractAddress, uint256 tokenId, address operator) external; + function setTimelockApproval(address contractAddress, uint256 tokenId, address operator) external; + function setApprovalForAll(address contractAddress, uint256 tokenId, address operator) external; + + function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) external; + function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) external; + function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) external; + function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) external; + function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) external; + + function setDischargeTimelock( + address contractAddress, + uint256 tokenId, + uint256 unlockBlock + ) external; + + function setReleaseTimelock( + address contractAddress, + uint256 tokenId, + uint256 unlockBlock + ) external; + + function setBreakBondTimelock( + address contractAddress, + uint256 tokenId, + uint256 unlockBlock + ) external; + + /***********************************| + | Only NFT Contract | + |__________________________________*/ + + function setTemporaryLock( + address contractAddress, + uint256 tokenId, + bool isLocked + ) external; + + /***********************************| + | Particle Events | + |__________________________________*/ + + event Initialized(address indexed initiator); + event ControllerSet(address indexed controllerAddress, string controllerId); + + event DischargeApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator); + event ReleaseApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator); + event BreakBondApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator); + event TimelockApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator); + + event TokenDischargeTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock); + event TokenReleaseTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock); + event TokenBreakBondTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock); + event TokenTempLock(address indexed contractAddress, uint256 indexed tokenId, uint256 unlockBlock); + + event PermsSetForRestrictCharge(address indexed contractAddress, uint256 indexed tokenId, bool state); + event PermsSetForAllowDischarge(address indexed contractAddress, uint256 indexed tokenId, bool state); + event PermsSetForAllowRelease(address indexed contractAddress, uint256 indexed tokenId, bool state); + event PermsSetForRestrictBond(address indexed contractAddress, uint256 indexed tokenId, bool state); + event PermsSetForAllowBreakBond(address indexed contractAddress, uint256 indexed tokenId, bool state); +} diff --git a/contracts/v1/interfaces/IDai.sol b/contracts/v1/interfaces/IDai.sol new file mode 100644 index 0000000..a0107f4 --- /dev/null +++ b/contracts/v1/interfaces/IDai.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.6.12; + +import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; + +interface IDai is IERC20Upgradeable { + // --- Approve by signature --- + function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external; + function transferFrom(address src, address dst, uint wad) external override returns (bool); +} \ No newline at end of file diff --git a/contracts/v1/interfaces/IERC20Detailed.sol b/contracts/v1/interfaces/IERC20Detailed.sol new file mode 100644 index 0000000..aa9202b --- /dev/null +++ b/contracts/v1/interfaces/IERC20Detailed.sol @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.6.0; + +/** + * @dev Interface of the ERC20 standard as defined in the EIP. + */ +interface IERC20Detailed { + function decimals() external view returns (uint8); + function symbol() external view returns (string memory); + function name() external view returns (string memory); + + /** + * @dev Returns the amount of tokens in existence. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns the amount of tokens owned by `account`. + */ + function balanceOf(address account) external view returns (uint256); + + /** + * @dev Moves `amount` tokens from the caller's account to `recipient`. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transfer(address recipient, uint256 amount) external returns (bool); + + /** + * @dev Returns the remaining number of tokens that `spender` will be + * allowed to spend on behalf of `owner` through {transferFrom}. This is + * zero by default. + * + * This value changes when {approve} or {transferFrom} are called. + */ + function allowance(address owner, address spender) external view returns (uint256); + + /** + * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * IMPORTANT: Beware that changing an allowance with this method brings the risk + * that someone may use both the old and the new allowance by unfortunate + * transaction ordering. One possible solution to mitigate this race + * condition is to first reduce the spender's allowance to 0 and set the + * desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * + * Emits an {Approval} event. + */ + function approve(address spender, uint256 amount) external returns (bool); + + /** + * @dev Moves `amount` tokens from `sender` to `recipient` using the + * allowance mechanism. `amount` is then deducted from the caller's + * allowance. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); + + /** + * @dev Emitted when `value` tokens are moved from one account (`from`) to + * another (`to`). + * + * Note that `value` may be zero. + */ + event Transfer(address indexed from, address indexed to, uint256 value); + + /** + * @dev Emitted when the allowance of a `spender` for an `owner` is set by + * a call to {approve}. `value` is the new allowance. + */ + event Approval(address indexed owner, address indexed spender, uint256 value); +} diff --git a/contracts/v1/interfaces/IERC721Chargeable.sol b/contracts/v1/interfaces/IERC721Chargeable.sol new file mode 100755 index 0000000..d06b36e --- /dev/null +++ b/contracts/v1/interfaces/IERC721Chargeable.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: MIT + +// IERC721Chargeable.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; + +import "@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol"; + +interface IERC721Chargeable is IERC165Upgradeable { + function owner() external view returns (address); + function creatorOf(uint256 tokenId) external view returns (address); + function balanceOf(address tokenOwner) external view returns (uint256 balance); + function ownerOf(uint256 tokenId) external view returns (address tokenOwner); + function safeTransferFrom(address from, address to, uint256 tokenId) external; + function transferFrom(address from, address to, uint256 tokenId) external; + function approve(address to, uint256 tokenId) external; + function getApproved(uint256 tokenId) external view returns (address operator); + function setApprovalForAll(address operator, bool _approved) external; + function isApprovedForAll(address tokenOwner, address operator) external view returns (bool); + function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; +} diff --git a/contracts/v1/interfaces/ILepton.sol b/contracts/v1/interfaces/ILepton.sol new file mode 100644 index 0000000..e3b28eb --- /dev/null +++ b/contracts/v1/interfaces/ILepton.sol @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: MIT + +// ILepton.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; + +/** + * @title Charged Particles Lepton Interface + * @dev ... + */ +interface ILepton { + + struct Classification { + string tokenUri; + uint256 price; + uint128 _upperBounds; + uint32 supply; + uint32 multiplier; + uint32 bonus; + } + + function mintLepton() external payable returns (uint256 newTokenId); + function batchMintLepton(uint256 count) external payable; + function getNextType() external view returns (uint256); + function getNextPrice() external view returns (uint256); + function getMultiplier(uint256 tokenId) external view returns (uint256); + function getBonus(uint256 tokenId) external view returns (uint256); + + + event MaxMintPerTxSet(uint256 maxAmount); + event LeptonTypeAdded(string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds); + event LeptonTypeUpdated(uint256 leptonIndex, string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds); + event LeptonMinted(address indexed receiver, uint256 indexed tokenId, uint256 price, uint32 multiplier); + event LeptonBatchMinted(address indexed receiver, uint256 indexed tokenId, uint256 count, uint256 price, uint32 multiplier); + event PausedStateSet(bool isPaused); +} diff --git a/contracts/v1/interfaces/IMerkleDistributor.sol b/contracts/v1/interfaces/IMerkleDistributor.sol new file mode 100644 index 0000000..6c7259b --- /dev/null +++ b/contracts/v1/interfaces/IMerkleDistributor.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.6.0; + +// Allows anyone to claim a token if they exist in a merkle root. +interface IMerkleDistributor { + // Returns the address of the token distributed by this contract. + function token() external view returns (address); + // Returns the merkle root of the merkle tree containing account balances available to claim. + function merkleRoot() external view returns (bytes32); + // Returns true if the index has been marked claimed. + function isClaimed(uint256 index) external view returns (bool); + // Claim the given amount of the token to the given address. Reverts if the inputs are invalid. + function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external; + + // This event is triggered whenever a call to #claim succeeds. + event Claimed(uint256 index, address account, uint256 amount); +} \ No newline at end of file diff --git a/contracts/v1/interfaces/IParticleSplitter.sol b/contracts/v1/interfaces/IParticleSplitter.sol new file mode 100644 index 0000000..78b4230 --- /dev/null +++ b/contracts/v1/interfaces/IParticleSplitter.sol @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: MIT + +// IParticleSplitter.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; + +/** + * @notice Interface for Particle Splitter + */ +interface IParticleSplitter { + + /***********************************| + | Public API | + |__________________________________*/ + + function executeForWallet( + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address externalAddress, + bytes memory encodedParams + ) external payable returns (bytes memory); + + function executeForBasket( + address contractAddress, + uint256 tokenId, + string calldata basketManagerId, + address externalAddress, + bytes memory encodedParams + ) external payable returns (bytes memory); + + function withdrawWalletRewards( + address receiver, + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address rewardsToken, + uint256 rewardsAmount + ) external returns (uint256 amountWithdrawn); + + function withdrawBasketRewards( + address receiver, + address contractAddress, + uint256 tokenId, + string calldata basketManagerId, + address rewardsToken, + uint256 rewardsAmount + ) external returns (uint256 amountWithdrawn); + + function refreshWalletPrincipal( + address contractAddress, + uint256 tokenId, + string calldata walletManagerId, + address assetToken + ) external; + + + /***********************************| + | Particle Events | + |__________________________________*/ + + event ChargedManagersSet(address indexed chargedManagers); + event TokenInfoProxySet(address indexed tokenInfoProxy); + + event ExecuteForWallet( + address indexed contractAddress, + uint256 tokenId, + string walletManagerId, + address indexed externalAddress, + bytes encodedParams, + uint256 ethValue + ); + event ExecuteForBasket( + address indexed contractAddress, + uint256 tokenId, + string basketManagerId, + address indexed externalAddress, + bytes encodedParams, + uint256 ethValue + ); + event PrincipalRefreshed( + address contractAddress, + uint256 tokenId, + string walletManagerId, + address assetToken + ); + event PermsSetForExternal( + address indexed contractAddress, + bool state + ); +} diff --git a/contracts/v1/interfaces/IProton.sol b/contracts/v1/interfaces/IProton.sol new file mode 100644 index 0000000..d10bc15 --- /dev/null +++ b/contracts/v1/interfaces/IProton.sol @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: MIT + +// Proton.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; +pragma experimental ABIEncoderV2; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/utils/Counters.sol"; +import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; + +import "../interfaces/IUniverse.sol"; +import "../interfaces/IChargedState.sol"; +import "../interfaces/IChargedSettings.sol"; +import "../interfaces/IChargedParticles.sol"; + +import "../lib/BlackholePrevention.sol"; +import "../lib/RelayRecipient.sol"; + + +interface IProton is IERC721 { + event UniverseSet(address indexed universe); + event ChargedStateSet(address indexed chargedState); + event ChargedSettingsSet(address indexed chargedSettings); + event ChargedParticlesSet(address indexed chargedParticles); + event PausedStateSet(bool isPaused); + event SalePriceSet(uint256 indexed tokenId, uint256 salePrice); + event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct); + event FeesWithdrawn(address indexed receiver, uint256 amount); + event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties); + event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed); + + /***********************************| + | Public | + |__________________________________*/ + + function creatorOf(uint256 tokenId) external view returns (address); + function getSalePrice(uint256 tokenId) external view returns (uint256); + function getLastSellPrice(uint256 tokenId) external view returns (uint256); + function getCreatorRoyalties(address account) external view returns (uint256); + function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256); + function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address); + + function buyProton(uint256 tokenId) external payable returns (bool); + function claimCreatorRoyalties() external returns (uint256); + + function createChargedParticle( + address creator, + address receiver, + address referrer, + string memory tokenMetaUri, + string memory walletManagerId, + address assetToken, + uint256 assetAmount, + uint256 annuityPercent + ) external returns (uint256 newTokenId); + + function createBasicProton( + address creator, + address receiver, + string memory tokenMetaUri + ) external returns (uint256 newTokenId); + + function createProton( + address creator, + address receiver, + string memory tokenMetaUri, + uint256 annuityPercent + ) external returns (uint256 newTokenId); + + function createProtonForSale( + address creator, + address receiver, + string memory tokenMetaUri, + uint256 annuityPercent, + uint256 royaltiesPercent, + uint256 salePrice + ) external returns (uint256 newTokenId); + + function batchProtonsForSale( + address creator, + uint256 annuityPercent, + uint256 royaltiesPercent, + string[] calldata tokenMetaUris, + uint256[] calldata salePrices + ) external; + + /***********************************| + | Only Token Creator/Owner | + |__________________________________*/ + + function setSalePrice(uint256 tokenId, uint256 salePrice) external; + function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external; + function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external; +} \ No newline at end of file diff --git a/contracts/v1/interfaces/IProtonB.sol b/contracts/v1/interfaces/IProtonB.sol new file mode 100644 index 0000000..5949769 --- /dev/null +++ b/contracts/v1/interfaces/IProtonB.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: MIT + +// Proton.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; +pragma experimental ABIEncoderV2; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/utils/Counters.sol"; +import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; + +import "../interfaces/IUniverse.sol"; +import "../interfaces/IChargedState.sol"; +import "../interfaces/IChargedSettings.sol"; +import "../interfaces/IChargedParticles.sol"; + +import "../lib/BlackholePrevention.sol"; +import "../lib/RelayRecipient.sol"; + + +interface IProtonB is IERC721 { + event UniverseSet(address indexed universe); + event ChargedStateSet(address indexed chargedState); + event ChargedSettingsSet(address indexed chargedSettings); + event ChargedParticlesSet(address indexed chargedParticles); + + /***********************************| + | Public | + |__________________________________*/ + + function createProtonForSale( + address creator, + address receiver, + string memory tokenMetaUri, + uint256 annuityPercent, + uint256 royaltiesPercent, + uint256 salePrice + ) external returns (uint256 newTokenId); + + function createChargedParticle( + address creator, + address receiver, + address referrer, + string memory tokenMetaUri, + string memory walletManagerId, + address assetToken, + uint256 assetAmount, + uint256 annuityPercent + ) external returns (uint256 newTokenId); +} \ No newline at end of file diff --git a/contracts/v1/interfaces/IRewardNft.sol b/contracts/v1/interfaces/IRewardNft.sol new file mode 100644 index 0000000..9557dd3 --- /dev/null +++ b/contracts/v1/interfaces/IRewardNft.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT + +// IRewardNft.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2023 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; + +/** + * @title Charged Particles Reward-NFT Interface + * @dev ... + */ +interface IRewardNft { + function getMultiplier(uint256 tokenId) external view returns (uint256); + function getBonus(uint256 tokenId) external view returns (uint256); +} diff --git a/contracts/v1/interfaces/IRewardProgram.sol b/contracts/v1/interfaces/IRewardProgram.sol new file mode 100644 index 0000000..c605226 --- /dev/null +++ b/contracts/v1/interfaces/IRewardProgram.sol @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: MIT + +// IRewardProgram.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2023 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; +pragma experimental ABIEncoderV2; + +interface IRewardProgram { + /* admin events */ + event RewardProgramFunded(uint256 amount); + event RewardProgramOutOfFunds(); + + /* user events */ + event RewardsClaimed(address indexed contractAddress, uint256 tokenId, address indexed receiver, uint256 rewarded, uint256 remaining); + + event AssetRegistered(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount); + event AssetDeposit(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount); + event AssetRelease(address indexed contractAddress, uint256 tokenId, uint256 interestAmount); + + /* data types */ + struct ProgramRewardData { + address stakingToken; + address rewardToken; + uint256 baseMultiplier; // Basis Points + } + + struct AssetStake { + uint256 start; + uint256 claimableRewards; + string walletManagerId; + } + + function initialize(address stakingToken, address rewardToken, uint256 baseMultiplier, address chargedManagers, address universe, address owner) external; + + /* user functions */ + function getProgramData() external view returns (ProgramRewardData memory programData); + function getAssetStake(uint256 uuid) external view returns (AssetStake memory); + function getFundBalance() external view returns (uint256); + function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) external view returns (uint256); + function getClaimableRewards(address contractAddress, uint256 tokenId) external view returns (uint256); + + function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external; + function registerAssetDeposit(address contractAddress, uint256 tokenId, string calldata walletManagerId, uint256 principalAmount) external; + function registerAssetRelease(address contractAddress, uint256 tokenId, uint256 interestAmount) external returns (uint256 rewards); +} \ No newline at end of file diff --git a/contracts/v1/interfaces/ISmartBasket.sol b/contracts/v1/interfaces/ISmartBasket.sol new file mode 100755 index 0000000..2b43b3d --- /dev/null +++ b/contracts/v1/interfaces/ISmartBasket.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MIT + +// ISmartBasket.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; + +/** + * @title Charged Particles Smart Basket + * @dev Manages holding and transferring NFTs within an NFT (if any), + */ +interface ISmartBasket { + function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256); + + function addToBasket(address contractAddress, uint256 tokenId) external returns (bool); + function removeFromBasket(address receiver, address contractAddress, uint256 tokenId) external returns (bool); + function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory); + + function withdrawEther(address payable receiver, uint256 amount) external; + function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external; + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external; + function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external; +} diff --git a/contracts/v1/interfaces/ISmartBasketB.sol b/contracts/v1/interfaces/ISmartBasketB.sol new file mode 100755 index 0000000..a11c9af --- /dev/null +++ b/contracts/v1/interfaces/ISmartBasketB.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT + +// ISmartBasketB.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; + +/** + * @title Charged Particles Smart Basket "B" + * @dev Manages holding and transferring NFTs within an NFT (if any), + */ +interface ISmartBasketB { + function getNestedNftCount() external view returns (uint256); + function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256); + + function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool); + function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool); + function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256); + function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory); + + function withdrawEther(address payable receiver, uint256 amount) external; + function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external; + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external; + function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external; +} diff --git a/contracts/v1/interfaces/ISmartWallet.sol b/contracts/v1/interfaces/ISmartWallet.sol new file mode 100755 index 0000000..13a00df --- /dev/null +++ b/contracts/v1/interfaces/ISmartWallet.sol @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: MIT + +// ISmartWallet.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; + +/** + * @title Charged Particles Smart Wallet + * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any), + */ +interface ISmartWallet { + function getAssetTokenCount() external view returns (uint256); + function getAssetTokenByIndex(uint256 index) external view returns (address); + + function setNftCreator(address creator, uint256 annuityPct) external; + + function isReserveActive(address assetToken) external view returns (bool); + function getReserveInterestToken(address assetToken) external view returns (address); + + function getPrincipal(address assetToken) external returns (uint256); + function getInterest(address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest); + function getTotal(address assetToken) external returns (uint256); + function getRewards(address assetToken) external returns (uint256); + + function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256); + function withdraw(address receiver, address creatorRedirect, address assetToken) external returns (uint256 creatorAmount, uint256 receiverAmount); + function withdrawAmount(address receiver, address creatorRedirect, address assetToken, uint256 assetAmount) external returns (uint256 creatorAmount, uint256 receiverAmount); + function withdrawAmountForCreator(address receiver, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount); + function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256); + function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory); + function refreshPrincipal(address assetToken) external; + + function withdrawEther(address payable receiver, uint256 amount) external; + function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external; + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external; +} diff --git a/contracts/v1/interfaces/ISmartWalletB.sol b/contracts/v1/interfaces/ISmartWalletB.sol new file mode 100755 index 0000000..9d7e732 --- /dev/null +++ b/contracts/v1/interfaces/ISmartWalletB.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: MIT + +// ISmartWallet.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; + +/** + * @title Charged Particles Smart Wallet + * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any), + */ +interface ISmartWalletB { + function getAssetTokenCount() external view returns (uint256); + function getAssetTokenByIndex(uint256 index) external view returns (address); + + function isReserveActive(address assetToken) external view returns (bool); + function getReserveInterestToken(address assetToken) external view returns (address); + + function getPrincipal(address assetToken) external returns (uint256); + function getInterest(address assetToken, uint256 creatorPct) external returns (uint256 creatorInterest, uint256 ownerInterest); + function getTotal(address assetToken) external returns (uint256); + function getRewards(address assetToken) external returns (uint256); + + function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256); + function withdraw( + address receiver, + address creator, + uint256 creatorPct, + address assetToken + ) external returns ( + uint256 creatorAmount, + uint256 receiverAmount + ); + function withdrawAmount( + address receiver, + address creator, + uint256 creatorPct, + address assetToken, + uint256 assetAmount + ) external returns ( + uint256 creatorAmount, + uint256 receiverAmount + ); + function withdrawAmountForCreator( + address receiver, + uint256 creatorPct, + address assetToken, + uint256 assetAmount + ) external returns ( + uint256 receiverAmount + ); + function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256); + function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory); + function refreshPrincipal(address assetToken) external; + + function withdrawEther(address payable receiver, uint256 amount) external; + function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external; + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external; + function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external; +} diff --git a/contracts/v1/interfaces/IStaking.sol b/contracts/v1/interfaces/IStaking.sol new file mode 100644 index 0000000..2e49b5b --- /dev/null +++ b/contracts/v1/interfaces/IStaking.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.6.0; + +import "@openzeppelin/contracts/access/Ownable.sol"; + +interface IStaking { + function manualEpochInit(address[] memory tokens, uint128 epochId) external; + function getCurrentEpoch() external view returns (uint128); + function getEpochId(uint timestamp) external view returns (uint); // get epoch id + function getEpochUserBalance(address user, address token, uint128 epoch) external view returns(uint); + function getEpochPoolSize(address token, uint128 epoch) external view returns (uint); + function epoch1Start() external view returns (uint); + function epochDuration() external view returns (uint); +} \ No newline at end of file diff --git a/contracts/v1/interfaces/ITokenInfoProxy.sol b/contracts/v1/interfaces/ITokenInfoProxy.sol new file mode 100644 index 0000000..449bb77 --- /dev/null +++ b/contracts/v1/interfaces/ITokenInfoProxy.sol @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: MIT + +// TokenInfoProxy.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + + +interface ITokenInfoProxy { + + event ContractFunctionSignatureSet(address indexed contractAddress, string fnName, bytes4 fnSig); + + struct FnSignatures { + bytes4 ownerOf; + bytes4 creatorOf; + } + + function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external; + function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external; + + function getTokenUUID(address contractAddress, uint256 tokenId) external pure returns (uint256); + function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external returns (bool); + function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external returns (bool); + function getTokenOwner(address contractAddress, uint256 tokenId) external returns (address); + function getTokenCreator(address contractAddress, uint256 tokenId) external returns (address); +} diff --git a/contracts/v1/interfaces/IUniswapERC20.sol b/contracts/v1/interfaces/IUniswapERC20.sol new file mode 100644 index 0000000..e0702e2 --- /dev/null +++ b/contracts/v1/interfaces/IUniswapERC20.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.5.0; + +interface IUniswapV2ERC20 { + event Approval(address indexed owner, address indexed spender, uint value); + event Transfer(address indexed from, address indexed to, uint value); + + function name() external pure returns (string memory); + function symbol() external pure returns (string memory); + function decimals() external pure returns (uint8); + function totalSupply() external view returns (uint); + function balanceOf(address owner) external view returns (uint); + function allowance(address owner, address spender) external view returns (uint); + + function approve(address spender, uint value) external returns (bool); + function transfer(address to, uint value) external returns (bool); + function transferFrom(address from, address to, uint value) external returns (bool); + + function DOMAIN_SEPARATOR() external view returns (bytes32); + function PERMIT_TYPEHASH() external pure returns (bytes32); + function nonces(address owner) external view returns (uint); + + function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; +} \ No newline at end of file diff --git a/contracts/v1/interfaces/IUniswapV2Pair.sol b/contracts/v1/interfaces/IUniswapV2Pair.sol new file mode 100644 index 0000000..ca51f77 --- /dev/null +++ b/contracts/v1/interfaces/IUniswapV2Pair.sol @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.5.0; + +interface IUniswapV2Pair { + event Approval(address indexed owner, address indexed spender, uint value); + event Transfer(address indexed from, address indexed to, uint value); + + function name() external pure returns (string memory); + function symbol() external pure returns (string memory); + function decimals() external pure returns (uint8); + function totalSupply() external view returns (uint); + function balanceOf(address owner) external view returns (uint); + function allowance(address owner, address spender) external view returns (uint); + + function approve(address spender, uint value) external returns (bool); + function transfer(address to, uint value) external returns (bool); + function transferFrom(address from, address to, uint value) external returns (bool); + + function DOMAIN_SEPARATOR() external view returns (bytes32); + function PERMIT_TYPEHASH() external pure returns (bytes32); + function nonces(address owner) external view returns (uint); + + function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; + + event Mint(address indexed sender, uint amount0, uint amount1); + event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); + event Swap( + address indexed sender, + uint amount0In, + uint amount1In, + uint amount0Out, + uint amount1Out, + address indexed to + ); + event Sync(uint112 reserve0, uint112 reserve1); + + function MINIMUM_LIQUIDITY() external pure returns (uint); + function factory() external view returns (address); + function token0() external view returns (address); + function token1() external view returns (address); + function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); + function price0CumulativeLast() external view returns (uint); + function price1CumulativeLast() external view returns (uint); + function kLast() external view returns (uint); + + function mint(address to) external returns (uint liquidity); + function burn(address to) external returns (uint amount0, uint amount1); + function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; + function skim(address to) external; + function sync() external; + + function initialize(address, address) external; +} \ No newline at end of file diff --git a/contracts/v1/interfaces/IUniswapV2Router01.sol b/contracts/v1/interfaces/IUniswapV2Router01.sol new file mode 100644 index 0000000..c1168d6 --- /dev/null +++ b/contracts/v1/interfaces/IUniswapV2Router01.sol @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.6.11; + +interface IUniswapV2Router01 { + function factory() external pure returns (address); + function WETH() external pure returns (address); + + function addLiquidity( + address tokenA, + address tokenB, + uint amountADesired, + uint amountBDesired, + uint amountAMin, + uint amountBMin, + address to, + uint deadline + ) external returns (uint amountA, uint amountB, uint liquidity); + function addLiquidityETH( + address token, + uint amountTokenDesired, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline + ) external payable returns (uint amountToken, uint amountETH, uint liquidity); + function removeLiquidity( + address tokenA, + address tokenB, + uint liquidity, + uint amountAMin, + uint amountBMin, + address to, + uint deadline + ) external returns (uint amountA, uint amountB); + function removeLiquidityETH( + address token, + uint liquidity, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline + ) external returns (uint amountToken, uint amountETH); + function removeLiquidityWithPermit( + address tokenA, + address tokenB, + uint liquidity, + uint amountAMin, + uint amountBMin, + address to, + uint deadline, + bool approveMax, uint8 v, bytes32 r, bytes32 s + ) external returns (uint amountA, uint amountB); + function removeLiquidityETHWithPermit( + address token, + uint liquidity, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline, + bool approveMax, uint8 v, bytes32 r, bytes32 s + ) external returns (uint amountToken, uint amountETH); + function swapExactTokensForTokens( + uint amountIn, + uint amountOutMin, + address[] calldata path, + address to, + uint deadline + ) external returns (uint[] memory amounts); + function swapTokensForExactTokens( + uint amountOut, + uint amountInMax, + address[] calldata path, + address to, + uint deadline + ) external returns (uint[] memory amounts); + function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) + external + payable + returns (uint[] memory amounts); + function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) + external + returns (uint[] memory amounts); + function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) + external + returns (uint[] memory amounts); + function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) + external + payable + returns (uint[] memory amounts); + + function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); + function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); + function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); + function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); + function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); +} diff --git a/contracts/v1/interfaces/IUniswapV2Router02.sol b/contracts/v1/interfaces/IUniswapV2Router02.sol new file mode 100644 index 0000000..8d64fe3 --- /dev/null +++ b/contracts/v1/interfaces/IUniswapV2Router02.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.6.11; + +import './IUniswapV2Router01.sol'; + +interface IUniswapV2Router02 is IUniswapV2Router01 { + function removeLiquidityETHSupportingFeeOnTransferTokens( + address token, + uint liquidity, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline + ) external returns (uint amountETH); + function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( + address token, + uint liquidity, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline, + bool approveMax, uint8 v, bytes32 r, bytes32 s + ) external returns (uint amountETH); + + function swapExactTokensForTokensSupportingFeeOnTransferTokens( + uint amountIn, + uint amountOutMin, + address[] calldata path, + address to, + uint deadline + ) external; + function swapExactETHForTokensSupportingFeeOnTransferTokens( + uint amountOutMin, + address[] calldata path, + address to, + uint deadline + ) external payable; + function swapExactTokensForETHSupportingFeeOnTransferTokens( + uint amountIn, + uint amountOutMin, + address[] calldata path, + address to, + uint deadline + ) external; +} diff --git a/contracts/v1/interfaces/IUniverse.sol b/contracts/v1/interfaces/IUniverse.sol new file mode 100755 index 0000000..2bcc2ff --- /dev/null +++ b/contracts/v1/interfaces/IUniverse.sol @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: MIT + +// IUniverse.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; + +/** + * @title Universal Controller interface + * @dev ... + */ +interface IUniverse { + + event ChargedParticlesSet(address indexed chargedParticles); + event PhotonSet(address indexed photonToken, uint256 maxSupply); + event ProtonTokenSet(address indexed protonToken); + event LeptonTokenSet(address indexed leptonToken); + event QuarkTokenSet(address indexed quarkToken); + event BosonTokenSet(address indexed bosonToken); + event EsaMultiplierSet(address indexed assetToken, uint256 multiplier); + event ElectrostaticAttraction(address indexed account, address photonSource, uint256 energy, uint256 multiplier); + event ElectrostaticDischarge(address indexed account, address photonSource, uint256 energy); + + function onEnergize( + address sender, + address referrer, + address contractAddress, + uint256 tokenId, + string calldata managerId, + address assetToken, + uint256 assetEnergy + ) external; + + function onDischarge( + address contractAddress, + uint256 tokenId, + string calldata managerId, + address assetToken, + uint256 creatorEnergy, + uint256 receiverEnergy + ) external; + + function onDischargeForCreator( + address contractAddress, + uint256 tokenId, + string calldata managerId, + address creator, + address assetToken, + uint256 receiverEnergy + ) external; + + function onRelease( + address contractAddress, + uint256 tokenId, + string calldata managerId, + address assetToken, + uint256 principalEnergy, + uint256 creatorEnergy, + uint256 receiverEnergy + ) external; + + function onCovalentBond( + address contractAddress, + uint256 tokenId, + string calldata managerId, + address nftTokenAddress, + uint256 nftTokenId, + uint256 nftTokenAmount + ) external; + + function onCovalentBreak( + address contractAddress, + uint256 tokenId, + string calldata managerId, + address nftTokenAddress, + uint256 nftTokenId, + uint256 nftTokenAmount + ) external; + + function onProtonSale( + address contractAddress, + uint256 tokenId, + address oldOwner, + address newOwner, + uint256 salePrice, + address creator, + uint256 creatorRoyalties + ) external; +} diff --git a/contracts/v1/interfaces/IUniverseRP.sol b/contracts/v1/interfaces/IUniverseRP.sol new file mode 100755 index 0000000..2d945e4 --- /dev/null +++ b/contracts/v1/interfaces/IUniverseRP.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT + +// IUniverseRP.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; +pragma experimental ABIEncoderV2; + +import "./IUniverse.sol"; + +/** + * @title Universal Controller interface for Rewards Program + * @dev ... + */ +interface IUniverseRP is IUniverse { + event RewardProgramSet(address indexed assetToken, address indexed rewardProgram); + event RewardProgramRemoved(address indexed assetToken); + event NftDeposit(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId); + event NftRelease(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId); + + struct NftStake { + uint256 multiplier; // in Basis Points + uint256 depositBlockNumber; + uint256 releaseBlockNumber; + } + + function getRewardProgram(address asset) external view returns (address); + function getNftStake(uint256 uuid) external view returns (NftStake memory); +} diff --git a/contracts/v1/interfaces/IWalletManager.sol b/contracts/v1/interfaces/IWalletManager.sol new file mode 100755 index 0000000..ccdab26 --- /dev/null +++ b/contracts/v1/interfaces/IWalletManager.sol @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: MIT + +// IWalletManager.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; + +/** + * @title Particle Wallet Manager interface + * @dev The wallet-manager for underlying assets attached to Charged Particles + * @dev Manages the link between NFTs and their respective Smart-Wallets + */ +interface IWalletManager { + + event ControllerSet(address indexed controller); + event ExecutorSet(address indexed executor); + event PausedStateSet(bool isPaused); + event NewSmartWallet(address indexed contractAddress, uint256 indexed tokenId, address indexed smartWallet, address creator, uint256 annuityPct); + event WalletEnergized(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 assetAmount, uint256 yieldTokensAmount); + event WalletDischarged(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 creatorAmount, uint256 receiverAmount); + event WalletDischargedForCreator(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, address creator, uint256 receiverAmount); + event WalletReleased(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address assetToken, uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount); + event WalletRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount); + + function isPaused() external view returns (bool); + + function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view returns (bool); + function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view returns (address); + + function getTotal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256); + function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256); + function getInterest(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest); + function getRewards(address contractAddress, uint256 tokenId, address rewardToken) external returns (uint256); + + function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount) external returns (uint256 yieldTokensAmount); + function discharge(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount); + function dischargeAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount); + function dischargeAmountForCreator(address receiver, address contractAddress, uint256 tokenId, address creator, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount); + function release(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount); + function releaseAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount); + function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount); + function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory); + function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken) external; + function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct) external returns (address); + + function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external; + function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external; + function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external; +} diff --git a/contracts/v1/leptons/store.sol b/contracts/v1/leptons/store.sol new file mode 100644 index 0000000..a283d1e --- /dev/null +++ b/contracts/v1/leptons/store.sol @@ -0,0 +1,121 @@ +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "../lib/BlackholePrevention.sol"; +import "../tokens/Ionx.sol"; +import "../tokens/Lepton2.sol"; + +interface ILepsonsStore { + function getLeptonBalance() external view returns (uint256); + function getIonxBalance() external view returns (uint256); + function buyWithIonx(uint256 leptonAmount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; + + function load(uint256 amount) external payable; + function setNextTokenId(uint256 tokenId) external; + function setLepton(address _lepton) external; + function setIonx(address _ionx) external; + function setIonxPerLepton(uint256 ionxAmount) external; +} + +contract LeptonsStore is ILepsonsStore, IERC721Receiver, Ownable, BlackholePrevention { + using SafeMath for uint256; + + event SoldLepton(address indexed buyer, uint256 amount, uint256 price); + + Lepton2 public lepton; + Ionx public ionx; + + uint256 public nextTokenId; + uint256 public ionxPerLepton; + + constructor(address _lepton, address _ionx, uint256 _ionxPerLepton) public { + lepton = Lepton2(_lepton); + ionx = Ionx(_ionx); + ionxPerLepton = _ionxPerLepton; + } + + function getLeptonBalance() external view override returns (uint256) { + return lepton.balanceOf(address(this)); + } + + function getIonxBalance() external view override returns (uint256) { + return ionx.balanceOf(address(this)); + } + + function buyWithIonx( + uint256 leptonAmount, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) external override { + uint256 ionxAmount = leptonAmount * ionxPerLepton; + require(ionx.balanceOf(msg.sender) >= ionxAmount, "Insufficient IONX balance"); + require(lepton.balanceOf(address(this)) >= leptonAmount, "Insufficient Lepton balance"); + + ionx.permit(msg.sender, address(this), ionxAmount, deadline, v, r, s); + ionx.transferFrom(msg.sender, address(this), ionxAmount); + + for (uint256 i = 0; i < leptonAmount; ++i) { + uint256 tokenId = nextTokenId; + nextTokenId = nextTokenId.add(1); + + lepton.safeTransferFrom(address(this), msg.sender, tokenId); + } + + emit SoldLepton(msg.sender, leptonAmount, ionxAmount); + } + + function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) { + return IERC721Receiver.onERC721Received.selector; + } + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + function load(uint256 amount) external payable override onlyOwner { + lepton.batchMintLepton{ value: msg.value }(amount); + } + + function setNextTokenId(uint256 tokenId) external override onlyOwner { + nextTokenId = (tokenId == 0) ? lepton.totalSupply().add(1) : tokenId; + } + + function setLepton(address _lepton) external override onlyOwner { + require(_lepton != address(0), "Invalid address"); + lepton = Lepton2(_lepton); + } + + function setIonx(address _ionx) external override onlyOwner { + require(_ionx != address(0), "Invalid address"); + ionx = Ionx(_ionx); + } + + function setIonxPerLepton(uint256 ionxAmount) external override onlyOwner { + ionxPerLepton = ionxAmount; + } + + /***********************************| + | Only Admin/DAO | + | (blackhole prevention) | + |__________________________________*/ + + function withdrawEther(address payable receiver, uint256 amount) external onlyOwner { + _withdrawEther(receiver, amount); + } + + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner { + _withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner { + _withdrawERC1155(receiver, tokenAddress, tokenId, amount); + } +} \ No newline at end of file diff --git a/contracts/v1/lib/BaseProton.sol b/contracts/v1/lib/BaseProton.sol new file mode 100644 index 0000000..1431d41 --- /dev/null +++ b/contracts/v1/lib/BaseProton.sol @@ -0,0 +1,534 @@ +// SPDX-License-Identifier: MIT + +// ProtonB.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; +pragma experimental ABIEncoderV2; + +import "../lib/ERC721.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/utils/Counters.sol"; +import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; + +import "../interfaces/IBaseProton.sol"; +import "../lib/TokenInfo.sol"; +import "../lib/BlackholePrevention.sol"; +import "../lib/RelayRecipient.sol"; + +/// @title Base Proton Contract for Charged Particles compatible ERC721 NFTs +/// @dev MUST NOT be Upgradeable, as Upgradeable NFTs are incompatible with Charged Particles. +contract BaseProton is + IBaseProton, + ERC721, + Ownable, + RelayRecipient, + ReentrancyGuard, + BlackholePrevention +{ + using SafeMath for uint256; + using TokenInfo for address payable; + using Counters for Counters.Counter; + + event Received(address, uint); + + uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%) + + /// @dev Sequential Token IDs storage + Counters.Counter internal _tokenIds; + + /// @dev NFT Token Creator settings + mapping (uint256 => address) internal _tokenCreator; + mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct; + mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect; + mapping (address => uint256) internal _tokenCreatorClaimableRoyalties; + + /// @dev NFT Token Sale settings + mapping (uint256 => uint256) internal _tokenSalePrice; + mapping (uint256 => uint256) internal _tokenLastSellPrice; + + /// @dev Whether of not the Contract is Paused + bool internal _paused; + + + /***********************************| + | Initialization | + |__________________________________*/ + + /// @dev Inherit from ERC721 standard + constructor(string memory _name, string memory _symbol) public ERC721(_name, _symbol) {} + + + /***********************************| + | Public | + |__________________________________*/ + receive() external payable virtual { + emit Received(msg.sender, msg.value); + } + + /// Returns the Creator address of an NFT by Token ID + /// @param tokenId The ID of the NFT Token to lookup + /// @return The address of the Creator account + function creatorOf(uint256 tokenId) external view virtual override returns (address) { + return _tokenCreator[tokenId]; + } + + /// Returns the Sale Price of an NFT by Token ID + /// @param tokenId The ID of the NFT Token to lookup + /// @return The sale price of the NFT + function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) { + return _tokenSalePrice[tokenId]; + } + + /// Returns the Last Sale Price of an NFT by Token ID + /// @notice This is used to determine any increase in sale price used in royalties calculations + /// @param tokenId The ID of the NFT Token to lookup + /// @return The last sale price of the NFT + function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) { + return _tokenLastSellPrice[tokenId]; + } + + /// Returns the Claimable Royalties for the NFT Creator + /// @param account The address of the Creator account to lookup + /// @return The amount of earned royalties for the creator account + function getCreatorRoyalties(address account) external view virtual override returns (uint256) { + return _tokenCreatorClaimableRoyalties[account]; + } + + /// Returns the Percentage of Royalties reserved for the NFT Creator + /// @param tokenId The ID of the NFT Token to lookup + /// @return The percentage of royalties reserved for the creator + function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) { + return _tokenCreatorRoyaltiesPct[tokenId]; + } + + /// Returns the Receiving address of the Creator Royalties (or Creator if not set) + /// @dev Returns the creator address if a receiving address has not been configured + /// @param tokenId The ID of the NFT Token to lookup + /// @return The Receiving address of the Creator Royalties + function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) { + return _creatorRoyaltiesReceiver(tokenId); + } + + /// Allows an NFT Creator to Claim any Royalties that have been earned from NFT sales + /// @dev Must be called by the royalties receiver account (not neccessarily the creator) + /// @return The amout of creator royalties claimed + function claimCreatorRoyalties() + external + virtual + override + nonReentrant + whenNotPaused + returns (uint256) + { + return _claimCreatorRoyalties(_msgSender()); + } + + + /***********************************| + | Create Single Protons | + |__________________________________*/ + + /// Creates a Basic NFT with no Royalties and no initial Sale Price + /// @dev Royalties and Sale Price can be configured later + /// @param creator The address of the NFT Creator (can be different from the caller) + /// @param receiver The receiving address of the NFT (can be different from the caller) + /// @param tokenMetaUri The unique metadata URI for the NFT + /// @return newTokenId The newly minted NFT Token ID + function createProton( + address creator, + address receiver, + string memory tokenMetaUri + ) + external + virtual + override + whenNotPaused + returns (uint256 newTokenId) + { + newTokenId = _createProton( + creator, + receiver, + tokenMetaUri, + 0, // royaltiesPercent + 0 // salePrice + ); + } + + + /***********************************| + | Create Multiple Protons | + |__________________________________*/ + + function createProtons( + address creator, + address receiver, + string[] calldata tokenMetaUris + ) + external + virtual + override + whenNotPaused + returns (bool) + { + _createProtons( + creator, + receiver, + 0, // royaltiesPercent + tokenMetaUris + ); + return true; + } + + function createProtonsForSale( + address creator, + address receiver, + uint256 royaltiesPercent, + string[] calldata tokenMetaUris, + uint256[] calldata salePrices + ) + external + virtual + override + whenNotPaused + returns (bool) + { + _createProtonsForSale( + creator, + receiver, + royaltiesPercent, + tokenMetaUris, + salePrices + ); + return true; + } + + + /***********************************| + | Buy Protons | + |__________________________________*/ + + function buyProton(uint256 tokenId, uint256 gasLimit) + external + payable + virtual + override + nonReentrant + whenNotPaused + returns (bool) + { + _buyProton(tokenId, gasLimit); + return true; + } + + /***********************************| + | Only Token Creator/Owner | + |__________________________________*/ + + function setSalePrice(uint256 tokenId, uint256 salePrice) + external + virtual + override + whenNotPaused + onlyTokenOwnerOrApproved(tokenId) + { + _setSalePrice(tokenId, salePrice); + } + + function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) + external + virtual + override + whenNotPaused + onlyTokenCreator(tokenId) + onlyTokenOwnerOrApproved(tokenId) + { + _setRoyaltiesPct(tokenId, royaltiesPct); + } + + function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) + external + virtual + override + whenNotPaused + onlyTokenCreator(tokenId) + { + _tokenCreatorRoyaltiesRedirect[tokenId] = receiver; + } + + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + function setPausedState(bool state) external virtual onlyOwner { + _paused = state; + emit PausedStateSet(state); + } + + function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner { + trustedForwarder = _trustedForwarder; + } + + + /***********************************| + | Only Admin/DAO | + | (blackhole prevention) | + |__________________________________*/ + + function withdrawEther(address payable receiver, uint256 amount) external onlyOwner { + _withdrawEther(receiver, amount); + } + + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner { + _withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual { + _tokenSalePrice[tokenId] = salePrice; + emit SalePriceSet(tokenId, salePrice); + } + + function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual { + require(royaltiesPct <= PERCENTAGE_SCALE, "PRT:E-421"); + _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct; + emit CreatorRoyaltiesSet(tokenId, royaltiesPct); + } + + function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) { + address receiver = _tokenCreatorRoyaltiesRedirect[tokenId]; + if (receiver == address(0x0)) { + receiver = _tokenCreator[tokenId]; + } + return receiver; + } + + function _createProton( + address creator, + address receiver, + string memory tokenMetaUri, + uint256 royaltiesPercent, + uint256 salePrice + ) + internal + virtual + returns (uint256 newTokenId) + { + _tokenIds.increment(); + + newTokenId = _tokenIds.current(); + _safeMint(receiver, newTokenId, ""); + _tokenCreator[newTokenId] = creator; + + _setTokenURI(newTokenId, tokenMetaUri); + + if (royaltiesPercent > 0) { + _setRoyaltiesPct(newTokenId, royaltiesPercent); + } + + if (salePrice > 0) { + _setSalePrice(newTokenId, salePrice); + } + } + + function _createProtons( + address creator, + address receiver, + uint256 royaltiesPercent, + string[] calldata tokenMetaUris + ) + internal + virtual + { + uint256 count = tokenMetaUris.length; + for (uint256 i; i < count; i++) { + _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, 0); + } + } + + function _createProtonsForSale( + address creator, + address receiver, + uint256 royaltiesPercent, + string[] calldata tokenMetaUris, + uint256[] calldata salePrices + ) + internal + virtual + { + require(tokenMetaUris.length == salePrices.length, "PRT:E-202"); + + uint256 count = tokenMetaUris.length; + for (uint256 i; i < count; i++) { + _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, salePrices[i]); + } + } + + function _buyProton(uint256 _tokenId, uint256 _gasLimit) + internal + virtual + returns ( + address contractAddress, + uint256 tokenId, + address oldOwner, + address newOwner, + uint256 salePrice, + address royaltiesReceiver, + uint256 creatorAmount + ) + { + contractAddress = address(this); + tokenId = _tokenId; + salePrice = _tokenSalePrice[_tokenId]; + require(salePrice > 0, "PRT:E-416"); + require(msg.value >= salePrice, "PRT:E-414"); + + uint256 ownerAmount = salePrice; + creatorAmount; + oldOwner = ownerOf(_tokenId); + newOwner = _msgSender(); + + // Creator Royalties + royaltiesReceiver = _creatorRoyaltiesReceiver(_tokenId); + uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[_tokenId]; + uint256 lastSellPrice = _tokenLastSellPrice[_tokenId]; + if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) { + creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE); + ownerAmount = ownerAmount.sub(creatorAmount); + } + _tokenLastSellPrice[_tokenId] = salePrice; + + // Reserve Royalties for Creator + if (creatorAmount > 0) { + _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount); + } + + // Transfer Token + _transfer(oldOwner, newOwner, _tokenId); + + // Transfer Payment + if (ownerAmount > 0) { + payable(oldOwner).sendValue(ownerAmount, _gasLimit); + } + + emit ProtonSold(_tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount); + + _refundOverpayment(salePrice, _gasLimit); + } + + /** + * @dev Pays out the Creator Royalties of the calling account + * @param receiver The receiver of the claimable royalties + * @return The amount of Creator Royalties claimed + */ + function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) { + uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver]; + require(claimableAmount > 0, "PRT:E-411"); + + delete _tokenCreatorClaimableRoyalties[receiver]; + payable(receiver).sendValue(claimableAmount, 0); + + emit RoyaltiesClaimed(receiver, claimableAmount); + } + + /** + * @dev Collects the Required Asset Token from the users wallet + * @param from The owner address to collect the Assets from + * @param assetAmount The Amount of Asset Tokens to Collect + */ + function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual { + uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from); + require(assetAmount <= _userAssetBalance, "PRT:E-411"); + // Be sure to Approve this Contract to transfer your Asset Token + require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), "PRT:E-401"); + } + + function _refundOverpayment(uint256 threshold, uint256 gasLimit) internal virtual { + uint256 overage = msg.value.sub(threshold); + if (overage > 0) { + payable(_msgSender()).sendValue(overage, gasLimit); + } + } + + function _transfer(address from, address to, uint256 tokenId) internal virtual override { + _tokenSalePrice[tokenId] = 0; + super._transfer(from, to, tokenId); + } + + + /***********************************| + | GSN/MetaTx Relay | + |__________________________________*/ + + /// @dev See {BaseRelayRecipient-_msgSender}. + function _msgSender() + internal + view + virtual + override(BaseRelayRecipient, Context) + returns (address payable) + { + return BaseRelayRecipient._msgSender(); + } + + /// @dev See {BaseRelayRecipient-_msgData}. + function _msgData() + internal + view + virtual + override(BaseRelayRecipient, Context) + returns (bytes memory) + { + return BaseRelayRecipient._msgData(); + } + + + /***********************************| + | Modifiers | + |__________________________________*/ + + modifier whenNotPaused() { + require(!_paused, "PRT:E-101"); + _; + } + + modifier onlyTokenOwnerOrApproved(uint256 tokenId) { + require(_isApprovedOrOwner(_msgSender(), tokenId), "PRT:E-105"); + _; + } + + modifier onlyTokenCreator(uint256 tokenId) { + require(_tokenCreator[tokenId] == _msgSender(), "PRT:E-104"); + _; + } +} \ No newline at end of file diff --git a/contracts/v1/lib/Bitwise.sol b/contracts/v1/lib/Bitwise.sol new file mode 100644 index 0000000..f77aa0b --- /dev/null +++ b/contracts/v1/lib/Bitwise.sol @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: MIT + +// Bitwise.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +library Bitwise { + function negate(uint32 a) internal pure returns (uint32) { + return a ^ maxInt(); + } + + function shiftLeft(uint32 a, uint32 n) internal pure returns (uint32) { + return a * uint32(2) ** n; + } + + function shiftRight(uint32 a, uint32 n) internal pure returns (uint32) { + return a / uint32(2) ** n; + } + + function maxInt() internal pure returns (uint32) { + return uint32(-1); + } + + // Get bit value at position + function hasBit(uint32 a, uint32 n) internal pure returns (bool) { + return a & shiftLeft(0x01, n) != 0; + } + + // Set bit value at position + function setBit(uint32 a, uint32 n) internal pure returns (uint32) { + return a | shiftLeft(0x01, n); + } + + // Set the bit into state "false" + function clearBit(uint32 a, uint32 n) internal pure returns (uint32) { + uint32 mask = negate(shiftLeft(0x01, n)); + return a & mask; + } +} diff --git a/contracts/v1/lib/BlackholePrevention.sol b/contracts/v1/lib/BlackholePrevention.sol new file mode 100644 index 0000000..d7d53c8 --- /dev/null +++ b/contracts/v1/lib/BlackholePrevention.sol @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: MIT + +// BlackholePrevention.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; + +import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; + +/** + * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing + * the Owner/DAO to pull them out on behalf of a user + * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them. + */ +contract BlackholePrevention { + using Address for address payable; + using SafeERC20 for IERC20; + + event WithdrawStuckEther(address indexed receiver, uint256 amount); + event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount); + event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId); + event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount); + + function _withdrawEther(address payable receiver, uint256 amount) internal virtual { + require(receiver != address(0x0), "BHP:E-403"); + if (address(this).balance >= amount) { + receiver.sendValue(amount); + emit WithdrawStuckEther(receiver, amount); + } + } + + function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual { + require(receiver != address(0x0), "BHP:E-403"); + if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) { + IERC20(tokenAddress).safeTransfer(receiver, amount); + emit WithdrawStuckERC20(receiver, tokenAddress, amount); + } + } + + function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual { + require(receiver != address(0x0), "BHP:E-403"); + if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) { + IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId); + emit WithdrawStuckERC721(receiver, tokenAddress, tokenId); + } + } + + function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual { + require(receiver != address(0x0), "BHP:E-403"); + if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) { + IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, ""); + emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount); + } + } +} diff --git a/contracts/v1/lib/ERC721.sol b/contracts/v1/lib/ERC721.sol new file mode 100644 index 0000000..d1dbe17 --- /dev/null +++ b/contracts/v1/lib/ERC721.sol @@ -0,0 +1,412 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.6.0; + +import "@openzeppelin/contracts/GSN/Context.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; +import "@openzeppelin/contracts/introspection/ERC165.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts/utils/EnumerableSet.sol"; +import "@openzeppelin/contracts/utils/EnumerableMap.sol"; +import "@openzeppelin/contracts/utils/Strings.sol"; + +/** + * @title ERC721 Non-Fungible Token Standard basic implementation + * @dev see https://eips.ethereum.org/EIPS/eip-721 + */ +contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable { + using SafeMath for uint256; + using Address for address; + using EnumerableSet for EnumerableSet.UintSet; + using EnumerableMap for EnumerableMap.UintToAddressMap; + using Strings for uint256; + + /** + * @dev Emitted when `tokenId` token is transfered from `from` to `to`. + */ + event TransferBatch(address indexed from, address indexed to, uint256 startTokenId, uint256 count); + + // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` + // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector` + bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; + + // Mapping from holder address to their (enumerable) set of owned tokens + mapping (address => EnumerableSet.UintSet) private _holderTokens; + + // Enumerable mapping from token ids to their owners + EnumerableMap.UintToAddressMap private _tokenOwners; + + // Mapping from token ID to approved address + mapping (uint256 => address) private _tokenApprovals; + + // Mapping from owner to operator approvals + mapping (address => mapping (address => bool)) private _operatorApprovals; + + // Token name + string private _name; + + // Token symbol + string private _symbol; + + // Optional mapping for token URIs + mapping(uint256 => string) private _tokenURIs; + + /* + * bytes4(keccak256('balanceOf(address)')) == 0x70a08231 + * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e + * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3 + * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc + * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465 + * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5 + * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd + * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e + * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde + * + * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^ + * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd + */ + bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd; + + /* + * bytes4(keccak256('name()')) == 0x06fdde03 + * bytes4(keccak256('symbol()')) == 0x95d89b41 + * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd + * + * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f + */ + bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f; + + /* + * bytes4(keccak256('totalSupply()')) == 0x18160ddd + * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59 + * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7 + * + * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63 + */ + bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63; + + /** + * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. + */ + constructor (string memory name, string memory symbol) public { + _name = name; + _symbol = symbol; + + // register the supported interfaces to conform to ERC721 via ERC165 + _registerInterface(_INTERFACE_ID_ERC721); + _registerInterface(_INTERFACE_ID_ERC721_METADATA); + _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE); + } + + /** + * @dev See {IERC721-balanceOf}. + */ + function balanceOf(address owner) public view override returns (uint256) { + require(owner != address(0), "ERC721:E-403"); + + return _holderTokens[owner].length(); + } + + /** + * @dev See {IERC721-ownerOf}. + */ + function ownerOf(uint256 tokenId) public view override returns (address) { + return _tokenOwners.get(tokenId, "ERC721:E-405"); + } + + /** + * @dev See {IERC721Metadata-name}. + */ + function name() public view override returns (string memory) { + return _name; + } + + /** + * @dev See {IERC721Metadata-symbol}. + */ + function symbol() public view override returns (string memory) { + return _symbol; + } + + /** + * @dev See {IERC721Metadata-tokenURI}. + */ + function tokenURI(uint256 tokenId) public view override returns (string memory) { + require(_exists(tokenId), "ERC721:E-405"); + return _tokenURIs[tokenId]; + } + + /** + * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. + */ + function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) { + return _holderTokens[owner].at(index); + } + + /** + * @dev See {IERC721Enumerable-totalSupply}. + */ + function totalSupply() public view override returns (uint256) { + // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds + return _tokenOwners.length(); + } + + /** + * @dev See {IERC721Enumerable-tokenByIndex}. + */ + function tokenByIndex(uint256 index) public view override returns (uint256) { + (uint256 tokenId, ) = _tokenOwners.at(index); + return tokenId; + } + + /** + * @dev See {IERC721-approve}. + */ + function approve(address to, uint256 tokenId) public virtual override { + address owner = ownerOf(tokenId); + require(to != owner, "ERC721:E-111"); + + require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721:E-105"); + + _approve(to, tokenId); + } + + /** + * @dev See {IERC721-getApproved}. + */ + function getApproved(uint256 tokenId) public view override returns (address) { + require(_exists(tokenId), "ERC721:E-405"); + + return _tokenApprovals[tokenId]; + } + + /** + * @dev See {IERC721-setApprovalForAll}. + */ + function setApprovalForAll(address operator, bool approved) public virtual override { + require(operator != _msgSender(), "ERC721:E-111"); + + _operatorApprovals[_msgSender()][operator] = approved; + emit ApprovalForAll(_msgSender(), operator, approved); + } + + /** + * @dev See {IERC721-isApprovedForAll}. + */ + function isApprovedForAll(address owner, address operator) public view override returns (bool) { + return _operatorApprovals[owner][operator]; + } + + /** + * @dev See {IERC721-transferFrom}. + */ + function transferFrom(address from, address to, uint256 tokenId) public virtual override { + //solhint-disable-next-line max-line-length + require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721:E-105"); + + _transfer(from, to, tokenId); + } + + /** + * @dev See {IERC721-safeTransferFrom}. + */ + function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override { + safeTransferFrom(from, to, tokenId, ""); + } + + /** + * @dev See {IERC721-safeTransferFrom}. + */ + function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override { + require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721:E-105"); + _safeTransfer(from, to, tokenId, _data); + } + + /** + * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients + * are aware of the ERC721 protocol to prevent tokens from being forever locked. + * + * `_data` is additional data, it has no specified format and it is sent in call to `to`. + * + * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. + * implement alternative mecanisms to perform token transfer, such as signature-based. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must exist and be owned by `from`. + * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + * + * Emits a {Transfer} event. + */ + function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual { + _transfer(from, to, tokenId); + require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721:E-402"); + } + + /** + * @dev Returns whether `tokenId` exists. + * + * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. + * + * Tokens start existing when they are minted (`_mint`), + * and stop existing when they are burned (`_burn`). + */ + function _exists(uint256 tokenId) internal view returns (bool) { + return _tokenOwners.contains(tokenId); + } + + /** + * @dev Returns whether `spender` is allowed to manage `tokenId`. + * + * Requirements: + * + * - `tokenId` must exist. + */ + function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) { + require(_exists(tokenId), "ERC721:E-405"); + address owner = ownerOf(tokenId); + return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); + } + + /** + * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is + * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. + */ + function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual { + _mint(to, tokenId); + require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721:E-402"); + } + + /** + * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is + * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. + */ + function _safeMintBatch(address to, uint256 startTokenId, uint256 count, bytes memory _data) internal virtual { + _mintBatch(to, startTokenId, count); + require(_checkOnERC721Received(address(0), to, startTokenId, _data), "ERC721:E-402"); + } + + /** + * @dev Mints `tokenId` and transfers it to `to`. + * + * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible + * + * Requirements: + * + * - `tokenId` must not exist. + * - `to` cannot be the zero address. + * + * Emits a {Transfer} event. + */ + function _mint(address to, uint256 tokenId) internal virtual { + require(to != address(0), "ERC721:E-403"); + require(!_exists(tokenId), "ERC721:E-407"); + + _holderTokens[to].add(tokenId); + + _tokenOwners.set(tokenId, to); + + emit Transfer(address(0), to, tokenId); + } + + /** + * @dev Mints `tokenId` and transfers it to `to`. + * + * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible + * + * Requirements: + * + * - `tokenId` must not exist. + * - `to` cannot be the zero address. + * + * Emits a {Transfer} event. + */ + function _mintBatch(address to, uint256 startTokenId, uint256 count) internal virtual { + require(to != address(0), "ERC721:E-403"); + require(!_exists(startTokenId), "ERC721:E-407"); + + for (uint i = 0; i < count; i++) { + uint256 tokenId = startTokenId.add(i); + _holderTokens[to].add(tokenId); + _tokenOwners.set(tokenId, to); + } + + emit TransferBatch(address(0), to, startTokenId, count); + } + + /** + * @dev Transfers `tokenId` from `from` to `to`. + * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. + * + * Requirements: + * + * - `to` cannot be the zero address. + * - `tokenId` token must be owned by `from`. + * + * Emits a {Transfer} event. + */ + function _transfer(address from, address to, uint256 tokenId) internal virtual { + require(ownerOf(tokenId) == from, "ERC721:E-102"); + require(to != address(0), "ERC721:E-403"); + + // Clear approvals from the previous owner + _approve(address(0), tokenId); + + _holderTokens[from].remove(tokenId); + _holderTokens[to].add(tokenId); + + _tokenOwners.set(tokenId, to); + + emit Transfer(from, to, tokenId); + } + + /** + * @dev Sets `_tokenURI` as the tokenURI of `tokenId`. + * + * Requirements: + * + * - `tokenId` must exist. + */ + function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { + require(_exists(tokenId), "ERC721:E-405"); + _tokenURIs[tokenId] = _tokenURI; + } + + /** + * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. + * The call is not executed if the target address is not a contract. + * + * @param from address representing the previous owner of the given token ID + * @param to target address that will receive the tokens + * @param tokenId uint256 ID of the token to be transferred + * @param _data bytes optional data to send along with the call + * @return bool whether the call correctly returned the expected magic value + */ + function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) + private returns (bool) + { + if (!to.isContract()) { + return true; + } + bytes memory returndata = to.functionCall(abi.encodeWithSelector( + IERC721Receiver(to).onERC721Received.selector, + _msgSender(), + from, + tokenId, + _data + ), "ERC721:E-402"); + bytes4 retval = abi.decode(returndata, (bytes4)); + return (retval == _ERC721_RECEIVED); + } + + function _approve(address to, uint256 tokenId) private { + _tokenApprovals[tokenId] = to; + emit Approval(ownerOf(tokenId), to, tokenId); + } +} diff --git a/contracts/v1/lib/ERC721Basic.sol b/contracts/v1/lib/ERC721Basic.sol new file mode 100644 index 0000000..0f0351d --- /dev/null +++ b/contracts/v1/lib/ERC721Basic.sol @@ -0,0 +1,357 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.6.0; + +import "@openzeppelin/contracts/GSN/Context.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; +import "@openzeppelin/contracts/introspection/ERC165.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/utils/Address.sol"; + +/** + * @title ERC721 Non-Fungible Token Standard basic implementation + * @dev see https://eips.ethereum.org/EIPS/eip-721 + */ +contract ERC721Basic is Context, ERC165, IERC721, IERC721Metadata { + using SafeMath for uint256; + using Address for address; + + // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` + // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector` + bytes4 internal constant _ERC721_RECEIVED = 0x150b7a02; + + // mapping from token ids to their owners + mapping (uint256 => address) internal _tokenOwners; + + // mapping from owner to token balance + mapping (address => uint256) internal _ownerBalance; + + // Mapping from token ID to approved address + mapping (uint256 => address) internal _tokenApprovals; + + // Mapping from owner to operator approvals + mapping (address => mapping (address => bool)) internal _operatorApprovals; + + // Token name + string internal _name; + + // Token symbol + string internal _symbol; + + // Token Count + uint256 internal _tokenCount; + + /* + * bytes4(keccak256('balanceOf(address)')) == 0x70a08231 + * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e + * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3 + * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc + * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465 + * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5 + * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd + * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e + * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde + * + * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^ + * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd + */ + bytes4 internal constant _INTERFACE_ID_ERC721 = 0x80ac58cd; + + /* + * bytes4(keccak256('name()')) == 0x06fdde03 + * bytes4(keccak256('symbol()')) == 0x95d89b41 + * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd + * + * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f + */ + bytes4 internal constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f; + + /** + * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. + */ + constructor (string memory name, string memory symbol) public { + _name = name; + _symbol = symbol; + + // register the supported interfaces to conform to ERC721 via ERC165 + _registerInterface(_INTERFACE_ID_ERC721); + _registerInterface(_INTERFACE_ID_ERC721_METADATA); + } + + /** + * @dev See {IERC721-balanceOf}. + */ + function balanceOf(address owner) public view override returns (uint256) { + require(owner != address(0), "ERC721:E-403"); + return _ownerBalance[owner]; + } + + /** + * @dev See {IERC721-ownerOf}. + */ + function ownerOf(uint256 tokenId) public view override returns (address) { + return _tokenOwners[tokenId]; + } + + /** + * @dev See {IERC721Metadata-name}. + */ + function name() public view override returns (string memory) { + return _name; + } + + /** + * @dev See {IERC721Metadata-symbol}. + */ + function symbol() public view override returns (string memory) { + return _symbol; + } + + /** + * @dev See {IERC721Metadata-tokenURI}. + */ + function tokenURI(uint256 /* tokenId */) public view virtual override returns (string memory) { + return ""; + } + + /** + * @dev See {IERC721-approve}. + */ + function approve(address to, uint256 tokenId) public virtual override { + address owner = ownerOf(tokenId); + require(to != owner, "ERC721:E-111"); + + require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721:E-105"); + + _approve(to, tokenId); + } + + /** + * @dev See {IERC721-getApproved}. + */ + function getApproved(uint256 tokenId) public view override returns (address) { + require(_exists(tokenId), "ERC721:E-405"); + return _tokenApprovals[tokenId]; + } + + /** + * @dev See {IERC721-setApprovalForAll}. + */ + function setApprovalForAll(address operator, bool approved) public virtual override { + require(operator != _msgSender(), "ERC721:E-111"); + + _operatorApprovals[_msgSender()][operator] = approved; + emit ApprovalForAll(_msgSender(), operator, approved); + } + + /** + * @dev See {IERC721-isApprovedForAll}. + */ + function isApprovedForAll(address owner, address operator) public view override returns (bool) { + return _operatorApprovals[owner][operator]; + } + + /** + * @dev See {IERC721-transferFrom}. + */ + function transferFrom(address from, address to, uint256 tokenId) public virtual override { + //solhint-disable-next-line max-line-length + require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721:E-105"); + + _transfer(from, to, tokenId); + } + + /** + * @dev See {IERC721-safeTransferFrom}. + */ + function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override { + safeTransferFrom(from, to, tokenId, ""); + } + + /** + * @dev See {IERC721-safeTransferFrom}. + */ + function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override { + require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721:E-105"); + _safeTransfer(from, to, tokenId, _data); + } + + /** + * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients + * are aware of the ERC721 protocol to prevent tokens from being forever locked. + * + * `_data` is additional data, it has no specified format and it is sent in call to `to`. + * + * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. + * implement alternative mecanisms to perform token transfer, such as signature-based. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must exist and be owned by `from`. + * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + * + * Emits a {Transfer} event. + */ + function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual { + _transfer(from, to, tokenId); + require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721:E-402"); + } + + /** + * @dev Returns whether `tokenId` exists. + * + * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. + * + * Tokens start existing when they are minted (`_mint`), + * and stop existing when they are burned (`_burn`). + */ + function _exists(uint256 tokenId) internal view returns (bool) { + return _tokenOwners[tokenId] != address(0x0); + } + + /** + * @dev Returns whether `spender` is allowed to manage `tokenId`. + * + * Requirements: + * + * - `tokenId` must exist. + */ + function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) { + require(_exists(tokenId), "ERC721:E-405"); + address owner = ownerOf(tokenId); + return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); + } + + /** + * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is + * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. + */ + function _safeMint(address to, bytes memory _data) internal virtual returns (uint256) { + uint256 tokenId = _mint(to); + require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721:E-402"); + return tokenId; + } + + /** + * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is + * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. + */ + function _safeMintBatch(address to, uint256 count, bytes memory _data) internal virtual { + uint256 startTokenId = _mintBatch(to, count); + require(_checkOnERC721Received(address(0), to, startTokenId, _data), "ERC721:E-402"); + } + + /** + * @dev Mints `tokenId` and transfers it to `to`. + * + * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible + * + * Requirements: + * + * - `tokenId` must not exist. + * - `to` cannot be the zero address. + * + * Emits a {Transfer} event. + */ + function _mint(address to) internal virtual returns (uint256) { + require(to != address(0), "ERC721:E-403"); + + _tokenCount = _tokenCount.add(1); + uint256 tokenId = _tokenCount; + require(!_exists(tokenId), "ERC721:E-407"); + + _tokenOwners[tokenId] = to; + _ownerBalance[to] = _ownerBalance[to].add(1); + + emit Transfer(address(0), to, tokenId); + return tokenId; + } + + /** + * @dev Mints `tokenId` and transfers it to `to`. + * + * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible + * + * Requirements: + * + * - `tokenId` must not exist. + * - `to` cannot be the zero address. + * + * Emits a {Transfer} event. + */ + function _mintBatch(address to, uint256 count) internal virtual returns (uint256) { + require(to != address(0), "ERC721:E-403"); + + uint256 startTokenId = _tokenCount.add(1); + for (uint i = 1; i <= count; i++) { + uint256 tokenId = _tokenCount.add(i); + _tokenOwners[tokenId] = to; + emit Transfer(address(0), to, tokenId); + } + + _tokenCount = _tokenCount.add(count); + _ownerBalance[to] = _ownerBalance[to].add(count); + return startTokenId; + } + + /** + * @dev Transfers `tokenId` from `from` to `to`. + * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. + * + * Requirements: + * + * - `to` cannot be the zero address. + * - `tokenId` token must be owned by `from`. + * + * Emits a {Transfer} event. + */ + function _transfer(address from, address to, uint256 tokenId) internal virtual { + require(ownerOf(tokenId) == from, "ERC721:E-102"); + require(to != address(0), "ERC721:E-403"); + + // Clear approvals from the previous owner + _approve(address(0), tokenId); + + _tokenOwners[tokenId] = to; + _ownerBalance[from] = _ownerBalance[from].sub(1); + _ownerBalance[to] = _ownerBalance[to].add(1); + + emit Transfer(from, to, tokenId); + } + + /** + * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. + * The call is not executed if the target address is not a contract. + * + * @param from address representing the previous owner of the given token ID + * @param to target address that will receive the tokens + * @param tokenId uint256 ID of the token to be transferred + * @param _data bytes optional data to send along with the call + * @return bool whether the call correctly returned the expected magic value + */ + function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) + internal returns (bool) + { + if (!to.isContract()) { + return true; + } + bytes memory returndata = to.functionCall(abi.encodeWithSelector( + IERC721Receiver(to).onERC721Received.selector, + _msgSender(), + from, + tokenId, + _data + ), "ERC721:E-402"); + bytes4 retval = abi.decode(returndata, (bytes4)); + return (retval == _ERC721_RECEIVED); + } + + function _approve(address to, uint256 tokenId) internal { + _tokenApprovals[tokenId] = to; + emit Approval(ownerOf(tokenId), to, tokenId); + } +} diff --git a/contracts/v1/lib/IERC5192.sol b/contracts/v1/lib/IERC5192.sol new file mode 100644 index 0000000..d0f591b --- /dev/null +++ b/contracts/v1/lib/IERC5192.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: CC0-1.0 +pragma solidity ^0.6.0; + +interface IERC5192 { + /// @notice Emitted when the locking status is changed to locked. + /// @dev If a token is minted and the status is locked, this event should be emitted. + /// @param tokenId The identifier for a token. + event Locked(uint256 tokenId); + + /// @notice Emitted when the locking status is changed to unlocked. + /// @dev If a token is minted and the status is unlocked, this event should be emitted. + /// @param tokenId The identifier for a token. + event Unlocked(uint256 tokenId); + + /// @notice Returns the locking status of an Soulbound Token + /// @dev SBTs assigned to zero address are considered invalid, and queries + /// about them do throw. + /// @param tokenId The identifier for an SBT. + function locked(uint256 tokenId) external view returns (bool); +} diff --git a/contracts/v1/lib/NftTokenType.sol b/contracts/v1/lib/NftTokenType.sol new file mode 100644 index 0000000..d89088a --- /dev/null +++ b/contracts/v1/lib/NftTokenType.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT + +// NftTokenType.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/introspection/IERC165.sol"; + +library NftTokenType { + bytes4 constant internal INTERFACE_SIGNATURE_ERC721 = 0x80ac58cd; + bytes4 constant internal INTERFACE_SIGNATURE_ERC1155 = 0xd9b67a26; + + uint256 constant internal TYPE_MASK = uint256(uint128(~0)) << 128; + uint256 constant internal TYPE_NFT_BIT = 1 << 255; + + function isERC721(address contractAddress) internal view returns (bool) { + return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC721); + } + + function isERC1155(address contractAddress) internal view returns (bool) { + return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC1155); + } + + function getTokenType(address contractAddress, uint256 tokenId) internal view returns (uint256) { + IERC165 tokenInterface = IERC165(contractAddress); + bool is1155 = tokenInterface.supportsInterface(INTERFACE_SIGNATURE_ERC1155); + + if (!is1155 || (tokenId & TYPE_NFT_BIT != TYPE_NFT_BIT)) { return 0; } + + return tokenId & TYPE_MASK; + } +} diff --git a/contracts/v1/lib/ReentrancyGuard.sol b/contracts/v1/lib/ReentrancyGuard.sol new file mode 100644 index 0000000..729d16e --- /dev/null +++ b/contracts/v1/lib/ReentrancyGuard.sol @@ -0,0 +1,74 @@ +pragma solidity 0.6.12; + +/** + * @dev Contract module that helps prevent reentrant calls to a function. + * + * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier + * available, which can be applied to functions to make sure there are no nested + * (reentrant) calls to them. + * + * Note that because there is a single `nonReentrant` guard, functions marked as + * `nonReentrant` may not call one another. This can be worked around by making + * those functions `private`, and then adding `external` `nonReentrant` entry + * points to them. + * + * TIP: If you would like to learn more about reentrancy and alternative ways + * to protect against it, check out our blog post + * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. + */ +abstract contract ReentrancyGuard { + // Booleans are more expensive than uint256 or any type that takes up a full + // word because each write operation emits an extra SLOAD to first read the + // slot's contents, replace the bits taken up by the boolean, and then write + // back. This is the compiler's defense against contract upgrades and + // pointer aliasing, and it cannot be disabled. + + // The values being non-zero value makes deployment a bit more expensive, + // but in exchange the refund on every call to nonReentrant will be lower in + // amount. Since refunds are capped to a percentage of the total + // transaction's gas, it is best to keep them low in cases like this one, to + // increase the likelihood of the full refund coming into effect. + uint256 private constant _NOT_ENTERED = 1; + uint256 private constant _ENTERED = 2; + + uint256 private _status; + + constructor () public { + _status = _NOT_ENTERED; + } + + /** + * @dev Prevents a contract from calling itself, directly or indirectly. + * Calling a `nonReentrant` function from another `nonReentrant` + * function is not supported. It is possible to prevent this from happening + * by making the `nonReentrant` function external, and making it call a + * `private` function that does the actual work. + */ + modifier nonReentrant() { + _nonReentrantBefore(); + _; + _nonReentrantAfter(); + } + + function _nonReentrantBefore() private { + // On the first call to nonReentrant, _status will be _NOT_ENTERED + require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); + + // Any calls to nonReentrant after this point will fail + _status = _ENTERED; + } + + function _nonReentrantAfter() private { + // By storing the original value once again, a refund is triggered (see + // https://eips.ethereum.org/EIPS/eip-2200) + _status = _NOT_ENTERED; + } + + /** + * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a + * `nonReentrant` function in the call stack. + */ + function _reentrancyGuardEntered() internal view returns (bool) { + return _status == _ENTERED; + } +} \ No newline at end of file diff --git a/contracts/v1/lib/RelayRecipient.sol b/contracts/v1/lib/RelayRecipient.sol new file mode 100755 index 0000000..dc24f81 --- /dev/null +++ b/contracts/v1/lib/RelayRecipient.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT + +pragma solidity >=0.6.0; + +import "@opengsn/gsn/contracts/BaseRelayRecipient.sol"; + +contract RelayRecipient is BaseRelayRecipient { + function versionRecipient() external override view returns (string memory) { + return "1.0.0-beta.1/charged-particles.relay.recipient"; + } +} diff --git a/contracts/v1/lib/SmartWalletBase.sol b/contracts/v1/lib/SmartWalletBase.sol new file mode 100755 index 0000000..60a8618 --- /dev/null +++ b/contracts/v1/lib/SmartWalletBase.sol @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: MIT + +// SmartWalletBase.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; + +import "@openzeppelin/contracts/utils/EnumerableSet.sol"; +import "../interfaces/ISmartWallet.sol"; +import "./BlackholePrevention.sol"; + +/** + * @notice ERC20-Token Smart-Wallet Base Contract + * @dev Non-upgradeable Contract + */ +abstract contract SmartWalletBase is ISmartWallet, BlackholePrevention { + using EnumerableSet for EnumerableSet.AddressSet; + + uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%) + + address internal _walletManager; + + address internal nftCreator; + uint256 internal nftCreatorAnnuityPct; + uint256 internal nftCreatorAmountDischarged; + + EnumerableSet.AddressSet internal _assetTokens; + + // Asset Token => Principal Balance + mapping (address => uint256) internal _assetPrincipalBalance; + + /***********************************| + | Initialization | + |__________________________________*/ + + function initializeBase() public { + require(_walletManager == address(0x0), "SWB:E-002"); + _walletManager = msg.sender; + } + + + /***********************************| + | Public | + |__________________________________*/ + + function getAssetTokenCount() external view virtual override returns (uint256) { + return _assetTokens.length(); + } + + function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) { + if (index >= _assetTokens.length()) { + return address(0); + } + return _assetTokens.at(index); + } + + function setNftCreator(address creator, uint256 annuityPct) external virtual override onlyWalletManager { + nftCreator = creator; + nftCreatorAnnuityPct = annuityPct; + } + + function executeForAccount( + address contractAddress, + uint256 ethValue, + bytes memory encodedParams + ) + external + override + onlyWalletManager + returns (bytes memory) + { + (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams); + require(success, string(result)); + return result; + } + + function refreshPrincipal(address assetToken) + external + virtual + override + onlyWalletManager + { + // no-op + } + + + /***********************************| + | Only Admin/DAO | + | (blackhole prevention) | + |__________________________________*/ + + function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager { + _withdrawEther(receiver, amount); + } + + function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager { + _withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _getPrincipal(address assetToken) internal view virtual returns (uint256) { + return _assetPrincipalBalance[assetToken]; + } + + function _trackAssetToken(address assetToken) internal virtual { + if (!_assetTokens.contains(assetToken)) { + _assetTokens.add(assetToken); + } + } + + /***********************************| + | Modifiers | + |__________________________________*/ + + /// @dev Throws if called by any account other than the wallet manager + modifier onlyWalletManager() { + require(_walletManager == msg.sender, "SWB:E-109"); + _; + } +} \ No newline at end of file diff --git a/contracts/v1/lib/SmartWalletBaseB.sol b/contracts/v1/lib/SmartWalletBaseB.sol new file mode 100755 index 0000000..e3ec49c --- /dev/null +++ b/contracts/v1/lib/SmartWalletBaseB.sol @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: MIT + +// SmartWalletBase.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; + +import "@openzeppelin/contracts/utils/EnumerableSet.sol"; +import "../interfaces/ISmartWalletB.sol"; +import "./BlackholePrevention.sol"; + +/** + * @notice ERC20-Token Smart-Wallet Base Contract + * @dev Non-upgradeable Contract + */ +abstract contract SmartWalletBaseB is ISmartWalletB, BlackholePrevention { + using EnumerableSet for EnumerableSet.AddressSet; + + uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%) + + address internal _walletManager; + + EnumerableSet.AddressSet internal _assetTokens; + + // Asset Token => Principal Balance + mapping (address => uint256) internal _assetPrincipalBalance; + + /***********************************| + | Initialization | + |__________________________________*/ + + function initializeBase() public { + require(_walletManager == address(0x0), "SWB:E-002"); + _walletManager = msg.sender; + } + + + /***********************************| + | Public | + |__________________________________*/ + + function getAssetTokenCount() external view virtual override returns (uint256) { + return _assetTokens.length(); + } + + function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) { + if (index >= _assetTokens.length()) { + return address(0); + } + return _assetTokens.at(index); + } + + function executeForAccount( + address contractAddress, + uint256 ethValue, + bytes memory encodedParams + ) + external + override + onlyWalletManager + returns (bytes memory) + { + (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams); + require(success, string(result)); + return result; + } + + + /***********************************| + | Only Admin/DAO | + | (blackhole prevention) | + |__________________________________*/ + + function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager { + _withdrawEther(receiver, amount); + } + + function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager { + _withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyWalletManager { + _withdrawERC1155(receiver, tokenAddress, tokenId, amount); + } + + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _getPrincipal(address assetToken) internal view virtual returns (uint256) { + return _assetPrincipalBalance[assetToken]; + } + + function _trackAssetToken(address assetToken) internal virtual { + if (!_assetTokens.contains(assetToken)) { + _assetTokens.add(assetToken); + } + } + + /***********************************| + | Modifiers | + |__________________________________*/ + + /// @dev Throws if called by any account other than the wallet manager + modifier onlyWalletManager() { + require(_walletManager == msg.sender, "SWB:E-109"); + _; + } +} \ No newline at end of file diff --git a/contracts/v1/lib/Soul.sol b/contracts/v1/lib/Soul.sol new file mode 100644 index 0000000..5ad4d91 --- /dev/null +++ b/contracts/v1/lib/Soul.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: CC0-1.0 +pragma solidity ^0.6.12; + +import "./IERC5192.sol"; + +contract Soul is IERC5192 { + + mapping (uint256 => bool) public lockedTokens; + + function _lockToken(uint256 tokenId) internal { + lockedTokens[tokenId] = true; + emit Locked(tokenId); + } + + function _unlockToken(uint256 tokenId) internal { + lockedTokens[tokenId] = false; + emit Unlocked(tokenId); + } + + function locked(uint256 tokenId) + external + view + override(IERC5192) + returns (bool) + { + return lockedTokens[tokenId]; + } +} diff --git a/contracts/v1/lib/TokenInfo.sol b/contracts/v1/lib/TokenInfo.sol new file mode 100644 index 0000000..3502ae7 --- /dev/null +++ b/contracts/v1/lib/TokenInfo.sol @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: MIT + +// TokenInfo.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; +import "../interfaces/IERC721Chargeable.sol"; + +library TokenInfo { + function getTokenUUID(address contractAddress, uint256 tokenId) internal pure virtual returns (uint256) { + return uint256(keccak256(abi.encodePacked(contractAddress, tokenId))); + } + + /// @dev DEPRECATED; Prefer TokenInfoProxy + function getTokenOwner(address contractAddress, uint256 tokenId) internal view virtual returns (address) { + IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress); + return tokenInterface.ownerOf(tokenId); + } + + /// @dev DEPRECATED; Prefer TokenInfoProxy + function getTokenCreator(address contractAddress, uint256 tokenId) internal view virtual returns (address) { + IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress); + return tokenInterface.creatorOf(tokenId); + } + + /// @dev DEPRECATED; Prefer TokenInfoProxy + /// @dev Checks if an account is the Owner of an External NFT contract + /// @param contractAddress The Address to the Contract of the NFT to check + /// @param account The Address of the Account to check + /// @return True if the account owns the contract + function isContractOwner(address contractAddress, address account) internal view virtual returns (bool) { + address contractOwner = IERC721Chargeable(contractAddress).owner(); + return contractOwner != address(0x0) && contractOwner == account; + } + + /// @dev DEPRECATED; Prefer TokenInfoProxy + /// @dev Checks if an account is the Creator of a Proton-based NFT + /// @param contractAddress The Address to the Contract of the Proton-based NFT to check + /// @param tokenId The Token ID of the Proton-based NFT to check + /// @param sender The Address of the Account to check + /// @return True if the account is the creator of the Proton-based NFT + function isTokenCreator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) { + IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress); + address tokenCreator = tokenInterface.creatorOf(tokenId); + return (sender == tokenCreator); + } + + /// @dev DEPRECATED; Prefer TokenInfoProxy + /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself + /// @param contractAddress The Address to the Contract of the Proton-based NFT to check + /// @param tokenId The Token ID of the Proton-based NFT to check + /// @param sender The Address of the Account to check + /// @return True if the account is the creator of the Proton-based NFT or the Contract itself + function isTokenContractOrCreator(address contractAddress, uint256 tokenId, address creator, address sender) internal view virtual returns (bool) { + IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress); + address tokenCreator = tokenInterface.creatorOf(tokenId); + if (sender == contractAddress && creator == tokenCreator) { return true; } + return (sender == tokenCreator); + } + + /// @dev DEPRECATED; Prefer TokenInfoProxy + /// @dev Checks if an account is the Owner or Operator of an External NFT + /// @param contractAddress The Address to the Contract of the External NFT to check + /// @param tokenId The Token ID of the External NFT to check + /// @param sender The Address of the Account to check + /// @return True if the account is the Owner or Operator of the External NFT + function isErc721OwnerOrOperator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) { + IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress); + address tokenOwner = tokenInterface.ownerOf(tokenId); + return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender)); + } + + /** + * @dev Returns true if `account` is a contract. + * @dev Taken from OpenZeppelin library + * + * [IMPORTANT] + * ==== + * It is unsafe to assume that an address for which this function returns + * false is an externally-owned account (EOA) and not a contract. + * + * Among others, `isContract` will return false for the following + * types of addresses: + * + * - an externally-owned account + * - a contract in construction + * - an address where a contract will be created + * - an address where a contract lived, but was destroyed + * ==== + */ + function isContract(address account) internal view returns (bool) { + // According to EIP-1052, 0x0 is the value returned for not-yet created accounts + // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned + // for accounts without code, i.e. `keccak256('')` + bytes32 codehash; + bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; + // solhint-disable-next-line no-inline-assembly + assembly { codehash := extcodehash(account) } + return (codehash != accountHash && codehash != 0x0); + } + + /** + * @dev Replacement for Solidity's `transfer`: sends `amount` wei to + * `recipient`, forwarding all available gas and reverting on errors. + * @dev Taken from OpenZeppelin library + * + * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost + * of certain opcodes, possibly making contracts go over the 2300 gas limit + * imposed by `transfer`, making them unable to receive funds via + * `transfer`. {sendValue} removes this limitation. + * + * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. + * + * IMPORTANT: because control is transferred to `recipient`, care must be + * taken to not create reentrancy vulnerabilities. Consider using + * {ReentrancyGuard} or the + * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. + */ + function sendValue(address payable recipient, uint256 amount, uint256 gasLimit) internal { + require(address(this).balance >= amount, "TokenInfo: insufficient balance"); + + // solhint-disable-next-line avoid-low-level-calls, avoid-call-value + (bool success, ) = (gasLimit > 0) + ? recipient.call{ value: amount, gas: gasLimit }("") + : recipient.call{ value: amount }(""); + require(success, "TokenInfo: unable to send value, recipient may have reverted"); + } +} diff --git a/contracts/v1/lib/TokenInfoProxy.sol b/contracts/v1/lib/TokenInfoProxy.sol new file mode 100644 index 0000000..198a38f --- /dev/null +++ b/contracts/v1/lib/TokenInfoProxy.sol @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: MIT + +// TokenInfoProxy.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "../interfaces/ITokenInfoProxy.sol"; +import "../interfaces/IERC721Chargeable.sol"; + + +contract TokenInfoProxy is ITokenInfoProxy, Ownable { + using Address for address; + + mapping (address => FnSignatures) internal _remappedFnSigs; + + function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner { + _remappedFnSigs[contractAddress].ownerOf = fnSig; + emit ContractFunctionSignatureSet(contractAddress, "ownerOf", fnSig); + } + + function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner { + _remappedFnSigs[contractAddress].creatorOf = fnSig; + emit ContractFunctionSignatureSet(contractAddress, "creatorOf", fnSig); + } + + + function getTokenUUID(address contractAddress, uint256 tokenId) external pure virtual override returns (uint256) { + return uint256(keccak256(abi.encodePacked(contractAddress, tokenId))); + } + + function getTokenOwner(address contractAddress, uint256 tokenId) external virtual override returns (address) { + return _getTokenOwner(contractAddress, tokenId); + } + + function getTokenCreator(address contractAddress, uint256 tokenId) external virtual override returns (address) { + return _getTokenCreator(contractAddress, tokenId); + } + + function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) { + IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress); + address tokenOwner = _getTokenOwner(contractAddress, tokenId); + return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender)); + } + + /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself + /// @param contractAddress The Address to the Contract of the Proton-based NFT to check + /// @param tokenId The Token ID of the Proton-based NFT to check + /// @param sender The Address of the Account to check + /// @return True if the account is the creator of the NFT or the Contract itself + function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) { + address tokenCreator = _getTokenCreator(contractAddress, tokenId); + return (sender == tokenCreator || sender == contractAddress); + } + + + + function _getTokenCreator(address contractAddress, uint256 tokenId) internal returns (address) { + bytes4 fnSig = IERC721Chargeable.creatorOf.selector; + if (_remappedFnSigs[contractAddress].creatorOf != bytes4(0)) { + fnSig = _remappedFnSigs[contractAddress].creatorOf; + } + + // solhint-disable-next-line + (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId)); + if (success) { + return abi.decode(returnData, (address)); + } else { + return address(0x0); + } + } + + function _getTokenOwner(address contractAddress, uint256 tokenId) internal returns (address) { + bytes4 fnSig = IERC721Chargeable.ownerOf.selector; + if (_remappedFnSigs[contractAddress].ownerOf != bytes4(0)) { + fnSig = _remappedFnSigs[contractAddress].ownerOf; + } + + // solhint-disable-next-line + (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId)); + if (success) { + return abi.decode(returnData, (address)); + } else { + return address(0x0); + } + } +} diff --git a/contracts/v1/lib/WalletManagerBase.sol b/contracts/v1/lib/WalletManagerBase.sol new file mode 100755 index 0000000..9d567e6 --- /dev/null +++ b/contracts/v1/lib/WalletManagerBase.sol @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: MIT + +// WalletManagerBase.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity >=0.6.0; + +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +import "../interfaces/IWalletManager.sol"; +import "../interfaces/ISmartWallet.sol"; +import "../lib/TokenInfo.sol"; +import "./BlackholePrevention.sol"; + + +/** + * @notice Wallet-Manager Base Contract + * @dev Non-upgradeable Contract + */ +abstract contract WalletManagerBase is Ownable, BlackholePrevention, IWalletManager { + using TokenInfo for address; + + // The Controller Contract Address + address internal _controller; + + // The Executor Contract Address + address internal _executor; + + // Template Contract for creating Token Smart-Wallet Bridges + address internal _walletTemplate; + + // TokenID => Token Smart-Wallet Address + mapping (uint256 => address) internal _wallets; + + // State of Wallet Manager + bool internal _paused; + + + /***********************************| + | Public | + |__________________________________*/ + + function isPaused() external view override returns (bool) { + return _paused; + } + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + /** + * @dev Sets the Paused-state of the Wallet Manager + */ + function setPausedState(bool paused) external onlyOwner { + _paused = paused; + emit PausedStateSet(paused); + } + + /** + * @dev Connects to the Charged Particles Controller + */ + function setController(address controller) external onlyOwner { + _controller = controller; + emit ControllerSet(controller); + } + + /** + * @dev Connects to the ExecForAccount Controller + */ + function setExecutor(address executor) external onlyOwner { + _executor = executor; + emit ExecutorSet(executor); + } + + function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) + external + virtual + override + onlyOwner + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + _withdrawEther(receiver, amount); + return ISmartWallet(wallet).withdrawEther(receiver, amount); + } + + function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) + external + virtual + override + onlyOwner + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + _withdrawERC20(receiver, tokenAddress, amount); + return ISmartWallet(wallet).withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) + external + virtual + override + onlyOwner + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + _withdrawERC721(receiver, nftTokenAddress, nftTokenId); + return ISmartWallet(wallet).withdrawERC721(receiver, nftTokenAddress, nftTokenId); + } + + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) { + return uint256(keccak256(abi.encodePacked(contractAddress, tokenId))); + } + + /** + * @dev Creates Contracts from a Template via Cloning + * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md + */ + function _createClone(address target) internal returns (address result) { + bytes20 targetBytes = bytes20(target); + assembly { + let clone := mload(0x40) + mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) + mstore(add(clone, 0x14), targetBytes) + mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) + result := create(0, clone, 0x37) + } + } + + + /***********************************| + | Modifiers | + |__________________________________*/ + + /// @dev Throws if called by any account other than the Controller contract + modifier onlyController() { + require(_controller == msg.sender, "WMB:E-108"); + _; + } + + /// @dev Throws if called by any account other than the Executor contract + modifier onlyExecutor() { + require(_executor == msg.sender, "WMB:E-108"); + _; + } + + /// @dev Throws if called by any account other than the Controller or Executor contract + modifier onlyControllerOrExecutor() { + require(_executor == msg.sender || _controller == msg.sender, "WMB:E-108"); + _; + } + + // Throws if called by any account other than the Charged Particles Escrow Controller. + modifier whenNotPaused() { + require(_paused != true, "WMB:E-101"); + _; + } + +} diff --git a/contracts/v1/test/Dai.sol b/contracts/v1/test/Dai.sol new file mode 100644 index 0000000..a6b41f5 --- /dev/null +++ b/contracts/v1/test/Dai.sol @@ -0,0 +1,337 @@ +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.6.12; + +import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; + +import "../interfaces/IDai.sol"; + +contract Dai is IDai { + using SafeMathUpgradeable for uint256; + using AddressUpgradeable for address; + + mapping (address => uint256) private _balances; + + mapping (address => mapping (address => uint256)) private _allowances; + + uint256 private _totalSupply; + + string private _name; + string private _symbol; + uint8 private _decimals; + + /** + * @dev Sets the values for {name} and {symbol}, initializes {decimals} with + * a default value of 18. + * + * To select a different value for {decimals}, use {_setupDecimals}. + * + * All three of these values are immutable: they can only be set once during + * construction. + */ + constructor (uint256 chainId_) public { + string memory version = "1"; + + _name = "Dai Stablecoin"; + _symbol = "DAI"; + _decimals = 18; + + DOMAIN_SEPARATOR = keccak256( + abi.encode( + keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), + keccak256(bytes(_name)), + keccak256(bytes(version)), + chainId_, + address(this) + ) + ); + } + + /** + * @dev Returns the name of the token. + */ + function name() public view returns (string memory) { + return _name; + } + + /** + * @dev Returns the symbol of the token, usually a shorter version of the + * name. + */ + function symbol() public view returns (string memory) { + return _symbol; + } + + /** + * @dev Returns the number of decimals used to get its user representation. + * For example, if `decimals` equals `2`, a balance of `505` tokens should + * be displayed to a user as `5,05` (`505 / 10 ** 2`). + * + * Tokens usually opt for a value of 18, imitating the relationship between + * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is + * called. + * + * NOTE: This information is only used for _display_ purposes: it in + * no way affects any of the arithmetic of the contract, including + * {IERC20-balanceOf} and {IERC20-transfer}. + */ + function decimals() public view returns (uint8) { + return _decimals; + } + + /** + * @dev See {IERC20-totalSupply}. + */ + function totalSupply() public view override returns (uint256) { + return _totalSupply; + } + + /** + * @dev See {IERC20-balanceOf}. + */ + function balanceOf(address account) public view override returns (uint256) { + return _balances[account]; + } + + /** + * @dev See {IERC20-transfer}. + * + * Requirements: + * + * - `recipient` cannot be the zero address. + * - the caller must have a balance of at least `amount`. + */ + function transfer(address recipient, uint256 amount) public virtual override returns (bool) { + _transfer(msg.sender, recipient, amount); + return true; + } + + /** + * @dev See {IERC20-allowance}. + */ + function allowance(address owner, address spender) public view virtual override returns (uint256) { + return _allowances[owner][spender]; + } + + /** + * @dev See {IERC20-approve}. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function approve(address spender, uint256 amount) public virtual override returns (bool) { + _approve(msg.sender, spender, amount); + return true; + } + + /** + * @dev See {IERC20-transferFrom}. + * + * Emits an {Approval} event indicating the updated allowance. This is not + * required by the EIP. See the note at the beginning of {ERC20}; + * + * Requirements: + * - `sender` and `recipient` cannot be the zero address. + * - `sender` must have a balance of at least `amount`. + * - the caller must have allowance for ``sender``'s tokens of at least + * `amount`. + */ + function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { + _transfer(sender, recipient, amount); + _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, "ERC20: transfer amount exceeds allowance")); + return true; + } + + /** + * @dev Atomically increases the allowance granted to `spender` by the caller. + * + * This is an alternative to {approve} that can be used as a mitigation for + * problems described in {IERC20-approve}. + * + * Emits an {Approval} event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { + _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue)); + return true; + } + + /** + * @dev Atomically decreases the allowance granted to `spender` by the caller. + * + * This is an alternative to {approve} that can be used as a mitigation for + * problems described in {IERC20-approve}. + * + * Emits an {Approval} event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + * - `spender` must have allowance for the caller of at least + * `subtractedValue`. + */ + function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { + _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); + return true; + } + + /** + * @dev Moves tokens `amount` from `sender` to `recipient`. + * + * This is internal function is equivalent to {transfer}, and can be used to + * e.g. implement automatic token fees, slashing mechanisms, etc. + * + * Emits a {Transfer} event. + * + * Requirements: + * + * - `sender` cannot be the zero address. + * - `recipient` cannot be the zero address. + * - `sender` must have a balance of at least `amount`. + */ + function _transfer(address sender, address recipient, uint256 amount) internal virtual { + require(sender != address(0), "ERC20:E-403"); + require(recipient != address(0), "ERC20:E-403"); + + _beforeTokenTransfer(sender, recipient, amount); + + _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); + _balances[recipient] = _balances[recipient].add(amount); + emit Transfer(sender, recipient, amount); + } + + /** @dev Creates `amount` tokens and assigns them to `account`, increasing + * the total supply. + * + * Emits a {Transfer} event with `from` set to the zero address. + * + * Requirements + * + * - `to` cannot be the zero address. + */ + function _mint(address account, uint256 amount) internal virtual { + require(account != address(0), "ERC20:E-403"); + + _beforeTokenTransfer(address(0), account, amount); + + _totalSupply = _totalSupply.add(amount); + _balances[account] = _balances[account].add(amount); + emit Transfer(address(0), account, amount); + } + + /** + * @dev Destroys `amount` tokens from `account`, reducing the + * total supply. + * + * Emits a {Transfer} event with `to` set to the zero address. + * + * Requirements + * + * - `account` cannot be the zero address. + * - `account` must have at least `amount` tokens. + */ + function _burn(address account, uint256 amount) internal virtual { + require(account != address(0), "ERC20:E-403"); + + _beforeTokenTransfer(account, address(0), amount); + + _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); + _totalSupply = _totalSupply.sub(amount); + emit Transfer(account, address(0), amount); + } + + /** + * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. + * + * This internal function is equivalent to `approve`, and can be used to + * e.g. set automatic allowances for certain subsystems, etc. + * + * Emits an {Approval} event. + * + * Requirements: + * + * - `owner` cannot be the zero address. + * - `spender` cannot be the zero address. + */ + function _approve(address owner, address spender, uint256 amount) internal virtual { + require(owner != address(0), "ERC20:E-403"); + require(spender != address(0), "ERC20:E-403"); + + _allowances[owner][spender] = amount; + emit Approval(owner, spender, amount); + } + + /** + * @dev Sets {decimals} to a value other than the default one of 18. + * + * WARNING: This function should only be called from the constructor. Most + * applications that interact with token contracts will not expect + * {decimals} to ever change, and may work incorrectly if it does. + */ + function _setupDecimals(uint8 decimals_) internal { + _decimals = decimals_; + } + + /** + * @dev Hook that is called before any transfer of tokens. This includes + * minting and burning. + * + * Calling conditions: + * + * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens + * will be to transferred to `to`. + * - when `from` is zero, `amount` tokens will be minted for `to`. + * - when `to` is zero, `amount` of ``from``'s tokens will be burned. + * - `from` and `to` are never both zero. + * + * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. + */ + function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } + + mapping (address => uint) public nonces; + + // --- EIP712 niceties --- + bytes32 public DOMAIN_SEPARATOR; + // bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)"); + bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb; + + // --- Approve by signature --- + function permit( + address holder, address spender, uint256 nonce, uint256 expiry, + bool allowed, uint8 v, bytes32 r, bytes32 s) external override + { + bytes32 digest = keccak256( + abi.encodePacked( + "\x19\x01", + DOMAIN_SEPARATOR, + keccak256( + abi.encode( + PERMIT_TYPEHASH, + holder, + spender, + nonce, + expiry, + allowed + ) + ) + ) + ); + + require(holder != address(0), "Dai/invalid-address-0"); + require(holder == ecrecover(digest, v, r, s), "Dai/invalid-permit"); + require(expiry == 0 || now <= expiry, "Dai/permit-expired"); + require(nonce == nonces[holder]++, "Dai/invalid-nonce"); + uint wad = allowed ? uint(-1) : 0; + _allowances[holder][spender] = wad; + emit Approval(holder, spender, wad); + } + + function mint(address to, uint256 amount) external { + _mint(to, amount); + } +} \ No newline at end of file diff --git a/contracts/v1/test/DoppelgangerWithExec.sol b/contracts/v1/test/DoppelgangerWithExec.sol new file mode 100755 index 0000000..3b93acc --- /dev/null +++ b/contracts/v1/test/DoppelgangerWithExec.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity >=0.6.0 <0.7.0; + +/* solium-disable security/no-inline-assembly */ +contract DoppelgangerWithExec { + struct MockCall { + bool initialized; + bool reverts; + bytes returnValue; + } + + mapping(bytes32 => MockCall) mockConfig; + + fallback() external payable { + MockCall storage mockCall = __internal__getMockCall(); + if (mockCall.reverts == true) { + __internal__mockRevert(); + return; + } + __internal__mockReturn(mockCall.returnValue); + } + + receive() external payable { + } + + function __waffle__mockReverts(bytes memory data) public { + mockConfig[keccak256(data)] = MockCall({ + initialized: true, + reverts: true, + returnValue: "" + }); + } + + function __waffle__mockReturns(bytes memory data, bytes memory value) public { + mockConfig[keccak256(data)] = MockCall({ + initialized: true, + reverts: false, + returnValue: value + }); + } + + function __waffle__call(address target, bytes calldata data) external returns (bytes memory) { + (bool succeeded, bytes memory returnValue) = target.call(data); + require(succeeded, string(returnValue)); + return returnValue; + } + + function __waffle__staticcall(address target, bytes calldata data) external view returns (bytes memory) { + (bool succeeded, bytes memory returnValue) = target.staticcall(data); + require(succeeded, string(returnValue)); + return returnValue; + } + + function __internal__getMockCall() view private returns (MockCall storage mockCall) { + mockCall = mockConfig[keccak256(msg.data)]; + if (mockCall.initialized == true) { + // Mock method with specified arguments + return mockCall; + } + mockCall = mockConfig[keccak256(abi.encodePacked(msg.sig))]; + if (mockCall.initialized == true) { + // Mock method with any arguments + return mockCall; + } + revert("Mock on the method is not initialized"); + } + + function __internal__mockReturn(bytes memory ret) pure private { + assembly { + return (add(ret, 0x20), mload(ret)) + } + } + + function __internal__mockRevert() pure private { + revert("Mock revert"); + } +} \ No newline at end of file diff --git a/contracts/v1/test/ERC20Mintable.sol b/contracts/v1/test/ERC20Mintable.sol new file mode 100644 index 0000000..db46924 --- /dev/null +++ b/contracts/v1/test/ERC20Mintable.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT + +pragma solidity >=0.6.0 <0.7.0; + +import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; + +/** + * @dev Extension of {ERC20} that adds a set of accounts with the {MinterRole}, + * which have permission to mint (create) new tokens as they see fit. + * + * At construction, the deployer of the contract is the only minter. + */ +contract ERC20Mintable is ERC20Upgradeable { + + constructor(string memory _name, string memory _symbol) public { + __ERC20_init(_name, _symbol); + } + + /** + * @dev See {ERC20-_mint}. + * + * Requirements: + * + * - the caller must have the {MinterRole}. + */ + function mint(address account, uint256 amount) public returns (bool) { + _mint(account, amount); + return true; + } + + function burn(address account, uint256 amount) public returns (bool) { + _burn(account, amount); + return true; + } +} \ No newline at end of file diff --git a/contracts/v1/test/ERC721Mintable.sol b/contracts/v1/test/ERC721Mintable.sol new file mode 100644 index 0000000..e1b8138 --- /dev/null +++ b/contracts/v1/test/ERC721Mintable.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MIT + +pragma solidity >=0.6.0 <0.7.0; + +import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; + +/** + * @dev Extension of {ERC721} for Minting/Burning + */ +contract ERC721Mintable is ERC721Upgradeable { + + constructor () public { + __ERC721_init("ERC 721", "NFT"); + } + + /** + * @dev See {ERC721-_mint}. + */ + function mint(address to, uint256 tokenId) public { + _mint(to, tokenId); + } + + /** + * @dev See {ERC721-_burn}. + */ + function burn(uint256 tokenId) public { + _burn(tokenId); + } +} diff --git a/contracts/v1/test/EthSender.sol b/contracts/v1/test/EthSender.sol new file mode 100644 index 0000000..749e61a --- /dev/null +++ b/contracts/v1/test/EthSender.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT + +pragma solidity >=0.6.0 <0.7.0; + +contract EthSender { + receive () external payable {} + + function sendEther(address target) public { + selfdestruct(payable(target)); + } +} diff --git a/contracts/v1/tokens/ExternalERC721.sol b/contracts/v1/tokens/ExternalERC721.sol new file mode 100644 index 0000000..601e8ae --- /dev/null +++ b/contracts/v1/tokens/ExternalERC721.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT + +// ExternalERC721.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/utils/Counters.sol"; +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; + +contract ExternalERC721 is ERC721 { + using Counters for Counters.Counter; + + Counters.Counter internal _tokenCount; + + constructor() public ERC721("Charged Particles - ExternalERC721", "ExNFT") {} + + function mintNft(address receiver, string memory tokenUri) external returns (uint256 newTokenId) { + return _mintNft(receiver, tokenUri); + } + + function _mintNft(address receiver, string memory tokenUri) internal returns (uint256 newTokenId) { + _tokenCount.increment(); + newTokenId = _tokenCount.current(); + + _safeMint(receiver, newTokenId, ""); + + _setTokenURI(newTokenId, tokenUri); + } +} diff --git a/contracts/v1/tokens/FungibleERC1155.sol b/contracts/v1/tokens/FungibleERC1155.sol new file mode 100644 index 0000000..5eaafd6 --- /dev/null +++ b/contracts/v1/tokens/FungibleERC1155.sol @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: MIT + +// FungibleERC1155.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/utils/Counters.sol"; +import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; + +contract FungibleERC1155 is ERC1155 { + using Counters for Counters.Counter; + + Counters.Counter internal _tokenCount; + + constructor() public ERC1155("https://staging.app.charged.fi/erc1155/metadata.json") {} + + function mintNft(address receiver, uint256 amount) external returns (uint256 newTokenId) { + return _mintNft(receiver, amount); + } + + function _mintNft(address receiver, uint256 amount) internal returns (uint256 newTokenId) { + _tokenCount.increment(); + newTokenId = _tokenCount.current(); + _mint(receiver, newTokenId, amount, ""); + } +} diff --git a/contracts/v1/tokens/Ionx.sol b/contracts/v1/tokens/Ionx.sol new file mode 100644 index 0000000..5081e90 --- /dev/null +++ b/contracts/v1/tokens/Ionx.sol @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: MIT + +// Ionx.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "erc20permit/contracts/ERC20Permit.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "../lib/BlackholePrevention.sol"; + + +contract Ionx is ERC20Permit, Ownable, BlackholePrevention { + using SafeMath for uint256; + + /// @notice An event thats emitted when the minter address is changed + event MinterChanged(address minter, address newMinter); + + /// @notice Total number of tokens in circulation + uint256 constant public INITIAL_SUPPLY = 1e8 ether; + + /// @notice Minimum time between mints + uint32 public constant INFLATION_EPOCH = 1 days * 365; + + /// @notice Cap on the percentage of totalSupply that can be minted at each mint + uint8 public constant INFLATION_CAP = 2; + + /// @notice Address which may mint new tokens + address public minter; + + /// @notice The timestamp after which minting may occur + uint256 public mintingAllowedAfter; + + + constructor() public ERC20Permit("Charged Particles - IONX", "IONX") {} + + + /** + * @notice Change the minter address + * @param newMinter The address of the new minter + */ + function setMinter(address newMinter) external onlyOwner { + emit MinterChanged(minter, newMinter); + minter = newMinter; + } + + /** + * @notice Mint new tokens + * @param receiver The address of the destination account + * @param amount The number of tokens to be minted + */ + function mint(address receiver, uint256 amount) external onlyMinter { + require(block.timestamp >= mintingAllowedAfter, "Ionx:E-114"); + require(receiver != address(0), "Ionx:E-403"); + + uint256 amountToMint = amount; + uint256 _totalSupply = totalSupply(); + + // From Inflationary Supply + if (_totalSupply >= INITIAL_SUPPLY) { + mintingAllowedAfter = mintingAllowedAfter.add(INFLATION_EPOCH); + amountToMint = _totalSupply.mul(INFLATION_CAP).div(100); + } + + // From Initial Supply + else { + if (_totalSupply.add(amountToMint) > INITIAL_SUPPLY) { + amountToMint = INITIAL_SUPPLY.sub(_totalSupply); + } + if (_totalSupply.add(amountToMint) == INITIAL_SUPPLY) { + mintingAllowedAfter = block.timestamp.add(INFLATION_EPOCH); + } + } + + // transfer the amount to the recipient + _mint(receiver, amountToMint); + } + + // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it + function withdrawEther(address payable receiver, uint256 amount) external onlyOwner { + _withdrawEther(receiver, amount); + } + + // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner { + _withdrawERC20(receiver, tokenAddress, amount); + } + + // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + modifier onlyMinter() { + require(msg.sender == minter, "Ionx:E-113"); + _; + } +} diff --git a/contracts/v1/tokens/Lepton.sol b/contracts/v1/tokens/Lepton.sol new file mode 100644 index 0000000..ac9b590 --- /dev/null +++ b/contracts/v1/tokens/Lepton.sol @@ -0,0 +1,250 @@ +// SPDX-License-Identifier: MIT + +// Lepton.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "../lib/ERC721.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/utils/Counters.sol"; +import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; + +import "../interfaces/ILepton.sol"; +import "../lib/BlackholePrevention.sol"; + + +contract Lepton is ILepton, ERC721, Ownable, ReentrancyGuard, BlackholePrevention { + using SafeMath for uint256; + using Address for address payable; + using Counters for Counters.Counter; + + Counters.Counter internal _tokenIds; + Classification[] internal _leptonTypes; + mapping (uint256 => Classification) internal _leptonData; + + uint256 internal _typeIndex; + uint256 internal _maxSupply; + uint256 internal _maxMintPerTx; + bool internal _paused; + + + /***********************************| + | Initialization | + |__________________________________*/ + + constructor() public ERC721("Charged Particles - Lepton", "LEPTON") { + _paused = true; + } + + + /***********************************| + | Public | + |__________________________________*/ + + function mintLepton() external payable virtual override nonReentrant whenNotPaused returns (uint256 newTokenId) { + newTokenId = _mintLepton(msg.sender); + } + + function batchMintLepton(uint256 count) external payable virtual override nonReentrant whenNotPaused { + _batchMintLepton(msg.sender, count); + } + + function getNextType() external view virtual override returns (uint256) { + if (_typeIndex >= _leptonTypes.length) { return 0; } + return _typeIndex; + } + + function getNextPrice() external view virtual override returns (uint256) { + if (_typeIndex >= _leptonTypes.length) { return 0; } + return _leptonTypes[_typeIndex].price; + } + + function getMultiplier(uint256 tokenId) external view virtual override returns (uint256) { + return _leptonData[tokenId].multiplier; + } + + function getBonus(uint256 tokenId) external view virtual override returns (uint256) { + return _leptonData[tokenId].bonus; + } + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + function addLeptonType( + string calldata tokenUri, + uint256 price, + uint32 supply, + uint32 multiplier, + uint32 bonus + ) + external + virtual + onlyOwner + { + _maxSupply = _maxSupply.add(uint256(supply)); + + Classification memory lepton = Classification({ + tokenUri: tokenUri, + price: price, + supply: supply, + multiplier: multiplier, + bonus: bonus, + _upperBounds: uint128(_maxSupply) + }); + _leptonTypes.push(lepton); + + emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply); + } + + function updateLeptonType( + uint256 leptonIndex, + string calldata tokenUri, + uint256 price, + uint32 supply, + uint32 multiplier, + uint32 bonus + ) + external + virtual + onlyOwner + { + _leptonTypes[leptonIndex].tokenUri = tokenUri; + _leptonTypes[leptonIndex].price = price; + _leptonTypes[leptonIndex].supply = supply; + _leptonTypes[leptonIndex].multiplier = multiplier; + _leptonTypes[leptonIndex].bonus = bonus; + + emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply); + } + + function setMaxMintPerTx(uint256 maxAmount) external virtual onlyOwner { + _maxMintPerTx = maxAmount; + emit MaxMintPerTxSet(maxAmount); + } + + function setPausedState(bool state) external virtual onlyOwner { + _paused = state; + emit PausedStateSet(state); + } + + + /***********************************| + | Only Admin/DAO | + | (blackhole prevention) | + |__________________________________*/ + + function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner { + _withdrawEther(receiver, amount); + } + + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner { + _withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _mintLepton(address receiver) internal virtual returns (uint256 newTokenId) { + require(_typeIndex < _leptonTypes.length, "LPT:E-408"); + + Classification memory lepton = _leptonTypes[_typeIndex]; + require(msg.value >= lepton.price, "LPT:E-414"); + + _tokenIds.increment(); + newTokenId = _tokenIds.current(); + + _leptonData[newTokenId] = lepton; + _safeMint(receiver, newTokenId, ""); + _setTokenURI(newTokenId, lepton.tokenUri); + + // Distribute Next Type + if (newTokenId == lepton._upperBounds) { + _typeIndex = _typeIndex.add(1); + } + + emit LeptonMinted(receiver, newTokenId, lepton.price, lepton.multiplier); + + _refundOverpayment(lepton.price); + } + + + function _batchMintLepton(address receiver, uint256 count) internal virtual { + require(_typeIndex < _leptonTypes.length, "LPT:E-408"); + require(_maxMintPerTx == 0 || count <= _maxMintPerTx, "LPT:E-429"); + + Classification memory lepton = _leptonTypes[_typeIndex]; + + uint256 startTokenId = _tokenIds.current(); + uint256 endTokenId = startTokenId.add(count); + if (endTokenId > lepton._upperBounds) { + count = count.sub(endTokenId.sub(lepton._upperBounds)); + } + + uint256 salePrice = lepton.price.mul(count); + require(msg.value >= salePrice, "LPT:E-414"); + + _safeMintBatch(receiver, startTokenId.add(1), count, ""); + + for (uint i = 0; i < count; i++) { + _tokenIds.increment(); + startTokenId = _tokenIds.current(); + + _leptonData[startTokenId] = lepton; + _setTokenURI(startTokenId, lepton.tokenUri); + } + + // Distribute Next Type + if (startTokenId >= lepton._upperBounds) { + _typeIndex = _typeIndex.add(1); + } + + emit LeptonBatchMinted(receiver, startTokenId, count, lepton.price, lepton.multiplier); + + _refundOverpayment(salePrice); + } + + function _refundOverpayment(uint256 threshold) internal virtual { + uint256 overage = msg.value.sub(threshold); + if (overage > 0) { + payable(_msgSender()).sendValue(overage); + } + } + + + /***********************************| + | Modifiers | + |__________________________________*/ + + modifier whenNotPaused() { + require(!_paused, "LPT:E-101"); + _; + } +} \ No newline at end of file diff --git a/contracts/v1/tokens/Lepton2.sol b/contracts/v1/tokens/Lepton2.sol new file mode 100644 index 0000000..c72c99a --- /dev/null +++ b/contracts/v1/tokens/Lepton2.sol @@ -0,0 +1,295 @@ +// SPDX-License-Identifier: MIT + +// Lepton2.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "../lib/ERC721Basic.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol"; + +import "../interfaces/ILepton.sol"; +import "../lib/BlackholePrevention.sol"; + +contract Lepton2 is ILepton, ERC721Basic, Ownable, ReentrancyGuard, BlackholePrevention { + using SafeMath for uint256; + using Address for address payable; + + Classification[] internal _leptonTypes; + + uint256 internal _typeIndex; + uint256 internal _maxSupply; + uint256 internal _maxMintPerTx; + uint256 internal _migratedCount; + + bool internal _paused; + bool internal _migrationComplete; + + + /***********************************| + | Initialization | + |__________________________________*/ + + constructor() public ERC721Basic("Charged Particles - Lepton2", "LEPTON2") { + _paused = true; + _migrationComplete = false; + _migratedCount = 0; + } + + + /***********************************| + | Public | + |__________________________________*/ + + function mintLepton() external payable override nonReentrant whenNotPaused returns (uint256 newTokenId) { + newTokenId = _mintLepton(msg.sender); + } + + function batchMintLepton(uint256 count) external payable override nonReentrant whenNotPaused { + _batchMintLepton(msg.sender, count); + } + + function totalSupply() public view returns (uint256) { + return _tokenCount; + } + + function maxSupply() external view returns (uint256) { + return _maxSupply; + } + + function getNextType() external view override returns (uint256) { + if (_typeIndex >= _leptonTypes.length) { return 0; } + return _typeIndex; + } + + function getNextPrice() external view override returns (uint256) { + if (_typeIndex >= _leptonTypes.length) { return 0; } + return _leptonTypes[_typeIndex].price; + } + + function getMultiplier(uint256 tokenId) external view override returns (uint256) { + require(_exists(tokenId), "LPT:E-405"); + return _getLepton(tokenId).multiplier; + } + + function getBonus(uint256 tokenId) external view override returns (uint256) { + require(_exists(tokenId), "LPT:E-405"); + return _getLepton(tokenId).bonus; + } + + function tokenURI(uint256 tokenId) public view override returns (string memory) { + require(_exists(tokenId), "LPT:E-405"); + return _getLepton(tokenId).tokenUri; + } + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + function addLeptonType( + string calldata tokenUri, + uint256 price, + uint32 supply, + uint32 multiplier, + uint32 bonus + ) + external + onlyOwner + { + _maxSupply = _maxSupply.add(uint256(supply)); + + Classification memory lepton = Classification({ + tokenUri: tokenUri, + price: price, + supply: supply, + multiplier: multiplier, + bonus: bonus, + _upperBounds: uint128(_maxSupply) + }); + _leptonTypes.push(lepton); + + emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply); + } + + function updateLeptonType( + uint256 leptonIndex, + string calldata tokenUri, + uint256 price, + uint32 supply, + uint32 multiplier, + uint32 bonus + ) + external + onlyOwner + { + _leptonTypes[leptonIndex].tokenUri = tokenUri; + _leptonTypes[leptonIndex].price = price; + _leptonTypes[leptonIndex].supply = supply; + _leptonTypes[leptonIndex].multiplier = multiplier; + _leptonTypes[leptonIndex].bonus = bonus; + + emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply); + } + + function setMaxMintPerTx(uint256 maxAmount) external onlyOwner { + _maxMintPerTx = maxAmount; + emit MaxMintPerTxSet(maxAmount); + } + + function setPausedState(bool state) external onlyOwner { + _paused = state; + emit PausedStateSet(state); + } + + + /***********************************| + | Only Admin/DAO | + | (blackhole prevention) | + |__________________________________*/ + + function withdrawEther(address payable receiver, uint256 amount) external onlyOwner { + _withdrawEther(receiver, amount); + } + + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner { + _withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + function migrateAccounts(address oldLeptonContract, uint256 count) external onlyOwner whenNotMigrated { + uint256 oldSupply = IERC721Enumerable(oldLeptonContract).totalSupply(); + require(oldSupply == 0 || oldSupply > _migratedCount, "LPT:E-004"); + + if (oldSupply > 0) { + uint256 endTokenId = _migratedCount.add(count); + if (endTokenId > oldSupply) { + count = count.sub(endTokenId.sub(oldSupply)); + } + + for (uint256 i = 1; i <= count; i++) { + uint256 tokenId = _migratedCount.add(i); + address tokenOwner = IERC721(oldLeptonContract).ownerOf(tokenId); + _mint(tokenOwner); + } + _migratedCount = _migratedCount.add(count); + } + + if (oldSupply == _migratedCount) { + _finalizeMigration(); + } + } + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _getLepton(uint256 tokenId) internal view returns (Classification memory) { + uint256 types = _leptonTypes.length; + for (uint256 i = 0; i < types; i++) { + Classification memory lepton = _leptonTypes[i]; + if (tokenId <= lepton._upperBounds) { + return lepton; + } + } + } + + function _mintLepton(address receiver) internal returns (uint256 newTokenId) { + require(_typeIndex < _leptonTypes.length, "LPT:E-408"); + + Classification memory lepton = _leptonTypes[_typeIndex]; + require(msg.value >= lepton.price, "LPT:E-414"); + + newTokenId = _safeMint(receiver, ""); + + // Determine Next Type + if (newTokenId == lepton._upperBounds) { + _typeIndex = _typeIndex.add(1); + } + + _refundOverpayment(lepton.price); + } + + function _batchMintLepton(address receiver, uint256 count) internal { + require(_typeIndex < _leptonTypes.length, "LPT:E-408"); + require(_maxMintPerTx == 0 || count <= _maxMintPerTx, "LPT:E-429"); + + Classification memory lepton = _leptonTypes[_typeIndex]; + + uint256 endTokenId = _tokenCount.add(count); + if (endTokenId > lepton._upperBounds) { + count = count.sub(endTokenId.sub(lepton._upperBounds)); + } + + uint256 salePrice = lepton.price.mul(count); + require(msg.value >= salePrice, "LPT:E-414"); + + _safeMintBatch(receiver, count, ""); + + // Determine Next Type + if (endTokenId >= lepton._upperBounds) { + _typeIndex = _typeIndex.add(1); + } + + _refundOverpayment(salePrice); + } + + function _refundOverpayment(uint256 threshold) internal { + uint256 overage = msg.value.sub(threshold); + if (overage > 0) { + payable(_msgSender()).sendValue(overage); + } + } + + function _finalizeMigration() internal { + // Determine Next Type + _typeIndex = 0; + for (uint256 i = 0; i < _leptonTypes.length; i++) { + Classification memory lepton = _leptonTypes[i]; + if (_migratedCount >= lepton._upperBounds) { + _typeIndex = i + 1; + } + } + _migrationComplete = true; + } + + + /***********************************| + | Modifiers | + |__________________________________*/ + + modifier whenNotMigrated() { + require(!_migrationComplete, "LPT:E-004"); + _; + } + + modifier whenNotPaused() { + require(!_paused, "LPT:E-101"); + _; + } +} \ No newline at end of file diff --git a/contracts/v1/tokens/NonFungibleERC1155.sol b/contracts/v1/tokens/NonFungibleERC1155.sol new file mode 100644 index 0000000..ae8f828 --- /dev/null +++ b/contracts/v1/tokens/NonFungibleERC1155.sol @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: MIT + +// NonFungibleERC1155.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/utils/Counters.sol"; +import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; + +contract NonFungibleERC1155 is ERC1155 { + using Counters for Counters.Counter; + + Counters.Counter internal _tokenCount; + mapping (uint256 => address) internal _tokenCreator; + mapping (uint256 => address) internal _tokenOwner; + + constructor() public ERC1155("https://staging.app.charged.fi/erc1155/metadata.json") {} + + function creatorOf(uint256 tokenId) external view returns (address) { + return _tokenCreator[tokenId]; + } + + function ownerOf(uint256 tokenId) external view returns (address) { + return _tokenOwner[tokenId]; + } + + function mintNft(address receiver) external returns (uint256 newTokenId) { + return _mintNft(msg.sender, receiver); + } + + function _mintNft(address creator, address receiver) internal returns (uint256 newTokenId) { + _tokenCount.increment(); + newTokenId = _tokenCount.current(); + + _mint(receiver, newTokenId, 1, ""); + _tokenCreator[newTokenId] = creator; + _tokenOwner[newTokenId] = receiver; + } +} diff --git a/contracts/v1/tokens/Proton.sol b/contracts/v1/tokens/Proton.sol new file mode 100644 index 0000000..9c3680a --- /dev/null +++ b/contracts/v1/tokens/Proton.sol @@ -0,0 +1,626 @@ +// SPDX-License-Identifier: MIT + +// Proton.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; +pragma experimental ABIEncoderV2; + +import "../lib/ERC721.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/utils/Counters.sol"; +import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; + +import "../interfaces/IProton.sol"; +import "../interfaces/IUniverse.sol"; +import "../interfaces/IChargedState.sol"; +import "../interfaces/IChargedSettings.sol"; +import "../interfaces/IChargedParticles.sol"; + +import "../lib/BlackholePrevention.sol"; +import "../lib/RelayRecipient.sol"; + + +contract Proton is IProton, ERC721, Ownable, RelayRecipient, ReentrancyGuard, BlackholePrevention { + using SafeMath for uint256; + using Address for address payable; + using Counters for Counters.Counter; + + uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%) + uint256 constant internal MAX_ROYALTIES = 8e3; // 8000 (80%) + + IUniverse internal _universe; + IChargedState internal _chargedState; + IChargedSettings internal _chargedSettings; + IChargedParticles internal _chargedParticles; + + Counters.Counter internal _tokenIds; + + mapping (uint256 => address) internal _tokenCreator; + mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct; + mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect; + mapping (address => uint256) internal _tokenCreatorClaimableRoyalties; + + mapping (uint256 => uint256) internal _tokenSalePrice; + mapping (uint256 => uint256) internal _tokenLastSellPrice; + + bool internal _paused; + + + /***********************************| + | Initialization | + |__________________________________*/ + + constructor() public ERC721("Charged Particles - Proton", "PROTON") {} + + + /***********************************| + | Public | + |__________________________________*/ + + function creatorOf(uint256 tokenId) external view virtual override returns (address) { + return _tokenCreator[tokenId]; + } + + function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) { + return _tokenSalePrice[tokenId]; + } + + function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) { + return _tokenLastSellPrice[tokenId]; + } + + function getCreatorRoyalties(address account) external view virtual override returns (uint256) { + return _tokenCreatorClaimableRoyalties[account]; + } + + function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) { + return _tokenCreatorRoyaltiesPct[tokenId]; + } + + function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) { + return _creatorRoyaltiesReceiver(tokenId); + } + + function claimCreatorRoyalties() + external + virtual + override + nonReentrant + whenNotPaused + returns (uint256) + { + return _claimCreatorRoyalties(_msgSender()); + } + + function createChargedParticle( + address creator, + address receiver, + address referrer, + string memory tokenMetaUri, + string memory walletManagerId, + address assetToken, + uint256 assetAmount, + uint256 annuityPercent + ) + external + virtual + override + nonReentrant + whenNotPaused + returns (uint256 newTokenId) + { + newTokenId = _createChargedParticle( + creator, + receiver, + referrer, + tokenMetaUri, + walletManagerId, + assetToken, + assetAmount, + annuityPercent + ); + } + + function createBasicProton( + address creator, + address receiver, + string memory tokenMetaUri + ) + external + virtual + override + whenNotPaused + returns (uint256 newTokenId) + { + newTokenId = _createProton( + creator, + receiver, + tokenMetaUri, + 0, // annuityPercent, + 0, // royaltiesPercent + 0 // salePrice + ); + } + + function createProton( + address creator, + address receiver, + string memory tokenMetaUri, + uint256 annuityPercent + ) + external + virtual + override + whenNotPaused + returns (uint256 newTokenId) + { + newTokenId = _createProton( + creator, + receiver, + tokenMetaUri, + annuityPercent, + 0, // royaltiesPercent + 0 // salePrice + ); + } + + function createProtonForSale( + address creator, + address receiver, + string memory tokenMetaUri, + uint256 annuityPercent, + uint256 royaltiesPercent, + uint256 salePrice + ) + external + virtual + override + whenNotPaused + returns (uint256 newTokenId) + { + newTokenId = _createProton( + creator, + receiver, + tokenMetaUri, + annuityPercent, + royaltiesPercent, + salePrice + ); + } + + function batchProtonsForSale( + address creator, + uint256 annuityPercent, + uint256 royaltiesPercent, + string[] calldata tokenMetaUris, + uint256[] calldata salePrices + ) + external + virtual + override + whenNotPaused + { + _batchProtonsForSale( + creator, + annuityPercent, + royaltiesPercent, + tokenMetaUris, + salePrices + ); + } + + function buyProton(uint256 tokenId) + external + payable + virtual + override + nonReentrant + whenNotPaused + returns (bool) + { + return _buyProton(tokenId); + } + + /***********************************| + | Only Token Creator/Owner | + |__________________________________*/ + + function setSalePrice(uint256 tokenId, uint256 salePrice) + external + virtual + override + whenNotPaused + onlyTokenOwnerOrApproved(tokenId) + { + _setSalePrice(tokenId, salePrice); + } + + function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) + external + virtual + override + whenNotPaused + onlyTokenCreator(tokenId) + onlyTokenOwnerOrApproved(tokenId) + { + _setRoyaltiesPct(tokenId, royaltiesPct); + } + + function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) + external + virtual + override + whenNotPaused + onlyTokenCreator(tokenId) + { + _tokenCreatorRoyaltiesRedirect[tokenId] = receiver; + } + + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + function setPausedState(bool state) external virtual onlyOwner { + _paused = state; + emit PausedStateSet(state); + } + + /** + * @dev Setup the ChargedParticles Interface + */ + function setUniverse(address universe) external virtual onlyOwner { + _universe = IUniverse(universe); + emit UniverseSet(universe); + } + + /** + * @dev Setup the ChargedParticles Interface + */ + function setChargedParticles(address chargedParticles) external virtual onlyOwner { + _chargedParticles = IChargedParticles(chargedParticles); + emit ChargedParticlesSet(chargedParticles); + } + + /// @dev Setup the Charged-State Controller + function setChargedState(address stateController) external virtual onlyOwner { + _chargedState = IChargedState(stateController); + emit ChargedStateSet(stateController); + } + + /// @dev Setup the Charged-Settings Controller + function setChargedSettings(address settings) external virtual onlyOwner { + _chargedSettings = IChargedSettings(settings); + emit ChargedSettingsSet(settings); + } + + function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner { + trustedForwarder = _trustedForwarder; + } + + /***********************************| + | Only Admin/DAO | + | (blackhole prevention) | + |__________________________________*/ + + function withdrawEther(address payable receiver, uint256 amount) external onlyOwner { + _withdrawEther(receiver, amount); + } + + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner { + _withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual { + // Temp-Lock/Unlock NFT + // prevents front-running the sale and draining the value of the NFT just before sale + _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0)); + + _tokenSalePrice[tokenId] = salePrice; + emit SalePriceSet(tokenId, salePrice); + } + + function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual { + require(royaltiesPct <= MAX_ROYALTIES, "PRT:E-421"); + _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct; + emit CreatorRoyaltiesSet(tokenId, royaltiesPct); + } + + function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) { + address receiver = _tokenCreatorRoyaltiesRedirect[tokenId]; + if (receiver == address(0x0)) { + receiver = _tokenCreator[tokenId]; + } + return receiver; + } + + function _createChargedParticle( + address creator, + address receiver, + address referrer, + string memory tokenMetaUri, + string memory walletManagerId, + address assetToken, + uint256 assetAmount, + uint256 annuityPercent + ) + internal + virtual + returns (uint256 newTokenId) + { + require(address(_chargedParticles) != address(0x0), "PRT:E-107"); + + newTokenId = _createProton(creator, receiver, tokenMetaUri, annuityPercent, 0, 0); + + _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer); + } + + function _createProton( + address creator, + address receiver, + string memory tokenMetaUri, + uint256 annuityPercent, + uint256 royaltiesPercent, + uint256 salePrice + ) + internal + virtual + returns (uint256 newTokenId) + { + _tokenIds.increment(); + + newTokenId = _tokenIds.current(); + _safeMint(receiver, newTokenId, ""); + _tokenCreator[newTokenId] = creator; + + _setTokenURI(newTokenId, tokenMetaUri); + + if (royaltiesPercent > 0) { + _setRoyaltiesPct(newTokenId, royaltiesPercent); + } + + if (salePrice > 0) { + _setSalePrice(newTokenId, salePrice); + } + + if (annuityPercent > 0) { + _chargedSettings.setCreatorAnnuities( + address(this), + newTokenId, + creator, + annuityPercent + ); + } + } + + function _batchProtonsForSale( + address creator, + uint256 annuityPercent, + uint256 royaltiesPercent, + string[] calldata tokenMetaUris, + uint256[] calldata salePrices + ) + internal + virtual + { + require(tokenMetaUris.length == salePrices.length, "PRT:E-202"); + address self = address(this); + + uint256 count = tokenMetaUris.length; + for (uint256 i = 0; i < count; i++) { + _tokenIds.increment(); + uint256 newTokenId = _tokenIds.current(); + + _safeMint(creator, newTokenId, ""); + _tokenCreator[newTokenId] = creator; + + _setTokenURI(newTokenId, tokenMetaUris[i]); + + if (royaltiesPercent > 0) { + _setRoyaltiesPct(newTokenId, royaltiesPercent); + } + + uint256 salePrice = salePrices[i]; + if (salePrice > 0) { + _setSalePrice(newTokenId, salePrice); + } + + if (annuityPercent > 0) { + _chargedSettings.setCreatorAnnuities( + self, + newTokenId, + creator, + annuityPercent + ); + } + } + } + + function _chargeParticle( + uint256 tokenId, + string memory walletManagerId, + address assetToken, + uint256 assetAmount, + address referrer + ) + internal + virtual + { + _collectAssetToken(_msgSender(), assetToken, assetAmount); + + IERC20(assetToken).approve(address(_chargedParticles), assetAmount); + + _chargedParticles.energizeParticle( + address(this), + tokenId, + walletManagerId, + assetToken, + assetAmount, + referrer + ); + } + + function _buyProton(uint256 tokenId) + internal + virtual + returns (bool) + { + uint256 salePrice = _tokenSalePrice[tokenId]; + require(salePrice > 0, "PRT:E-416"); + require(msg.value >= salePrice, "PRT:E-414"); + + uint256 ownerAmount = salePrice; + uint256 creatorAmount; + address oldOwner = ownerOf(tokenId); + address newOwner = _msgSender(); + + // Creator Royalties + address royaltiesReceiver = _creatorRoyaltiesReceiver(tokenId); + uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[tokenId]; + uint256 lastSellPrice = _tokenLastSellPrice[tokenId]; + if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) { + creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE); + ownerAmount = ownerAmount.sub(creatorAmount); + } + _tokenLastSellPrice[tokenId] = salePrice; + + // Signal to Universe Controller + if (address(_universe) != address(0)) { + _universe.onProtonSale(address(this), tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount); + } + + // Reserve Royalties for Creator + if (creatorAmount > 0) { + _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount); + } + + // Transfer Token + _transfer(oldOwner, newOwner, tokenId); + + // Transfer Payment + payable(oldOwner).sendValue(ownerAmount); + + emit ProtonSold(tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount); + + _refundOverpayment(salePrice); + return true; + } + + /** + * @dev Pays out the Creator Royalties of the calling account + * @param receiver The receiver of the claimable royalties + * @return The amount of Creator Royalties claimed + */ + function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) { + uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver]; + require(claimableAmount > 0, "PRT:E-411"); + + delete _tokenCreatorClaimableRoyalties[receiver]; + payable(receiver).sendValue(claimableAmount); + + emit RoyaltiesClaimed(receiver, claimableAmount); + } + + /** + * @dev Collects the Required Asset Token from the users wallet + * @param from The owner address to collect the Assets from + * @param assetAmount The Amount of Asset Tokens to Collect + */ + function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual { + uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from); + require(assetAmount <= _userAssetBalance, "PRT:E-411"); + // Be sure to Approve this Contract to transfer your Asset Token + require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), "PRT:E-401"); + } + + function _refundOverpayment(uint256 threshold) internal virtual { + uint256 overage = msg.value.sub(threshold); + if (overage > 0) { + payable(_msgSender()).sendValue(overage); + } + } + + function _transfer(address from, address to, uint256 tokenId) internal virtual override { + _tokenSalePrice[tokenId] = 0; + _chargedState.setTemporaryLock(address(this), tokenId, false); + super._transfer(from, to, tokenId); + } + + + /***********************************| + | GSN/MetaTx Relay | + |__________________________________*/ + + /// @dev See {BaseRelayRecipient-_msgSender}. + function _msgSender() + internal + view + virtual + override(BaseRelayRecipient, Context) + returns (address payable) + { + return BaseRelayRecipient._msgSender(); + } + + /// @dev See {BaseRelayRecipient-_msgData}. + function _msgData() + internal + view + virtual + override(BaseRelayRecipient, Context) + returns (bytes memory) + { + return BaseRelayRecipient._msgData(); + } + + + /***********************************| + | Modifiers | + |__________________________________*/ + + modifier whenNotPaused() { + require(!_paused, "PRT:E-101"); + _; + } + + modifier onlyTokenOwnerOrApproved(uint256 tokenId) { + require(_isApprovedOrOwner(_msgSender(), tokenId), "PRT:E-105"); + _; + } + + modifier onlyTokenCreator(uint256 tokenId) { + require(_tokenCreator[tokenId] == _msgSender(), "PRT:E-104"); + _; + } +} \ No newline at end of file diff --git a/contracts/v1/tokens/ProtonB.sol b/contracts/v1/tokens/ProtonB.sol new file mode 100644 index 0000000..640b707 --- /dev/null +++ b/contracts/v1/tokens/ProtonB.sol @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: MIT + +// ProtonB.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; +pragma experimental ABIEncoderV2; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; + +import "../interfaces/IUniverse.sol"; +import "../interfaces/IChargedState.sol"; +import "../interfaces/IChargedSettings.sol"; +import "../interfaces/IChargedParticles.sol"; +import "../interfaces/IProtonB.sol"; + +import "../lib/BaseProton.sol"; +import "../lib/TokenInfo.sol"; +import "../lib/BlackholePrevention.sol"; +import "../lib/RelayRecipient.sol"; + + +contract ProtonB is BaseProton, IProtonB { + using SafeMath for uint256; + using TokenInfo for address payable; + using Counters for Counters.Counter; + + IUniverse internal _universe; + IChargedState internal _chargedState; + IChargedSettings internal _chargedSettings; + IChargedParticles internal _chargedParticles; + + + /***********************************| + | Initialization | + |__________________________________*/ + + constructor() public BaseProton("Charged Particles - ProtonB", "PROTON.B") {} + + + /***********************************| + | Public | + |__________________________________*/ + + function createProtonForSale( + address creator, + address receiver, + string memory tokenMetaUri, + uint256 annuityPercent, + uint256 royaltiesPercent, + uint256 salePrice + ) + external + virtual + override + returns (uint256 newTokenId) + { + newTokenId = _createProton( + creator, + receiver, + tokenMetaUri, + royaltiesPercent, + salePrice + ); + + if (annuityPercent > 0) { + _chargedSettings.setCreatorAnnuities( + address(this), + newTokenId, + creator, + annuityPercent + ); + } + } + + function createChargedParticle( + address creator, + address receiver, + address referrer, + string memory tokenMetaUri, + string memory walletManagerId, + address assetToken, + uint256 assetAmount, + uint256 annuityPercent + ) + external + virtual + override + nonReentrant + whenNotPaused + returns (uint256 newTokenId) + { + newTokenId = _createChargedParticle( + creator, + receiver, + referrer, + tokenMetaUri, + walletManagerId, + assetToken, + assetAmount, + annuityPercent + ); + } + + /// @dev for backwards compatibility with v1 + function createBasicProton( + address creator, + address receiver, + string memory tokenMetaUri + ) + external + virtual + whenNotPaused + returns (uint256 newTokenId) + { + newTokenId = _createProton( + creator, + receiver, + tokenMetaUri, + 0, // royaltiesPercent + 0 // salePrice + ); + } + + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + /** + * @dev Setup the ChargedParticles Interface + */ + function setUniverse(address universe) external virtual onlyOwner { + _universe = IUniverse(universe); + emit UniverseSet(universe); + } + + /** + * @dev Setup the ChargedParticles Interface + */ + function setChargedParticles(address chargedParticles) external virtual onlyOwner { + _chargedParticles = IChargedParticles(chargedParticles); + emit ChargedParticlesSet(chargedParticles); + } + + /// @dev Setup the Charged-State Controller + function setChargedState(address stateController) external virtual onlyOwner { + _chargedState = IChargedState(stateController); + emit ChargedStateSet(stateController); + } + + /// @dev Setup the Charged-Settings Controller + function setChargedSettings(address settings) external virtual onlyOwner { + _chargedSettings = IChargedSettings(settings); + emit ChargedSettingsSet(settings); + } + + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _createChargedParticle( + address creator, + address receiver, + address referrer, + string memory tokenMetaUri, + string memory walletManagerId, + address assetToken, + uint256 assetAmount, + uint256 annuityPercent + ) + internal + virtual + returns (uint256 newTokenId) + { + require(address(_chargedParticles) != address(0x0), "PRT:E-107"); + + newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0); + + if (annuityPercent > 0) { + _chargedSettings.setCreatorAnnuities( + address(this), + newTokenId, + creator, + annuityPercent + ); + } + + _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer); + } + + function _chargeParticle( + uint256 tokenId, + string memory walletManagerId, + address assetToken, + uint256 assetAmount, + address referrer + ) + internal + virtual + { + _collectAssetToken(_msgSender(), assetToken, assetAmount); + + IERC20(assetToken).approve(address(_chargedParticles), assetAmount); + + _chargedParticles.energizeParticle( + address(this), + tokenId, + walletManagerId, + assetToken, + assetAmount, + referrer + ); + } + + + /***********************************| + | Function Overrides | + |__________________________________*/ + + function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override { + super._setSalePrice(tokenId, salePrice); + + // Temp-Lock/Unlock NFT + // prevents front-running the sale and draining the value of the NFT just before sale + _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0)); + } + + + function _buyProton(uint256 _tokenId, uint256 _gasLimit) + internal + virtual + override + returns ( + address contractAddress, + uint256 tokenId, + address oldOwner, + address newOwner, + uint256 salePrice, + address royaltiesReceiver, + uint256 creatorAmount + ) + { + (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit); + + // Signal to Universe Controller + if (address(_universe) != address(0)) { + _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount); + } + } + + + function _transfer(address from, address to, uint256 tokenId) internal virtual override { + // Unlock NFT + _chargedState.setTemporaryLock(address(this), tokenId, false); + + super._transfer(from, to, tokenId); + } +} \ No newline at end of file diff --git a/contracts/v1/tokens/ProtonC.sol b/contracts/v1/tokens/ProtonC.sol new file mode 100644 index 0000000..c6118ff --- /dev/null +++ b/contracts/v1/tokens/ProtonC.sol @@ -0,0 +1,332 @@ +// SPDX-License-Identifier: MIT + +// ProtonB.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; +pragma experimental ABIEncoderV2; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; + +import "../interfaces/IUniverse.sol"; +import "../interfaces/IChargedState.sol"; +import "../interfaces/IChargedSettings.sol"; +import "../interfaces/IChargedParticles.sol"; + +import "../lib/BaseProton.sol"; +import "../lib/TokenInfo.sol"; +import "../lib/BlackholePrevention.sol"; +import "../lib/RelayRecipient.sol"; +import "../lib/Soul.sol"; + + +contract ProtonC is BaseProton, Soul { + using SafeMath for uint256; + using TokenInfo for address payable; + using Counters for Counters.Counter; + + IUniverse internal _universe; + IChargedState internal _chargedState; + IChargedSettings internal _chargedSettings; + IChargedParticles internal _chargedParticles; + + event UniverseSet(address indexed universe); + event ChargedStateSet(address indexed chargedState); + event ChargedSettingsSet(address indexed chargedSettings); + event ChargedParticlesSet(address indexed chargedParticles); + + /***********************************| + | Initialization | + |__________________________________*/ + + constructor() public BaseProton("Charged Particles - ProtonC", "PROTON.C") {} + + + /***********************************| + | Public | + |__________________________________*/ + + function createBondedToken( + address creator, + address receiver, + string memory tokenMetaUri, + uint256 annuityPercent, + uint256 royaltiesPercent + ) + external + virtual + payable + returns (uint256 newTokenId) + { + uint256 tokenId = createProtonForSale( + creator, + receiver, + tokenMetaUri, + annuityPercent, + royaltiesPercent, + 0 + ); + lockToken(tokenId); + + return tokenId; + } + + function createProtonForSale( + address creator, + address receiver, + string memory tokenMetaUri, + uint256 annuityPercent, + uint256 royaltiesPercent, + uint256 salePrice + ) + public + virtual + payable + returns (uint256 newTokenId) + { + newTokenId = _createProton( + creator, + receiver, + tokenMetaUri, + royaltiesPercent, + salePrice + ); + + if (annuityPercent > 0) { + _chargedSettings.setCreatorAnnuities( + address(this), + newTokenId, + creator, + annuityPercent + ); + } + } + + function createChargedParticle( + address creator, + address receiver, + address referrer, + string memory tokenMetaUri, + string memory walletManagerId, + address assetToken, + uint256 assetAmount, + uint256 annuityPercent + ) + external + virtual + nonReentrant + whenNotPaused + payable + returns (uint256 newTokenId) + { + newTokenId = _createChargedParticle( + creator, + receiver, + referrer, + tokenMetaUri, + walletManagerId, + assetToken, + assetAmount, + annuityPercent + ); + } + + /// @dev for backwards compatibility with v1 + function createBasicProton( + address creator, + address receiver, + string memory tokenMetaUri + ) + external + virtual + whenNotPaused + payable + returns (uint256 newTokenId) + { + newTokenId = _createProton( + creator, + receiver, + tokenMetaUri, + 0, // royaltiesPercent + 0 // salePrice + ); + } + + function burn(uint256 tokenId) public { + requireTokenOwner(tokenId); + _burn(tokenId); + } + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + /** + * @dev Setup the ChargedParticles Interface + */ + function setUniverse(address universe) external virtual onlyOwner { + _universe = IUniverse(universe); + emit UniverseSet(universe); + } + + /** + * @dev Setup the ChargedParticles Interface + */ + function setChargedParticles(address chargedParticles) external virtual onlyOwner { + _chargedParticles = IChargedParticles(chargedParticles); + emit ChargedParticlesSet(chargedParticles); + } + + /// @dev Setup the Charged-State Controller + function setChargedState(address stateController) external virtual onlyOwner { + _chargedState = IChargedState(stateController); + emit ChargedStateSet(stateController); + } + + /// @dev Setup the Charged-Settings Controller + function setChargedSettings(address settings) external virtual onlyOwner { + _chargedSettings = IChargedSettings(settings); + emit ChargedSettingsSet(settings); + } + + function requireTokenOwner(uint256 tokenId) public view { + require(ownerOf(tokenId) == msg.sender, "Only token owner"); + } + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _createChargedParticle( + address creator, + address receiver, + address referrer, + string memory tokenMetaUri, + string memory walletManagerId, + address assetToken, + uint256 assetAmount, + uint256 annuityPercent + ) + internal + virtual + returns (uint256 newTokenId) + { + require(address(_chargedParticles) != address(0x0), "PRT:E-107"); + + newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0); + + if (annuityPercent > 0) { + _chargedSettings.setCreatorAnnuities( + address(this), + newTokenId, + creator, + annuityPercent + ); + } + + _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer); + } + + function _chargeParticle( + uint256 tokenId, + string memory walletManagerId, + address assetToken, + uint256 assetAmount, + address referrer + ) + internal + virtual + { + _collectAssetToken(_msgSender(), assetToken, assetAmount); + + IERC20(assetToken).approve(address(_chargedParticles), assetAmount); + + _chargedParticles.energizeParticle( + address(this), + tokenId, + walletManagerId, + assetToken, + assetAmount, + referrer + ); + } + + function _burn(uint256 tokenId) internal { + _unlockToken(tokenId); + _transfer(ownerOf(tokenId), address(0x000000000000000000000000000000000000dEaD), tokenId); + } + + /***********************************| + | Soul bounded | + |__________________________________*/ + + function lockToken(uint256 tokenId) public { + requireTokenOwner(tokenId); + _lockToken(tokenId); + } + + /***********************************| + | Function Overrides | + |__________________________________*/ + + function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override { + super._setSalePrice(tokenId, salePrice); + + // Temp-Lock/Unlock NFT + // prevents front-running the sale and draining the value of the NFT just before sale + _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0)); + } + + + function _buyProton(uint256 _tokenId, uint256 _gasLimit) + internal + virtual + override + returns ( + address contractAddress, + uint256 tokenId, + address oldOwner, + address newOwner, + uint256 salePrice, + address royaltiesReceiver, + uint256 creatorAmount + ) + { + (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit); + + // Signal to Universe Controller + if (address(_universe) != address(0)) { + _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount); + } + } + + function _transfer(address from, address to, uint256 tokenId) internal virtual override { + require(lockedTokens[tokenId] == false, "BondedToken: Token is locked"); + + // Unlock NFT + _chargedState.setTemporaryLock(address(this), tokenId, false); + + super._transfer(from, to, tokenId); + } +} \ No newline at end of file diff --git a/contracts/v1/vesting/VestingClaim7.sol b/contracts/v1/vesting/VestingClaim7.sol new file mode 100644 index 0000000..b9fcac1 --- /dev/null +++ b/contracts/v1/vesting/VestingClaim7.sol @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/cryptography/MerkleProof.sol"; +import "../interfaces/IMerkleDistributor.sol"; + +contract VestingClaim7 is IMerkleDistributor { + address public immutable override token; + bytes32 public immutable override merkleRoot; + + address public owner; + uint256 public immutable expiryDate; + + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + // This is a packed array of booleans. + mapping(uint256 => uint256) private claimedBitMap; + + constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public { + owner = msg.sender; + token = token_; + merkleRoot = merkleRoot_; + expiryDate = expiryDate_; + } + + function isClaimed(uint256 index) public view override returns (bool) { + uint256 claimedWordIndex = index / 256; + uint256 claimedBitIndex = index % 256; + uint256 claimedWord = claimedBitMap[claimedWordIndex]; + uint256 mask = (1 << claimedBitIndex); + return claimedWord & mask == mask; + } + + function _setClaimed(uint256 index) private { + uint256 claimedWordIndex = index / 256; + uint256 claimedBitIndex = index % 256; + claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex); + } + + function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override { + require(!isClaimed(index), "VestingClaim7: Drop already claimed."); + + // Verify the merkle proof. + bytes32 node = keccak256(abi.encodePacked(index, account, amount)); + require(MerkleProof.verify(merkleProof, merkleRoot, node), "VestingClaim7: Invalid proof."); + + // Mark it claimed and send the token. + _setClaimed(index); + require(IERC20(token).transfer(account, amount), "VestingClaim7: Transfer failed."); + + emit Claimed(index, account, amount); + } + + function expire(address exitAddress) external onlyOwner { + require(block.timestamp >= expiryDate, "VestingClaim7: expiry date not reached"); + uint256 remainingBalance = IERC20(token).balanceOf(address(this)); + IERC20(token).transfer(exitAddress, remainingBalance); + } + + function transferOwnership(address newOwner) external onlyOwner { + require(newOwner != address(0), "VestingClaim7: new owner is the zero address"); + emit OwnershipTransferred(owner, newOwner); + owner = newOwner; + } + + modifier onlyOwner() { + require(msg.sender == owner, "VestingClaim7: not owner"); + _; + } +} diff --git a/contracts/v1/yield/aave/AaveSmartWallet.sol b/contracts/v1/yield/aave/AaveSmartWallet.sol new file mode 100755 index 0000000..a5c8553 --- /dev/null +++ b/contracts/v1/yield/aave/AaveSmartWallet.sol @@ -0,0 +1,320 @@ +// SPDX-License-Identifier: MIT + +// AaveSmartWallet.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; + +import "../../interfaces/IAaveBridge.sol"; +import "../../lib/SmartWalletBase.sol"; + +/** + * @notice ERC20-Token Smart-Wallet for Aave Assets + * @dev Non-upgradeable Contract + */ +contract AaveSmartWallet is SmartWalletBase { + using SafeMath for uint256; + using SafeERC20 for IERC20; + + uint256 constant internal RAY = 1e27; + + IAaveBridge internal _bridge; + + + /***********************************| + | Initialization | + |__________________________________*/ + + function initialize( + address aaveBridge + ) + public + { + SmartWalletBase.initializeBase(); + _bridge = IAaveBridge(aaveBridge); + } + + + /***********************************| + | Public | + |__________________________________*/ + + function isReserveActive(address assetToken) external view override returns (bool) { + return _bridge.isReserveActive(assetToken); + } + + function getReserveInterestToken(address assetToken) external view override returns (address) { + return _bridge.getReserveInterestToken(assetToken); + } + + function getPrincipal(address assetToken) external override returns (uint256) { + return _getPrincipal(assetToken); + } + + function getInterest(address assetToken) external override returns (uint256 creatorInterest, uint256 ownerInterest) { + return _getInterest(assetToken); + } + + function getTotal(address assetToken) external override returns (uint256) { + return _getTotal(assetToken); + } + + function getRewards(address rewardToken) external override returns (uint256) { + return IERC20(rewardToken).balanceOf(address(this)); + } + + function deposit( + address assetToken, + uint256 assetAmount, + uint256 referralCode + ) + external + override + onlyWalletManager + returns (uint256) + { + return _deposit(assetToken, assetAmount, referralCode); + } + + + function withdraw( + address receiver, + address creatorRedirect, + address assetToken + ) + external + override + onlyWalletManager + returns (uint256 creatorAmount, uint256 receiverAmount) + { + uint256 walletPrincipal = _getPrincipal(assetToken); + (, uint256 ownerInterest) = _getInterest(assetToken); + return _withdraw(receiver, creatorRedirect, assetToken, walletPrincipal.add(ownerInterest)); + } + + function withdrawAmount( + address receiver, + address creatorRedirect, + address assetToken, + uint256 assetAmount + ) + external + override + onlyWalletManager + returns (uint256 creatorAmount, uint256 receiverAmount) + { + return _withdraw(receiver, creatorRedirect, assetToken, assetAmount); + } + + function withdrawAmountForCreator( + address receiver, + address assetToken, + uint256 assetAmount + ) + external + override + onlyWalletManager + returns (uint256 receiverAmount) + { + return _withdrawForCreator(receiver, assetToken, assetAmount); + } + + function withdrawRewards( + address receiver, + address rewardsToken, + uint256 rewardsAmount + ) + external + override + onlyWalletManager + returns (uint256) + { + return _withdrawRewards(receiver, rewardsToken, rewardsAmount); + } + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _deposit( + address assetToken, + uint256 assetAmount, + uint256 referralCode + ) + internal + returns (uint256) + { + _trackAssetToken(assetToken); + + // Track Principal + _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount); + + // Deposit Assets into Aave (reverts on fail) + _sendToken(address(_bridge), assetToken, assetAmount); + uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode); + + // Return amount of aTokens transfered + return aTokensAmount; + } + + function _withdraw( + address receiver, + address creatorRedirect, + address assetToken, + uint256 assetAmount + ) + internal + returns (uint256 creatorAmount, uint256 receiverAmount) + { + uint256 walletPrincipal = _getPrincipal(assetToken); + (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken); + + // Withdraw from Interest only + if (assetAmount < ownerInterest) { + if (creatorInterest > 0) { + uint256 ratio = assetAmount.mul(RAY).div(ownerInterest); + creatorAmount = creatorInterest.add(nftCreatorAmountDischarged).mul(ratio).div(RAY); + + if (creatorAmount <= nftCreatorAmountDischarged) { + nftCreatorAmountDischarged = nftCreatorAmountDischarged.sub(creatorAmount); + creatorAmount = 0; + } + + else { + creatorAmount = creatorAmount.sub(nftCreatorAmountDischarged); + nftCreatorAmountDischarged = 0; + } + } + receiverAmount = assetAmount; + } + + // Withdraw from Interest + Principal + else { + uint256 fromPrincipal = assetAmount.sub(ownerInterest); + if (fromPrincipal > walletPrincipal) { + fromPrincipal = walletPrincipal.sub(ownerInterest); + } + + creatorAmount = creatorInterest; + receiverAmount = ownerInterest.add(fromPrincipal); + nftCreatorAmountDischarged = 0; + + // Track Principal + _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal); + } + + // Send aTokens to Bridge + address aTokenAddress = _bridge.getReserveInterestToken(assetToken); + _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount)); + + // Withdraw Assets for Creator + if (creatorAmount > 0) { + address receivesForCreator = (creatorRedirect != address(0x0)) ? creatorRedirect : nftCreator; + _bridge.withdraw(receivesForCreator, assetToken, creatorAmount); + } + + // Withdraw Assets for Receiver + _bridge.withdraw(receiver, assetToken, receiverAmount); + } + + function _withdrawForCreator( + address receiver, + address assetToken, + uint256 assetAmount + ) + internal + returns (uint256 receiverAmount) + { + (uint256 creatorInterest,) = _getInterest(assetToken); + if (creatorInterest == 0) { return 0; } + if (assetAmount > creatorInterest) { + assetAmount = creatorInterest; + } + + nftCreatorAmountDischarged = nftCreatorAmountDischarged.add(assetAmount); + + // Send aTokens to Bridge + address aTokenAddress = _bridge.getReserveInterestToken(assetToken); + _sendToken(address(_bridge), aTokenAddress, assetAmount); + + // Withdraw Assets for Receiver on behalf of Creator + _bridge.withdraw(receiver, assetToken, assetAmount); + } + + function _withdrawRewards( + address receiver, + address rewardsTokenAddress, + uint256 rewardsAmount + ) + internal + returns (uint256) + { + address self = address(this); + IERC20 rewardsToken = IERC20(rewardsTokenAddress); + + uint256 walletBalance = rewardsToken.balanceOf(self); + require(walletBalance >= rewardsAmount, "ASW:E-411"); + + // Transfer Rewards to Receiver + rewardsToken.safeTransfer(receiver, rewardsAmount); + return rewardsAmount; + } + + function _getTotal(address assetToken) internal view returns (uint256) { + return _bridge.getTotalBalance(address(this), assetToken); + } + + function _getInterest(address assetToken) internal view returns (uint256 creatorInterest, uint256 ownerInterest) { + uint256 total = _getTotal(assetToken); + uint256 principal = _getPrincipal(assetToken); + uint256 interest = total.sub(principal); + + // Creator Royalties + if (nftCreatorAnnuityPct > 0) { + + // Interest too small to calculate percentage; + if (interest <= PERCENTAGE_SCALE) { + // creatorInterest = interest.div(2); // split evenly? + creatorInterest = 0; // All to owner + } + + // Calculate percentage for Creator + else { + creatorInterest = interest + .add(nftCreatorAmountDischarged) + .mul(nftCreatorAnnuityPct) + .div(PERCENTAGE_SCALE) + .sub(nftCreatorAmountDischarged); + } + } + + // Owner Portion + ownerInterest = interest.sub(creatorInterest); + } + + function _sendToken(address to, address token, uint256 amount) internal { + IERC20(token).safeTransfer(to, amount); + } +} diff --git a/contracts/v1/yield/aave/AaveSmartWalletB.sol b/contracts/v1/yield/aave/AaveSmartWalletB.sol new file mode 100755 index 0000000..92ccce6 --- /dev/null +++ b/contracts/v1/yield/aave/AaveSmartWalletB.sol @@ -0,0 +1,346 @@ +// SPDX-License-Identifier: MIT + +// AaveSmartWallet.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; + +import "../../interfaces/IAaveBridge.sol"; +import "../../lib/SmartWalletBaseB.sol"; + +/** + * @notice ERC20-Token Smart-Wallet for Aave Assets + * @dev Non-upgradeable Contract + */ +contract AaveSmartWalletB is SmartWalletBaseB { + using SafeMath for uint256; + using SafeERC20 for IERC20; + + uint256 constant internal RAY = 1e27; + + IAaveBridge internal _bridge; + + uint256 internal _nftCreatorAmountDischarged; + + mapping (address => address) internal _assetATokens; + + /***********************************| + | Initialization | + |__________________________________*/ + + function initialize( + address aaveBridge + ) + public + { + SmartWalletBaseB.initializeBase(); + _bridge = IAaveBridge(aaveBridge); + } + + + /***********************************| + | Public | + |__________________________________*/ + + function isReserveActive(address assetToken) external view override returns (bool) { + return _bridge.isReserveActive(assetToken); + } + + function getReserveInterestToken(address assetToken) external view override returns (address) { + return _bridge.getReserveInterestToken(assetToken); + } + + function getPrincipal(address assetToken) external override returns (uint256) { + return _getPrincipal(assetToken); + } + + function getInterest(address assetToken, uint256 creatorPct) external override returns (uint256 creatorInterest, uint256 ownerInterest) { + return _getInterest(assetToken, creatorPct); + } + + function getTotal(address assetToken) external override returns (uint256) { + return _getTotal(assetToken); + } + + function getRewards(address rewardToken) external override returns (uint256) { + return IERC20(rewardToken).balanceOf(address(this)); + } + + function deposit( + address assetToken, + uint256 assetAmount, + uint256 referralCode + ) + external + override + onlyWalletManager + returns (uint256) + { + return _deposit(assetToken, assetAmount, referralCode); + } + + + function withdraw( + address receiver, + address creator, + uint256 creatorPct, + address assetToken + ) + external + override + onlyWalletManager + returns (uint256 creatorAmount, uint256 receiverAmount) + { + uint256 walletPrincipal = _getPrincipal(assetToken); + (, uint256 ownerInterest) = _getInterest(assetToken, creatorPct); + return _withdraw(receiver, creator, creatorPct, assetToken, walletPrincipal.add(ownerInterest)); + } + + function withdrawAmount( + address receiver, + address creator, + uint256 creatorPct, + address assetToken, + uint256 assetAmount + ) + external + override + onlyWalletManager + returns (uint256 creatorAmount, uint256 receiverAmount) + { + return _withdraw(receiver, creator, creatorPct, assetToken, assetAmount); + } + + function withdrawAmountForCreator( + address receiver, + uint256 creatorPct, + address assetToken, + uint256 assetAmount + ) + external + override + onlyWalletManager + returns (uint256 receiverAmount) + { + return _withdrawForCreator(receiver, creatorPct, assetToken, assetAmount); + } + + function withdrawRewards( + address receiver, + address rewardsToken, + uint256 rewardsAmount + ) + external + override + onlyWalletManager + returns (uint256) + { + return _withdrawRewards(receiver, rewardsToken, rewardsAmount); + } + + function refreshPrincipal(address assetToken) external virtual override onlyWalletManager { + uint256 aTokenBalance = IERC20(_assetATokens[assetToken]).balanceOf(address(this)); + if (_assetPrincipalBalance[assetToken] > aTokenBalance) { + _assetPrincipalBalance[assetToken] = aTokenBalance; + } + } + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _deposit( + address assetToken, + uint256 assetAmount, + uint256 referralCode + ) + internal + returns (uint256) + { + _trackAssetToken(assetToken); + + // Track Principal + _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount); + + // Deposit Assets into Aave (reverts on fail) + _sendToken(address(_bridge), assetToken, assetAmount); + uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode); + + // Return amount of aTokens transfered + return aTokensAmount; + } + + function _withdraw( + address receiver, + address creator, + uint256 creatorPct, + address assetToken, + uint256 assetAmount + ) + internal + returns (uint256 creatorAmount, uint256 receiverAmount) + { + uint256 walletPrincipal = _getPrincipal(assetToken); + (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken, creatorPct); + + // Withdraw from Interest only + if (assetAmount < ownerInterest) { + if (creatorInterest > 0) { + uint256 ratio = assetAmount.mul(RAY).div(ownerInterest); + creatorAmount = creatorInterest.add(_nftCreatorAmountDischarged).mul(ratio).div(RAY); + + if (creatorAmount <= _nftCreatorAmountDischarged) { + _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.sub(creatorAmount); + creatorAmount = 0; + } + else { + creatorAmount = creatorAmount.sub(_nftCreatorAmountDischarged); + _nftCreatorAmountDischarged = 0; + } + } + receiverAmount = assetAmount; + } + + // Withdraw from Interest + Principal + else { + uint256 fromPrincipal = assetAmount.sub(ownerInterest); + if (fromPrincipal > walletPrincipal) { + fromPrincipal = walletPrincipal.sub(ownerInterest); + } + + creatorAmount = creatorInterest; + receiverAmount = ownerInterest.add(fromPrincipal); + _nftCreatorAmountDischarged = 0; + + // Track Principal + _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal); + } + + // Send aTokens to Bridge + address aTokenAddress = _bridge.getReserveInterestToken(assetToken); + _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount)); + + // Withdraw Assets for Creator + if (creatorAmount > 0) { + if (creator != address(0)) { + _bridge.withdraw(creator, assetToken, creatorAmount); + } else { + receiverAmount = receiverAmount.add(creatorAmount); + creatorAmount = 0; + } + } + + // Withdraw Assets for Receiver + _bridge.withdraw(receiver, assetToken, receiverAmount); + } + + function _withdrawForCreator( + address receiver, + uint256 creatorPct, + address assetToken, + uint256 assetAmount + ) + internal + returns (uint256 receiverAmount) + { + (uint256 creatorInterest,) = _getInterest(assetToken, creatorPct); + if (creatorInterest == 0) { return 0; } + if (assetAmount > creatorInterest) { + assetAmount = creatorInterest; + } + + _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.add(assetAmount); + + // Send aTokens to Bridge + address aTokenAddress = _bridge.getReserveInterestToken(assetToken); + _sendToken(address(_bridge), aTokenAddress, assetAmount); + + // Withdraw Assets for Receiver on behalf of Creator + _bridge.withdraw(receiver, assetToken, assetAmount); + } + + function _withdrawRewards( + address receiver, + address rewardsTokenAddress, + uint256 rewardsAmount + ) + internal + returns (uint256) + { + address self = address(this); + IERC20 rewardsToken = IERC20(rewardsTokenAddress); + + uint256 walletBalance = rewardsToken.balanceOf(self); + require(walletBalance >= rewardsAmount, "ASW:E-411"); + + // Transfer Rewards to Receiver + rewardsToken.safeTransfer(receiver, rewardsAmount); + return rewardsAmount; + } + + function _getTotal(address assetToken) internal view returns (uint256) { + return _bridge.getTotalBalance(address(this), assetToken); + } + + function _getInterest(address assetToken, uint256 creatorPct) internal view returns (uint256 creatorInterest, uint256 ownerInterest) { + uint256 total = _getTotal(assetToken); + uint256 principal = _getPrincipal(assetToken); + uint256 interest = total.sub(principal); + + // Creator Royalties + if (creatorPct > 0) { + + // Interest too small to calculate percentage; + if (interest <= PERCENTAGE_SCALE) { + // creatorInterest = interest.div(2); // split evenly? + creatorInterest = 0; // All to owner + } + + // Calculate percentage for Creator + else { + creatorInterest = interest + .add(_nftCreatorAmountDischarged) + .mul(creatorPct) + .div(PERCENTAGE_SCALE) + .sub(_nftCreatorAmountDischarged); + } + } + + // Owner Portion + ownerInterest = interest.sub(creatorInterest); + } + + function _trackAssetToken(address assetToken) internal override { + if (!_assetTokens.contains(assetToken)) { + _assetTokens.add(assetToken); + address aTokenAddress = _bridge.getReserveInterestToken(assetToken); + _assetATokens[assetToken] = aTokenAddress; + } + } + + function _sendToken(address to, address token, uint256 amount) internal { + IERC20(token).safeTransfer(to, amount); + } +} diff --git a/contracts/v1/yield/aave/AaveWalletManager.sol b/contracts/v1/yield/aave/AaveWalletManager.sol new file mode 100755 index 0000000..caf696d --- /dev/null +++ b/contracts/v1/yield/aave/AaveWalletManager.sol @@ -0,0 +1,386 @@ +// SPDX-License-Identifier: MIT + +// AaveWalletManager.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "../../lib/WalletManagerBase.sol"; + +import "./AaveSmartWallet.sol"; + +/** + * @notice Wallet Manager for Aave + * @dev Non-upgradeable Contract + */ +contract AaveWalletManager is WalletManagerBase { + using SafeMath for uint256; + + event AaveBridgeSet(address indexed aaveBridge); + event ValidRewardsTokenSet(address indexed rewardsToken, bool state); + + address internal _aaveBridge; + uint256 internal _referralCode; + + mapping (address => bool) public rewardsTokenWhitelist; + + /***********************************| + | Initialization | + |__________________________________*/ + + constructor () public { + _walletTemplate = address(new AaveSmartWallet()); + } + + /***********************************| + | Public | + |__________________________________*/ + + function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] == address(0x0)) { return false; } + return AaveSmartWallet(_wallets[uuid]).isReserveActive(assetToken); + } + + function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] == address(0x0)) { return address(0x0); } + return AaveSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken); + } + + /** + * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet + * @param contractAddress The Address to the External Contract of the Token + * @param tokenId The ID of the Token within the External Contract + * @return The Principal-Balance of the Smart-Wallet + */ + function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] == address(0x0)) { return 0; } + return AaveSmartWallet(_wallets[uuid]).getPrincipal(assetToken); + } + + /** + * @notice Gets the Interest-Amount that the Token has generated + * @param contractAddress The Address to the External Contract of the Token + * @param tokenId The ID of the Token within the External Contract + * @return creatorInterest The NFT Creator's portion of the Interest + * @return ownerInterest The NFT Owner's portion of the Interest + */ + function getInterest(address contractAddress, uint256 tokenId, address assetToken) + external + override + returns (uint256 creatorInterest, uint256 ownerInterest) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] != address(0x0)) { + return AaveSmartWallet(_wallets[uuid]).getInterest(assetToken); + } + } + + /** + * @notice Gets the Available Balance of Assets held in the Token + * @param contractAddress The Address to the External Contract of the Token + * @param tokenId The ID of the Token within the External Contract + * @return The Available Balance of the Token + */ + function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] == address(0x0)) { return 0; } + return AaveSmartWallet(_wallets[uuid]).getTotal(assetToken); + } + + function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] == address(0x0)) { return 0; } + return AaveSmartWallet(_wallets[uuid]).getRewards(_rewardToken); + } + + + /***********************************| + | Only Controller | + |__________________________________*/ + + function energize( + address contractAddress, + uint256 tokenId, + address assetToken, + uint256 assetAmount + ) + external + override + onlyController + returns (uint256 yieldTokensAmount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + + // Deposit into Smart-Wallet + yieldTokensAmount = AaveSmartWallet(wallet).deposit(assetToken, assetAmount, _referralCode); + + // Log Event + emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount); + } + + function discharge( + address receiver, + address contractAddress, + uint256 tokenId, + address assetToken, + address creatorRedirect + ) + external + override + onlyController + returns (uint256 creatorAmount, uint256 receiverAmount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + require(wallet != address(0x0), "AWM:E-403"); + + (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken); + require(ownerInterest > 0, "AWM:E-412"); + + // Discharge the full amount of interest + (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, ownerInterest); + + // Log Event + emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount); + } + + function dischargeAmount( + address receiver, + address contractAddress, + uint256 tokenId, + address assetToken, + uint256 assetAmount, + address creatorRedirect + ) + external + override + onlyController + returns (uint256 creatorAmount, uint256 receiverAmount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + require(wallet != address(0x0), "AWM:E-403"); + + (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken); + require(assetAmount > 0 && ownerInterest >= assetAmount, "AWM:E-412"); + + // Discharge a portion of the interest + (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount); + + // Log Event + emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount); + } + + function dischargeAmountForCreator( + address receiver, + address contractAddress, + uint256 tokenId, + address creator, + address assetToken, + uint256 assetAmount + ) + external + override + onlyController + returns (uint256 receiverAmount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + require(wallet != address(0x0), "AWM:E-403"); + + (uint256 creatorInterest,) = AaveSmartWallet(wallet).getInterest(assetToken); + require(assetAmount > 0 && creatorInterest >= assetAmount, "AWM:E-412"); + + // Discharge a portion of the interest + receiverAmount = AaveSmartWallet(wallet).withdrawAmountForCreator(receiver, assetToken, assetAmount); + + // Log Event + emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount); + } + + function release( + address receiver, + address contractAddress, + uint256 tokenId, + address assetToken, + address creatorRedirect + ) + external + override + onlyController + returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + require(wallet != address(0x0), "AWM:E-403"); + + // Release Principal + Interest + principalAmount = AaveSmartWallet(wallet).getPrincipal(assetToken); + (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken); + + // Log Event + emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount); + } + + function releaseAmount( + address receiver, + address contractAddress, + uint256 tokenId, + address assetToken, + uint256 assetAmount, + address creatorRedirect + ) + external + override + onlyController + returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + require(wallet != address(0x0), "AWM:E-403"); + + (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken); + principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0; + + // Release from interest first + principal if needed + (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount); + + // Log Event + emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount); + } + + function withdrawRewards( + address receiver, + address contractAddress, + uint256 tokenId, + address rewardsToken, + uint256 rewardsAmount + ) + external + override + onlyController + returns (uint256 amount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + require(wallet != address(0x0), "AWM:E-403"); + require(rewardsTokenWhitelist[rewardsToken], "AWM:E-423"); + + // Withdraw Rewards to Receiver + amount = AaveSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount); + + // Log Event + emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount); + } + + function executeForAccount( + address contractAddress, + uint256 tokenId, + address externalAddress, + uint256 ethValue, + bytes memory encodedParams + ) + external + override + onlyController + returns (bytes memory) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + return AaveSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams); + } + + function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken) + external + override + onlyControllerOrExecutor + { + // no-op + } + + function getWalletAddressById( + address contractAddress, + uint256 tokenId, + address creator, + uint256 annuityPct + ) + external + override + onlyController + returns (address) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + + // Create Smart-Wallet if none exists + if (wallet == address(0x0)) { + wallet = _createWallet(); + _wallets[uuid] = wallet; + + if (creator != address(0x0)) { + AaveSmartWallet(wallet).setNftCreator(creator, annuityPct); + } + + emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct); + } + + return wallet; + } + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + function setAaveBridge(address aaveBridge) external onlyOwner { + require(aaveBridge != address(0x0), "AWM:E-403"); + _aaveBridge = aaveBridge; + emit AaveBridgeSet(aaveBridge); + } + + // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool + function setReferralCode(uint256 referralCode) external onlyOwner { + _referralCode = referralCode; + } + + function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner { + rewardsTokenWhitelist[rewardsToken] = state; + emit ValidRewardsTokenSet(rewardsToken, state); + } + + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _createWallet() + internal + returns (address) + { + address newWallet = _createClone(_walletTemplate); + AaveSmartWallet(newWallet).initialize(_aaveBridge); + return newWallet; + } +} \ No newline at end of file diff --git a/contracts/v1/yield/aave/AaveWalletManagerB.sol b/contracts/v1/yield/aave/AaveWalletManagerB.sol new file mode 100755 index 0000000..5835788 --- /dev/null +++ b/contracts/v1/yield/aave/AaveWalletManagerB.sol @@ -0,0 +1,414 @@ +// SPDX-License-Identifier: MIT + +// AaveWalletManager.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "../../lib/WalletManagerBase.sol"; +import "../../interfaces/IChargedSettings.sol"; +import "./AaveSmartWalletB.sol"; + +/** + * @notice Wallet Manager for Aave + * @dev Non-upgradeable Contract + */ +contract AaveWalletManagerB is WalletManagerBase { + using SafeMath for uint256; + + event AaveBridgeSet(address indexed aaveBridge); + event ChargedSettingsSet(address indexed settings); + event ValidRewardsTokenSet(address indexed rewardsToken, bool state); + + IChargedSettings internal _chargedSettings; + + address internal _aaveBridge; + uint256 internal _referralCode; + + mapping (address => bool) public _rewardsTokenWhitelist; + + /***********************************| + | Initialization | + |__________________________________*/ + + constructor () public { + _walletTemplate = address(new AaveSmartWalletB()); + } + + /***********************************| + | Public | + |__________________________________*/ + + function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] == address(0x0)) { return false; } + return AaveSmartWalletB(_wallets[uuid]).isReserveActive(assetToken); + } + + function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] == address(0x0)) { return address(0x0); } + return AaveSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken); + } + + /** + * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet + * @param contractAddress The Address to the External Contract of the Token + * @param tokenId The ID of the Token within the External Contract + * @return The Principal-Balance of the Smart-Wallet + */ + function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] == address(0x0)) { return 0; } + return AaveSmartWalletB(_wallets[uuid]).getPrincipal(assetToken); + } + + /** + * @notice Gets the Interest-Amount that the Token has generated + * @param contractAddress The Address to the External Contract of the Token + * @param tokenId The ID of the Token within the External Contract + * @return creatorInterest The NFT Creator's portion of the Interest + * @return ownerInterest The NFT Owner's portion of the Interest + */ + function getInterest(address contractAddress, uint256 tokenId, address assetToken) + external + override + returns (uint256 creatorInterest, uint256 ownerInterest) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] != address(0x0)) { + (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId); + return AaveSmartWalletB(_wallets[uuid]).getInterest(assetToken, annuityPct); + } + } + + /** + * @notice Gets the Available Balance of Assets held in the Token + * @param contractAddress The Address to the External Contract of the Token + * @param tokenId The ID of the Token within the External Contract + * @return The Available Balance of the Token + */ + function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] == address(0x0)) { return 0; } + return AaveSmartWalletB(_wallets[uuid]).getTotal(assetToken); + } + + function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] == address(0x0)) { return 0; } + return AaveSmartWalletB(_wallets[uuid]).getRewards(_rewardToken); + } + + + /***********************************| + | Only Controller | + |__________________________________*/ + + function energize( + address contractAddress, + uint256 tokenId, + address assetToken, + uint256 assetAmount + ) + external + override + onlyController + returns (uint256 yieldTokensAmount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + + // Deposit into Smart-Wallet + yieldTokensAmount = AaveSmartWalletB(wallet).deposit(assetToken, assetAmount, _referralCode); + + // Log Event + emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount); + } + + function discharge( + address receiver, + address contractAddress, + uint256 tokenId, + address assetToken, + address creatorRedirect + ) + external + override + onlyController + returns (uint256 creatorAmount, uint256 receiverAmount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + require(wallet != address(0x0), "AWM:E-403"); + + (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId); + (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct); + require(ownerInterest > 0, "AWM:E-412"); + + if (creatorRedirect != address(0)) { + creator = creatorRedirect; + } + + // Discharge the full amount of interest + (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, ownerInterest); + + // Log Event + emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount); + } + + function dischargeAmount( + address receiver, + address contractAddress, + uint256 tokenId, + address assetToken, + uint256 assetAmount, + address creatorRedirect + ) + external + override + onlyController + returns (uint256 creatorAmount, uint256 receiverAmount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + require(wallet != address(0x0), "AWM:E-403"); + + (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId); + (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct); + require(assetAmount > 0 && ownerInterest >= assetAmount, "AWM:E-412"); + + if (creatorRedirect != address(0)) { + creator = creatorRedirect; + } + + // Discharge a portion of the interest + (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount); + + // Log Event + emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount); + } + + function dischargeAmountForCreator( + address receiver, + address contractAddress, + uint256 tokenId, + address creator, + address assetToken, + uint256 assetAmount + ) + external + override + onlyController + returns (uint256 receiverAmount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + require(wallet != address(0x0), "AWM:E-403"); + + (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId); + (uint256 creatorInterest,) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct); + require(assetAmount > 0 && creatorInterest >= assetAmount, "AWM:E-412"); + + // Discharge a portion of the interest + receiverAmount = AaveSmartWalletB(wallet).withdrawAmountForCreator(receiver, annuityPct, assetToken, assetAmount); + + // Log Event + emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount); + } + + function release( + address receiver, + address contractAddress, + uint256 tokenId, + address assetToken, + address creatorRedirect + ) + external + override + onlyController + returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + require(wallet != address(0x0), "AWM:E-403"); + + (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId); + if (creatorRedirect != address(0)) { + creator = creatorRedirect; + } + + // Release Principal + Interest + principalAmount = AaveSmartWalletB(wallet).getPrincipal(assetToken); + (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdraw(receiver, creator, annuityPct, assetToken); + + // Log Event + emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount); + } + + function releaseAmount( + address receiver, + address contractAddress, + uint256 tokenId, + address assetToken, + uint256 assetAmount, + address creatorRedirect + ) + external + override + onlyController + returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + require(wallet != address(0x0), "AWM:E-403"); + + (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId); + if (creatorRedirect != address(0)) { + creator = creatorRedirect; + } + + (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct); + principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0; + + // Release from interest first + principal if needed + (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount); + + // Log Event + emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount); + } + + function withdrawRewards( + address receiver, + address contractAddress, + uint256 tokenId, + address rewardsToken, + uint256 rewardsAmount + ) + external + override + onlyController + returns (uint256 amount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + require(wallet != address(0x0), "AWM:E-403"); + require(_rewardsTokenWhitelist[rewardsToken], "AWM:E-423"); + + // Withdraw Rewards to Receiver + amount = AaveSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount); + + // Log Event + emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount); + } + + function executeForAccount( + address contractAddress, + uint256 tokenId, + address externalAddress, + uint256 ethValue, + bytes memory encodedParams + ) + external + override + onlyControllerOrExecutor + returns (bytes memory) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + return AaveSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams); + } + + function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken) + external + override + onlyControllerOrExecutor + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + AaveSmartWalletB(wallet).refreshPrincipal(assetToken); + } + + function getWalletAddressById( + address contractAddress, + uint256 tokenId, + address /* creator */, + uint256 /* annuityPct */ + ) + external + override + onlyControllerOrExecutor + returns (address) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + + // Create Smart-Wallet if none exists + if (wallet == address(0x0)) { + wallet = _createWallet(); + _wallets[uuid] = wallet; + emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0); + } + + return wallet; + } + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + function setAaveBridge(address aaveBridge) external onlyOwner { + require(aaveBridge != address(0x0), "AWM:E-403"); + _aaveBridge = aaveBridge; + emit AaveBridgeSet(aaveBridge); + } + + function setChargedSettings(address settings) external onlyOwner { + require(settings != address(0x0), "AWM:E-403"); + _chargedSettings = IChargedSettings(settings); + emit ChargedSettingsSet(settings); + } + + // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool + function setReferralCode(uint256 referralCode) external onlyOwner { + _referralCode = referralCode; + } + + function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner { + _rewardsTokenWhitelist[rewardsToken] = state; + emit ValidRewardsTokenSet(rewardsToken, state); + } + + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _createWallet() + internal + returns (address) + { + address newWallet = _createClone(_walletTemplate); + AaveSmartWalletB(newWallet).initialize(_aaveBridge); + return newWallet; + } +} \ No newline at end of file diff --git a/contracts/v1/yield/aave/v2/AaveBridgeV2.sol b/contracts/v1/yield/aave/v2/AaveBridgeV2.sol new file mode 100755 index 0000000..ba4b6d6 --- /dev/null +++ b/contracts/v1/yield/aave/v2/AaveBridgeV2.sol @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: MIT + +// AaveBridgeV2.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; +pragma experimental ABIEncoderV2; + +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/utils/SafeCast.sol"; + +import "./IATokenV2.sol"; +import "./ILendingPoolV2.sol"; +import "./ILendingPoolAddressesProviderV2.sol"; + +import "../../../interfaces/IAaveBridge.sol"; +import "../../../lib/BlackholePrevention.sol"; + +contract AaveBridgeV2 is Ownable, IAaveBridge, BlackholePrevention { + using SafeMath for uint256; + using SafeCast for uint256; + using SafeERC20 for IERC20; + using ReserveLogic for ReserveLogic.ReserveData; + + ILendingPoolAddressesProviderV2 public provider; + ILendingPoolV2 public lendingPool; + + constructor (address lendingPoolProvider) public { + provider = ILendingPoolAddressesProviderV2(lendingPoolProvider); + lendingPool = ILendingPoolV2(provider.getLendingPool()); + } + + function getReserveInterestToken(address assetToken) external view override returns (address aTokenAddress) { + return _getReserveInterestToken(assetToken); + } + + function isReserveActive(address assetToken) external view override returns (bool) { + return _isReserveActive(assetToken); + } + + function getTotalBalance(address account, address assetToken) external view override returns (uint256) { + address aTokenAddress = _getReserveInterestToken(assetToken); + if (aTokenAddress == address(0x0)) { return 0; } + return IATokenV2(aTokenAddress).balanceOf(account); + } + + function deposit( + address assetToken, + uint256 assetAmount, + uint256 referralCode + ) + external + override + returns (uint256) + { + address self = address(this); + address aTokenAddress = _getReserveInterestToken(assetToken); + require(_isReserveActive(assetToken), "ABV2:E-424"); + + IERC20 token = IERC20(assetToken); + IATokenV2 aToken = IATokenV2(aTokenAddress); + + if (token.allowance(address(this), address(lendingPool)) < assetAmount) { + token.approve(address(lendingPool), uint256(-1)); + } + + // Deposit Assets into Aave + uint256 preBalance = aToken.balanceOf(self); + lendingPool.deposit(assetToken, assetAmount, self, referralCode.toUint16()); + uint256 postBalance = aToken.balanceOf(self); + uint256 aTokensAmount = postBalance.sub(preBalance); + + // Transfer back the Interest Tokens + _sendToken(msg.sender, aTokenAddress, aTokensAmount); + + // Return amount of aTokens transfered + return aTokensAmount; + } + + function withdraw( + address receiver, + address assetToken, + uint256 assetAmount + ) + external + override + { + address self = address(this); + require(_isReserveActive(assetToken), "ABV2:E-424"); + + // Redeem aTokens for Asset Tokens + lendingPool.withdraw(assetToken, assetAmount, self); + + // Transfer back the Asset Tokens + _sendToken(receiver, assetToken, assetAmount); + } + + + /***********************************| + | Only Admin/DAO | + | (blackhole prevention) | + |__________________________________*/ + + function withdrawEther(address payable receiver, uint256 amount) external onlyOwner { + _withdrawEther(receiver, amount); + } + + function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner { + _withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _sendToken(address to, address token, uint256 amount) internal { + IERC20(token).safeTransfer(to, amount); + } + + function _getReserveInterestToken(address assetToken) internal view returns (address aTokenAddress) { + ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken); + return config.aTokenAddress; + } + + function _isReserveActive(address assetToken) internal view returns (bool) { + ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken); + uint256 isActiveFlag = 2 ** 56; // bit 56: reserve is active + return (config.configuration.data & isActiveFlag) == isActiveFlag; + } +} diff --git a/contracts/v1/yield/aave/v2/IATokenV2.sol b/contracts/v1/yield/aave/v2/IATokenV2.sol new file mode 100755 index 0000000..41b7874 --- /dev/null +++ b/contracts/v1/yield/aave/v2/IATokenV2.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: agpl-3.0 +pragma solidity >=0.6.0; + +interface IATokenV2 { + function balanceOf(address account) external view returns (uint256); +} diff --git a/contracts/v1/yield/aave/v2/ILendingPoolAddressesProviderV2.sol b/contracts/v1/yield/aave/v2/ILendingPoolAddressesProviderV2.sol new file mode 100755 index 0000000..9c1babf --- /dev/null +++ b/contracts/v1/yield/aave/v2/ILendingPoolAddressesProviderV2.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: agpl-3.0 +pragma solidity >=0.6.0; + +interface ILendingPoolAddressesProviderV2 { + function getLendingPool() external view returns (address); +} \ No newline at end of file diff --git a/contracts/v1/yield/aave/v2/ILendingPoolV2.sol b/contracts/v1/yield/aave/v2/ILendingPoolV2.sol new file mode 100755 index 0000000..f277a96 --- /dev/null +++ b/contracts/v1/yield/aave/v2/ILendingPoolV2.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: agpl-3.0 +pragma solidity >=0.6.0; +pragma experimental ABIEncoderV2; + +import "./ILendingPoolAddressesProviderV2.sol"; + +library ReserveConfiguration { + struct Map { + uint256 data; + } +} + +library ReserveLogic { + struct ReserveData { + ReserveConfiguration.Map configuration; + uint128 liquidityIndex; + uint128 variableBorrowIndex; + uint128 currentLiquidityRate; + uint128 currentVariableBorrowRate; + uint128 currentStableBorrowRate; + uint40 lastUpdateTimestamp; + address aTokenAddress; + address stableDebtTokenAddress; + address variableDebtTokenAddress; + address interestRateStrategyAddress; + uint8 id; + } +} + +interface ILendingPoolV2 { + function deposit(address reserve, uint256 amount, address onBehalfOf, uint16 referralCode) external; + function withdraw(address reserve, uint256 amount, address to) external; + function getReserveData(address asset) external view returns (ReserveLogic.ReserveData memory); +} diff --git a/contracts/v1/yield/generic/ERC20/GenericSmartWallet.sol b/contracts/v1/yield/generic/ERC20/GenericSmartWallet.sol new file mode 100644 index 0000000..fdfac21 --- /dev/null +++ b/contracts/v1/yield/generic/ERC20/GenericSmartWallet.sol @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: MIT + +// GenericSmartWallet.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; +import "../../../lib/SmartWalletBase.sol"; + + +/** + * @notice Generic ERC20-Token Smart-Wallet Bridge + * @dev Non-upgradeable Contract + */ +contract GenericSmartWallet is SmartWalletBase { + using SafeMath for uint256; + using SafeERC20 for IERC20; + + /***********************************| + | Initialization | + |__________________________________*/ + + function initialize() + public + { + SmartWalletBase.initializeBase(); + } + + function isReserveActive(address assetToken) + external + override + view + returns (bool) + { + return _getPrincipal(assetToken) == 0; + } + + function getReserveInterestToken(address assetToken) + external + override + view + returns (address) + { + return assetToken; + } + + function getPrincipal(address assetToken) + external + override + returns (uint256) + { + return _getPrincipal(assetToken); + } + + function getInterest(address /* assetToken */) + external + override + returns (uint256 creatorInterest, uint256 ownerInterest) + { + return (0, 0); + } + + function getTotal(address assetToken) + external + override + returns (uint256) + { + return _getPrincipal(assetToken); + } + + function getRewards(address assetToken) + external + override + returns (uint256) + { + return IERC20(assetToken).balanceOf(address(this)); + } + + function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */) + external + override + onlyWalletManager + returns (uint256) + { + // Track Principal + _trackAssetToken(assetToken); + _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount); + } + + function withdraw(address receiver, address /* creatorRedirect */, address assetToken) + external + override + onlyWalletManager + returns (uint256 creatorAmount, uint256 receiverAmount) + { + creatorAmount = 0; + receiverAmount = _getPrincipal(assetToken); + // Track Principal + _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount); + IERC20(assetToken).safeTransfer(receiver, receiverAmount); + } + + function withdrawAmount(address receiver, address /* creatorRedirect */, address assetToken, uint256 assetAmount) + external + override + onlyWalletManager + returns (uint256 creatorAmount, uint256 receiverAmount) + { + creatorAmount = 0; + receiverAmount = _getPrincipal(assetToken); + if (receiverAmount >= assetAmount) { + receiverAmount = assetAmount; + } + // Track Principal + _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount); + IERC20(assetToken).safeTransfer(receiver, receiverAmount); + } + + function withdrawAmountForCreator( + address /* receiver */, + address /* assetToken */, + uint256 /* assetID */ + ) + external + override + onlyWalletManager + returns (uint256 receiverAmount) + { + return 0; + } + + function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount) + external + override + onlyWalletManager + returns (uint256) + { + address self = address(this); + IERC20 rewardsToken = IERC20(rewardsTokenAddress); + + uint256 walletBalance = rewardsToken.balanceOf(self); + require(walletBalance >= rewardsAmount, "GSW:E-411"); + + // Transfer Rewards to Receiver + rewardsToken.safeTransfer(receiver, rewardsAmount); + return rewardsAmount; + } + +} diff --git a/contracts/v1/yield/generic/ERC20/GenericSmartWalletB.sol b/contracts/v1/yield/generic/ERC20/GenericSmartWalletB.sol new file mode 100644 index 0000000..5cf8a2f --- /dev/null +++ b/contracts/v1/yield/generic/ERC20/GenericSmartWalletB.sol @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: MIT + +// GenericSmartWalletB.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; +import "../../../lib/SmartWalletBaseB.sol"; + + +/** + * @notice Generic ERC20-Token Smart-Wallet Bridge + * @dev Non-upgradeable Contract + */ +contract GenericSmartWalletB is SmartWalletBaseB { + using SafeMath for uint256; + using SafeERC20 for IERC20; + + /***********************************| + | Initialization | + |__________________________________*/ + + function initialize() + public + { + SmartWalletBaseB.initializeBase(); + } + + function isReserveActive(address assetToken) + external + override + view + returns (bool) + { + return _getPrincipal(assetToken) == 0; + } + + function getReserveInterestToken(address assetToken) + external + override + view + returns (address) + { + return assetToken; + } + + function getPrincipal(address assetToken) + external + override + returns (uint256) + { + return _getPrincipal(assetToken); + } + + function getInterest(address /* assetToken */, uint256 /* creatorPct */) + external + override + returns (uint256 creatorInterest, uint256 ownerInterest) + { + return (0, 0); + } + + function getTotal(address assetToken) + external + override + returns (uint256) + { + return _getPrincipal(assetToken); + } + + function getRewards(address assetToken) + external + override + returns (uint256) + { + return IERC20(assetToken).balanceOf(address(this)); + } + + function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */) + external + override + onlyWalletManager + returns (uint256) + { + // Track Principal + _trackAssetToken(assetToken); + _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount); + } + + function withdraw(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken) + external + override + onlyWalletManager + returns (uint256 creatorAmount, uint256 receiverAmount) + { + creatorAmount = 0; + receiverAmount = _getPrincipal(assetToken); + // Track Principal + _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount); + IERC20(assetToken).safeTransfer(receiver, receiverAmount); + } + + function withdrawAmount(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken, uint256 assetAmount) + external + override + onlyWalletManager + returns (uint256 creatorAmount, uint256 receiverAmount) + { + creatorAmount = 0; + receiverAmount = _getPrincipal(assetToken); + if (receiverAmount >= assetAmount) { + receiverAmount = assetAmount; + } + // Track Principal + _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount); + IERC20(assetToken).safeTransfer(receiver, receiverAmount); + } + + function withdrawAmountForCreator( + address /* receiver */, + uint256 /* creatorPct */, + address /* assetToken */, + uint256 /* assetID */ + ) + external + override + onlyWalletManager + returns (uint256 receiverAmount) + { + return 0; + } + + function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount) + external + override + onlyWalletManager + returns (uint256) + { + address self = address(this); + IERC20 rewardsToken = IERC20(rewardsTokenAddress); + + uint256 walletBalance = rewardsToken.balanceOf(self); + require(walletBalance >= rewardsAmount, "GSW:E-411"); + + // Transfer Rewards to Receiver + rewardsToken.safeTransfer(receiver, rewardsAmount); + return rewardsAmount; + } + + function refreshPrincipal(address assetToken) external virtual override onlyWalletManager { + _assetPrincipalBalance[assetToken] = IERC20(assetToken).balanceOf(address(this)); + } +} diff --git a/contracts/v1/yield/generic/ERC20/GenericWalletManager.sol b/contracts/v1/yield/generic/ERC20/GenericWalletManager.sol new file mode 100644 index 0000000..72d4106 --- /dev/null +++ b/contracts/v1/yield/generic/ERC20/GenericWalletManager.sol @@ -0,0 +1,303 @@ +// SPDX-License-Identifier: MIT + +// GenericWalletManager.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "../../../lib/WalletManagerBase.sol"; +import "./GenericSmartWallet.sol"; + +/** + * @notice Generic ERC20 Wallet Manager + * @dev Non-upgradeable Contract + */ +contract GenericWalletManager is WalletManagerBase { + using SafeMath for uint256; + + /***********************************| + | Initialization | + |__________________________________*/ + + constructor () public { + _walletTemplate = address(new GenericSmartWallet()); + } + + /***********************************| + | Public | + |__________________________________*/ + + function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) + external + override + view + returns (bool) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] == address(0x0)) { return false; } + return GenericSmartWallet(_wallets[uuid]).isReserveActive(assetToken); + } + + function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) + external + override + view + returns (address) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] == address(0x0)) { return address(0x0); } + return GenericSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken); + } + + /** + * @notice Gets the Available Balance of Assets held in the Token + * @param contractAddress The Address to the External Contract of the Token + * @param tokenId The ID of the Token within the External Contract + * @return The Available Balance of the Token + */ + function getTotal(address contractAddress, uint256 tokenId, address assetToken) + external + override + returns (uint256) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] == address(0x0)) { return 0; } + return GenericSmartWallet(_wallets[uuid]).getTotal(assetToken); + } + + /** + * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet + * @param contractAddress The Address to the External Contract of the Token + * @param tokenId The ID of the Token within the External Contract + * @return The Principal-Balance of the Smart-Wallet + */ + function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) + external + override + returns (uint256) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] == address(0x0)) { return 0; } + return GenericSmartWallet(_wallets[uuid]).getPrincipal(assetToken); + } + + /** + * @notice Gets the Interest-Amount that the Token has generated + * @param contractAddress The Address to the External Contract of the Token + * @param tokenId The ID of the Token within the External Contract + * @return creatorInterest The NFT Creator's portion of the Interest + * @return ownerInterest The NFT Owner's portion of the Interest + */ + function getInterest(address contractAddress, uint256 tokenId, address assetToken) + external + override + returns (uint256 creatorInterest, uint256 ownerInterest) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] != address(0x0)) { + return GenericSmartWallet(_wallets[uuid]).getInterest(assetToken); + } + } + + function getRewards(address contractAddress, uint256 tokenId, address rewardToken) + external + override + returns (uint256) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] == address(0x0)) { return 0; } + return GenericSmartWallet(_wallets[uuid]).getRewards(rewardToken); + } + + function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount) + external + override + onlyController + returns (uint256 yieldTokensAmount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + + // Deposit into Smart-Wallet + yieldTokensAmount = GenericSmartWallet(wallet).deposit(assetToken, assetAmount, 0); + + // Log Event + emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount); + } + + function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */) + external + override + onlyController + returns (uint256 creatorAmount, uint256 receiverAmount) + { + return (0, 0); + } + + function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */) + external + override + onlyController + returns (uint256 creatorAmount, uint256 receiverAmount) + { + return (0, 0); + } + + function dischargeAmountForCreator( + address /* receiver */, + address /* contractAddress */, + uint256 /* tokenId */, + address /* creator */, + address /* assetToken */, + uint256 /* assetAmount */ + ) + external + override + onlyController + returns (uint256 receiverAmount) + { + return 0; + } + + function release( + address receiver, + address contractAddress, + uint256 tokenId, + address assetToken, + address creatorRedirect + ) + external + override + onlyController + returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + require(wallet != address(0x0), "GWM:E-403"); + + // Release Principal + Interest + principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken); + (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken); + + // Log Event + emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount); + } + + function releaseAmount( + address receiver, + address contractAddress, + uint256 tokenId, + address assetToken, + uint256 assetAmount, + address creatorRedirect + ) + external + override + onlyController + returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + require(wallet != address(0x0), "GWM:E-403"); + + // Release from interest first + principal if needed + principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken); + (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount); + + // Log Event + emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount); + } + + function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) + external + override + onlyController + returns (uint256 amount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + require(wallet != address(0x0), "GWM:E-403"); + + // Withdraw Rewards to Receiver + amount = GenericSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount); + + // Log Event + emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount); + } + + function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) + external + override + onlyController + returns (bytes memory) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + return GenericSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams); + } + + function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken) + external + override + onlyControllerOrExecutor + { + // no-op + } + + function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct) + external + override + onlyController + returns (address) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + + // Create Smart-Wallet if none exists + if (wallet == address(0x0)) { + wallet = _createWallet(); + _wallets[uuid] = wallet; + + if (creator != address(0x0)) { + GenericSmartWallet(wallet).setNftCreator(creator, annuityPct); + } + + emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct); + } + + return wallet; + } + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _createWallet() + internal + returns (address) + { + address newWallet = _createClone(_walletTemplate); + GenericSmartWallet(newWallet).initialize(); + return newWallet; + } + +} diff --git a/contracts/v1/yield/generic/ERC20/GenericWalletManagerB.sol b/contracts/v1/yield/generic/ERC20/GenericWalletManagerB.sol new file mode 100644 index 0000000..b69829e --- /dev/null +++ b/contracts/v1/yield/generic/ERC20/GenericWalletManagerB.sol @@ -0,0 +1,300 @@ +// SPDX-License-Identifier: MIT + +// GenericWalletManagerB.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/math/SafeMath.sol"; +import "../../../lib/WalletManagerBase.sol"; +import "./GenericSmartWalletB.sol"; + +/** + * @notice Generic ERC20 Wallet Manager B + * @dev Non-upgradeable Contract + */ +contract GenericWalletManagerB is WalletManagerBase { + using SafeMath for uint256; + + /***********************************| + | Initialization | + |__________________________________*/ + + constructor () public { + _walletTemplate = address(new GenericSmartWalletB()); + } + + /***********************************| + | Public | + |__________________________________*/ + + function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) + external + override + view + returns (bool) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] == address(0x0)) { return false; } + return GenericSmartWalletB(_wallets[uuid]).isReserveActive(assetToken); + } + + function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) + external + override + view + returns (address) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] == address(0x0)) { return address(0x0); } + return GenericSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken); + } + + /** + * @notice Gets the Available Balance of Assets held in the Token + * @param contractAddress The Address to the External Contract of the Token + * @param tokenId The ID of the Token within the External Contract + * @return The Available Balance of the Token + */ + function getTotal(address contractAddress, uint256 tokenId, address assetToken) + external + override + returns (uint256) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] == address(0x0)) { return 0; } + return GenericSmartWalletB(_wallets[uuid]).getTotal(assetToken); + } + + /** + * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet + * @param contractAddress The Address to the External Contract of the Token + * @param tokenId The ID of the Token within the External Contract + * @return The Principal-Balance of the Smart-Wallet + */ + function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) + external + override + returns (uint256) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] == address(0x0)) { return 0; } + return GenericSmartWalletB(_wallets[uuid]).getPrincipal(assetToken); + } + + /** + * @notice Gets the Interest-Amount that the Token has generated + * @param contractAddress The Address to the External Contract of the Token + * @param tokenId The ID of the Token within the External Contract + * @return creatorInterest The NFT Creator's portion of the Interest + * @return ownerInterest The NFT Owner's portion of the Interest + */ + function getInterest(address contractAddress, uint256 tokenId, address assetToken) + external + override + returns (uint256 creatorInterest, uint256 ownerInterest) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] != address(0x0)) { + return GenericSmartWalletB(_wallets[uuid]).getInterest(assetToken, 0); + } + } + + function getRewards(address contractAddress, uint256 tokenId, address rewardToken) + external + override + returns (uint256) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + if (_wallets[uuid] == address(0x0)) { return 0; } + return GenericSmartWalletB(_wallets[uuid]).getRewards(rewardToken); + } + + function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount) + external + override + onlyController + returns (uint256 yieldTokensAmount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + + // Deposit into Smart-Wallet + yieldTokensAmount = GenericSmartWalletB(wallet).deposit(assetToken, assetAmount, 0); + + // Log Event + emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount); + } + + function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */) + external + override + onlyController + returns (uint256 creatorAmount, uint256 receiverAmount) + { + return (0, 0); + } + + function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */) + external + override + onlyController + returns (uint256 creatorAmount, uint256 receiverAmount) + { + return (0, 0); + } + + function dischargeAmountForCreator( + address /* receiver */, + address /* contractAddress */, + uint256 /* tokenId */, + address /* creator */, + address /* assetToken */, + uint256 /* assetAmount */ + ) + external + override + onlyController + returns (uint256 receiverAmount) + { + return 0; + } + + function release( + address receiver, + address contractAddress, + uint256 tokenId, + address assetToken, + address creatorRedirect + ) + external + override + onlyController + returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + require(wallet != address(0x0), "GWM:E-403"); + + // Release Principal + Interest + principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken); + (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdraw(receiver, creatorRedirect, 0, assetToken); + + // Log Event + emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount); + } + + function releaseAmount( + address receiver, + address contractAddress, + uint256 tokenId, + address assetToken, + uint256 assetAmount, + address creatorRedirect + ) + external + override + onlyController + returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + require(wallet != address(0x0), "GWM:E-403"); + + // Release from interest first + principal if needed + principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken); + (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdrawAmount(receiver, creatorRedirect, 0, assetToken, assetAmount); + + // Log Event + emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount); + } + + function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) + external + override + onlyControllerOrExecutor + returns (uint256 amount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + require(wallet != address(0x0), "GWM:E-403"); + + // Withdraw Rewards to Receiver + amount = GenericSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount); + + // Log Event + emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount); + } + + function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) + external + override + onlyControllerOrExecutor + returns (bytes memory) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + return GenericSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams); + } + + function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken) + external + override + onlyControllerOrExecutor + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + GenericSmartWalletB(wallet).refreshPrincipal(assetToken); + } + + function getWalletAddressById(address contractAddress, uint256 tokenId, address /* creator */, uint256 /* annuityPct */) + external + override + onlyControllerOrExecutor + returns (address) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address wallet = _wallets[uuid]; + + // Create Smart-Wallet if none exists + if (wallet == address(0x0)) { + wallet = _createWallet(); + _wallets[uuid] = wallet; + emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0); + } + + return wallet; + } + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _createWallet() + internal + returns (address) + { + address newWallet = _createClone(_walletTemplate); + GenericSmartWalletB(newWallet).initialize(); + return newWallet; + } + +} diff --git a/contracts/v1/yield/generic/ERC721/GenericBasketManager.sol b/contracts/v1/yield/generic/ERC721/GenericBasketManager.sol new file mode 100644 index 0000000..9a2ac4f --- /dev/null +++ b/contracts/v1/yield/generic/ERC721/GenericBasketManager.sol @@ -0,0 +1,311 @@ +// SPDX-License-Identifier: MIT + +// GenericBasketManager.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/utils/Counters.sol"; +import "../../../interfaces/IBasketManager.sol"; +import "../../../interfaces/ISmartBasket.sol"; +import "../../../lib/BlackholePrevention.sol"; +import "../../../lib/TokenInfo.sol"; +import "./GenericSmartBasket.sol"; + +/** + * @notice Generic ERC721 Basket Manager + * @dev Non-upgradeable Contract + */ +contract GenericBasketManager is Ownable, BlackholePrevention, IBasketManager { + using Counters for Counters.Counter; + using TokenInfo for address; + + // The Controller Contract Address + address internal _controller; + + // Template Contract for creating Token Smart-Baskets + address internal _basketTemplate; + + // TokenID => Token Smart-Basket Address + mapping (uint256 => address) internal _baskets; + + mapping (uint256 => Counters.Counter) internal _totalTokens; + + // State of Basket Manager + bool internal _paused; + + /***********************************| + | Initialization | + |__________________________________*/ + + constructor () public { + _basketTemplate = address(new GenericSmartBasket()); + } + + /***********************************| + | Public | + |__________________________________*/ + + function isPaused() external view override returns (bool) { + return _paused; + } + + function getTokenTotalCount( + address contractAddress, + uint256 tokenId + ) + external + view + override + returns (uint256) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + return _totalTokens[uuid].current(); + } + + function getTokenCountByType( + address contractAddress, + uint256 tokenId, + address basketTokenAddress, + uint256 basketTokenId + ) + external + override + returns (uint256) + { + address basket = getBasketAddressById(contractAddress, tokenId); + return GenericSmartBasket(basket).getTokenCountByType(basketTokenAddress, basketTokenId); + } + + function prepareTransferAmount(uint256 /* nftTokenAmount */) external override onlyController { + // no-op + } + + function addToBasket( + address contractAddress, + uint256 tokenId, + address basketTokenAddress, + uint256 basketTokenId + ) + public + override + onlyController + whenNotPaused + returns (bool added) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address basket = _baskets[uuid]; + + added = GenericSmartBasket(basket).addToBasket(basketTokenAddress, basketTokenId); + + // Log Event + if (added) { + _totalTokens[uuid].increment(); + emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, 1); + } + } + + + function removeFromBasket( + address receiver, + address contractAddress, + uint256 tokenId, + address basketTokenAddress, + uint256 basketTokenId + ) + public + override + onlyController + returns (bool removed) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address basket = _baskets[uuid]; + require(basket != address(0x0), "GBM:E-403"); + + removed = GenericSmartBasket(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId); + + // Log Event + if (removed) { + _totalTokens[uuid].decrement(); + emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, 1); + } + } + + function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) + external + override + onlyController + returns (uint256 amount) + { + // no-op + } + + function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) + public + override + onlyController + returns (bytes memory) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address basket = _baskets[uuid]; + return GenericSmartBasket(basket).executeForAccount(externalAddress, ethValue, encodedParams); + } + + function getBasketAddressById(address contractAddress, uint256 tokenId) + public + override + onlyController + returns (address) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address basket = _baskets[uuid]; + + // Create Smart-Basket if none exists + if (basket == address(0x0)) { + basket = _createBasket(); + _baskets[uuid] = basket; + + emit NewSmartBasket(contractAddress, tokenId, basket); + } + + return basket; + } + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + /** + * @dev Sets the Paused-state of the Basket Manager + */ + function setPausedState(bool paused) external onlyOwner { + _paused = paused; + emit PausedStateSet(paused); + } + + /** + * @dev Connects to the Charged Particles Controller + */ + function setController(address controller) external onlyOwner { + _controller = controller; + emit ControllerSet(controller); + } + + function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) + external + virtual + override + onlyOwner + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address basket = _baskets[uuid]; + _withdrawEther(receiver, amount); + return ISmartBasket(basket).withdrawEther(receiver, amount); + } + + function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) + external + virtual + override + onlyOwner + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address basket = _baskets[uuid]; + _withdrawERC20(receiver, tokenAddress, amount); + return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) + external + virtual + override + onlyOwner + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address basket = _baskets[uuid]; + _withdrawERC721(receiver, nftTokenAddress, nftTokenId); + return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId); + } + + function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount) + external + virtual + override + onlyOwner + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address basket = _baskets[uuid]; + _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount); + return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount); + } + + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) { + return uint256(keccak256(abi.encodePacked(contractAddress, tokenId))); + } + + function _createBasket() + internal + returns (address) + { + address newBasket = _createClone(_basketTemplate); + GenericSmartBasket(newBasket).initialize(); + return newBasket; + } + + /** + * @dev Creates Contracts from a Template via Cloning + * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md + */ + function _createClone(address target) internal returns (address result) { + bytes20 targetBytes = bytes20(target); + assembly { + let clone := mload(0x40) + mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) + mstore(add(clone, 0x14), targetBytes) + mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) + result := create(0, clone, 0x37) + } + } + + + /***********************************| + | Modifiers | + |__________________________________*/ + + /// @dev Throws if called by any account other than the Controller contract + modifier onlyController() { + require(_controller == msg.sender, "GBM:E-108"); + _; + } + + // Throws if called by any account other than the Charged Particles Escrow Controller. + modifier whenNotPaused() { + require(_paused != true, "GBM:E-101"); + _; + } + +} diff --git a/contracts/v1/yield/generic/ERC721/GenericBasketManagerB.sol b/contracts/v1/yield/generic/ERC721/GenericBasketManagerB.sol new file mode 100644 index 0000000..c9d5acc --- /dev/null +++ b/contracts/v1/yield/generic/ERC721/GenericBasketManagerB.sol @@ -0,0 +1,359 @@ +// SPDX-License-Identifier: MIT + +// GenericBasketManager.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts/utils/Counters.sol"; +import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; +import "../../../interfaces/IBasketManager.sol"; +import "../../../interfaces/ISmartBasket.sol"; +import "../../../interfaces/ITokenInfoProxy.sol"; +import "../../../lib/BlackholePrevention.sol"; +import "../../../lib/TokenInfo.sol"; +import "../../../lib/NftTokenType.sol"; +import "./GenericSmartBasketB.sol"; + +/** + * @notice Generic ERC721 Basket Manager + * @dev Non-upgradeable Contract + */ +contract GenericBasketManagerB is Ownable, BlackholePrevention, IBasketManager { + using Counters for Counters.Counter; + using TokenInfo for address; + using NftTokenType for address; + + ITokenInfoProxy internal _tokenInfoProxy; + + // The Controller Contract Address + address internal _controller; + + // The Executor Contract Address + address internal _executor; + + // Template Contract for creating Token Smart-Baskets + address internal _basketTemplate; + + // TokenID => Token Smart-Basket Address + mapping (uint256 => address) internal _baskets; + + // Prepared Amount + uint256 internal _preparedAmount; + + // State of Basket Manager + bool internal _paused; + + /***********************************| + | Initialization | + |__________________________________*/ + + constructor () public { + _basketTemplate = address(new GenericSmartBasketB()); + } + + /***********************************| + | Public | + |__________________________________*/ + + function isPaused() external view override returns (bool) { + return _paused; + } + + function getTokenTotalCount( + address contractAddress, + uint256 tokenId + ) + external + view + override + returns (uint256) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address basket = _baskets[uuid]; + if (basket == address(0)) { return 0; } + return GenericSmartBasketB(basket).getNestedNftCount(); + } + + function getTokenCountByType( + address contractAddress, + uint256 tokenId, + address basketTokenAddress, + uint256 basketTokenId + ) + external + override + returns (uint256) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address basket = _baskets[uuid]; + if (basket == address(0)) { return 0; } + return GenericSmartBasketB(basket).getTokenCountByType(basketTokenAddress, basketTokenId); + } + + function prepareTransferAmount(uint256 nftTokenAmount) external override onlyController { + _preparedAmount = nftTokenAmount; + } + + function addToBasket( + address contractAddress, + uint256 tokenId, + address basketTokenAddress, + uint256 basketTokenId + ) + public + override + onlyController + whenNotPaused + returns (bool added) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address basket = _baskets[uuid]; + require(basket != address(0x0), "GBM:E-403"); + + uint256 nftTokenAmount = 1; + if (_preparedAmount > 0) { + nftTokenAmount = _preparedAmount; + _preparedAmount = 0; + } + + added = GenericSmartBasketB(basket).addToBasket(basketTokenAddress, basketTokenId, nftTokenAmount); + if (added) { + emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount); + } + } + + + function removeFromBasket( + address receiver, + address contractAddress, + uint256 tokenId, + address basketTokenAddress, + uint256 basketTokenId + ) + public + override + onlyController + returns (bool removed) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address basket = _baskets[uuid]; + require(basket != address(0x0), "GBM:E-403"); + + uint256 nftTokenAmount = 1; + if (_preparedAmount > 0) { + nftTokenAmount = _preparedAmount; + _preparedAmount = 0; + } + + removed = GenericSmartBasketB(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId, nftTokenAmount); + if (removed) { + emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount); + } + } + + function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) + external + override + onlyControllerOrExecutor + returns (uint256 amount) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address basket = _baskets[uuid]; + require(basket != address(0x0), "GWM:E-403"); + + // Withdraw Rewards to Receiver + amount = GenericSmartBasketB(basket).withdrawRewards(receiver, rewardsToken, rewardsAmount); + + // Log Event + emit BasketRewarded(contractAddress, tokenId, receiver, rewardsToken, amount); + } + + + function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) + public + override + onlyControllerOrExecutor + returns (bytes memory) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address basket = _baskets[uuid]; + require(basket != address(0x0), "GBM:E-403"); + return GenericSmartBasketB(basket).executeForAccount(externalAddress, ethValue, encodedParams); + } + + function getBasketAddressById(address contractAddress, uint256 tokenId) + public + override + onlyControllerOrExecutor + returns (address) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address basket = _baskets[uuid]; + + // Create Smart-Basket if none exists + if (basket == address(0x0)) { + basket = _createBasket(); + _baskets[uuid] = basket; + + emit NewSmartBasket(contractAddress, tokenId, basket); + } + + return basket; + } + + /***********************************| + | Only Admin/DAO | + |__________________________________*/ + + /** + * @dev Sets the Paused-state of the Basket Manager + */ + function setPausedState(bool paused) external onlyOwner { + _paused = paused; + emit PausedStateSet(paused); + } + + /** + * @dev Connects to the Charged Particles Controller + */ + function setController(address controller) external onlyOwner { + _controller = controller; + emit ControllerSet(controller); + } + + /** + * @dev Connects to the ExecForAccount Controller + */ + function setExecutor(address executor) external onlyOwner { + _executor = executor; + emit ExecutorSet(executor); + } + + /** + * @dev Connects to the Charged Particles Controller + */ + function setTokenInfoProxy(address tokenInfoProxy) external onlyOwner { + _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy); + } + + function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) + external + virtual + override + onlyOwner + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address basket = _baskets[uuid]; + _withdrawEther(receiver, amount); + return ISmartBasket(basket).withdrawEther(receiver, amount); + } + + function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) + external + virtual + override + onlyOwner + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address basket = _baskets[uuid]; + _withdrawERC20(receiver, tokenAddress, amount); + return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) + external + virtual + override + onlyOwner + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address basket = _baskets[uuid]; + _withdrawERC721(receiver, nftTokenAddress, nftTokenId); + return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId); + } + + function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount) + external + virtual + override + onlyOwner + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + address basket = _baskets[uuid]; + _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount); + return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount); + } + + + /***********************************| + | Private Functions | + |__________________________________*/ + + function _createBasket() + internal + returns (address) + { + address newBasket = _createClone(_basketTemplate); + GenericSmartBasketB(newBasket).initialize(_tokenInfoProxy); + return newBasket; + } + + /** + * @dev Creates Contracts from a Template via Cloning + * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md + */ + function _createClone(address target) internal returns (address result) { + bytes20 targetBytes = bytes20(target); + assembly { + let clone := mload(0x40) + mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) + mstore(add(clone, 0x14), targetBytes) + mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) + result := create(0, clone, 0x37) + } + } + + + /***********************************| + | Modifiers | + |__________________________________*/ + + /// @dev Throws if called by any account other than the Controller contract + modifier onlyController() { + require(_controller == msg.sender, "GBM:E-108"); + _; + } + + /// @dev Throws if called by any account other than the Controller or Executor contract + modifier onlyControllerOrExecutor() { + require(_executor == msg.sender || _controller == msg.sender, "WMB:E-108"); + _; + } + + // Throws if called by any account other than the Charged Particles Escrow Controller. + modifier whenNotPaused() { + require(_paused != true, "GBM:E-101"); + _; + } + +} diff --git a/contracts/v1/yield/generic/ERC721/GenericSmartBasket.sol b/contracts/v1/yield/generic/ERC721/GenericSmartBasket.sol new file mode 100644 index 0000000..bff3be1 --- /dev/null +++ b/contracts/v1/yield/generic/ERC721/GenericSmartBasket.sol @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: MIT + +// GenericSmartWallet.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; +import "@openzeppelin/contracts/utils/EnumerableSet.sol"; +import "../../../interfaces/ISmartBasket.sol"; +import "../../../lib/BlackholePrevention.sol"; +import "../../../lib/NftTokenType.sol"; + + +/** + * @notice Generic ERC721-Token Smart-Basket + * @dev Non-upgradeable Contract + */ +contract GenericSmartBasket is ISmartBasket, BlackholePrevention, IERC721Receiver { + using EnumerableSet for EnumerableSet.UintSet; + using EnumerableSet for EnumerableSet.AddressSet; + using NftTokenType for address; + + address internal _basketManager; + + // NFT contract address => Token Ids in Basket + mapping (address => mapping(uint256 => EnumerableSet.UintSet)) internal _nftContractTokens; + + + /***********************************| + | Initialization | + |__________________________________*/ + + function initialize() public { + require(_basketManager == address(0x0), "GSB:E-002"); + _basketManager = msg.sender; + } + + + /***********************************| + | Public | + |__________________________________*/ + + function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) { + uint256 nftType = contractAddress.getTokenType(tokenId); + return _nftContractTokens[contractAddress][nftType].length(); + } + + function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) { + return IERC721Receiver(0).onERC721Received.selector; + } + + function addToBasket(address contractAddress, uint256 tokenId) + external + override + onlyBasketManager + returns (bool) + { + uint256 nftType = contractAddress.getTokenType(tokenId); + require(!_nftContractTokens[contractAddress][nftType].contains(tokenId), "GSB:E-425"); + + bool added = _nftContractTokens[contractAddress][nftType].add(tokenId); + if (added) { + // NFT should have been Transferred into here via Charged-Particles + added = (IERC721(contractAddress).ownerOf(tokenId) == address(this)); + } + return added; + } + + function removeFromBasket(address receiver, address contractAddress, uint256 tokenId) + external + override + onlyBasketManager + returns (bool) + { + uint256 nftType = contractAddress.getTokenType(tokenId); + require(_nftContractTokens[contractAddress][nftType].contains(tokenId), "GSB:E-426"); + + bool removed = _nftContractTokens[contractAddress][nftType].remove(tokenId); + if (removed) { + IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId); + } + return removed; + } + + function executeForAccount( + address contractAddress, + uint256 ethValue, + bytes memory encodedParams + ) + external + override + onlyBasketManager + returns (bytes memory) + { + (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams); + require(success, string(result)); + return result; + } + + + /***********************************| + | Only Admin/DAO | + | (blackhole prevention) | + |__________________________________*/ + + function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager { + _withdrawEther(receiver, amount); + } + + function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager { + _withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager { + _withdrawERC1155(receiver, tokenAddress, tokenId, amount); + } + + + /***********************************| + | Private Functions | + |__________________________________*/ + + /// @dev Throws if called by any account other than the basket manager + modifier onlyBasketManager() { + require(_basketManager == msg.sender, "GSB:E-109"); + _; + } +} diff --git a/contracts/v1/yield/generic/ERC721/GenericSmartBasketB.sol b/contracts/v1/yield/generic/ERC721/GenericSmartBasketB.sol new file mode 100644 index 0000000..e60f180 --- /dev/null +++ b/contracts/v1/yield/generic/ERC721/GenericSmartBasketB.sol @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: MIT + +// GenericSmartWallet.sol -- Part of the Charged Particles Protocol +// Copyright (c) 2021 Firma Lux, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; +import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; +import "@openzeppelin/contracts/token/ERC1155/ERC1155Receiver.sol"; +import "../../../interfaces/ISmartBasketB.sol"; +import "../../../interfaces/ITokenInfoProxy.sol"; +import "../../../lib/TokenInfo.sol"; +import "../../../lib/NftTokenType.sol"; +import "../../../lib/BlackholePrevention.sol"; + +/** + * @notice Generic ERC721-Token Smart-Basket + * @dev Non-upgradeable Contract + */ +contract GenericSmartBasketB is ISmartBasketB, BlackholePrevention, IERC721Receiver, ERC1155Receiver { + using TokenInfo for address; + using NftTokenType for address; + + address internal _basketManager; + + // NFT TokenUUID => ERC1155 Balance + mapping (uint256 => uint256) internal _nftContractTokenBalance; + uint256 internal _nestedNftCount; + + + /***********************************| + | Initialization | + |__________________________________*/ + + function initialize(ITokenInfoProxy /* tokenInfoProxy */) public { + require(_basketManager == address(0x0), "GSB:E-002"); + _basketManager = msg.sender; + } + + + /***********************************| + | Public | + |__________________________________*/ + + function getNestedNftCount() external view override returns (uint256) { + return _nestedNftCount; + } + + function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) { + return _nftContractTokenBalance[contractAddress.getTokenUUID(tokenId)]; + } + + function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) { + return IERC721Receiver(0).onERC721Received.selector; + } + + function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) { + return IERC1155Receiver(0).onERC1155Received.selector; + } + + // Unimplemented + function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) { + return ""; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector; + } + + function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount) + external + override + onlyBasketManager + returns (bool) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + _nftContractTokenBalance[uuid] += nftTokenAmount; + _nestedNftCount += nftTokenAmount; + return true; + } + + function removeFromBasket( + address receiver, + address contractAddress, + uint256 tokenId, + uint256 nftTokenAmount + ) + external + override + onlyBasketManager + returns (bool) + { + uint256 uuid = contractAddress.getTokenUUID(tokenId); + _nftContractTokenBalance[uuid] -= nftTokenAmount; + _nestedNftCount -= nftTokenAmount; + + if (contractAddress.isERC1155()) { + IERC1155(contractAddress).safeTransferFrom(address(this), receiver, tokenId, nftTokenAmount, ""); + } else { + IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId); + } + return true; + } + + function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount) + external + override + onlyBasketManager + returns (uint256) + { + address self = address(this); + IERC20 rewardsToken = IERC20(rewardsTokenAddress); + + uint256 walletBalance = rewardsToken.balanceOf(self); + require(walletBalance >= rewardsAmount, "GSB:E-411"); + + // Transfer Rewards to Receiver + rewardsToken.safeTransfer(receiver, rewardsAmount); + return rewardsAmount; + } + + function executeForAccount( + address contractAddress, + uint256 ethValue, + bytes memory encodedParams + ) + external + override + onlyBasketManager + returns (bytes memory) + { + (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams); + require(success, string(result)); + return result; + } + + + /***********************************| + | Only Admin/DAO | + | (blackhole prevention) | + |__________________________________*/ + + function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager { + _withdrawEther(receiver, amount); + } + + function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager { + _withdrawERC20(receiver, tokenAddress, amount); + } + + function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager { + _withdrawERC721(receiver, tokenAddress, tokenId); + } + + function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager { + _withdrawERC1155(receiver, tokenAddress, tokenId, amount); + } + + + /***********************************| + | Private Functions | + |__________________________________*/ + + /// @dev Throws if called by any account other than the basket manager + modifier onlyBasketManager() { + require(_basketManager == msg.sender, "GSB:E-109"); + _; + } +} diff --git a/deploy/ChargedParticles.ts b/deploy/ChargedParticles.ts deleted file mode 100644 index 29da014..0000000 --- a/deploy/ChargedParticles.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {HardhatRuntimeEnvironment} from 'hardhat/types'; -import {DeployFunction} from 'hardhat-deploy/types'; - -const DeployChargedParticlesAccount: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - const {deployments, getNamedAccounts} = hre; - const {deploy} = deployments; - - const { deployer } = await getNamedAccounts(); - - await deploy('ChargedParticlesAccount', { - from: deployer, - args: [], - log: true, - }); -}; -export default DeployChargedParticlesAccount; - -DeployChargedParticlesAccount.tags = ['ChargedParticlesAccount']; \ No newline at end of file diff --git a/deploy/Ionx.ts b/deploy/Ionx.ts new file mode 100644 index 0000000..72c5116 --- /dev/null +++ b/deploy/Ionx.ts @@ -0,0 +1,32 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { Ionx } from '../typechain-types'; +import { addressBook } from '../utils/globals'; +import { parseEther } from 'ethers'; + +const Ionx: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { deployments, getNamedAccounts, ethers, network } = hre; + const { deploy } = deployments; + const { deployer } = await getNamedAccounts(); + + console.log(deployer) + const chainId = network.config.chainId ?? 1; + + // Check for Previously Deployed Version + await deploy('Ionx', { + from: deployer, + args: [], + log: true, + skipIfAlreadyDeployed: true + }); + console.log(` - IONX Deployed...`); + + console.log(` - Setting Minter and Minting 100,000,000 to deployer...`); + const ionx: Ionx = await ethers.getContract('Ionx', deployer); + // await ionx.transfer('0xEdbbdB06eAAeb5Ba283a819eB8bBbe956c3cfeBb', parseEther('1000')).then(tx => tx.wait()); + await ionx.setMinter(deployer).then(tx => tx.wait()); + await ionx.mint(deployer, ethers.parseEther('10000000000')).then(tx => tx.wait()); +}; +export default Ionx; + +Ionx.tags = ['Ionx']; \ No newline at end of file diff --git a/deploy/Lepton2.ts b/deploy/Lepton2.ts new file mode 100644 index 0000000..666d515 --- /dev/null +++ b/deploy/Lepton2.ts @@ -0,0 +1,115 @@ +import { ethers, network } from 'hardhat'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { parseEther as toWei } from 'ethers'; +import { Lepton2 } from '../typechain-types'; +import { isTestnet } from '../utils/isTestnet'; +import { addressBook } from '../utils/globals'; +import { isHardhat } from '../utils/isHardhat'; + +export interface LeptonType { + tokenUri: string; + price: { [key: string]: bigint }; + supply: { [key: string]: bigint }; + multiplier: bigint; + bonus: bigint; +} + +export const leptonConfig = { + maxMintPerTx: 25n, + types: [ + { + name : 'Electron Neutrino', + tokenUri : 'https://gateway.pinata.cloud/ipfs/QmcWuHx4MgywyEMzsqT9J3boJu1gk7GdtAMQ1pyQYRR3XS', + price : {live: toWei('0.3'), test: toWei('0.000000003')}, + supply : {live: 721n, test: 40n}, + multiplier : 110n, // 1.1% + bonus : 0n, + }, + { + name : 'Muon Neutrino', + tokenUri : 'https://gateway.pinata.cloud/ipfs/QmccGhGhvi37QScB4u2VmuVwENtEsMpx6hAKUqu3x3nU9V', + price : {live: toWei('0.9'), test: toWei('0.000000009')}, + supply : {live: 401n, test: 20n}, + multiplier : 130n, // 1.3% + bonus : 1n, + }, + { + name : 'Tau Neutrino', + tokenUri : 'https://gateway.pinata.cloud/ipfs/Qma2ZPnCM95AYZ1wPxZdDVvRiS114Svrw2J632ZpLiX7JV', + price : {live: toWei('0.1'), test: toWei('0.000000017')}, + supply : {live: 301n, test: 12n}, + multiplier : 150n, // 1.5% + bonus : 2n, + }, + { + name : 'Electron', + tokenUri : 'https://gateway.pinata.cloud/ipfs/QmNRKJsUwqEE9zYK6sEND8HDGa4cHFkkC2ntjQA5bFL6jJ', + price : {live: toWei('0.5'), test: toWei('0.00000029')}, + supply : {live: 201n, test: 8n}, + multiplier : 180n, // 1.8% + bonus : 4n, + }, + { + name : 'Muon', + tokenUri : 'https://gateway.pinata.cloud/ipfs/QmWiH5F9yPp7yRzcqocmQKuhrA3KVY9fGJZxD9UKBDu5wr', + price : {live: toWei('0.7'), test: toWei('0.00000051')}, + supply : {live: 88n, test: 5n}, + multiplier : 230n, // 2.3% + bonus : 8n, + }, + { + name : 'Tau', + tokenUri : 'https://gateway.pinata.cloud/ipfs/QmUkCXgyguBSxnGRtfBAvofAkyhFbRCwS7HPaoytAZvemt', + price : {live: toWei('1'), test: toWei('0.0000021')}, + supply : {live: 21n, test: 2n}, + multiplier : 510n, // 5.1% + bonus : 16n, + }, + ] +} + +const Lepton2: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { deployments, getNamedAccounts, network } = hre; + const { deploy } = deployments; + const { deployer } = await getNamedAccounts(); + const chainId = network.config.chainId ?? 1; + + // Check for Previously Deployed Version + const leptonAddress = addressBook[chainId].lepton; + if (leptonAddress.length) { + await deploy('Lepton2', { + from: deployer, + args: [], + log: true, + }); + console.log(` - Lepton2 Deployed...`); + + console.log(` - Setting Max-Mint-Per-Transaction...`); + const lepton2: Lepton2 = await ethers.getContract('Lepton2'); + await lepton2.setMaxMintPerTx(leptonConfig.maxMintPerTx).then(tx => tx.wait()); + + // mint + const chainType = isHardhat() ? 'test' : 'live'; + for (const leptonKey in leptonConfig.types) { + const lepton: LeptonType = leptonConfig.types[leptonKey]; + + console.log(` - Adding Lepton Tier ${leptonKey}...`); + await lepton2.addLeptonType( + lepton.tokenUri, + lepton.price[chainType], + lepton.supply[chainType], + lepton.multiplier, + lepton.bonus, + ) + } + + console.log(` - Unpausing Lepton Contract...`); + await lepton2.setPausedState(false).then(tx => tx.wait()); + } else { + console.log(` - Using Lepton2 Deployed at ${leptonAddress}`); + } +}; +export default Lepton2; + +Lepton2.tags = ['Lepton2']; \ No newline at end of file diff --git a/deploy/LeptonsStore.ts b/deploy/LeptonsStore.ts new file mode 100644 index 0000000..d282e29 --- /dev/null +++ b/deploy/LeptonsStore.ts @@ -0,0 +1,48 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { verifyContract } from '../utils/verifyContract'; +import { isTestnet } from '../utils/isTestnet'; +import { isHardhat } from '../utils/isHardhat'; +import { Ionx, Lepton2 } from '../typechain-types'; + +const LeptonStore: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { ethers, deployments, getNamedAccounts } = hre; + const { deploy } = deployments; + const { deployer } = await getNamedAccounts(); + + let lepton: Lepton2; + let ionx: Ionx; + + if (isTestnet() || isHardhat()) { + lepton = await ethers.getContract('Lepton2'); + ionx = await ethers.getContract('Ionx'); + } else { + lepton = await ethers.getContractAt('Lepton2', '0x3Cd2410EAa9c2dCE50aF6CCAb72Dc93879a09c1F'); + ionx = await ethers.getContractAt('Ionx', '0x02D3A27Ac3f55d5D91Fb0f52759842696a864217'); + } + + const leptonAddress = await lepton.getAddress(); + const ionxAddress = await ionx.getAddress(); + const leptonPrice = (isTestnet() || isHardhat()) ? 1 : ethers.parseEther('15000'); // in IONX + + console.log(`Deployer = "${deployer}"`); + console.log('Deploying LeptonsStore with:'); + console.log(`Lepton Address: "${leptonAddress}"`); + console.log(`IONX Address: "${ionxAddress}"`); + console.log(`Lepton Price: "${leptonPrice}"`); + + await deploy('LeptonsStore', { + from: deployer, + args: [ leptonAddress, ionxAddress, leptonPrice ], + log: true, + }); + + console.log(` - Leptons Store Deployed...`); + + if (!isTestnet() && !isHardhat()) { + await verifyContract('LeptonsStore', await ethers.getContract('LeptonsStore'), [ leptonAddress, ionxAddress, leptonPrice ]); + } +}; +export default LeptonStore; + +LeptonStore.tags = ['LeptonsStore']; \ No newline at end of file diff --git a/deploy/MinimalisticAccount.ts b/deploy/MinimalisticAccount.ts deleted file mode 100644 index d1f0c8c..0000000 --- a/deploy/MinimalisticAccount.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {HardhatRuntimeEnvironment} from 'hardhat/types'; -import {DeployFunction} from 'hardhat-deploy/types'; - -const MinimalisticAccountDeploy: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - const {deployments, getNamedAccounts} = hre; - const {deploy} = deployments; - - const { deployer } = await getNamedAccounts(); - - await deploy('MinimalisticAccount', { - from: deployer, - args: [], - log: true, - }); -}; -export default MinimalisticAccountDeploy; - -MinimalisticAccountDeploy.tags = ['MinimalisticAccount']; \ No newline at end of file diff --git a/deploy/NFTMock.ts b/deploy/NFTMock.ts deleted file mode 100644 index 1a26610..0000000 --- a/deploy/NFTMock.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {HardhatRuntimeEnvironment} from 'hardhat/types'; -import {DeployFunction} from 'hardhat-deploy/types'; - -const NFTMockMock: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - const {deployments, getNamedAccounts} = hre; - const {deploy} = deployments; - - const { deployer } = await getNamedAccounts(); - - await deploy('NFTMock', { - from: deployer, - args: ['Game of NTF', 'GONFT'], - log: true, - }); -}; -export default NFTMockMock; - -NFTMockMock.tags = ['NFTMock']; \ No newline at end of file diff --git a/deploy/RewardProgramDeploy.ts b/deploy/RewardProgramDeploy.ts new file mode 100644 index 0000000..fa7580b --- /dev/null +++ b/deploy/RewardProgramDeploy.ts @@ -0,0 +1,65 @@ +import { Ionx, RewardProgram, UniverseRP } from '../typechain-types'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { ethers, getNamedAccounts } from 'hardhat'; +import { isTestnet } from '../utils/isTestnet'; +import { isHardhat } from '../utils/isHardhat'; +import { addressBook } from '../utils/globals'; +import { verifyContract } from '../utils/verifyContract'; +import { getChargedParticlesOwner } from '../utils/getSigners'; +import { parseEther } from 'ethers'; + +const RewardProgramDeploy: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { network } = hre; + const chainId = network.config.chainId ?? 1; + + // Load IONX + let ionx: Ionx; + if (!isHardhat() && addressBook[chainId].ionx.length > 0) { + const { deployer } = await getNamedAccounts(); + ionx = await ethers.getContractAt('Ionx', addressBook[chainId].ionx, await ethers.getSigner(deployer)); + // fund signer + const ionxOwner = await ionx.owner(); + await ionx.connect(await ethers.getSigner(ionxOwner)).transfer(deployer, parseEther('100')).then(tx => tx.wait()); + + } else { + const { deployer } = await getNamedAccounts(); + ionx = await ethers.getContract('Ionx', await ethers.getSigner(deployer)); + // ionx = await ethers.getContractAt('Ionx', addressBook[chainId].ionx, await ethers.getSigner(deployer)); + // fund signer + const ionxOwner = await ionx.owner(); + await ionx.connect(await ethers.getSigner(ionxOwner)).transfer(deployer, parseEther('100000')).then(tx => tx.wait()); + ionx = await ethers.getContract('Ionx', await ethers.getSigner(deployer)); + } + + // const ionxAddress = await ionx.getAddress(); + const universe: UniverseRP = await ethers.getContract('UniverseRP'); + + // Register & Fund Reward Programs for each Staking Token + for (let i = 0; i < addressBook[chainId].stakingTokens.length; i++) { + const stakingToken = addressBook[chainId].stakingTokens[i]; + const rewardProgram: RewardProgram = await ethers.getContract(`RewardProgram${stakingToken.id}`); + const rewardProgramAddress = await rewardProgram.getAddress(); + + // verify reward program + if (!isTestnet() && !isHardhat()) { + await verifyContract(`RewardProgram${stakingToken.id}`, rewardProgram); + } + + // fund reward program + const { deployer } = await getNamedAccounts(); + await ionx.connect(await ethers.getSigner(deployer)).approve(rewardProgramAddress, ethers.parseEther(stakingToken.funding)).then(tx => tx.wait()); + await rewardProgram.connect(await ethers.getSigner(deployer)).fundProgram(1).then(tx => tx.wait()); + + // register reward program in universe + console.log(` -- Registering RewardProgram in the Universe...`); + await universe.setRewardProgram(rewardProgramAddress, stakingToken.address); + + console.log(` -- RewardProgram for ${stakingToken.id} is registered!`); + } +}; + +export default RewardProgramDeploy; + +RewardProgramDeploy.dependencies = ['RewardPrograms']; +RewardProgramDeploy.tags = ['RPDeploy']; diff --git a/deploy/RewardProgramFactory.ts b/deploy/RewardProgramFactory.ts new file mode 100644 index 0000000..ce2d514 --- /dev/null +++ b/deploy/RewardProgramFactory.ts @@ -0,0 +1,26 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { RewardProgramFactory } from '../typechain-types'; +import { verifyContract } from '../utils/verifyContract'; +import { isTestnet } from '../utils/isTestnet'; +import { isHardhat } from '../utils/isHardhat'; + +const RewardProgramFactory: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { ethers, deployments, getNamedAccounts } = hre; + const { deploy } = deployments; + const { deployer } = await getNamedAccounts(); + + await deploy('RewardProgramFactory', { + from: deployer, + args: [], + log: true, + }); + console.log(` - RewardProgramFactory Deployed...`); + + if (!isTestnet() && !isHardhat()) { + await verifyContract('RewardProgramFactory', await ethers.getContract('RewardProgramFactory')); + } +}; +export default RewardProgramFactory; + +RewardProgramFactory.tags = ['RewardProgramFactory']; \ No newline at end of file diff --git a/deploy/RewardProgramSetupMainnet.ts b/deploy/RewardProgramSetupMainnet.ts new file mode 100644 index 0000000..7ca1137 --- /dev/null +++ b/deploy/RewardProgramSetupMainnet.ts @@ -0,0 +1,34 @@ +import { ChargedParticles, Lepton2, UniverseRP } from '../typechain-types'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { ethers } from 'hardhat'; + +import { addressBook } from '../utils/globals'; + +const RewardProgramSetupMainnet: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { network, getNamedAccounts } = hre; + const { deployer } = await getNamedAccounts(); + const deployerSigner = await ethers.getSigner(deployer); + const chainId = network.config.chainId ?? 1; + + const chargedParticles: ChargedParticles = await ethers.getContractAt('ChargedParticles', addressBook[chainId].chargedParticles); + const lepton: Lepton2 = await ethers.getContractAt('Lepton2', addressBook[chainId].lepton); + const universe: UniverseRP = await ethers.getContract('UniverseRP'); + + const leptonAddress = await lepton.getAddress(); + const universeAddress = await universe.getAddress(); + + // setup universe + console.log(`Preparing UniverseRP...`); + await universe.setChargedParticles(addressBook[chainId].chargedParticles); + await universe.setMultiplierNft(leptonAddress).then(tx => tx.wait()); + + // finally: setup charged particles + console.log(`Registering UniverseRP in Charged Particles...`); + await chargedParticles.connect(deployerSigner).setController(universeAddress, 'universe'); +}; + +export default RewardProgramSetupMainnet; + +RewardProgramSetupMainnet.dependencies = ['RewardPrograms']; +RewardProgramSetupMainnet.tags = ['RPSetupMain']; diff --git a/deploy/RewardProgramSetupPolygon.ts b/deploy/RewardProgramSetupPolygon.ts new file mode 100644 index 0000000..933e88f --- /dev/null +++ b/deploy/RewardProgramSetupPolygon.ts @@ -0,0 +1,55 @@ +import { ChargedParticles, Lepton2, RewardProgram, UniverseRP } from '../typechain-types'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { ethers } from 'hardhat'; + +import { addressBook } from '../utils/globals'; + +const RewardProgramSetupPolygon: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { network, getNamedAccounts } = hre; + const { deployer } = await getNamedAccounts(); + const deployerSigner = await ethers.getSigner(deployer); + const chainId = network.config.chainId ?? 1; + + if (chainId !== 137 && chainId !== 80001) { + console.log(` - Wrong Network - Polygon Only`); + return; + } + + const chargedParticles: ChargedParticles = await ethers.getContractAt('ChargedParticles', addressBook[chainId].chargedParticles); + const lepton: Lepton2 = await ethers.getContractAt('Lepton2', addressBook[chainId].lepton); + const universe: UniverseRP = await ethers.getContract('UniverseRPPolygon'); + + const leptonAddress = await lepton.getAddress(); + const universeAddress = await universe.getAddress(); + + // setup universe + console.log(`Preparing UniverseRPPolygon...`); + await universe.setChargedParticles(addressBook[chainId].chargedParticles); + await universe.setMultiplierNft(leptonAddress).then(tx => tx.wait()); + + // finally: setup charged particles + console.log(`Registering UniverseRPPolygon in Charged Particles...`); + await chargedParticles.connect(deployerSigner).setController(universeAddress, 'universe'); + + // Set reward program in Universe + for (let i = 0; i < addressBook[chainId].stakingTokens.length; i++) { + const stakingToken = addressBook[chainId].stakingTokens[i]; + const rewardProgram: RewardProgram = await ethers.getContract(`RewardProgram${stakingToken.id}`); + const rewardProgramAddress = await rewardProgram.getAddress(); + + // register reward program in universe + console.log(` -- Registering RewardProgram in the Universe...`); + await universe.setRewardProgram(rewardProgramAddress, stakingToken.address); + + console.log(` -- RewardProgram for ${stakingToken.id} is registered!`); + + await rewardProgram.setUniverse(universeAddress).then(tx => tx.wait()); + } +}; + + +export default RewardProgramSetupPolygon; + +RewardProgramSetupPolygon.dependencies = ['UniverseRPPolygon']; +RewardProgramSetupPolygon.tags = ['RPSetupPolygon']; diff --git a/deploy/RewardProgramSetupTestnet.ts b/deploy/RewardProgramSetupTestnet.ts new file mode 100644 index 0000000..ba1b4d8 --- /dev/null +++ b/deploy/RewardProgramSetupTestnet.ts @@ -0,0 +1,55 @@ +import { ChargedParticles, Lepton2, UniverseRP } from '../typechain-types'; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { ethers, network } from 'hardhat'; + +import { isHardhat } from '../utils/isHardhat'; +import { addressBook } from '../utils/globals'; +import { getChargedParticlesOwner } from '../utils/getSigners'; +import { Signer } from 'ethers'; + + +const RewardProgramSetupTestnet: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { getNamedAccounts } = hre; + const { deployer } = await getNamedAccounts(); + const deployerSigner = await ethers.getSigner(deployer); + const chainId = network.config.chainId ?? 80001; + const _isHardhat = isHardhat(); + + const chargedParticles: ChargedParticles = await ethers.getContractAt('ChargedParticles', addressBook[chainId].chargedParticles); + const universe: UniverseRP = await ethers.getContract('UniverseRP'); + + // Load Lepton2 + let lepton: Lepton2; + if (!_isHardhat && addressBook[chainId].lepton.length > 0) { + lepton = await ethers.getContractAt('Lepton2', addressBook[chainId].lepton); + } else { + lepton = await ethers.getContract('Lepton2'); + } + + const leptonAddress = await lepton.getAddress(); + const universeAddress = await universe.getAddress(); + const chargedParticlesOwner = await chargedParticles.owner(); + + let chargedParticlesOwnerSigner: Signer; + if (_isHardhat) { + chargedParticlesOwnerSigner = await getChargedParticlesOwner(); + await deployerSigner.sendTransaction({ to: chargedParticlesOwner, value: ethers.parseEther('1') }); + } else { + chargedParticlesOwnerSigner = deployerSigner; + } + + // setup universe + console.log(` - Preparing UniverseRP...`); + await universe.setChargedParticles(addressBook[chainId].chargedParticles); + await universe.setMultiplierNft(leptonAddress).then(tx => tx.wait()); + + // setup charged particles + console.log(` - Registering UniverseRP in Charged Particles...`); + await chargedParticles.connect(chargedParticlesOwnerSigner).setController(universeAddress, 'universe'); +}; + +export default RewardProgramSetupTestnet; + +RewardProgramSetupTestnet.dependencies = ['Lepton2', 'Ionx', 'RewardPrograms']; +RewardProgramSetupTestnet.tags = ['RPSetupTest']; diff --git a/deploy/RewardPrograms.ts b/deploy/RewardPrograms.ts new file mode 100644 index 0000000..11ce41c --- /dev/null +++ b/deploy/RewardPrograms.ts @@ -0,0 +1,67 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { Ionx, RewardProgramFactory, UniverseRP } from '../typechain-types'; +import { ContractTransactionReceipt, EventLog, Log } from 'ethers'; +import { addressBook } from '../utils/globals'; +import { isTestnet } from '../utils/isTestnet'; +import * as RewardProgramJson from '../build/contracts/contracts/v1/incentives/RewardProgram.sol/RewardProgram.json'; +import { isHardhat } from '../utils/isHardhat'; + +const RewardPrograms: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { network, deployments, ethers } = hre; + const chainId = network.config.chainId ?? 1; + + // Load Universe + const universe: UniverseRP = await ethers.getContract('UniverseRP'); + const universeAddress = await universe.getAddress(); + + // Load RewardProgramFactory + const rewardProgramFactory: RewardProgramFactory = await ethers.getContract('RewardProgramFactory'); + + // Load IONX + let ionx: Ionx; + if (!isHardhat() && addressBook[chainId].ionx.length > 0) { + ionx = await ethers.getContractAt('Ionx', addressBook[chainId].ionx); + } else { + ionx = await ethers.getContract('Ionx'); + } + const ionxAddress = await ionx.getAddress(); + + // Deploy Reward Programs for each Staking Token + for (let i = 0; i < addressBook[chainId].stakingTokens.length; i++) { + const stakingToken = addressBook[chainId].stakingTokens[i]; + + console.log(` - Deploying RewardProgram for ${stakingToken.id}...`); + const tx = await rewardProgramFactory.createRewardProgram( + stakingToken.address, + ionxAddress, + stakingToken.multiplier, + addressBook[chainId].chargedManager, + universeAddress, + ); + + // Get reward program address + let rewardProgramAddress: string; + const rc: ContractTransactionReceipt | null = await tx.wait(); + if (rc !== null) { + const evt: EventLog | Log = rc.logs[0]; + // @ts-ignore + rewardProgramAddress = evt.args[0]; + + // save to deployments + console.log(` -- Saving RewardProgram Deployment at address ${rewardProgramAddress}...`); + await deployments.save(`RewardProgram${stakingToken.id}`, { + abi: RewardProgramJson.abi, + address: rewardProgramAddress, + transactionHash: tx.hash, + }); + + console.log(` -- RewardProgram for ${stakingToken.id} is deployed!`); + } + } + +}; +export default RewardPrograms; + +RewardPrograms.dependencies = ['UniverseRP', 'Ionx', 'RewardProgramFactory']; +RewardPrograms.tags = ['RewardPrograms']; \ No newline at end of file diff --git a/deploy/UniverseRP.ts b/deploy/UniverseRP.ts new file mode 100644 index 0000000..4128e3e --- /dev/null +++ b/deploy/UniverseRP.ts @@ -0,0 +1,29 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { verifyContract } from '../utils/verifyContract'; +import { isTestnet } from '../utils/isTestnet'; +import { isHardhat } from '../utils/isHardhat'; + +const UniverseRP: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { ethers, deployments, getNamedAccounts } = hre; + const { deploy } = deployments; + const { deployer } = await getNamedAccounts(); + + await deploy('UniverseRP', { + from: deployer, + args: [], + log: true, + proxy: { + proxyContract: 'OpenZeppelinTransparentProxy', + methodName: 'initialize', + }, + }); + console.log(` - UniverseRP Deployed...`); + + if (!isTestnet() && !isHardhat()) { + await verifyContract('UniverseRP', await ethers.getContract('UniverseRP')); + } +}; +export default UniverseRP; + +UniverseRP.tags = ['UniverseRP']; \ No newline at end of file diff --git a/deploy/UniverseRPPolygon.ts b/deploy/UniverseRPPolygon.ts new file mode 100644 index 0000000..a283e39 --- /dev/null +++ b/deploy/UniverseRPPolygon.ts @@ -0,0 +1,35 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { verifyContract } from '../utils/verifyContract'; +import { isTestnet } from '../utils/isTestnet'; +import { isHardhat } from '../utils/isHardhat'; + +const UniverseRPPolygon: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { network, ethers, deployments, getNamedAccounts } = hre; + const { deploy } = deployments; + const { deployer } = await getNamedAccounts(); + const chainId = network.config.chainId ?? 1; + + if (chainId !== 137 && chainId !== 80001) { + console.log(` - Wrong Network - Polygon Only`); + return; + } + + await deploy('UniverseRPPolygon', { + from: deployer, + args: [], + log: true, + proxy: { + proxyContract: 'OpenZeppelinTransparentProxy', + methodName: 'initialize', + }, + }); + console.log(` - UniverseRP Deployed...`); + + if (!isTestnet() && !isHardhat()) { + await verifyContract('UniverseRPPolygon', await ethers.getContract('UniverseRPPolygon')); + } +}; +export default UniverseRPPolygon; + +UniverseRPPolygon.tags = ['UniverseRPPolygon']; \ No newline at end of file diff --git a/deployments/goerli/.chainId b/deployments/goerli/.chainId new file mode 100644 index 0000000..7813681 --- /dev/null +++ b/deployments/goerli/.chainId @@ -0,0 +1 @@ +5 \ No newline at end of file diff --git a/deployments/goerli/DefaultProxyAdmin.json b/deployments/goerli/DefaultProxyAdmin.json new file mode 100644 index 0000000..d021349 --- /dev/null +++ b/deployments/goerli/DefaultProxyAdmin.json @@ -0,0 +1,259 @@ +{ + "address": "0xd34060fa3eA8AC05abA386ac8Cbb019C4594b204", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "initialOwner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "upgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ], + "transactionHash": "0x708ff5f120c29867896c618f003a14eb3098f6e8d5cc3c65989db354b18b891e", + "receipt": { + "to": null, + "from": "0x6d46b37708dA7Ed4E5C4509495768Fecd3D17C01", + "contractAddress": "0xd34060fa3eA8AC05abA386ac8Cbb019C4594b204", + "transactionIndex": 59, + "gasUsed": "644163", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000100000000000000000000000000000040000000000000000000000000000020000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000000000000040000000400000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xe65d6b513c50b05ae6eaab567eb00472b20a621649d99acd7cc451140bbe26be", + "transactionHash": "0x708ff5f120c29867896c618f003a14eb3098f6e8d5cc3c65989db354b18b891e", + "logs": [ + { + "transactionIndex": 59, + "blockNumber": 9608558, + "transactionHash": "0x708ff5f120c29867896c618f003a14eb3098f6e8d5cc3c65989db354b18b891e", + "address": "0xd34060fa3eA8AC05abA386ac8Cbb019C4594b204", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000006d46b37708da7ed4e5c4509495768fecd3d17c01" + ], + "data": "0x", + "logIndex": 192, + "blockHash": "0xe65d6b513c50b05ae6eaab567eb00472b20a621649d99acd7cc451140bbe26be" + } + ], + "blockNumber": 9608558, + "cumulativeGasUsed": "25893448", + "status": 1, + "byzantium": true + }, + "args": [ + "0x6d46b37708dA7Ed4E5C4509495768Fecd3D17C01" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"initialOwner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\",\"kind\":\"dev\",\"methods\":{\"changeProxyAdmin(address,address)\":{\"details\":\"Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`.\"},\"getProxyAdmin(address)\":{\"details\":\"Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"getProxyImplementation(address)\":{\"details\":\"Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"upgrade(address,address)\":{\"details\":\"Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`.\"},\"upgradeAndCall(address,address,bytes)\":{\"details\":\"Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol\":\"ProxyAdmin\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/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 (address initialOwner) {\\n _transferOwnership(initialOwner);\\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\",\"keccak256\":\"0x9b2bbba5bb04f53f277739c1cdff896ba8b3bf591cfc4eab2098c655e8ac251e\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./TransparentUpgradeableProxy.sol\\\";\\nimport \\\"../../access/Ownable.sol\\\";\\n\\n/**\\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\\n */\\ncontract ProxyAdmin is Ownable {\\n\\n constructor (address initialOwner) Ownable(initialOwner) {}\\n\\n /**\\n * @dev Returns the current implementation of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"implementation()\\\")) == 0x5c60da1b\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"5c60da1b\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Returns the current admin of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"admin()\\\")) == 0xf851a440\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"f851a440\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Changes the admin of `proxy` to `newAdmin`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the current admin of `proxy`.\\n */\\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\\n proxy.changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\\n proxy.upgradeTo(implementation);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgradeAndCall(\\n TransparentUpgradeableProxy proxy,\\n address implementation,\\n bytes memory data\\n ) public payable virtual onlyOwner {\\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\\n }\\n}\\n\",\"keccak256\":\"0x754888b9c9ab5525343460b0a4fa2e2f4fca9b6a7e0e7ddea4154e2b1182a45d\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev 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\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/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\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50604051610b17380380610b1783398101604081905261002f91610090565b8061003981610040565b50506100c0565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156100a257600080fd5b81516001600160a01b03811681146100b957600080fd5b9392505050565b610a48806100cf6000396000f3fe60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461012b57806399a88ec41461013e578063f2fde38b1461015e578063f3b7dead1461017e57600080fd5b8063204e1c7a14610080578063715018a6146100c95780637eff275e146100e05780638da5cb5b14610100575b600080fd5b34801561008c57600080fd5b506100a061009b3660046107e4565b61019e565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d557600080fd5b506100de610255565b005b3480156100ec57600080fd5b506100de6100fb366004610808565b6102e7565b34801561010c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100a0565b6100de610139366004610870565b6103ee565b34801561014a57600080fd5b506100de610159366004610808565b6104fc565b34801561016a57600080fd5b506100de6101793660046107e4565b6105d1565b34801561018a57600080fd5b506100a06101993660046107e4565b610701565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b600060405180830381855afa9150503d8060008114610225576040519150601f19603f3d011682016040523d82523d6000602084013e61022a565b606091505b50915091508161023957600080fd5b8080602001905181019061024d9190610964565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6102e5600061074d565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610368576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b600060405180830381600087803b1580156103d257600080fd5b505af11580156103e6573d6000803e3d6000fd5b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461046f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef2869034906104c59086908690600401610981565b6000604051808303818588803b1580156104de57600080fd5b505af11580156104f2573d6000803e3d6000fd5b5050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461057d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016103b8565b60005473ffffffffffffffffffffffffffffffffffffffff163314610652576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b73ffffffffffffffffffffffffffffffffffffffff81166106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102d2565b6106fe8161074d565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146106fe57600080fd5b6000602082840312156107f657600080fd5b8135610801816107c2565b9392505050565b6000806040838503121561081b57600080fd5b8235610826816107c2565b91506020830135610836816107c2565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561088557600080fd5b8335610890816107c2565b925060208401356108a0816107c2565b9150604084013567ffffffffffffffff808211156108bd57600080fd5b818601915086601f8301126108d157600080fd5b8135818111156108e3576108e3610841565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561092957610929610841565b8160405282815289602084870101111561094257600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561097657600080fd5b8151610801816107c2565b73ffffffffffffffffffffffffffffffffffffffff8316815260006020604081840152835180604085015260005b818110156109cb578581018301518582016060015282016109af565b818111156109dd576000606083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160600194935050505056fea2646970667358221220bd6c09ab03bfaf9ec60a4bf8cd98903cecb891974e17e2d76a3b2002c97eeb8964736f6c634300080a0033", + "deployedBytecode": "0x60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461012b57806399a88ec41461013e578063f2fde38b1461015e578063f3b7dead1461017e57600080fd5b8063204e1c7a14610080578063715018a6146100c95780637eff275e146100e05780638da5cb5b14610100575b600080fd5b34801561008c57600080fd5b506100a061009b3660046107e4565b61019e565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d557600080fd5b506100de610255565b005b3480156100ec57600080fd5b506100de6100fb366004610808565b6102e7565b34801561010c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100a0565b6100de610139366004610870565b6103ee565b34801561014a57600080fd5b506100de610159366004610808565b6104fc565b34801561016a57600080fd5b506100de6101793660046107e4565b6105d1565b34801561018a57600080fd5b506100a06101993660046107e4565b610701565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b600060405180830381855afa9150503d8060008114610225576040519150601f19603f3d011682016040523d82523d6000602084013e61022a565b606091505b50915091508161023957600080fd5b8080602001905181019061024d9190610964565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6102e5600061074d565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610368576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b600060405180830381600087803b1580156103d257600080fd5b505af11580156103e6573d6000803e3d6000fd5b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461046f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef2869034906104c59086908690600401610981565b6000604051808303818588803b1580156104de57600080fd5b505af11580156104f2573d6000803e3d6000fd5b5050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461057d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016103b8565b60005473ffffffffffffffffffffffffffffffffffffffff163314610652576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b73ffffffffffffffffffffffffffffffffffffffff81166106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102d2565b6106fe8161074d565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146106fe57600080fd5b6000602082840312156107f657600080fd5b8135610801816107c2565b9392505050565b6000806040838503121561081b57600080fd5b8235610826816107c2565b91506020830135610836816107c2565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561088557600080fd5b8335610890816107c2565b925060208401356108a0816107c2565b9150604084013567ffffffffffffffff808211156108bd57600080fd5b818601915086601f8301126108d157600080fd5b8135818111156108e3576108e3610841565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561092957610929610841565b8160405282815289602084870101111561094257600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561097657600080fd5b8151610801816107c2565b73ffffffffffffffffffffffffffffffffffffffff8316815260006020604081840152835180604085015260005b818110156109cb578581018301518582016060015282016109af565b818111156109dd576000606083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160600194935050505056fea2646970667358221220bd6c09ab03bfaf9ec60a4bf8cd98903cecb891974e17e2d76a3b2002c97eeb8964736f6c634300080a0033", + "devdoc": { + "details": "This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.", + "kind": "dev", + "methods": { + "changeProxyAdmin(address,address)": { + "details": "Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`." + }, + "getProxyAdmin(address)": { + "details": "Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`." + }, + "getProxyImplementation(address)": { + "details": "Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`." + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + }, + "upgrade(address,address)": { + "details": "Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`." + }, + "upgradeAndCall(address,address,bytes)": { + "details": "Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 7, + "contract": "solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol:ProxyAdmin", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + } + } + } +} \ No newline at end of file diff --git a/build/contracts/contracts/interfaces/IChargedParticles.sol/IChargedParticles.json b/deployments/goerli/RewardProgramDAI.json similarity index 53% rename from build/contracts/contracts/interfaces/IChargedParticles.sol/IChargedParticles.json rename to deployments/goerli/RewardProgramDAI.json index d7b235f..e244774 100644 --- a/build/contracts/contracts/interfaces/IChargedParticles.sol/IChargedParticles.json +++ b/deployments/goerli/RewardProgramDAI.json @@ -1,159 +1,268 @@ { - "_format": "hh-sol-artifact-1", - "contractName": "IChargedParticles", - "sourceName": "contracts/interfaces/IChargedParticles.sol", + "address": "0xC644778186614E47Dc702b39F710556322b9f3C3", "abi": [ { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", "name": "contractAddress", "type": "address" }, { + "indexed": false, "internalType": "uint256", "name": "tokenId", "type": "uint256" }, { + "indexed": false, "internalType": "string", "name": "walletManagerId", "type": "string" }, { - "internalType": "address", - "name": "assetToken", - "type": "address" - } - ], - "name": "baseParticleMass", - "outputs": [ - { + "indexed": false, "internalType": "uint256", - "name": "", + "name": "principalAmount", "type": "uint256" } ], - "stateMutability": "nonpayable", - "type": "function" + "name": "AssetDeposit", + "type": "event" }, { + "anonymous": false, "inputs": [ { - "internalType": "address", - "name": "receiver", - "type": "address" - }, - { + "indexed": true, "internalType": "address", "name": "contractAddress", "type": "address" }, { + "indexed": false, "internalType": "uint256", "name": "tokenId", "type": "uint256" }, { + "indexed": false, "internalType": "string", - "name": "basketManagerId", + "name": "walletManagerId", "type": "string" }, { + "indexed": false, + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "AssetRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, "internalType": "address", - "name": "nftTokenAddress", + "name": "contractAddress", "type": "address" }, { + "indexed": false, "internalType": "uint256", - "name": "nftTokenId", + "name": "tokenId", "type": "uint256" }, { + "indexed": false, "internalType": "uint256", - "name": "nftTokenAmount", + "name": "interestAmount", "type": "uint256" } ], - "name": "breakCovalentBond", - "outputs": [ + "name": "AssetRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "bool", - "name": "success", - "type": "bool" + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" } ], - "stateMutability": "nonpayable", - "type": "function" + "name": "RewardProgramFunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "RewardProgramOutOfFunds", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", "name": "contractAddress", "type": "address" }, { + "indexed": false, "internalType": "uint256", "name": "tokenId", "type": "uint256" }, { - "internalType": "string", - "name": "basketManagerId", - "type": "string" + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" }, { + "indexed": false, + "internalType": "uint256", + "name": "rewarded", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remaining", + "type": "uint256" + } + ], + "name": "RewardsClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, "internalType": "address", - "name": "nftTokenAddress", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", "type": "address" }, { + "indexed": true, "internalType": "uint256", - "name": "nftTokenId", + "name": "tokenId", "type": "uint256" }, { + "indexed": false, "internalType": "uint256", - "name": "nftTokenAmount", + "name": "amount", "type": "uint256" } ], - "name": "covalentBond", - "outputs": [ + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { - "internalType": "bool", - "name": "success", - "type": "bool" + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" } ], - "stateMutability": "nonpayable", - "type": "function" + "name": "WithdrawStuckERC20", + "type": "event" }, { + "anonymous": false, "inputs": [ { + "indexed": true, "internalType": "address", - "name": "contractAddress", + "name": "receiver", "type": "address" }, { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, "internalType": "uint256", "name": "tokenId", "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" }, { - "internalType": "string", - "name": "walletManagerId", - "type": "string" + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "parentNftUuid", + "type": "uint256" }, { - "internalType": "address", - "name": "assetToken", - "type": "address" + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" } ], - "name": "currentParticleCharge", + "name": "calculateRewardsEarned", "outputs": [ { "internalType": "uint256", @@ -161,9 +270,58 @@ "type": "uint256" } ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "fundProgram", + "outputs": [], "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "parentNftUuid", + "type": "uint256" + } + ], + "name": "getAssetStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimableRewards", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + } + ], + "internalType": "struct IRewardProgram.AssetStake", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -175,14 +333,22 @@ "internalType": "uint256", "name": "tokenId", "type": "uint256" - }, + } + ], + "name": "getClaimableRewards", + "outputs": [ { - "internalType": "string", - "name": "basketManagerId", - "type": "string" + "internalType": "uint256", + "name": "", + "type": "uint256" } ], - "name": "currentParticleCovalentBonds", + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFundBalance", "outputs": [ { "internalType": "uint256", @@ -193,37 +359,71 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "getProgramData", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + } + ], + "internalType": "struct IRewardProgram.ProgramRewardData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { "internalType": "address", - "name": "contractAddress", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", "type": "address" }, { "internalType": "uint256", - "name": "tokenId", + "name": "baseMultiplier", "type": "uint256" }, { - "internalType": "string", - "name": "walletManagerId", - "type": "string" + "internalType": "address", + "name": "chargedManagers", + "type": "address" }, { "internalType": "address", - "name": "assetToken", + "name": "universe", "type": "address" - } - ], - "name": "currentParticleKinetics", - "outputs": [ + }, { - "internalType": "uint256", - "name": "", - "type": "uint256" + "internalType": "address", + "name": "owner", + "type": "address" } ], + "name": "initialize", + "outputs": [], "stateMutability": "nonpayable", "type": "function" }, @@ -231,41 +431,36 @@ "inputs": [ { "internalType": "address", - "name": "receiver", + "name": "", "type": "address" }, { "internalType": "address", - "name": "contractAddress", + "name": "", "type": "address" }, { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" }, { - "internalType": "string", - "name": "walletManagerId", - "type": "string" + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" }, { - "internalType": "address", - "name": "assetToken", - "type": "address" + "internalType": "bytes", + "name": "", + "type": "bytes" } ], - "name": "dischargeParticle", + "name": "onERC1155BatchReceived", "outputs": [ { - "internalType": "uint256", - "name": "creatorAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "receiverAmount", - "type": "uint256" + "internalType": "bytes4", + "name": "", + "type": "bytes4" } ], "stateMutability": "nonpayable", @@ -275,58 +470,90 @@ "inputs": [ { "internalType": "address", - "name": "receiver", + "name": "", "type": "address" }, { "internalType": "address", - "name": "contractAddress", + "name": "", "type": "address" }, { "internalType": "uint256", - "name": "tokenId", + "name": "", "type": "uint256" }, { - "internalType": "string", - "name": "walletManagerId", - "type": "string" + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC1155Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" }, { "internalType": "address", - "name": "assetToken", + "name": "", "type": "address" }, { "internalType": "uint256", - "name": "assetAmount", + "name": "", "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" } ], - "name": "dischargeParticleAmount", + "name": "onERC721Received", "outputs": [ { - "internalType": "uint256", - "name": "creatorAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "receiverAmount", - "type": "uint256" + "internalType": "bytes4", + "name": "", + "type": "bytes4" } ], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ + "inputs": [], + "name": "owner", + "outputs": [ { "internalType": "address", - "name": "receiver", + "name": "", "type": "address" - }, + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ { "internalType": "address", "name": "contractAddress", @@ -342,22 +569,40 @@ "name": "walletManagerId", "type": "string" }, + { + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "registerAssetDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { "internalType": "address", - "name": "assetToken", + "name": "contractAddress", "type": "address" }, { "internalType": "uint256", - "name": "assetAmount", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestAmount", "type": "uint256" } ], - "name": "dischargeParticleForCreator", + "name": "registerAssetRelease", "outputs": [ { "internalType": "uint256", - "name": "receiverAmount", + "name": "rewards", "type": "uint256" } ], @@ -380,87 +625,92 @@ "internalType": "string", "name": "walletManagerId", "type": "string" - }, - { - "internalType": "address", - "name": "assetToken", - "type": "address" - }, - { - "internalType": "uint256", - "name": "assetAmount", - "type": "uint256" - }, - { - "internalType": "address", - "name": "referrer", - "type": "address" } ], - "name": "energizeParticle", - "outputs": [ + "name": "registerExistingDeposits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { "internalType": "uint256", - "name": "yieldTokensAmount", + "name": "newMultiplier", "type": "uint256" } ], + "name": "setBaseMultiplier", + "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "uint256", - "name": "assetAmount", - "type": "uint256" + "internalType": "address", + "name": "manager", + "type": "address" } ], - "name": "getFeesForDeposit", - "outputs": [ + "name": "setChargedManagers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { - "internalType": "uint256", - "name": "protocolFee", - "type": "uint256" + "internalType": "address", + "name": "newRewardToken", + "type": "address" } ], - "stateMutability": "view", + "name": "setRewardToken", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "getManagersAddress", - "outputs": [ + "inputs": [ { "internalType": "address", - "name": "managersAddress", + "name": "newStakingToken", "type": "address" } ], - "stateMutability": "view", + "name": "setStakingToken", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "getSettingsAddress", - "outputs": [ + "inputs": [ { "internalType": "address", - "name": "settingsAddress", + "name": "universe", "type": "address" } ], - "stateMutability": "view", + "name": "setUniverse", + "outputs": [], + "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "getStateAddress", + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", "outputs": [ { - "internalType": "address", - "name": "stateAddress", - "type": "address" + "internalType": "bool", + "name": "", + "type": "bool" } ], "stateMutability": "view", @@ -469,13 +719,13 @@ { "inputs": [ { - "internalType": "address", + "internalType": "address payable", "name": "receiver", "type": "address" }, { "internalType": "address", - "name": "contractAddress", + "name": "tokenAddress", "type": "address" }, { @@ -483,85 +733,82 @@ "name": "tokenId", "type": "uint256" }, - { - "internalType": "string", - "name": "walletManagerId", - "type": "string" - }, - { - "internalType": "address", - "name": "assetToken", - "type": "address" - } - ], - "name": "releaseParticle", - "outputs": [ { "internalType": "uint256", - "name": "creatorAmount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "receiverAmount", + "name": "amount", "type": "uint256" } ], + "name": "withdrawERC1155", + "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { - "internalType": "address", + "internalType": "address payable", "name": "receiver", "type": "address" }, { "internalType": "address", - "name": "contractAddress", + "name": "tokenAddress", "type": "address" }, { "internalType": "uint256", "name": "tokenId", "type": "uint256" - }, + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { - "internalType": "string", - "name": "walletManagerId", - "type": "string" + "internalType": "address payable", + "name": "receiver", + "type": "address" }, { "internalType": "address", - "name": "assetToken", + "name": "tokenAddress", "type": "address" }, { "internalType": "uint256", - "name": "assetAmount", + "name": "amount", "type": "uint256" } ], - "name": "releaseParticleAmount", - "outputs": [ + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { - "internalType": "uint256", - "name": "creatorAmount", - "type": "uint256" + "internalType": "address payable", + "name": "receiver", + "type": "address" }, { "internalType": "uint256", - "name": "receiverAmount", + "name": "amount", "type": "uint256" } ], + "name": "withdrawEther", + "outputs": [], "stateMutability": "nonpayable", "type": "function" } ], - "bytecode": "0x", - "deployedBytecode": "0x", - "linkReferences": {}, - "deployedLinkReferences": {} -} + "transactionHash": "0x8877fb00e17a25c09e2b06a8f1c08e7212878553d539c79b4ff6bf9493f3065f", + "numDeployments": 1 +} \ No newline at end of file diff --git a/deployments/goerli/RewardProgramFactory.json b/deployments/goerli/RewardProgramFactory.json new file mode 100644 index 0000000..697ea01 --- /dev/null +++ b/deployments/goerli/RewardProgramFactory.json @@ -0,0 +1,403 @@ +{ + "address": "0xF7CdB7bD236615f90246b9607D553CcB6E554c5D", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "rewardProgram", + "type": "address" + } + ], + "name": "RewardProgramCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [], + "name": "_template", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + }, + { + "internalType": "address", + "name": "chargedManagers", + "type": "address" + }, + { + "internalType": "address", + "name": "universe", + "type": "address" + } + ], + "name": "createRewardProgram", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x2f7db929b8ca684d681bb85e06df3307f78800aa3e19da58a972251689ec3c14", + "receipt": { + "to": null, + "from": "0x6d46b37708dA7Ed4E5C4509495768Fecd3D17C01", + "contractAddress": "0xF7CdB7bD236615f90246b9607D553CcB6E554c5D", + "transactionIndex": 14, + "gasUsed": "3261080", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000001000000000000000000000000000000000000020000000000000000000820000000000000000000000000000000400000000000800000000000000000000000000000040000000400000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xa301e1e4e4daf683ff6ac29edd44506ecdfc4d0a3fc4d4600a349e976753cd9d", + "transactionHash": "0x2f7db929b8ca684d681bb85e06df3307f78800aa3e19da58a972251689ec3c14", + "logs": [ + { + "transactionIndex": 14, + "blockNumber": 9608561, + "transactionHash": "0x2f7db929b8ca684d681bb85e06df3307f78800aa3e19da58a972251689ec3c14", + "address": "0xF7CdB7bD236615f90246b9607D553CcB6E554c5D", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000006d46b37708da7ed4e5c4509495768fecd3d17c01" + ], + "data": "0x", + "logIndex": 50, + "blockHash": "0xa301e1e4e4daf683ff6ac29edd44506ecdfc4d0a3fc4d4600a349e976753cd9d" + } + ], + "blockNumber": 9608561, + "cumulativeGasUsed": "7330564", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "39876b9d6995fafd8c4442fb1a03f418", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"rewardProgram\",\"type\":\"address\"}],\"name\":\"RewardProgramCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC1155\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckEther\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"_template\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"stakingToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rewardToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"baseMultiplier\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"chargedManagers\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"universe\",\"type\":\"address\"}],\"name\":\"createRewardProgram\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC1155\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawErc20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawEther\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/v1/incentives/RewardProgramFactory.sol\":\"RewardProgramFactory\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <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\",\"keccak256\":\"0x4784c3f8a520a739dd25d76f514833a653990902d0e21601aed45bda44c87524\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0xa1931c47a617014f858580db625aa0dcf343796f39acd4b5b51effc092a1f0a9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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 GSN 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 payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xdb26cbf4d028490f49831a7865c2fe1b28db44b535ca8d343785a3b768aae183\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"../GSN/Context.sol\\\";\\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 */\\ncontract 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 () internal {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view 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 emit OwnershipTransferred(_owner, address(0));\\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x4bd6402ca6b3419008c2b482aff54e66836e8cb4eba2680e42ac5884ae6424fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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\",\"keccak256\":\"0xfa152b6e88a1dc50780e8f1580426dc23ad2e1e2c2f086a088adf206a202f453\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\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 uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\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 sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\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 * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\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 // 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) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts 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 mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9a9cf02622cd7a64261b10534fc3260449da25c98c9e96d1b4ae8110a20e5806\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x31691ad0817f8cb338531b78d2ab2989027d9f27e6f8e62492b754fed9429b10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"../../introspection/IERC165.sol\\\";\\n\\n/**\\n * _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n\\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 )\\n external\\n 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 )\\n external\\n returns(bytes4);\\n}\\n\",\"keccak256\":\"0x0bc1d0b8fa3b262a6fb98b88dceab8b3348903b95dcc5909b9074fb19a3d2da5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0x5c26b39d26f7ed489e555d955dcd3e01872972e71fdd1528e93ec164e4f23385\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.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 SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf3b30f8a49631420635a8c35daacfcaa338012755f18a76fdd118730256f9a27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0xaf936da92f3a9a4f98b237323b5eb1d813fb86c4d07a184beba7027cf0509ba3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 /**\\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\",\"keccak256\":\"0x3636662804cd8f474536b2875a9038a4c3fb91879f1bbff48af5c3f140fcd2f0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address operator, address from, uint256 tokenId, bytes calldata data)\\n external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x321ee37ef4925020aa818a03ec7fe48e057561f65ab009a84f6c20c86026ade7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 in 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 // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n return _functionCallWithValue(target, data, value, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\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 // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf5fa8cbdffa5ef8be49b246b5628facc30b71707e78a45d80d93b64eff3fe390\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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.0.0, only sets of type `address` (`AddressSet`) and `uint256`\\n * (`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\\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\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] = toDeleteIndex + 1; // All indexes are 1-based\\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 require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\n return set._values[index];\\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(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(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(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(uint256(_at(set._inner, index)));\\n }\\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\",\"keccak256\":\"0xb2a11b236f073662f5a196995863f51c11d006bf7c3de158b316dfa1506c4b79\",\"license\":\"MIT\"},\"contracts/v1/incentives/RewardProgram.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// RewardProgram.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../interfaces/IRewardProgram.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/introspection/IERC165.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/EnumerableSet.sol\\\";\\n\\nimport \\\"../interfaces/IUniverseRP.sol\\\";\\nimport \\\"../interfaces/IChargedManagers.sol\\\";\\nimport \\\"../interfaces/IWalletManager.sol\\\";\\nimport \\\"../lib/TokenInfo.sol\\\";\\nimport \\\"../lib/ReentrancyGuard.sol\\\";\\nimport \\\"../lib/BlackholePrevention.sol\\\";\\nimport \\\"../interfaces/IERC20Detailed.sol\\\";\\n\\ncontract RewardProgram is\\n IRewardProgram,\\n BlackholePrevention,\\n IERC165,\\n ReentrancyGuard,\\n IERC721Receiver,\\n IERC1155Receiver\\n{\\n using SafeMath for uint256;\\n using TokenInfo for address;\\n using SafeERC20 for IERC20;\\n using EnumerableSet for EnumerableSet.UintSet;\\n\\n uint256 constant private PERCENTAGE_SCALE = 1e4; // 10000 (100%)\\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\\n\\n address private _owner;\\n IUniverseRP private _universe;\\n IChargedManagers private _chargedManagers;\\n ProgramRewardData private _programData;\\n mapping(uint256 => AssetStake) private _assetStake;\\n\\n\\n /***********************************|\\n | Initialization |\\n |__________________________________*/\\n\\n constructor() public {}\\n\\n function initialize(\\n address stakingToken,\\n address rewardToken,\\n uint256 baseMultiplier,\\n address chargedManagers,\\n address universe,\\n address owner\\n ) external override {\\n require(_owner == address(0x0), \\\"Already initialized\\\");\\n _owner = owner;\\n\\n // Prepare Reward Program\\n _programData.stakingToken = stakingToken;\\n _programData.rewardToken = rewardToken;\\n _programData.baseMultiplier = baseMultiplier; // Basis Points\\n\\n // Connect to Charged Particles\\n _chargedManagers = IChargedManagers(chargedManagers);\\n _universe = IUniverseRP(universe);\\n }\\n\\n\\n /***********************************|\\n | Public Functions |\\n |__________________________________*/\\n\\n function getProgramData() external view override returns (ProgramRewardData memory) {\\n return _programData;\\n }\\n\\n function getAssetStake(uint256 parentNftUuid) external view override returns (AssetStake memory) {\\n return _assetStake[parentNftUuid];\\n }\\n\\n function getFundBalance() external view override returns (uint256) {\\n return _getFundBalance();\\n }\\n\\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) public view override returns (uint256) {\\n return _calculateRewardsEarned(parentNftUuid, interestAmount);\\n }\\n\\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view override returns (uint256) {\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n return _assetStake[parentNftUuid].claimableRewards;\\n }\\n\\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\\n return IERC721Receiver.onERC721Received.selector;\\n }\\n\\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\\n return IERC1155Receiver.onERC1155BatchReceived.selector;\\n }\\n\\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\\n return \\\"\\\";\\n }\\n\\n function supportsInterface(bytes4 interfaceId)\\n public\\n view\\n virtual\\n override(IERC165)\\n returns (bool)\\n {\\n // default interface support\\n if (\\n interfaceId == type(IERC721Receiver).interfaceId ||\\n interfaceId == type(IERC1155Receiver).interfaceId ||\\n interfaceId == type(IERC165).interfaceId\\n ) {\\n return true;\\n }\\n }\\n\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n\\n /***********************************|\\n | Only Universe |\\n |__________________________________*/\\n\\n function registerAssetDeposit(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n uint256 principalAmount\\n )\\n external\\n override\\n onlyUniverse\\n {\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n AssetStake storage assetStake = _assetStake[parentNftUuid];\\n\\n if (assetStake.start == 0) {\\n assetStake.start = block.number;\\n assetStake.walletManagerId = walletManagerId;\\n }\\n emit AssetDeposit(contractAddress, tokenId, walletManagerId, principalAmount);\\n }\\n\\n function registerAssetRelease(\\n address contractAddress,\\n uint256 tokenId,\\n uint256 interestAmount\\n )\\n external\\n override\\n onlyUniverse\\n nonReentrant\\n returns (uint256 rewards)\\n {\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n AssetStake storage assetStake = _assetStake[parentNftUuid];\\n\\n // Update Claimable Rewards\\n uint256 newRewards = _calculateRewardsEarned(parentNftUuid, interestAmount);\\n assetStake.claimableRewards = assetStake.claimableRewards.add(newRewards);\\n\\n // Reset Stake if Principal Balance falls to Zero\\n IWalletManager walletMgr = _chargedManagers.getWalletManager(assetStake.walletManagerId);\\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\\n if (principal == 0) {\\n assetStake.start = 0;\\n }\\n\\n // Issue Rewards to NFT Owner\\n rewards = _claimRewards(contractAddress, tokenId);\\n\\n emit AssetRelease(contractAddress, tokenId, interestAmount);\\n }\\n\\n\\n /***********************************|\\n | Reward Calculation |\\n |__________________________________*/\\n\\n function _calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) internal view returns (uint256 totalReward) {\\n uint256 baseReward = _calculateBaseReward(interestAmount);\\n uint256 leptonMultipliedReward = _calculateMultipliedReward(parentNftUuid, baseReward);\\n totalReward = _convertDecimals(leptonMultipliedReward);\\n }\\n\\n function _calculateBaseReward(uint256 amount) internal view returns(uint256 baseReward) {\\n baseReward = amount.mul(_programData.baseMultiplier).div(PERCENTAGE_SCALE);\\n }\\n\\n function _calculateMultipliedReward(uint256 parentNftUuid, uint256 baseReward) internal view returns(uint256) {\\n AssetStake storage assetStake = _assetStake[parentNftUuid];\\n if (assetStake.start == 0) { return baseReward; }\\n\\n IUniverseRP.NftStake memory nftStake = _universe.getNftStake(parentNftUuid);\\n uint256 multiplierBP = nftStake.multiplier;\\n\\n uint256 assetDepositLength = block.number.sub(assetStake.start);\\n uint256 nftDepositLength = 0;\\n if (nftStake.releaseBlockNumber > 0) {\\n nftDepositLength = nftStake.releaseBlockNumber.sub(nftStake.depositBlockNumber);\\n } else {\\n nftDepositLength = block.number.sub(nftStake.depositBlockNumber);\\n }\\n\\n if (multiplierBP == 0 || nftDepositLength == 0 || assetDepositLength == 0) {\\n return baseReward;\\n }\\n\\n if (nftDepositLength > assetDepositLength) {\\n nftDepositLength = assetDepositLength;\\n }\\n\\n // Percentage of the total program that the Multiplier Nft was deposited for\\n uint256 nftRewardRatioBP = nftDepositLength.mul(PERCENTAGE_SCALE).div(assetDepositLength);\\n\\n // Amount of reward that the Multiplier Nft is responsible for\\n uint256 amountGeneratedDuringNftDeposit = baseReward.mul(nftRewardRatioBP).div(PERCENTAGE_SCALE);\\n\\n // Amount of Multiplied Reward from NFT\\n uint256 multipliedReward = amountGeneratedDuringNftDeposit.mul(multiplierBP.mul(LEPTON_MULTIPLIER_SCALE)).div(PERCENTAGE_SCALE);\\n\\n // Amount of Base Reward without Multiplied NFT Rewards\\n uint256 amountGeneratedWithoutNftDeposit = baseReward.sub(amountGeneratedDuringNftDeposit);\\n\\n // Amount of Base Rewards + Multiplied NFT Rewards\\n return amountGeneratedWithoutNftDeposit.add(multipliedReward);\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n |__________________________________*/\\n\\n function fundProgram(uint256 amount) external onlyOwner {\\n require(_programData.rewardToken != address(0), \\\"RP:E-405\\\");\\n IERC20(_programData.rewardToken).safeTransferFrom(msg.sender, address(this), amount);\\n emit RewardProgramFunded(amount);\\n }\\n\\n function setStakingToken(address newStakingToken) external onlyOwner {\\n _programData.stakingToken = newStakingToken;\\n }\\n\\n function setRewardToken(address newRewardToken) external onlyOwner {\\n _programData.rewardToken = newRewardToken;\\n }\\n\\n function setBaseMultiplier(uint256 newMultiplier) external onlyOwner {\\n _programData.baseMultiplier = newMultiplier; // Basis Points\\n }\\n\\n function setChargedManagers(address manager) external onlyOwner {\\n _chargedManagers = IChargedManagers(manager);\\n }\\n\\n function setUniverse(address universe) external onlyOwner {\\n _universe = IUniverseRP(universe);\\n }\\n\\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external override onlyOwner {\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n\\n // Initiate Asset Stake\\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\\n if (principal > 0) {\\n _assetStake[parentNftUuid] = AssetStake(block.number, 0, walletManagerId);\\n emit AssetRegistered(contractAddress, tokenId, walletManagerId, principal);\\n }\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n | (blackhole prevention) |\\n |__________________________________*/\\n\\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n\\n\\n /***********************************|\\n | Private Functions |\\n |__________________________________*/\\n\\n function _claimRewards(\\n address contractAddress,\\n uint256 tokenId\\n )\\n internal\\n returns (uint256 totalReward)\\n {\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n AssetStake storage assetStake = _assetStake[parentNftUuid];\\n\\n // Rewards Receiver\\n address receiver = IERC721(contractAddress).ownerOf(tokenId);\\n\\n // Ensure Reward Pool has Sufficient Balance\\n totalReward = assetStake.claimableRewards;\\n uint256 fundBalance = _getFundBalance();\\n uint256 unavailReward = totalReward > fundBalance ? totalReward.sub(fundBalance) : 0;\\n\\n // Determine amount of Rewards to Transfer\\n if (unavailReward > 0) {\\n totalReward = totalReward.sub(unavailReward);\\n emit RewardProgramOutOfFunds();\\n }\\n\\n // Update Asset Stake\\n assetStake.claimableRewards = unavailReward;\\n\\n if (totalReward > 0) {\\n // Transfer Available Rewards to Receiver\\n IERC20(_programData.rewardToken).safeTransfer(receiver, totalReward);\\n }\\n\\n emit RewardsClaimed(contractAddress, tokenId, receiver, totalReward, unavailReward);\\n }\\n\\n function _convertDecimals(uint256 reward) internal view returns (uint256) {\\n uint8 stakingTokenDecimals = IERC20Detailed(_programData.stakingToken).decimals();\\n return reward.mul(10**(18 - uint256(stakingTokenDecimals)));\\n }\\n\\n function _getFundBalance() internal view returns (uint256) {\\n return IERC20Detailed(_programData.rewardToken).balanceOf(address(this));\\n }\\n\\n\\n modifier onlyOwner() {\\n require(_owner == msg.sender, \\\"Caller is not the owner\\\");\\n _;\\n }\\n\\n modifier onlyUniverse() {\\n require(msg.sender == address(_universe), \\\"RP:E-108\\\");\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x2c6b66490dda8cea12387706aa49742f7d8c90ff3b699abd3c84dae227277e3f\",\"license\":\"MIT\"},\"contracts/v1/incentives/RewardProgramFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// RewardProgramFactory.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\nimport \\\"./RewardProgram.sol\\\";\\nimport \\\"../lib/BlackholePrevention.sol\\\";\\n\\ncontract RewardProgramFactory is BlackholePrevention, Ownable {\\n event RewardProgramCreated(address indexed rewardProgram);\\n\\n address public _template;\\n\\n constructor () public {\\n _template = address(new RewardProgram());\\n }\\n\\n // function _msgSender() internal view override returns (address payable) {\\n // return msg.sender;\\n // }\\n\\n function createRewardProgram(\\n address stakingToken,\\n address rewardToken,\\n uint256 baseMultiplier,\\n address chargedManagers,\\n address universe\\n )\\n external\\n onlyOwner\\n returns (address)\\n {\\n address newRewardProgram = _createClone(_template);\\n RewardProgram rewardProgram = RewardProgram(newRewardProgram);\\n rewardProgram.initialize(stakingToken, rewardToken, baseMultiplier, chargedManagers, universe, _msgSender());\\n emit RewardProgramCreated(newRewardProgram);\\n return newRewardProgram;\\n }\\n\\n /**\\n * @dev Creates Contracts from a Template via Cloning\\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\\n */\\n function _createClone(address target) internal returns (address result) {\\n bytes20 targetBytes = bytes20(target);\\n assembly {\\n let clone := mload(0x40)\\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\\n mstore(add(clone, 0x14), targetBytes)\\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\\n result := create(0, clone, 0x37)\\n }\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n | (blackhole prevention) |\\n |__________________________________*/\\n\\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n}\\n\",\"keccak256\":\"0x5a3692f0c9dee582d05013bc2f808cca4e7257756ed8125d81586d674c166559\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IBasketManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IBasketManager.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Particle Basket Manager interface\\n * @dev The basket-manager for underlying assets attached to Charged Particles\\n * @dev Manages the link between NFTs and their respective Smart-Baskets\\n */\\ninterface IBasketManager {\\n\\n event ControllerSet(address indexed controller);\\n event ExecutorSet(address indexed executor);\\n event PausedStateSet(bool isPaused);\\n event NewSmartBasket(address indexed contractAddress, uint256 indexed tokenId, address indexed smartBasket);\\n event BasketAdd(address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\\n event BasketRemove(address indexed receiver, address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\\n event BasketRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\\n event RewardProgramSet(address indexed rewardProgram);\\n\\n function isPaused() external view returns (bool);\\n\\n function getTokenTotalCount(address contractAddress, uint256 tokenId) external view returns (uint256);\\n function getTokenCountByType(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (uint256);\\n\\n function prepareTransferAmount(uint256 nftTokenAmount) external;\\n function addToBasket(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\\n function getBasketAddressById(address contractAddress, uint256 tokenId) external returns (address);\\n\\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount) external;\\n}\\n\",\"keccak256\":\"0x20367a08a95c30ed283f46877bef9c5f1ccd0f07409fe632f4f82a5d33b6a0c3\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IChargedManagers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"./IWalletManager.sol\\\";\\nimport \\\"./IBasketManager.sol\\\";\\n\\n/**\\n * @notice Interface for Charged Wallet-Managers\\n */\\ninterface IChargedManagers {\\n\\n /***********************************|\\n | Public API |\\n |__________________________________*/\\n\\n function isContractOwner(address contractAddress, address account) external view returns (bool);\\n\\n // ERC20\\n function isWalletManagerEnabled(string calldata walletManagerId) external view returns (bool);\\n function getWalletManager(string calldata walletManagerId) external view returns (IWalletManager);\\n\\n // ERC721\\n function isNftBasketEnabled(string calldata basketId) external view returns (bool);\\n function getBasketManager(string calldata basketId) external view returns (IBasketManager);\\n\\n // Validation\\n function validateDeposit(\\n address sender,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external;\\n function validateNftDeposit(\\n address sender,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external;\\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external;\\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external;\\n\\n /***********************************|\\n | Particle Events |\\n |__________________________________*/\\n\\n event Initialized(address indexed initiator);\\n event ControllerSet(address indexed controllerAddress, string controllerId);\\n event WalletManagerRegistered(string indexed walletManagerId, address indexed walletManager);\\n event BasketManagerRegistered(string indexed basketId, address indexed basketManager);\\n}\\n\",\"keccak256\":\"0x98103c0832064c1e446dcfebfdeeec1a9189675e9cf630f568c65c16c94d5478\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IERC20Detailed.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Detailed {\\n function decimals() external view returns (uint8);\\n function symbol() external view returns (string memory);\\n function name() external view returns (string memory);\\n\\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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0x96b8e4b6723a052ec16a1a729854532c953fb2eb758a0e01f75a3eafe242ccd8\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IERC721Chargeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IERC721Chargeable.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\\\";\\n\\ninterface IERC721Chargeable is IERC165Upgradeable {\\n function owner() external view returns (address);\\n function creatorOf(uint256 tokenId) external view returns (address);\\n function balanceOf(address tokenOwner) external view returns (uint256 balance);\\n function ownerOf(uint256 tokenId) external view returns (address tokenOwner);\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n function transferFrom(address from, address to, uint256 tokenId) external;\\n function approve(address to, uint256 tokenId) external;\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n function setApprovalForAll(address operator, bool _approved) external;\\n function isApprovedForAll(address tokenOwner, address operator) external view returns (bool);\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x459e57b2d35c7cd78e6c3d47eb9f3e981529a18c89e2c318b10fe369c479c737\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IRewardProgram.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IRewardProgram.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\npragma experimental ABIEncoderV2;\\n\\ninterface IRewardProgram {\\n /* admin events */\\n event RewardProgramFunded(uint256 amount);\\n event RewardProgramOutOfFunds();\\n\\n /* user events */\\n event RewardsClaimed(address indexed contractAddress, uint256 tokenId, address indexed receiver, uint256 rewarded, uint256 remaining);\\n\\n event AssetRegistered(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\\n event AssetDeposit(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\\n event AssetRelease(address indexed contractAddress, uint256 tokenId, uint256 interestAmount);\\n\\n /* data types */\\n struct ProgramRewardData {\\n address stakingToken;\\n address rewardToken;\\n uint256 baseMultiplier; // Basis Points\\n }\\n\\n struct AssetStake {\\n uint256 start;\\n uint256 claimableRewards;\\n string walletManagerId;\\n }\\n\\n function initialize(address stakingToken, address rewardToken, uint256 baseMultiplier, address chargedManagers, address universe, address owner) external;\\n\\n /* user functions */\\n function getProgramData() external view returns (ProgramRewardData memory programData);\\n function getAssetStake(uint256 uuid) external view returns (AssetStake memory);\\n function getFundBalance() external view returns (uint256);\\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) external view returns (uint256);\\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view returns (uint256);\\n\\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external;\\n function registerAssetDeposit(address contractAddress, uint256 tokenId, string calldata walletManagerId, uint256 principalAmount) external;\\n function registerAssetRelease(address contractAddress, uint256 tokenId, uint256 interestAmount) external returns (uint256 rewards);\\n}\",\"keccak256\":\"0xe0f4076a4b001856c54cb8a63decedc81ca34c71708f8cbe9b3a26603dc9c050\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IUniverse.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IUniverse.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Universal Controller interface\\n * @dev ...\\n */\\ninterface IUniverse {\\n\\n event ChargedParticlesSet(address indexed chargedParticles);\\n event PhotonSet(address indexed photonToken, uint256 maxSupply);\\n event ProtonTokenSet(address indexed protonToken);\\n event LeptonTokenSet(address indexed leptonToken);\\n event QuarkTokenSet(address indexed quarkToken);\\n event BosonTokenSet(address indexed bosonToken);\\n event EsaMultiplierSet(address indexed assetToken, uint256 multiplier);\\n event ElectrostaticAttraction(address indexed account, address photonSource, uint256 energy, uint256 multiplier);\\n event ElectrostaticDischarge(address indexed account, address photonSource, uint256 energy);\\n\\n function onEnergize(\\n address sender,\\n address referrer,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 assetEnergy\\n ) external;\\n\\n function onDischarge(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onDischargeForCreator(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address creator,\\n address assetToken,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onRelease(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 principalEnergy,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onCovalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n\\n function onCovalentBreak(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n\\n function onProtonSale(\\n address contractAddress,\\n uint256 tokenId,\\n address oldOwner,\\n address newOwner,\\n uint256 salePrice,\\n address creator,\\n uint256 creatorRoyalties\\n ) external;\\n}\\n\",\"keccak256\":\"0x6cebb97ce4d32c61afc746e4a6538eb605bb01276dfa66fa4bd6f63362bdc9ef\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IUniverseRP.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IUniverseRP.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"./IUniverse.sol\\\";\\n\\n/**\\n * @title Universal Controller interface for Rewards Program\\n * @dev ...\\n */\\ninterface IUniverseRP is IUniverse {\\n event RewardProgramSet(address indexed assetToken, address indexed rewardProgram);\\n event RewardProgramRemoved(address indexed assetToken);\\n event NftDeposit(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\\n event NftRelease(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\\n\\n struct NftStake {\\n uint256 multiplier; // in Basis Points\\n uint256 depositBlockNumber;\\n uint256 releaseBlockNumber;\\n }\\n\\n function getRewardProgram(address asset) external view returns (address);\\n function getNftStake(uint256 uuid) external view returns (NftStake memory);\\n}\\n\",\"keccak256\":\"0xd9c5a996bbb7f2a27bb85dde52587f7368c7b6512fc1064821a3975acdf4b7db\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IWalletManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IWalletManager.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Particle Wallet Manager interface\\n * @dev The wallet-manager for underlying assets attached to Charged Particles\\n * @dev Manages the link between NFTs and their respective Smart-Wallets\\n */\\ninterface IWalletManager {\\n\\n event ControllerSet(address indexed controller);\\n event ExecutorSet(address indexed executor);\\n event PausedStateSet(bool isPaused);\\n event NewSmartWallet(address indexed contractAddress, uint256 indexed tokenId, address indexed smartWallet, address creator, uint256 annuityPct);\\n event WalletEnergized(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 assetAmount, uint256 yieldTokensAmount);\\n event WalletDischarged(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 creatorAmount, uint256 receiverAmount);\\n event WalletDischargedForCreator(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, address creator, uint256 receiverAmount);\\n event WalletReleased(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address assetToken, uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\\n event WalletRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\\n\\n function isPaused() external view returns (bool);\\n\\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view returns (bool);\\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view returns (address);\\n\\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\\n function getInterest(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken) external returns (uint256);\\n\\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount) external returns (uint256 yieldTokensAmount);\\n function discharge(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n function dischargeAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n function dischargeAmountForCreator(address receiver, address contractAddress, uint256 tokenId, address creator, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\\n function release(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\\n function releaseAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken) external;\\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct) external returns (address);\\n\\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\\n}\\n\",\"keccak256\":\"0xb03ee0e216d7444e72af388814d219ad9aa87006ec96d660b45dcad0875ef0d7\",\"license\":\"MIT\"},\"contracts/v1/lib/BlackholePrevention.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\\\";\\n\\n/**\\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\\n * the Owner/DAO to pull them out on behalf of a user\\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\\n */\\ncontract BlackholePrevention {\\n using Address for address payable;\\n using SafeERC20 for IERC20;\\n\\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\\n\\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (address(this).balance >= amount) {\\n receiver.sendValue(amount);\\n emit WithdrawStuckEther(receiver, amount);\\n }\\n }\\n\\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\\n IERC20(tokenAddress).safeTransfer(receiver, amount);\\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\\n }\\n }\\n\\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\\n }\\n }\\n\\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \\\"\\\");\\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6a664c8a1c1d7fb32ade2c11f75756b1fdb4c489daa32c1d58e6b867ea2ba8d6\",\"license\":\"MIT\"},\"contracts/v1/lib/ReentrancyGuard.sol\":{\"content\":\"pragma solidity 0.6.12;\\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 () public {\\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 _nonReentrantBefore();\\n _;\\n _nonReentrantAfter();\\n }\\n\\n function _nonReentrantBefore() private {\\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n }\\n\\n function _nonReentrantAfter() private {\\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 /**\\n * @dev Returns true if the reentrancy guard is currently set to \\\"entered\\\", which indicates there is a\\n * `nonReentrant` function in the call stack.\\n */\\n function _reentrancyGuardEntered() internal view returns (bool) {\\n return _status == _ENTERED;\\n }\\n}\",\"keccak256\":\"0x4897c6fee5e1601d203efa54d29b2cef20825cab134b8e63b0b13ee9603642ad\"},\"contracts/v1/lib/TokenInfo.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// TokenInfo.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport \\\"../interfaces/IERC721Chargeable.sol\\\";\\n\\nlibrary TokenInfo {\\n function getTokenUUID(address contractAddress, uint256 tokenId) internal pure virtual returns (uint256) {\\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n function getTokenOwner(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n return tokenInterface.ownerOf(tokenId);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n function getTokenCreator(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n return tokenInterface.creatorOf(tokenId);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Owner of an External NFT contract\\n /// @param contractAddress The Address to the Contract of the NFT to check\\n /// @param account The Address of the Account to check\\n /// @return True if the account owns the contract\\n function isContractOwner(address contractAddress, address account) internal view virtual returns (bool) {\\n address contractOwner = IERC721Chargeable(contractAddress).owner();\\n return contractOwner != address(0x0) && contractOwner == account;\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Creator of a Proton-based NFT\\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\\n /// @param tokenId The Token ID of the Proton-based NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the creator of the Proton-based NFT\\n function isTokenCreator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenCreator = tokenInterface.creatorOf(tokenId);\\n return (sender == tokenCreator);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\\n /// @param tokenId The Token ID of the Proton-based NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the creator of the Proton-based NFT or the Contract itself\\n function isTokenContractOrCreator(address contractAddress, uint256 tokenId, address creator, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenCreator = tokenInterface.creatorOf(tokenId);\\n if (sender == contractAddress && creator == tokenCreator) { return true; }\\n return (sender == tokenCreator);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Owner or Operator of an External NFT\\n /// @param contractAddress The Address to the Contract of the External NFT to check\\n /// @param tokenId The Token ID of the External NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the Owner or Operator of the External NFT\\n function isErc721OwnerOrOperator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenOwner = tokenInterface.ownerOf(tokenId);\\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\\n }\\n\\n /**\\n * @dev Returns true if `account` is a contract.\\n * @dev Taken from OpenZeppelin library\\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { codehash := extcodehash(account) }\\n return (codehash != accountHash && codehash != 0x0);\\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 * @dev Taken from OpenZeppelin library\\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, uint256 gasLimit) internal {\\n require(address(this).balance >= amount, \\\"TokenInfo: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = (gasLimit > 0)\\n ? recipient.call{ value: amount, gas: gasLimit }(\\\"\\\")\\n : recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"TokenInfo: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0xbc78c6173db068d95084288246642402d0f4af399e1eb754182cae2d9173af5e\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50600061001b6100b3565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350604051610071906100b7565b604051809103906000f08015801561008d573d6000803e3d6000fd5b50600180546001600160a01b0319166001600160a01b03929092169190911790556100c4565b3390565b6127bd8061115483390190565b611081806100d36000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c80636fe6fabb116100665780636fe6fabb146100fc578063715018a6146101045780638da5cb5b1461010c578063a0edb48b14610114578063f2fde38b1461012757610093565b80631593dee1146100985780634025feb2146100ad578063522f6815146100c05780636f9d5f78146100d3575b600080fd5b6100ab6100a6366004610be7565b61013a565b005b6100ab6100bb366004610be7565b610188565b6100ab6100ce366004610c6c565b6101c8565b6100e66100e1366004610c97565b61020b565b6040516100f39190610d55565b60405180910390f35b6100e661030b565b6100ab61031a565b6100e6610399565b6100ab610122366004610c27565b6103a8565b6100ab610135366004610ba8565b6103ef565b6101426104a5565b6000546001600160a01b039081169116146101785760405162461bcd60e51b815260040161016f90610f48565b60405180910390fd5b6101838383836104a9565b505050565b6101906104a5565b6000546001600160a01b039081169116146101bd5760405162461bcd60e51b815260040161016f90610f48565b6101838383836105b6565b6101d06104a5565b6000546001600160a01b039081169116146101fd5760405162461bcd60e51b815260040161016f90610f48565b6102078282610711565b5050565b60006102156104a5565b6000546001600160a01b039081169116146102425760405162461bcd60e51b815260040161016f90610f48565b60015460009061025a906001600160a01b0316610795565b9050806001600160a01b03811663ff9935cb89898989896102796104a5565b6040518763ffffffff1660e01b815260040161029a96959493929190610dc5565b600060405180830381600087803b1580156102b457600080fd5b505af11580156102c8573d6000803e3d6000fd5b50506040516001600160a01b03851692507f6ecb2838bef4560681475e8bb5e7feccefe33df915df2d6757024bc6fe4c616a9150600090a2509695505050505050565b6001546001600160a01b031681565b6103226104a5565b6000546001600160a01b0390811691161461034f5760405162461bcd60e51b815260040161016f90610f48565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b6103b06104a5565b6000546001600160a01b039081169116146103dd5760405162461bcd60e51b815260040161016f90610f48565b6103e9848484846107e7565b50505050565b6103f76104a5565b6000546001600160a01b039081169116146104245760405162461bcd60e51b815260040161016f90610f48565b6001600160a01b03811661044a5760405162461bcd60e51b815260040161016f90610e4b565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b0383166104cf5760405162461bcd60e51b815260040161016f90610e91565b6040516370a0823160e01b815281906001600160a01b038416906370a08231906104fd903090600401610d55565b60206040518083038186803b15801561051557600080fd5b505afa158015610529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061054d9190610d1e565b10610183576105666001600160a01b0383168483610946565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b836040516105a99190610ffe565b60405180910390a3505050565b6001600160a01b0383166105dc5760405162461bcd60e51b815260040161016f90610e91565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e9061060a908590600401610ffe565b60206040518083038186803b15801561062257600080fd5b505afa158015610636573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065a9190610bcb565b6001600160a01b03161415610183576040516323b872dd60e01b81526001600160a01b038316906323b872dd9061069990309087908690600401610d69565b600060405180830381600087803b1580156106b357600080fd5b505af11580156106c7573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b0382166107375760405162461bcd60e51b815260040161016f90610e91565b804710610207576107516001600160a01b0383168261099c565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd826040516107899190610ffe565b60405180910390a25050565b6000808260601b9050604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528160148201526e5af43d82803e903d91602b57fd5bf360881b60288201526037816000f0949350505050565b6001600160a01b03841661080d5760405162461bcd60e51b815260040161016f90610e91565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e9061083b9030908790600401610dff565b60206040518083038186803b15801561085357600080fd5b505afa158015610867573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088b9190610d1e565b106103e957604051637921219560e11b81526001600160a01b0384169063f242432a906108c2903090889087908790600401610d8d565b600060405180830381600087803b1580156108dc57600080fd5b505af11580156108f0573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b846040516109389190610ffe565b60405180910390a450505050565b6101838363a9059cbb60e01b8484604051602401610965929190610dff565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610a38565b804710156109bc5760405162461bcd60e51b815260040161016f90610f11565b6000826001600160a01b0316826040516109d590610d52565b60006040518083038185875af1925050503d8060008114610a12576040519150601f19603f3d011682016040523d82523d6000602084013e610a17565b606091505b50509050806101835760405162461bcd60e51b815260040161016f90610eb4565b6060610a8d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610ac79092919063ffffffff16565b8051909150156101835780806020019051810190610aab9190610cfe565b6101835760405162461bcd60e51b815260040161016f90610fb4565b6060610ad68484600085610ade565b949350505050565b6060610ae985610ba2565b610b055760405162461bcd60e51b815260040161016f90610f7d565b60006060866001600160a01b03168587604051610b229190610d36565b60006040518083038185875af1925050503d8060008114610b5f576040519150601f19603f3d011682016040523d82523d6000602084013e610b64565b606091505b50915091508115610b78579150610ad69050565b805115610b885780518082602001fd5b8360405162461bcd60e51b815260040161016f9190610e18565b3b151590565b600060208284031215610bb9578081fd5b8135610bc481611033565b9392505050565b600060208284031215610bdc578081fd5b8151610bc481611033565b600080600060608486031215610bfb578182fd5b8335610c0681611033565b92506020840135610c1681611033565b929592945050506040919091013590565b60008060008060808587031215610c3c578081fd5b8435610c4781611033565b93506020850135610c5781611033565b93969395505050506040820135916060013590565b60008060408385031215610c7e578182fd5b8235610c8981611033565b946020939093013593505050565b600080600080600060a08688031215610cae578081fd5b8535610cb981611033565b94506020860135610cc981611033565b9350604086013592506060860135610ce081611033565b91506080860135610cf081611033565b809150509295509295909350565b600060208284031215610d0f578081fd5b81518015158114610bc4578182fd5b600060208284031215610d2f578081fd5b5051919050565b60008251610d48818460208701611007565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b0396871681529486166020860152604085019390935290841660608401528316608083015290911660a082015260c00190565b6001600160a01b03929092168252602082015260400190565b6000602082528251806020840152610e37816040850160208701611007565b601f01601f19169190910160400192915050565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b90815260200190565b60005b8381101561102257818101518382015260200161100a565b838111156103e95750506000910152565b6001600160a01b038116811461104857600080fd5b5056fea2646970667358221220260383f23709db660967a522664682b39439430262c686f1ff999462e44f3aff64736f6c634300060c0033608060405234801561001057600080fd5b506001600055612798806100256000396000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c8063533f852e116100c3578063ae9704cd1161007c578063ae9704cd146102f6578063bc197c8114610309578063dae9e3791461031c578063e3043ee814610324578063f23a6e6114610337578063ff9935cb1461034a57610158565b8063533f852e1461027557806370d2e5cd14610288578063784483491461029b5780638aee8127146102bb5780638da5cb5b146102ce578063a0edb48b146102e357610158565b8063352685bc11610115578063352685bc146101f65780634025feb21461020957806346c65f621461021c578063494b01001461022f57806350d0c63c14610242578063522f68151461026257610158565b806301ffc9a71461015d57806314e5f66814610186578063150b7a021461019b5780631593dee1146101bb5780631e9b12ef146101d05780631f5b149f146101e3575b600080fd5b61017061016b3660046120c8565b61035d565b60405161017d91906122fc565b60405180910390f35b61018e6103b7565b60405161017d919061268b565b6101ae6101a9366004611ecd565b6103f0565b60405161017d9190612307565b6101ce6101c9366004611cea565b610401565b005b6101ce6101de366004611cb2565b610444565b6101ce6101f1366004611cb2565b610490565b6101ce610204366004612147565b6104dc565b6101ce610217366004611cea565b610580565b6101ce61022a366004612012565b6105b5565b6101ce61023d366004611fb8565b61066f565b610255610250366004612074565b61089f565b60405161017d91906126ba565b6101ce610270366004611d6f565b610a9a565b610255610283366004611d6f565b610ad2565b6101ce610296366004612147565b610b04565b6102ae6102a9366004612147565b610b33565b60405161017d919061265c565b6101ce6102c9366004611cb2565b610c16565b6102d6610c62565b60405161017d9190612250565b6101ce6102f1366004611d2a565b610c71565b6101ce610304366004611cb2565b610cad565b6101ae610317366004611d9a565b610cf9565b610255610d07565b610255610332366004612177565b610d16565b6101ae610345366004611f3e565b610d22565b6101ce610358366004611e55565b610d34565b60006001600160e01b03198216630a85bd0160e11b148061038e57506001600160e01b03198216630271189760e51b145b806103a957506001600160e01b031982166301ffc9a760e01b145b156103b2575060015b919050565b6103bf611ac6565b50604080516060810182526004546001600160a01b0390811682526005541660208201526006549181019190915290565b630a85bd0160e11b95945050505050565b6001546001600160a01b031633146104345760405162461bcd60e51b815260040161042b906123cd565b60405180910390fd5b61043f838383610dbf565b505050565b6001546001600160a01b0316331461046e5760405162461bcd60e51b815260040161042b906123cd565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633146104ba5760405162461bcd60e51b815260040161042b906123cd565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633146105065760405162461bcd60e51b815260040161042b906123cd565b6005546001600160a01b031661052e5760405162461bcd60e51b815260040161042b90612514565b600554610546906001600160a01b0316333084610ecc565b7fcbd64454da4b3587b11b8f8170d7656cbe58e29ee18fd715b0e79ad85edb6e5d8160405161057591906126ba565b60405180910390a150565b6001546001600160a01b031633146105aa5760405162461bcd60e51b815260040161042b906123cd565b61043f838383610f24565b6002546001600160a01b031633146105df5760405162461bcd60e51b815260040161042b906124f2565b60006105f46001600160a01b0387168661107f565b600081815260076020526040902080549192509061061f5743815561061d600282018686611ae6565b505b866001600160a01b03167f30d53e48465c48642e346a636a4eef45c72095b65bef5825308376e2f59f09e28787878760405161065e94939291906126c3565b60405180910390a250505050505050565b6001546001600160a01b031633146106995760405162461bcd60e51b815260040161042b906123cd565b60006106ae6001600160a01b0386168561107f565b6003546040516334b7328d60e01b81529192506000916001600160a01b03909116906334b7328d906106e6908790879060040161231c565b60206040518083038186803b1580156106fe57600080fd5b505afa158015610712573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107369190611cce565b60048054604051632da9ef8160e01b81529293506000926001600160a01b0380861693632da9ef8193610770938d938d93921691016122d9565b602060405180830381600087803b15801561078a57600080fd5b505af115801561079e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c2919061215f565b905080156108965760405180606001604052804381526020016000815260200186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093909452505085815260076020908152604091829020845181558482015160018201559184015180519293506108539260028501929190910190611b64565b50905050866001600160a01b03167fdd1b8616b3983aa94529955a2f7d0dd75e5a93e53875372ea41a9eab5e3ef3268787878560405161065e94939291906126c3565b50505050505050565b6002546000906001600160a01b031633146108cc5760405162461bcd60e51b815260040161042b906124f2565b6108d46110b3565b60006108e96001600160a01b0386168561107f565b600081815260076020526040812091925061090483866110dd565b6001830154909150610916908261110b565b60018301556003546040516334b7328d60e01b81526000916001600160a01b0316906334b7328d9061094f906002870190600401612343565b60206040518083038186803b15801561096757600080fd5b505afa15801561097b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099f9190611cce565b60048054604051632da9ef8160e01b81529293506000926001600160a01b0380861693632da9ef81936109d9938f938f93921691016122d9565b602060405180830381600087803b1580156109f357600080fd5b505af1158015610a07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2b919061215f565b905080610a3757600084555b610a418989611130565b9550886001600160a01b03167f8abeaea5da22bf1966530d4f970ac7c71ae0999eb1d2181afaeff8b56c394f3f8989604051610a7e9291906126ee565b60405180910390a25050505050610a936112c0565b9392505050565b6001546001600160a01b03163314610ac45760405162461bcd60e51b815260040161042b906123cd565b610ace82826112c7565b5050565b600080610ae86001600160a01b0385168461107f565b6000908152600760205260409020600101549150505b92915050565b6001546001600160a01b03163314610b2e5760405162461bcd60e51b815260040161042b906123cd565b600655565b610b3b611bd2565b600760008381526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610c065780601f10610bdb57610100808354040283529160200191610c06565b820191906000526020600020905b815481529060010190602001808311610be957829003601f168201915b5050505050815250509050919050565b6001546001600160a01b03163314610c405760405162461bcd60e51b815260040161042b906123cd565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031690565b6001546001600160a01b03163314610c9b5760405162461bcd60e51b815260040161042b906123cd565b610ca78484848461134b565b50505050565b6001546001600160a01b03163314610cd75760405162461bcd60e51b815260040161042b906123cd565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b600098975050505050505050565b6000610d116114aa565b905090565b6000610a9383836110dd565b63bc197c8160e01b9695505050505050565b6001546001600160a01b031615610d5d5760405162461bcd60e51b815260040161042b906125ae565b600180546001600160a01b03199081166001600160a01b03938416179091556004805482169783169790971790965560058054871695821695909517909455600692909255600380548516918416919091179055600280549093169116179055565b6001600160a01b038316610de55760405162461bcd60e51b815260040161042b90612404565b6040516370a0823160e01b815281906001600160a01b038416906370a0823190610e13903090600401612250565b60206040518083038186803b158015610e2b57600080fd5b505afa158015610e3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e63919061215f565b1061043f57610e7c6001600160a01b038316848361152b565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b83604051610ebf91906126ba565b60405180910390a3505050565b610ca7846323b872dd60e01b858585604051602401610eed93929190612264565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261154a565b6001600160a01b038316610f4a5760405162461bcd60e51b815260040161042b90612404565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e90610f789085906004016126ba565b60206040518083038186803b158015610f9057600080fd5b505afa158015610fa4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc89190611cce565b6001600160a01b0316141561043f576040516323b872dd60e01b81526001600160a01b038316906323b872dd9061100790309087908690600401612264565b600060405180830381600087803b15801561102157600080fd5b505af1158015611035573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6000828260405160200161109492919061220f565b60408051601f1981840301815291905280516020909101209392505050565b600260005414156110d65760405162461bcd60e51b815260040161042b90612625565b6002600055565b6000806110e9836115d9565b905060006110f785836115ff565b905061110281611797565b95945050505050565b600082820183811015610a935760405162461bcd60e51b815260040161042b90612427565b6000806111466001600160a01b0385168461107f565b60008181526007602052604080822090516331a9108f60e11b8152929350916001600160a01b03871690636352211e906111849088906004016126ba565b60206040518083038186803b15801561119c57600080fd5b505afa1580156111b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d49190611cce565b90508160010154935060006111e76114aa565b905060008186116111f9576000611203565b6112038683611828565b90508015611242576112158682611828565b6040519096507f9fc735fd421d3eb45362ea6d0d94945975bce33842b1bc94840719e66d937e4790600090a15b60018401819055851561126657600554611266906001600160a01b0316848861152b565b826001600160a01b0316886001600160a01b03167fb918e5bcd5ce5aadd59ae96fe4c568669afc7af190dbf16061540816cb407c738989856040516112ad939291906126fc565b60405180910390a3505050505092915050565b6001600055565b6001600160a01b0382166112ed5760405162461bcd60e51b815260040161042b90612404565b804710610ace576113076001600160a01b0383168261186a565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd8260405161133f91906126ba565b60405180910390a25050565b6001600160a01b0384166113715760405162461bcd60e51b815260040161042b90612404565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e9061139f90309087906004016122c0565b60206040518083038186803b1580156113b757600080fd5b505afa1580156113cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ef919061215f565b10610ca757604051637921219560e11b81526001600160a01b0384169063f242432a90611426903090889087908790600401612288565b600060405180830381600087803b15801561144057600080fd5b505af1158015611454573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b8460405161149c91906126ba565b60405180910390a450505050565b6005546040516370a0823160e01b81526000916001600160a01b0316906370a08231906114db903090600401612250565b60206040518083038186803b1580156114f357600080fd5b505afa158015611507573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d11919061215f565b61043f8363a9059cbb60e01b8484604051602401610eed9291906122c0565b606061159f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166119069092919063ffffffff16565b80519091501561043f57808060200190518101906115bd91906120a8565b61043f5760405162461bcd60e51b815260040161042b906125db565b6000610afe6127106115f96004600201548561191d90919063ffffffff16565b90611957565b6000828152600760205260408120805461161c5782915050610afe565b611624611bf3565b60025460405163836c478d60e01b81526001600160a01b039091169063836c478d906116549088906004016126ba565b60606040518083038186803b15801561166c57600080fd5b505afa158015611680573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a491906120f0565b80518354919250906000906116ba904390611828565b9050600080846040015111156116e457602084015160408501516116dd91611828565b90506116f7565b60208401516116f4904390611828565b90505b821580611702575080155b8061170b575081155b1561171d578695505050505050610afe565b818111156117285750805b600061173a836115f98461271061191d565b9050600061174e6127106115f98b8561191d565b9050600061176d6127106115f961176689606461191d565b859061191d565b9050600061177b8b84611828565b9050611787818361110b565b9c9b505050505050505050505050565b600480546040805163313ce56760e01b8152905160009384936001600160a01b03169263313ce5679281830192602092829003018186803b1580156117db57600080fd5b505afa1580156117ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118139190612198565b9050610a938360ff8316601203600a0a61191d565b6000610a9383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611999565b8047101561188a5760405162461bcd60e51b815260040161042b906124bb565b6000826001600160a01b0316826040516118a39061224d565b60006040518083038185875af1925050503d80600081146118e0576040519150601f19603f3d011682016040523d82523d6000602084013e6118e5565b606091505b505090508061043f5760405162461bcd60e51b815260040161042b9061245e565b606061191584846000856119c5565b949350505050565b60008261192c57506000610afe565b8282028284828161193957fe5b0414610a935760405162461bcd60e51b815260040161042b90612536565b6000610a9383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611a89565b600081848411156119bd5760405162461bcd60e51b815260040161042b9190612330565b505050900390565b60606119d085611ac0565b6119ec5760405162461bcd60e51b815260040161042b90612577565b60006060866001600160a01b03168587604051611a099190612231565b60006040518083038185875af1925050503d8060008114611a46576040519150601f19603f3d011682016040523d82523d6000602084013e611a4b565b606091505b50915091508115611a5f5791506119159050565b805115611a6f5780518082602001fd5b8360405162461bcd60e51b815260040161042b9190612330565b60008183611aaa5760405162461bcd60e51b815260040161042b9190612330565b506000838581611ab657fe5b0495945050505050565b3b151590565b604080516060810182526000808252602082018190529181019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611b275782800160ff19823516178555611b54565b82800160010185558215611b54579182015b82811115611b54578235825591602001919060010190611b39565b50611b60929150611c14565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611ba557805160ff1916838001178555611b54565b82800160010185558215611b54579182015b82811115611b54578251825591602001919060010190611bb7565b60405180606001604052806000815260200160008152602001606081525090565b60405180606001604052806000815260200160008152602001600081525090565b5b80821115611b605760008155600101611c15565b60008083601f840112611c3a578182fd5b50813567ffffffffffffffff811115611c51578182fd5b6020830191508360208083028501011115611c6b57600080fd5b9250929050565b60008083601f840112611c83578182fd5b50813567ffffffffffffffff811115611c9a578182fd5b602083019150836020828501011115611c6b57600080fd5b600060208284031215611cc3578081fd5b8135610a938161274a565b600060208284031215611cdf578081fd5b8151610a938161274a565b600080600060608486031215611cfe578182fd5b8335611d098161274a565b92506020840135611d198161274a565b929592945050506040919091013590565b60008060008060808587031215611d3f578081fd5b8435611d4a8161274a565b93506020850135611d5a8161274a565b93969395505050506040820135916060013590565b60008060408385031215611d81578182fd5b8235611d8c8161274a565b946020939093013593505050565b60008060008060008060008060a0898b031215611db5578384fd5b8835611dc08161274a565b97506020890135611dd08161274a565b9650604089013567ffffffffffffffff80821115611dec578586fd5b611df88c838d01611c29565b909850965060608b0135915080821115611e10578586fd5b611e1c8c838d01611c29565b909650945060808b0135915080821115611e34578384fd5b50611e418b828c01611c72565b999c989b5096995094979396929594505050565b60008060008060008060c08789031215611e6d578182fd5b8635611e788161274a565b95506020870135611e888161274a565b9450604087013593506060870135611e9f8161274a565b92506080870135611eaf8161274a565b915060a0870135611ebf8161274a565b809150509295509295509295565b600080600080600060808688031215611ee4578081fd5b8535611eef8161274a565b94506020860135611eff8161274a565b935060408601359250606086013567ffffffffffffffff811115611f21578182fd5b611f2d88828901611c72565b969995985093965092949392505050565b60008060008060008060a08789031215611f56578384fd5b8635611f618161274a565b95506020870135611f718161274a565b94506040870135935060608701359250608087013567ffffffffffffffff811115611f9a578283fd5b611fa689828a01611c72565b979a9699509497509295939492505050565b60008060008060608587031215611fcd578182fd5b8435611fd88161274a565b935060208501359250604085013567ffffffffffffffff811115611ffa578283fd5b61200687828801611c72565b95989497509550505050565b600080600080600060808688031215612029578283fd5b85356120348161274a565b945060208601359350604086013567ffffffffffffffff811115612056578384fd5b61206288828901611c72565b96999598509660600135949350505050565b600080600060608486031215612088578081fd5b83356120938161274a565b95602085013595506040909401359392505050565b6000602082840312156120b9578081fd5b81518015158114610a93578182fd5b6000602082840312156120d9578081fd5b81356001600160e01b031981168114610a93578182fd5b600060608284031215612101578081fd5b6040516060810181811067ffffffffffffffff82111715612120578283fd5b80604052508251815260208301516020820152604083015160408201528091505092915050565b600060208284031215612158578081fd5b5035919050565b600060208284031215612170578081fd5b5051919050565b60008060408385031215612189578182fd5b50508035926020909101359150565b6000602082840312156121a9578081fd5b815160ff81168114610a93578182fd5b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526121fb81602086016020860161271e565b601f01601f19169290920160200192915050565b60609290921b6bffffffffffffffffffffffff19168252601482015260340190565b6000825161224381846020870161271e565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b901515815260200190565b6001600160e01b031991909116815260200190565b6000602082526119156020830184866121b9565b600060208252610a9360208301846121e3565b6000602080830181845282855460018082166000811461236a5760018114612388576123c0565b60028304607f16855260ff19831660408901526060880193506123c0565b600283048086526123988a612712565b885b828110156123b65781548b82016040015290840190880161239a565b8a01604001955050505b5091979650505050505050565b60208082526017908201527f43616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252600890820152670a4a0748a5a6260760c31b604082015260600190565b60208082526008908201526752503a452d34303560c01b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b602080825260139082015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6000602082528251602083015260208301516040830152604083015160608084015261191560808401826121e3565b81516001600160a01b039081168252602080840151909116908201526040918201519181019190915260600190565b90815260200190565b6000858252606060208301526126dd6060830185876121b9565b905082604083015295945050505050565b918252602082015260400190565b9283526020830191909152604082015260600190565b60009081526020902090565b60005b83811015612739578181015183820152602001612721565b83811115610ca75750506000910152565b6001600160a01b038116811461275f57600080fd5b5056fea264697066735822122089923bf05c0e88235caef82d9eb9c338dbdb5c9a300cc0b182773089e351721e64736f6c634300060c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100935760003560e01c80636fe6fabb116100665780636fe6fabb146100fc578063715018a6146101045780638da5cb5b1461010c578063a0edb48b14610114578063f2fde38b1461012757610093565b80631593dee1146100985780634025feb2146100ad578063522f6815146100c05780636f9d5f78146100d3575b600080fd5b6100ab6100a6366004610be7565b61013a565b005b6100ab6100bb366004610be7565b610188565b6100ab6100ce366004610c6c565b6101c8565b6100e66100e1366004610c97565b61020b565b6040516100f39190610d55565b60405180910390f35b6100e661030b565b6100ab61031a565b6100e6610399565b6100ab610122366004610c27565b6103a8565b6100ab610135366004610ba8565b6103ef565b6101426104a5565b6000546001600160a01b039081169116146101785760405162461bcd60e51b815260040161016f90610f48565b60405180910390fd5b6101838383836104a9565b505050565b6101906104a5565b6000546001600160a01b039081169116146101bd5760405162461bcd60e51b815260040161016f90610f48565b6101838383836105b6565b6101d06104a5565b6000546001600160a01b039081169116146101fd5760405162461bcd60e51b815260040161016f90610f48565b6102078282610711565b5050565b60006102156104a5565b6000546001600160a01b039081169116146102425760405162461bcd60e51b815260040161016f90610f48565b60015460009061025a906001600160a01b0316610795565b9050806001600160a01b03811663ff9935cb89898989896102796104a5565b6040518763ffffffff1660e01b815260040161029a96959493929190610dc5565b600060405180830381600087803b1580156102b457600080fd5b505af11580156102c8573d6000803e3d6000fd5b50506040516001600160a01b03851692507f6ecb2838bef4560681475e8bb5e7feccefe33df915df2d6757024bc6fe4c616a9150600090a2509695505050505050565b6001546001600160a01b031681565b6103226104a5565b6000546001600160a01b0390811691161461034f5760405162461bcd60e51b815260040161016f90610f48565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b6103b06104a5565b6000546001600160a01b039081169116146103dd5760405162461bcd60e51b815260040161016f90610f48565b6103e9848484846107e7565b50505050565b6103f76104a5565b6000546001600160a01b039081169116146104245760405162461bcd60e51b815260040161016f90610f48565b6001600160a01b03811661044a5760405162461bcd60e51b815260040161016f90610e4b565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b0383166104cf5760405162461bcd60e51b815260040161016f90610e91565b6040516370a0823160e01b815281906001600160a01b038416906370a08231906104fd903090600401610d55565b60206040518083038186803b15801561051557600080fd5b505afa158015610529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061054d9190610d1e565b10610183576105666001600160a01b0383168483610946565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b836040516105a99190610ffe565b60405180910390a3505050565b6001600160a01b0383166105dc5760405162461bcd60e51b815260040161016f90610e91565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e9061060a908590600401610ffe565b60206040518083038186803b15801561062257600080fd5b505afa158015610636573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065a9190610bcb565b6001600160a01b03161415610183576040516323b872dd60e01b81526001600160a01b038316906323b872dd9061069990309087908690600401610d69565b600060405180830381600087803b1580156106b357600080fd5b505af11580156106c7573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b0382166107375760405162461bcd60e51b815260040161016f90610e91565b804710610207576107516001600160a01b0383168261099c565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd826040516107899190610ffe565b60405180910390a25050565b6000808260601b9050604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528160148201526e5af43d82803e903d91602b57fd5bf360881b60288201526037816000f0949350505050565b6001600160a01b03841661080d5760405162461bcd60e51b815260040161016f90610e91565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e9061083b9030908790600401610dff565b60206040518083038186803b15801561085357600080fd5b505afa158015610867573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088b9190610d1e565b106103e957604051637921219560e11b81526001600160a01b0384169063f242432a906108c2903090889087908790600401610d8d565b600060405180830381600087803b1580156108dc57600080fd5b505af11580156108f0573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b846040516109389190610ffe565b60405180910390a450505050565b6101838363a9059cbb60e01b8484604051602401610965929190610dff565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610a38565b804710156109bc5760405162461bcd60e51b815260040161016f90610f11565b6000826001600160a01b0316826040516109d590610d52565b60006040518083038185875af1925050503d8060008114610a12576040519150601f19603f3d011682016040523d82523d6000602084013e610a17565b606091505b50509050806101835760405162461bcd60e51b815260040161016f90610eb4565b6060610a8d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610ac79092919063ffffffff16565b8051909150156101835780806020019051810190610aab9190610cfe565b6101835760405162461bcd60e51b815260040161016f90610fb4565b6060610ad68484600085610ade565b949350505050565b6060610ae985610ba2565b610b055760405162461bcd60e51b815260040161016f90610f7d565b60006060866001600160a01b03168587604051610b229190610d36565b60006040518083038185875af1925050503d8060008114610b5f576040519150601f19603f3d011682016040523d82523d6000602084013e610b64565b606091505b50915091508115610b78579150610ad69050565b805115610b885780518082602001fd5b8360405162461bcd60e51b815260040161016f9190610e18565b3b151590565b600060208284031215610bb9578081fd5b8135610bc481611033565b9392505050565b600060208284031215610bdc578081fd5b8151610bc481611033565b600080600060608486031215610bfb578182fd5b8335610c0681611033565b92506020840135610c1681611033565b929592945050506040919091013590565b60008060008060808587031215610c3c578081fd5b8435610c4781611033565b93506020850135610c5781611033565b93969395505050506040820135916060013590565b60008060408385031215610c7e578182fd5b8235610c8981611033565b946020939093013593505050565b600080600080600060a08688031215610cae578081fd5b8535610cb981611033565b94506020860135610cc981611033565b9350604086013592506060860135610ce081611033565b91506080860135610cf081611033565b809150509295509295909350565b600060208284031215610d0f578081fd5b81518015158114610bc4578182fd5b600060208284031215610d2f578081fd5b5051919050565b60008251610d48818460208701611007565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b0396871681529486166020860152604085019390935290841660608401528316608083015290911660a082015260c00190565b6001600160a01b03929092168252602082015260400190565b6000602082528251806020840152610e37816040850160208701611007565b601f01601f19169190910160400192915050565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b90815260200190565b60005b8381101561102257818101518382015260200161100a565b838111156103e95750506000910152565b6001600160a01b038116811461104857600080fd5b5056fea2646970667358221220260383f23709db660967a522664682b39439430262c686f1ff999462e44f3aff64736f6c634300060c0033", + "devdoc": { + "kind": "dev", + "methods": { + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 4406, + "contract": "contracts/v1/incentives/RewardProgramFactory.sol:RewardProgramFactory", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 19454, + "contract": "contracts/v1/incentives/RewardProgramFactory.sol:RewardProgramFactory", + "label": "_template", + "offset": 0, + "slot": "1", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + } + } + } +} \ No newline at end of file diff --git a/deployments/goerli/UniverseRP.json b/deployments/goerli/UniverseRP.json new file mode 100644 index 0000000..af40812 --- /dev/null +++ b/deployments/goerli/UniverseRP.json @@ -0,0 +1,1177 @@ +{ + "address": "0x5618Fa2E1Cb2F0F4e55db1d3F83ac3dA14BCdc4B", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bosonToken", + "type": "address" + } + ], + "name": "BosonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "chargedParticles", + "type": "address" + } + ], + "name": "ChargedParticlesSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "photonSource", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "energy", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "ElectrostaticAttraction", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "photonSource", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "energy", + "type": "uint256" + } + ], + "name": "ElectrostaticDischarge", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "EsaMultiplierSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "leptonToken", + "type": "address" + } + ], + "name": "LeptonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + } + ], + "name": "NftDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + } + ], + "name": "NftRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "photonToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxSupply", + "type": "uint256" + } + ], + "name": "PhotonSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "protonToken", + "type": "address" + } + ], + "name": "ProtonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "quarkToken", + "type": "address" + } + ], + "name": "QuarkTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "RewardProgramRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardProgram", + "type": "address" + } + ], + "name": "RewardProgramSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [], + "name": "_chargedParticles", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_multiplierNft", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "uuid", + "type": "uint256" + } + ], + "name": "getNftStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositBlockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "releaseBlockNumber", + "type": "uint256" + } + ], + "internalType": "struct IUniverseRP.NftStake", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getRewardProgram", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nftTokenAmount", + "type": "uint256" + } + ], + "name": "onCovalentBond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nftTokenAmount", + "type": "uint256" + } + ], + "name": "onCovalentBreak", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creatorEnergy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onDischarge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onDischargeForCreator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assetAmount", + "type": "uint256" + } + ], + "name": "onEnergize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "newOwner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "salePrice", + "type": "uint256" + }, + { + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creatorRoyalties", + "type": "uint256" + } + ], + "name": "onProtonSale", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "creatorEnergy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onRelease", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "removeRewardProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "controller", + "type": "address" + } + ], + "name": "setChargedParticles", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + } + ], + "name": "setMultiplierNft", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "rewardProgam", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "setRewardProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0xf59e7ac181a04210addd00fd6e08c4d822126361f639391b1320caa86daaa82b", + "receipt": { + "to": null, + "from": "0x6d46b37708dA7Ed4E5C4509495768Fecd3D17C01", + "contractAddress": "0x5618Fa2E1Cb2F0F4e55db1d3F83ac3dA14BCdc4B", + "transactionIndex": 18, + "gasUsed": "769740", + "logsBloom": "0x00000000000000000000000000000000400000000000000000800000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000022000001000000000000000000000000000000000000020000000000000000000800000000800000000000000010000000400000000000000000000000000000000800000000040000000400000000800000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000800000400000000000000000020000000000000000200000000000000000000000000000000000000000020000000", + "blockHash": "0x775f0bd1b1d52b62ce1280ba7a5a5a55b1f900393b54f010eda639e155d17616", + "transactionHash": "0xf59e7ac181a04210addd00fd6e08c4d822126361f639391b1320caa86daaa82b", + "logs": [ + { + "transactionIndex": 18, + "blockNumber": 9608560, + "transactionHash": "0xf59e7ac181a04210addd00fd6e08c4d822126361f639391b1320caa86daaa82b", + "address": "0x5618Fa2E1Cb2F0F4e55db1d3F83ac3dA14BCdc4B", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000bbe78410e9cf6c1d68ab99f1c9595803c795cba5" + ], + "data": "0x", + "logIndex": 27, + "blockHash": "0x775f0bd1b1d52b62ce1280ba7a5a5a55b1f900393b54f010eda639e155d17616" + }, + { + "transactionIndex": 18, + "blockNumber": 9608560, + "transactionHash": "0xf59e7ac181a04210addd00fd6e08c4d822126361f639391b1320caa86daaa82b", + "address": "0x5618Fa2E1Cb2F0F4e55db1d3F83ac3dA14BCdc4B", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000006d46b37708da7ed4e5c4509495768fecd3d17c01" + ], + "data": "0x", + "logIndex": 28, + "blockHash": "0x775f0bd1b1d52b62ce1280ba7a5a5a55b1f900393b54f010eda639e155d17616" + }, + { + "transactionIndex": 18, + "blockNumber": 9608560, + "transactionHash": "0xf59e7ac181a04210addd00fd6e08c4d822126361f639391b1320caa86daaa82b", + "address": "0x5618Fa2E1Cb2F0F4e55db1d3F83ac3dA14BCdc4B", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d34060fa3ea8ac05aba386ac8cbb019c4594b204", + "logIndex": 29, + "blockHash": "0x775f0bd1b1d52b62ce1280ba7a5a5a55b1f900393b54f010eda639e155d17616" + } + ], + "blockNumber": 9608560, + "cumulativeGasUsed": "4929378", + "status": 1, + "byzantium": true + }, + "args": [ + "0xbbe78410e9cf6C1d68AB99f1c9595803C795cBA5", + "0xd34060fa3eA8AC05abA386ac8Cbb019C4594b204", + "0x8129fc1c" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev 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\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "execute": { + "methodName": "initialize", + "args": [] + }, + "implementation": "0xbbe78410e9cf6C1d68AB99f1c9595803C795cBA5", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/goerli/UniverseRP_Implementation.json b/deployments/goerli/UniverseRP_Implementation.json new file mode 100644 index 0000000..93cb645 --- /dev/null +++ b/deployments/goerli/UniverseRP_Implementation.json @@ -0,0 +1,1193 @@ +{ + "address": "0xbbe78410e9cf6C1d68AB99f1c9595803C795cBA5", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bosonToken", + "type": "address" + } + ], + "name": "BosonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "chargedParticles", + "type": "address" + } + ], + "name": "ChargedParticlesSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "photonSource", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "energy", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "ElectrostaticAttraction", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "photonSource", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "energy", + "type": "uint256" + } + ], + "name": "ElectrostaticDischarge", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "EsaMultiplierSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "leptonToken", + "type": "address" + } + ], + "name": "LeptonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + } + ], + "name": "NftDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + } + ], + "name": "NftRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "photonToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxSupply", + "type": "uint256" + } + ], + "name": "PhotonSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "protonToken", + "type": "address" + } + ], + "name": "ProtonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "quarkToken", + "type": "address" + } + ], + "name": "QuarkTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "RewardProgramRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardProgram", + "type": "address" + } + ], + "name": "RewardProgramSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [], + "name": "_chargedParticles", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_multiplierNft", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "uuid", + "type": "uint256" + } + ], + "name": "getNftStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositBlockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "releaseBlockNumber", + "type": "uint256" + } + ], + "internalType": "struct IUniverseRP.NftStake", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getRewardProgram", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nftTokenAmount", + "type": "uint256" + } + ], + "name": "onCovalentBond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nftTokenAmount", + "type": "uint256" + } + ], + "name": "onCovalentBreak", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creatorEnergy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onDischarge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onDischargeForCreator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assetAmount", + "type": "uint256" + } + ], + "name": "onEnergize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "newOwner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "salePrice", + "type": "uint256" + }, + { + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creatorRoyalties", + "type": "uint256" + } + ], + "name": "onProtonSale", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "creatorEnergy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onRelease", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "removeRewardProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "controller", + "type": "address" + } + ], + "name": "setChargedParticles", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + } + ], + "name": "setMultiplierNft", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "rewardProgam", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "setRewardProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x6c471f1d5332d95df9ed8b7b92d79a78d9cd8e5daf20149064f54a4a298773ae", + "receipt": { + "to": null, + "from": "0x6d46b37708dA7Ed4E5C4509495768Fecd3D17C01", + "contractAddress": "0xbbe78410e9cf6C1d68AB99f1c9595803C795cBA5", + "transactionIndex": 11, + "gasUsed": "2212048", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xb5bb7f91ccca06e871a394ed3143ebf999d159f04bef6773ff62afef11fc6e8c", + "transactionHash": "0x6c471f1d5332d95df9ed8b7b92d79a78d9cd8e5daf20149064f54a4a298773ae", + "logs": [], + "blockNumber": 9608559, + "cumulativeGasUsed": "5081674", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "39876b9d6995fafd8c4442fb1a03f418", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bosonToken\",\"type\":\"address\"}],\"name\":\"BosonTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"chargedParticles\",\"type\":\"address\"}],\"name\":\"ChargedParticlesSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"photonSource\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"energy\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"multiplier\",\"type\":\"uint256\"}],\"name\":\"ElectrostaticAttraction\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"photonSource\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"energy\",\"type\":\"uint256\"}],\"name\":\"ElectrostaticDischarge\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"multiplier\",\"type\":\"uint256\"}],\"name\":\"EsaMultiplierSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"leptonToken\",\"type\":\"address\"}],\"name\":\"LeptonTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"}],\"name\":\"NftDeposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"}],\"name\":\"NftRelease\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"photonToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxSupply\",\"type\":\"uint256\"}],\"name\":\"PhotonSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"protonToken\",\"type\":\"address\"}],\"name\":\"ProtonTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"quarkToken\",\"type\":\"address\"}],\"name\":\"QuarkTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"RewardProgramRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"rewardProgram\",\"type\":\"address\"}],\"name\":\"RewardProgramSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC1155\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckEther\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"_chargedParticles\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"_multiplierNft\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"uuid\",\"type\":\"uint256\"}],\"name\":\"getNftStake\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"multiplier\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"depositBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"releaseBlockNumber\",\"type\":\"uint256\"}],\"internalType\":\"struct IUniverseRP.NftStake\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"getRewardProgram\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"onCovalentBond\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"onCovalentBreak\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"creatorEnergy\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverEnergy\",\"type\":\"uint256\"}],\"name\":\"onDischarge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"receiverEnergy\",\"type\":\"uint256\"}],\"name\":\"onDischargeForCreator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"}],\"name\":\"onEnergize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"salePrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"creatorRoyalties\",\"type\":\"uint256\"}],\"name\":\"onProtonSale\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"principalAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creatorEnergy\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverEnergy\",\"type\":\"uint256\"}],\"name\":\"onRelease\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"removeRewardProgram\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"controller\",\"type\":\"address\"}],\"name\":\"setChargedParticles\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"}],\"name\":\"setMultiplierNft\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rewardProgam\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"setRewardProgram\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC1155\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawErc20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawEther\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Upgradeable Contract\",\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Charged Particles Universe Contract with Rewards Program\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/v1/UniverseRP.sol\":\"UniverseRP\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/Initializable.sol\\\";\\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 initializer {\\n __Context_init_unchained();\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal initializer {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), 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 emit OwnershipTransferred(_owner, address(0));\\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xb419e68addcb82ecda3ad3974b0d2db76435ce9b08435a04d5b119a0c5d45ea5\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <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\",\"keccak256\":\"0x4784c3f8a520a739dd25d76f514833a653990902d0e21601aed45bda44c87524\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMathUpgradeable {\\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 uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\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 if (b > a) return (false, 0);\\n return (true, a - b);\\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 // 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 * @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 if (b == 0) return (false, 0);\\n return (true, a / b);\\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 if (b == 0) return (false, 0);\\n return (true, a % b);\\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 uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\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 require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\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 if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\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. 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(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\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 require(b > 0, \\\"SafeMath: modulo by zero\\\");\\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x0dd1e9b19801e3e7d900fbf4182d81e1afd23ad7be39504e33df6bbcba91d724\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// solhint-disable-next-line compiler-version\\npragma solidity >=0.4.24 <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 {UpgradeableProxy-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 */\\nabstract contract Initializable {\\n\\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 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 /// @dev Returns true if and only if the function is running in the constructor\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0xd8e4eb08dcc1d1860fb347ba5ffd595242b9a1b66d49a47f2b4cb51c3f35017e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0xa1931c47a617014f858580db625aa0dcf343796f39acd4b5b51effc092a1f0a9\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"../../math/SafeMathUpgradeable.sol\\\";\\nimport \\\"../../utils/AddressUpgradeable.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 SafeERC20Upgradeable {\\n using SafeMathUpgradeable for uint256;\\n using AddressUpgradeable for address;\\n\\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) 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(IERC20Upgradeable token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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(IERC20Upgradeable 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) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x8457e15aa90badabe0d6ef6f572f1ebd47bebf156921c825ae6e009dda15b706\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.2 <0.8.0;\\n\\nimport \\\"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x3dab19bb4a63bcbda1ee153ca291694f92f9009fad28626126b15a8503b0e5ff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.2 <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 // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) 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 // solhint-disable-next-line avoid-low-level-calls\\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(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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 // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfc5ea91fa9ceb1961023b2a6c978b902888c52b90847ac7813fe3b79524165f6\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\nimport \\\"../proxy/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 GSN 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 initializer {\\n __Context_init_unchained();\\n }\\n\\n function __Context_init_unchained() internal initializer {\\n }\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xbbf8a21b9a66c48d45ff771b8563c6df19ba451d63dfb8380a865c1e1f29d1a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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\",\"keccak256\":\"0xfa152b6e88a1dc50780e8f1580426dc23ad2e1e2c2f086a088adf206a202f453\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\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 uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\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 sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\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 * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\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 // 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) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts 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 mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9a9cf02622cd7a64261b10534fc3260449da25c98c9e96d1b4ae8110a20e5806\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x31691ad0817f8cb338531b78d2ab2989027d9f27e6f8e62492b754fed9429b10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0x5c26b39d26f7ed489e555d955dcd3e01872972e71fdd1528e93ec164e4f23385\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.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 SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf3b30f8a49631420635a8c35daacfcaa338012755f18a76fdd118730256f9a27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0xaf936da92f3a9a4f98b237323b5eb1d813fb86c4d07a184beba7027cf0509ba3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 in 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 // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n return _functionCallWithValue(target, data, value, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\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 // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf5fa8cbdffa5ef8be49b246b5628facc30b71707e78a45d80d93b64eff3fe390\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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.0.0, only sets of type `address` (`AddressSet`) and `uint256`\\n * (`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\\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\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] = toDeleteIndex + 1; // All indexes are 1-based\\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 require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\n return set._values[index];\\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(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(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(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(uint256(_at(set._inner, index)));\\n }\\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\",\"keccak256\":\"0xb2a11b236f073662f5a196995863f51c11d006bf7c3de158b316dfa1506c4b79\",\"license\":\"MIT\"},\"contracts/v1/UniverseRP.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// Universe.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/EnumerableSet.sol\\\";\\n\\nimport \\\"./interfaces/IUniverseRP.sol\\\";\\nimport \\\"./interfaces/IChargedParticles.sol\\\";\\nimport \\\"./interfaces/ILepton.sol\\\";\\nimport \\\"./interfaces/IRewardNft.sol\\\";\\nimport \\\"./lib/TokenInfo.sol\\\";\\nimport \\\"./lib/BlackholePrevention.sol\\\";\\nimport \\\"./interfaces/IRewardProgram.sol\\\";\\n\\n/**\\n * @notice Charged Particles Universe Contract with Rewards Program\\n * @dev Upgradeable Contract\\n */\\ncontract UniverseRP is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\\n using SafeMathUpgradeable for uint256;\\n using TokenInfo for address;\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n using EnumerableSet for EnumerableSet.UintSet;\\n\\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\\n\\n // The ChargedParticles Contract Address\\n address public _chargedParticles;\\n\\n // The Lepton NFT Contract Address\\n address public _multiplierNft;\\n\\n // Asset Token => Reward Program\\n mapping (address => address) internal _assetRewardPrograms;\\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\\n\\n // Token UUID => NFT Staking Data\\n mapping (uint256 => NftStake) private _nftStake;\\n\\n\\n /***********************************|\\n | Initialization |\\n |__________________________________*/\\n\\n function initialize() public initializer {\\n __Ownable_init();\\n }\\n\\n function getRewardProgram(address asset) external view override returns (address) {\\n return _getRewardProgram(asset);\\n }\\n\\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\\n return _nftStake[uuid];\\n }\\n\\n /***********************************|\\n | Only Charged Particles |\\n |__________________________________*/\\n\\n function onEnergize(\\n address /* sender */,\\n address /* referrer */,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n address rewardProgram = _getRewardProgram(assetToken);\\n if (rewardProgram != address(0)) {\\n IRewardProgram(rewardProgram).registerAssetDeposit(\\n contractAddress,\\n tokenId,\\n walletManagerId,\\n assetAmount\\n );\\n }\\n }\\n\\n function onDischarge(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* walletManagerId */,\\n address assetToken,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n address rewardProgram = _getRewardProgram(assetToken);\\n if (rewardProgram != address(0)) {\\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\\n }\\n }\\n\\n function onDischargeForCreator(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* walletManagerId */,\\n address /* creator */,\\n address assetToken,\\n uint256 receiverEnergy\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n address rewardProgram = _getRewardProgram(assetToken);\\n if (rewardProgram != address(0)) {\\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\\n }\\n }\\n\\n function onRelease(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* walletManagerId */,\\n address assetToken,\\n uint256 principalAmount,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n address rewardProgram = _getRewardProgram(assetToken);\\n if (rewardProgram != address(0)) {\\n // \\\"receiverEnergy\\\" includes the \\\"principalAmount\\\"\\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\\n }\\n }\\n\\n function onCovalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* managerId */,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\\n }\\n\\n function onCovalentBreak(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* managerId */,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\\n }\\n\\n function onProtonSale(\\n address contractAddress,\\n uint256 tokenId,\\n address oldOwner,\\n address newOwner,\\n uint256 salePrice,\\n address creator,\\n uint256 creatorRoyalties\\n )\\n external\\n virtual\\n override\\n {\\n // no-op\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n |__________________________________*/\\n\\n function setChargedParticles(\\n address controller\\n )\\n external\\n onlyOwner\\n onlyValidContractAddress(controller)\\n {\\n _chargedParticles = controller;\\n emit ChargedParticlesSet(controller);\\n }\\n\\n function setMultiplierNft(address nftTokenAddress)\\n external\\n onlyOwner\\n onlyValidContractAddress(nftTokenAddress)\\n {\\n _multiplierNft = nftTokenAddress;\\n }\\n\\n function setRewardProgram(\\n address rewardProgam,\\n address assetToken\\n )\\n external\\n onlyOwner\\n onlyValidContractAddress(rewardProgam)\\n {\\n require(assetToken != address(0x0), \\\"UNI:E-403\\\");\\n _assetRewardPrograms[assetToken] = rewardProgam;\\n emit RewardProgramSet(assetToken, rewardProgam);\\n }\\n\\n function removeRewardProgram(address assetToken) external onlyOwner {\\n delete _assetRewardPrograms[assetToken];\\n emit RewardProgramRemoved(assetToken);\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n | (blackhole prevention) |\\n |__________________________________*/\\n\\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n\\n\\n /***********************************|\\n | Private Functions |\\n |__________________________________*/\\n\\n function _getRewardProgram(address assetToken) internal view returns (address) {\\n return _assetRewardPrograms[assetToken];\\n }\\n\\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\\n internal\\n {\\n // We only care about the Multiplier NFT\\n if (_multiplierNft != depositNftAddress) { return; }\\n\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n uint256 multiplier = _getNftMultiplier(depositNftAddress, depositNftTokenId);\\n\\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\\n // Add to Multipliers Set\\n _multiplierNftsSet[parentNftUuid].add(multiplier);\\n\\n // Update NFT Stake\\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\\n } else {\\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\\n }\\n }\\n\\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\\n }\\n\\n function _registerNftRelease(\\n address contractAddress,\\n uint256 tokenId,\\n address releaseNftAddress,\\n uint256 releaseNftTokenId,\\n uint256 /* nftTokenAmount */\\n )\\n internal\\n {\\n // We only care about the Multiplier NFT\\n if (_multiplierNft != releaseNftAddress) { return; }\\n\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n NftStake storage nftStake = _nftStake[parentNftUuid];\\n\\n // Remove from Multipliers Set\\n uint256 multiplier = _getNftMultiplier(releaseNftAddress, releaseNftTokenId);\\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\\n\\n // Determine New Multiplier or Mark as Released\\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\\n } else {\\n nftStake.releaseBlockNumber = block.number;\\n }\\n\\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\\n }\\n\\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\\n uint256 multiplier = 0;\\n uint256 loss = 50;\\n uint256 i = 0;\\n\\n for (; i < len; i++) {\\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\\n }\\n if (len > 1) {\\n multiplier = multiplier.sub(loss.mul(len));\\n }\\n return multiplier;\\n }\\n\\n function _getNftMultiplier(address contractAddress, uint256 tokenId) internal returns (uint256) {\\n bytes4 fnSig = IRewardNft.getMultiplier.selector;\\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\\n\\n if (success) {\\n return abi.decode(returnData, (uint256));\\n } else {\\n return 0;\\n }\\n }\\n\\n\\n /***********************************|\\n | Modifiers |\\n |__________________________________*/\\n\\n /// @dev Throws if called by any non-account\\n modifier onlyValidContractAddress(address account) {\\n require(account != address(0x0) && account.isContract(), \\\"UNI:E-417\\\");\\n _;\\n }\\n\\n /// @dev Throws if called by any account other than the Charged Particles contract\\n modifier onlyChargedParticles() {\\n require(_chargedParticles == msg.sender, \\\"UNI:E-108\\\");\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x5ec2e8a1bbcbb7cc8bb11a500e29df20aaa34c76a3c6963b508a377da076ba0b\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IChargedParticles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @notice Interface for Charged Particles\\n */\\ninterface IChargedParticles {\\n\\n /***********************************|\\n | Public API |\\n |__________________________________*/\\n\\n function getStateAddress() external view returns (address stateAddress);\\n function getSettingsAddress() external view returns (address settingsAddress);\\n function getManagersAddress() external view returns (address managersAddress);\\n\\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\\n\\n /***********************************|\\n | Particle Mechanics |\\n |__________________________________*/\\n\\n function energizeParticle(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount,\\n address referrer\\n ) external returns (uint256 yieldTokensAmount);\\n\\n function dischargeParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function dischargeParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function dischargeParticleForCreator(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 receiverAmount);\\n\\n function releaseParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function releaseParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function covalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success);\\n\\n function breakCovalentBond(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success);\\n\\n /***********************************|\\n | Particle Events |\\n |__________________________________*/\\n\\n event Initialized(address indexed initiator);\\n event ControllerSet(address indexed controllerAddress, string controllerId);\\n event DepositFeeSet(uint256 depositFee);\\n event ProtocolFeesCollected(address indexed assetToken, uint256 depositAmount, uint256 feesCollected);\\n}\\n\",\"keccak256\":\"0x37104c629e40193ddc8677af8a632adf53754e7915f055a5a14861cd9b417729\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IERC721Chargeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IERC721Chargeable.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\\\";\\n\\ninterface IERC721Chargeable is IERC165Upgradeable {\\n function owner() external view returns (address);\\n function creatorOf(uint256 tokenId) external view returns (address);\\n function balanceOf(address tokenOwner) external view returns (uint256 balance);\\n function ownerOf(uint256 tokenId) external view returns (address tokenOwner);\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n function transferFrom(address from, address to, uint256 tokenId) external;\\n function approve(address to, uint256 tokenId) external;\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n function setApprovalForAll(address operator, bool _approved) external;\\n function isApprovedForAll(address tokenOwner, address operator) external view returns (bool);\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x459e57b2d35c7cd78e6c3d47eb9f3e981529a18c89e2c318b10fe369c479c737\",\"license\":\"MIT\"},\"contracts/v1/interfaces/ILepton.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// ILepton.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Charged Particles Lepton Interface\\n * @dev ...\\n */\\ninterface ILepton {\\n\\n struct Classification {\\n string tokenUri;\\n uint256 price;\\n uint128 _upperBounds;\\n uint32 supply;\\n uint32 multiplier;\\n uint32 bonus;\\n }\\n\\n function mintLepton() external payable returns (uint256 newTokenId);\\n function batchMintLepton(uint256 count) external payable;\\n function getNextType() external view returns (uint256);\\n function getNextPrice() external view returns (uint256);\\n function getMultiplier(uint256 tokenId) external view returns (uint256);\\n function getBonus(uint256 tokenId) external view returns (uint256);\\n\\n\\n event MaxMintPerTxSet(uint256 maxAmount);\\n event LeptonTypeAdded(string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\\n event LeptonTypeUpdated(uint256 leptonIndex, string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\\n event LeptonMinted(address indexed receiver, uint256 indexed tokenId, uint256 price, uint32 multiplier);\\n event LeptonBatchMinted(address indexed receiver, uint256 indexed tokenId, uint256 count, uint256 price, uint32 multiplier);\\n event PausedStateSet(bool isPaused);\\n}\\n\",\"keccak256\":\"0x4903085427fa5dbee690fe79854fba60afaf21189957406ade55f6fc12556a01\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IRewardNft.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IRewardNft.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Charged Particles Reward-NFT Interface\\n * @dev ...\\n */\\ninterface IRewardNft {\\n function getMultiplier(uint256 tokenId) external view returns (uint256);\\n function getBonus(uint256 tokenId) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x51a5666003af460a55356974a286dde959c5f166104c75b4d563e8294a90b07a\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IRewardProgram.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IRewardProgram.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\npragma experimental ABIEncoderV2;\\n\\ninterface IRewardProgram {\\n /* admin events */\\n event RewardProgramFunded(uint256 amount);\\n event RewardProgramOutOfFunds();\\n\\n /* user events */\\n event RewardsClaimed(address indexed contractAddress, uint256 tokenId, address indexed receiver, uint256 rewarded, uint256 remaining);\\n\\n event AssetRegistered(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\\n event AssetDeposit(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\\n event AssetRelease(address indexed contractAddress, uint256 tokenId, uint256 interestAmount);\\n\\n /* data types */\\n struct ProgramRewardData {\\n address stakingToken;\\n address rewardToken;\\n uint256 baseMultiplier; // Basis Points\\n }\\n\\n struct AssetStake {\\n uint256 start;\\n uint256 claimableRewards;\\n string walletManagerId;\\n }\\n\\n function initialize(address stakingToken, address rewardToken, uint256 baseMultiplier, address chargedManagers, address universe, address owner) external;\\n\\n /* user functions */\\n function getProgramData() external view returns (ProgramRewardData memory programData);\\n function getAssetStake(uint256 uuid) external view returns (AssetStake memory);\\n function getFundBalance() external view returns (uint256);\\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) external view returns (uint256);\\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view returns (uint256);\\n\\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external;\\n function registerAssetDeposit(address contractAddress, uint256 tokenId, string calldata walletManagerId, uint256 principalAmount) external;\\n function registerAssetRelease(address contractAddress, uint256 tokenId, uint256 interestAmount) external returns (uint256 rewards);\\n}\",\"keccak256\":\"0xe0f4076a4b001856c54cb8a63decedc81ca34c71708f8cbe9b3a26603dc9c050\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IUniverse.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IUniverse.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Universal Controller interface\\n * @dev ...\\n */\\ninterface IUniverse {\\n\\n event ChargedParticlesSet(address indexed chargedParticles);\\n event PhotonSet(address indexed photonToken, uint256 maxSupply);\\n event ProtonTokenSet(address indexed protonToken);\\n event LeptonTokenSet(address indexed leptonToken);\\n event QuarkTokenSet(address indexed quarkToken);\\n event BosonTokenSet(address indexed bosonToken);\\n event EsaMultiplierSet(address indexed assetToken, uint256 multiplier);\\n event ElectrostaticAttraction(address indexed account, address photonSource, uint256 energy, uint256 multiplier);\\n event ElectrostaticDischarge(address indexed account, address photonSource, uint256 energy);\\n\\n function onEnergize(\\n address sender,\\n address referrer,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 assetEnergy\\n ) external;\\n\\n function onDischarge(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onDischargeForCreator(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address creator,\\n address assetToken,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onRelease(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 principalEnergy,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onCovalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n\\n function onCovalentBreak(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n\\n function onProtonSale(\\n address contractAddress,\\n uint256 tokenId,\\n address oldOwner,\\n address newOwner,\\n uint256 salePrice,\\n address creator,\\n uint256 creatorRoyalties\\n ) external;\\n}\\n\",\"keccak256\":\"0x6cebb97ce4d32c61afc746e4a6538eb605bb01276dfa66fa4bd6f63362bdc9ef\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IUniverseRP.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IUniverseRP.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"./IUniverse.sol\\\";\\n\\n/**\\n * @title Universal Controller interface for Rewards Program\\n * @dev ...\\n */\\ninterface IUniverseRP is IUniverse {\\n event RewardProgramSet(address indexed assetToken, address indexed rewardProgram);\\n event RewardProgramRemoved(address indexed assetToken);\\n event NftDeposit(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\\n event NftRelease(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\\n\\n struct NftStake {\\n uint256 multiplier; // in Basis Points\\n uint256 depositBlockNumber;\\n uint256 releaseBlockNumber;\\n }\\n\\n function getRewardProgram(address asset) external view returns (address);\\n function getNftStake(uint256 uuid) external view returns (NftStake memory);\\n}\\n\",\"keccak256\":\"0xd9c5a996bbb7f2a27bb85dde52587f7368c7b6512fc1064821a3975acdf4b7db\",\"license\":\"MIT\"},\"contracts/v1/lib/BlackholePrevention.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\\\";\\n\\n/**\\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\\n * the Owner/DAO to pull them out on behalf of a user\\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\\n */\\ncontract BlackholePrevention {\\n using Address for address payable;\\n using SafeERC20 for IERC20;\\n\\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\\n\\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (address(this).balance >= amount) {\\n receiver.sendValue(amount);\\n emit WithdrawStuckEther(receiver, amount);\\n }\\n }\\n\\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\\n IERC20(tokenAddress).safeTransfer(receiver, amount);\\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\\n }\\n }\\n\\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\\n }\\n }\\n\\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \\\"\\\");\\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6a664c8a1c1d7fb32ade2c11f75756b1fdb4c489daa32c1d58e6b867ea2ba8d6\",\"license\":\"MIT\"},\"contracts/v1/lib/TokenInfo.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// TokenInfo.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport \\\"../interfaces/IERC721Chargeable.sol\\\";\\n\\nlibrary TokenInfo {\\n function getTokenUUID(address contractAddress, uint256 tokenId) internal pure virtual returns (uint256) {\\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n function getTokenOwner(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n return tokenInterface.ownerOf(tokenId);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n function getTokenCreator(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n return tokenInterface.creatorOf(tokenId);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Owner of an External NFT contract\\n /// @param contractAddress The Address to the Contract of the NFT to check\\n /// @param account The Address of the Account to check\\n /// @return True if the account owns the contract\\n function isContractOwner(address contractAddress, address account) internal view virtual returns (bool) {\\n address contractOwner = IERC721Chargeable(contractAddress).owner();\\n return contractOwner != address(0x0) && contractOwner == account;\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Creator of a Proton-based NFT\\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\\n /// @param tokenId The Token ID of the Proton-based NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the creator of the Proton-based NFT\\n function isTokenCreator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenCreator = tokenInterface.creatorOf(tokenId);\\n return (sender == tokenCreator);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\\n /// @param tokenId The Token ID of the Proton-based NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the creator of the Proton-based NFT or the Contract itself\\n function isTokenContractOrCreator(address contractAddress, uint256 tokenId, address creator, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenCreator = tokenInterface.creatorOf(tokenId);\\n if (sender == contractAddress && creator == tokenCreator) { return true; }\\n return (sender == tokenCreator);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Owner or Operator of an External NFT\\n /// @param contractAddress The Address to the Contract of the External NFT to check\\n /// @param tokenId The Token ID of the External NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the Owner or Operator of the External NFT\\n function isErc721OwnerOrOperator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenOwner = tokenInterface.ownerOf(tokenId);\\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\\n }\\n\\n /**\\n * @dev Returns true if `account` is a contract.\\n * @dev Taken from OpenZeppelin library\\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { codehash := extcodehash(account) }\\n return (codehash != accountHash && codehash != 0x0);\\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 * @dev Taken from OpenZeppelin library\\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, uint256 gasLimit) internal {\\n require(address(this).balance >= amount, \\\"TokenInfo: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = (gasLimit > 0)\\n ? recipient.call{ value: amount, gas: gasLimit }(\\\"\\\")\\n : recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"TokenInfo: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0xbc78c6173db068d95084288246642402d0f4af399e1eb754182cae2d9173af5e\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061270a806100206000396000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c80638da5cb5b116100c3578063b9e09b4b1161007c578063b9e09b4b1461028e578063bbf1da84146102a1578063bea38be0146102a9578063c5d1d706146102bc578063f2fde38b146102cf578063fbf5ca14146102e25761014d565b80638da5cb5b14610227578063945233e21461022f57806395469dfc146102425780639a87c0de14610255578063a0edb48b14610268578063aa29542d1461027b5761014d565b8063522f681511610115578063522f6815146101be5780636e5559fd146101d1578063715018a6146101e45780638129fc1c146101ec578063836c478d146101f45780638b9309b2146102145761014d565b80631593dee1146101525780632bdbb77f1461016757806330219ef41461017a5780634025feb21461019857806341db85d6146101ab575b600080fd5b610165610160366004611d6c565b6102f5565b005b610165610175366004611ffc565b61034d565b61018261038d565b60405161018f919061219b565b60405180910390f35b6101656101a6366004611d6c565b61039c565b6101656101b9366004611ffc565b6103e6565b6101656101cc366004611df1565b6104ca565b6101656101df366004611d34565b610517565b6101656105e3565b61016561066c565b61020761020236600461212a565b6106f7565b60405161018f919061265b565b610165610222366004611ef4565b610384565b610182610738565b61016561023d366004611d34565b610747565b610165610250366004611e1c565b6107d5565b610165610263366004611d34565b6108d4565b610165610276366004611dac565b610978565b610165610289366004611f6e565b6109c9565b61016561029c366004611e54565b610a9c565b610182610b53565b6101656102b7366004611ffc565b610b62565b6101826102ca366004611d34565b610b99565b6101656102dd366004611d34565b610baa565b6101656102f0366004612080565b610c6b565b6102fd610d59565b6001600160a01b031661030e610738565b6001600160a01b03161461033d5760405162461bcd60e51b815260040161033490612582565b60405180910390fd5b610348838383610d5d565b505050565b6065546001600160a01b031633146103775760405162461bcd60e51b8152600401610334906125b7565b6103848787858585610e6a565b50505050505050565b6065546001600160a01b031681565b6103a4610d59565b6001600160a01b03166103b5610738565b6001600160a01b0316146103db5760405162461bcd60e51b815260040161033490612582565b610348838383610ffd565b6065546001600160a01b031633146104105760405162461bcd60e51b8152600401610334906125b7565b600061041b84611158565b90506001600160a01b038116156104c05760006104388385611176565b604051631434318f60e21b81529091506001600160a01b038316906350d0c63c9061046b908c908c908690600401612275565b602060405180830381600087803b15801561048557600080fd5b505af1158015610499573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bd9190612142565b50505b5050505050505050565b6104d2610d59565b6001600160a01b03166104e3610738565b6001600160a01b0316146105095760405162461bcd60e51b815260040161033490612582565b61051382826111a2565b5050565b61051f610d59565b6001600160a01b0316610530610738565b6001600160a01b0316146105565760405162461bcd60e51b815260040161033490612582565b806001600160a01b0381161580159061057c575061057c816001600160a01b0316611226565b6105985760405162461bcd60e51b815260040161033490612397565b606580546001600160a01b0319166001600160a01b0384169081179091556040517f5ce0e6b7fd36339ee97339831b6c72694ecee88c62aab49919d9cabe0a732e4190600090a25050565b6105eb610d59565b6001600160a01b03166105fc610738565b6001600160a01b0316146106225760405162461bcd60e51b815260040161033490612582565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b600054610100900460ff16806106855750610685611262565b80610693575060005460ff16155b6106af5760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff161580156106da576000805460ff1961ff0019909116610100171660011790555b6106e2611273565b80156106f4576000805461ff00191690555b50565b6106ff611ccc565b50600090815260696020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b6033546001600160a01b031690565b61074f610d59565b6001600160a01b0316610760610738565b6001600160a01b0316146107865760405162461bcd60e51b815260040161033490612582565b6001600160a01b03811660008181526067602052604080822080546001600160a01b0319169055517f87e1027e3dc61d1977f39f0dfe911b66a943946b4ceb39210dee01495621de529190a250565b6107dd610d59565b6001600160a01b03166107ee610738565b6001600160a01b0316146108145760405162461bcd60e51b815260040161033490612582565b816001600160a01b0381161580159061083a575061083a816001600160a01b0316611226565b6108565760405162461bcd60e51b815260040161033490612397565b6001600160a01b03821661087c5760405162461bcd60e51b81526004016103349061230b565b6001600160a01b0382811660008181526067602052604080822080546001600160a01b0319169488169485179055517f3b76c6366ef8a1f8d2dbb75e4be27be1e0749716fff3e6bc327da9c6158deada9190a3505050565b6108dc610d59565b6001600160a01b03166108ed610738565b6001600160a01b0316146109135760405162461bcd60e51b815260040161033490612582565b806001600160a01b038116158015906109395750610939816001600160a01b0316611226565b6109555760405162461bcd60e51b815260040161033490612397565b50606680546001600160a01b0319166001600160a01b0392909216919091179055565b610980610d59565b6001600160a01b0316610991610738565b6001600160a01b0316146109b75760405162461bcd60e51b815260040161033490612582565b6109c3848484846112f1565b50505050565b6065546001600160a01b031633146109f35760405162461bcd60e51b8152600401610334906125b7565b60006109fe83611158565b90506001600160a01b038116156104c057604051631434318f60e21b81526001600160a01b038216906350d0c63c90610a3f908b908b908790600401612275565b602060405180830381600087803b158015610a5957600080fd5b505af1158015610a6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a919190612142565b505050505050505050565b6065546001600160a01b03163314610ac65760405162461bcd60e51b8152600401610334906125b7565b6000610ad183611158565b90506001600160a01b03811615610a91576040516323632fb160e11b81526001600160a01b038216906346c65f6290610b16908a908a908a908a908990600401612224565b600060405180830381600087803b158015610b3057600080fd5b505af1158015610b44573d6000803e3d6000fd5b50505050505050505050505050565b6066546001600160a01b031681565b6065546001600160a01b03163314610b8c5760405162461bcd60e51b8152600401610334906125b7565b6103848787858585611450565b6000610ba482611158565b92915050565b610bb2610d59565b6001600160a01b0316610bc3610738565b6001600160a01b031614610be95760405162461bcd60e51b815260040161033490612582565b6001600160a01b038116610c0f5760405162461bcd60e51b81526004016103349061232e565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6065546001600160a01b03163314610c955760405162461bcd60e51b8152600401610334906125b7565b6000610ca085611158565b90506001600160a01b03811615610a91576000610cc784610cc18588611541565b90611176565b604051631434318f60e21b81529091506001600160a01b038316906350d0c63c90610cfa908d908d908690600401612275565b602060405180830381600087803b158015610d1457600080fd5b505af1158015610d28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4c9190612142565b5050505050505050505050565b3390565b6001600160a01b038316610d835760405162461bcd60e51b815260040161033490612374565b6040516370a0823160e01b815281906001600160a01b038416906370a0823190610db190309060040161219b565b60206040518083038186803b158015610dc957600080fd5b505afa158015610ddd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e019190612142565b1061034857610e1a6001600160a01b0383168483611569565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b83604051610e5d919061267c565b60405180910390a3505050565b6066546001600160a01b03848116911614610e8457610ff6565b6000610e996001600160a01b038716866115bf565b90506000610ea785856115f3565b9050600081118015610ece57506000828152606860205260409020610ecc90826116d5565b155b15610fa6576000828152606860205260409020610eeb90826116e1565b506000610ef7836116ed565b600084815260696020526040902060010154909150610f5157604080516060810182528281524360208083019182526000838501818152888252606990925293909320915182555160018201559051600290910155610fa4565b60008381526069602052604090206001810154908290554303610f90610f7882600261176d565b60008681526069602052604090206001015490611176565b600085815260696020526040902060010155505b505b846001600160a01b0316876001600160a01b03167f186ebbe503be539e070ca73b33a78f4266d96003e62b888dc31f88a39ddc9c878887604051610feb929190612685565b60405180910390a350505b5050505050565b6001600160a01b0383166110235760405162461bcd60e51b815260040161033490612374565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e9061105190859060040161267c565b60206040518083038186803b15801561106957600080fd5b505afa15801561107d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a19190611d50565b6001600160a01b03161415610348576040516323b872dd60e01b81526001600160a01b038316906323b872dd906110e0903090879086906004016121af565b600060405180830381600087803b1580156110fa57600080fd5b505af115801561110e573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b039081166000908152606760205260409020541690565b60008282018381101561119b5760405162461bcd60e51b8152600401610334906123ba565b9392505050565b6001600160a01b0382166111c85760405162461bcd60e51b815260040161033490612374565b804710610513576111e26001600160a01b0383168261179f565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd8260405161121a919061267c565b60405180910390a25050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061125a57508115155b949350505050565b600061126d3061183b565b15905090565b600054610100900460ff168061128c575061128c611262565b8061129a575060005460ff16155b6112b65760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff161580156112e1576000805460ff1961ff0019909116610100171660011790555b6112e9611841565b6106e26118c2565b6001600160a01b0384166113175760405162461bcd60e51b815260040161033490612374565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e90611345903090879060040161220b565b60206040518083038186803b15801561135d57600080fd5b505afa158015611371573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113959190612142565b106109c357604051637921219560e11b81526001600160a01b0384169063f242432a906113cc9030908890879087906004016121d3565b600060405180830381600087803b1580156113e657600080fd5b505af11580156113fa573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b84604051611442919061267c565b60405180910390a450505050565b6066546001600160a01b0384811691161461146a57610ff6565b600061147f6001600160a01b038716866115bf565b600081815260696020526040812091925061149a86866115f3565b60008481526068602052604090209091506114b5908261199c565b5060008381526068602052604081206114cd906119a8565b11156114e3576114dc836116ed565b82556114ea565b4360028301555b856001600160a01b0316886001600160a01b03167ff3cfcfc091fdd683cf6c013de9806af93f3af27b256a57cb776331291cef4085898860405161152f929190612685565b60405180910390a35050505050505050565b6000828211156115635760405162461bcd60e51b8152600401610334906123f1565b50900390565b6103488363a9059cbb60e01b848460405160240161158892919061220b565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526119b3565b600082826040516020016115d492919061215a565b60408051601f1981840301815291905280516020909101209392505050565b60008063adf8252d60e01b905060006060856001600160a01b03168386604051602401611620919061267c565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161165e919061217c565b6000604051808303816000865af19150503d806000811461169b576040519150601f19603f3d011682016040523d82523d6000602084013e6116a0565b606091505b509150915081156116c957808060200190518101906116bf9190612142565b9350505050610ba4565b60009350505050610ba4565b600061119b8383611a42565b600061119b8383611a5a565b60008181526068602052604081208190611706906119a8565b905060006032815b83811015611743576000868152606860205260409020611739906117329083611aa4565b8490611176565b925060010161170e565b6001841115611763576117606117598386611ab0565b8490611541565b92505b5090949350505050565b600080821161178e5760405162461bcd60e51b8152600401610334906124bc565b81838161179757fe5b049392505050565b804710156117bf5760405162461bcd60e51b815260040161033490612485565b6000826001600160a01b0316826040516117d890612198565b60006040518083038185875af1925050503d8060008114611815576040519150601f19603f3d011682016040523d82523d6000602084013e61181a565b606091505b50509050806103485760405162461bcd60e51b815260040161033490612428565b3b151590565b600054610100900460ff168061185a575061185a611262565b80611868575060005460ff16155b6118845760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff161580156106e2576000805460ff1961ff00199091166101001716600117905580156106f4576000805461ff001916905550565b600054610100900460ff16806118db57506118db611262565b806118e9575060005460ff16155b6119055760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff16158015611930576000805460ff1961ff0019909116610100171660011790555b600061193a610d59565b603380546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35080156106f4576000805461ff001916905550565b600061119b8383611aea565b6000610ba482611bb0565b6060611a08826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611bb49092919063ffffffff16565b8051909150156103485780806020019051810190611a26919061210a565b6103485760405162461bcd60e51b815260040161033490612611565b60009081526001919091016020526040902054151590565b6000611a668383611a42565b611a9c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ba4565b506000610ba4565b600061119b8383611bc3565b600082611abf57506000610ba4565b82820282848281611acc57fe5b041461119b5760405162461bcd60e51b815260040161033490612541565b60008181526001830160205260408120548015611ba65783546000198083019190810190600090879083908110611b1d57fe5b9060005260206000200154905080876000018481548110611b3a57fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080611b6a57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610ba4565b6000915050610ba4565b5490565b606061125a8484600085611c08565b81546000908210611be65760405162461bcd60e51b8152600401610334906122c9565b826000018281548110611bf557fe5b9060005260206000200154905092915050565b6060611c138561183b565b611c2f5760405162461bcd60e51b8152600401610334906125da565b60006060866001600160a01b03168587604051611c4c919061217c565b60006040518083038185875af1925050503d8060008114611c89576040519150601f19603f3d011682016040523d82523d6000602084013e611c8e565b606091505b50915091508115611ca257915061125a9050565b805115611cb25780518082602001fd5b8360405162461bcd60e51b81526004016103349190612296565b60405180606001604052806000815260200160008152602001600081525090565b60008083601f840112611cfe578182fd5b50813567ffffffffffffffff811115611d15578182fd5b602083019150836020828501011115611d2d57600080fd5b9250929050565b600060208284031215611d45578081fd5b813561119b816126bf565b600060208284031215611d61578081fd5b815161119b816126bf565b600080600060608486031215611d80578182fd5b8335611d8b816126bf565b92506020840135611d9b816126bf565b929592945050506040919091013590565b60008060008060808587031215611dc1578081fd5b8435611dcc816126bf565b93506020850135611ddc816126bf565b93969395505050506040820135916060013590565b60008060408385031215611e03578182fd5b8235611e0e816126bf565b946020939093013593505050565b60008060408385031215611e2e578182fd5b8235611e39816126bf565b91506020830135611e49816126bf565b809150509250929050565b60008060008060008060008060e0898b031215611e6f578384fd5b8835611e7a816126bf565b97506020890135611e8a816126bf565b96506040890135611e9a816126bf565b955060608901359450608089013567ffffffffffffffff811115611ebc578485fd5b611ec88b828c01611ced565b90955093505060a0890135611edc816126bf565b8092505060c089013590509295985092959890939650565b600080600080600080600060e0888a031215611f0e578283fd5b8735611f19816126bf565b9650602088013595506040880135611f30816126bf565b94506060880135611f40816126bf565b93506080880135925060a0880135611f57816126bf565b8092505060c0880135905092959891949750929550565b600080600080600080600060c0888a031215611f88578283fd5b8735611f93816126bf565b965060208801359550604088013567ffffffffffffffff811115611fb5578384fd5b611fc18a828b01611ced565b9096509450506060880135611fd5816126bf565b92506080880135611fe5816126bf565b8092505060a0880135905092959891949750929550565b600080600080600080600060c0888a031215612016578081fd5b8735612021816126bf565b965060208801359550604088013567ffffffffffffffff811115612043578182fd5b61204f8a828b01611ced565b9096509450506060880135612063816126bf565b969995985093969295946080840135945060a09093013592915050565b60008060008060008060008060e0898b03121561209b578182fd5b88356120a6816126bf565b975060208901359650604089013567ffffffffffffffff8111156120c8578283fd5b6120d48b828c01611ced565b90975095505060608901356120e8816126bf565b979a96995094979396956080850135955060a08501359460c001359350915050565b60006020828403121561211b578081fd5b8151801515811461119b578182fd5b60006020828403121561213b578081fd5b5035919050565b600060208284031215612153578081fd5b5051919050565b60609290921b6bffffffffffffffffffffffff19168252601482015260340190565b6000825161218e818460208701612693565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03861681526020810185905260806040820181905281018390526000838560a08401378060a0858401015260a0601f19601f86011683010190508260608301529695505050505050565b6001600160a01b039390931683526020830191909152604082015260600190565b60006020825282518060208401526122b5816040850160208701612693565b601f01601f19169190910160400192915050565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b602080825260099082015268554e493a452d34303360b81b604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b602080825260099082015268554e493a452d34313760b81b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252600990820152680aa9c92748a5a6260760bb1b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b81518152602080830151908201526040918201519181019190915260600190565b90815260200190565b918252602082015260400190565b60005b838110156126ae578181015183820152602001612696565b838111156109c35750506000910152565b6001600160a01b03811681146106f457600080fdfea264697066735822122055c84894697dd3e92642a98fce78fc85de39452936a89059494ec186a3b80f2d64736f6c634300060c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061014d5760003560e01c80638da5cb5b116100c3578063b9e09b4b1161007c578063b9e09b4b1461028e578063bbf1da84146102a1578063bea38be0146102a9578063c5d1d706146102bc578063f2fde38b146102cf578063fbf5ca14146102e25761014d565b80638da5cb5b14610227578063945233e21461022f57806395469dfc146102425780639a87c0de14610255578063a0edb48b14610268578063aa29542d1461027b5761014d565b8063522f681511610115578063522f6815146101be5780636e5559fd146101d1578063715018a6146101e45780638129fc1c146101ec578063836c478d146101f45780638b9309b2146102145761014d565b80631593dee1146101525780632bdbb77f1461016757806330219ef41461017a5780634025feb21461019857806341db85d6146101ab575b600080fd5b610165610160366004611d6c565b6102f5565b005b610165610175366004611ffc565b61034d565b61018261038d565b60405161018f919061219b565b60405180910390f35b6101656101a6366004611d6c565b61039c565b6101656101b9366004611ffc565b6103e6565b6101656101cc366004611df1565b6104ca565b6101656101df366004611d34565b610517565b6101656105e3565b61016561066c565b61020761020236600461212a565b6106f7565b60405161018f919061265b565b610165610222366004611ef4565b610384565b610182610738565b61016561023d366004611d34565b610747565b610165610250366004611e1c565b6107d5565b610165610263366004611d34565b6108d4565b610165610276366004611dac565b610978565b610165610289366004611f6e565b6109c9565b61016561029c366004611e54565b610a9c565b610182610b53565b6101656102b7366004611ffc565b610b62565b6101826102ca366004611d34565b610b99565b6101656102dd366004611d34565b610baa565b6101656102f0366004612080565b610c6b565b6102fd610d59565b6001600160a01b031661030e610738565b6001600160a01b03161461033d5760405162461bcd60e51b815260040161033490612582565b60405180910390fd5b610348838383610d5d565b505050565b6065546001600160a01b031633146103775760405162461bcd60e51b8152600401610334906125b7565b6103848787858585610e6a565b50505050505050565b6065546001600160a01b031681565b6103a4610d59565b6001600160a01b03166103b5610738565b6001600160a01b0316146103db5760405162461bcd60e51b815260040161033490612582565b610348838383610ffd565b6065546001600160a01b031633146104105760405162461bcd60e51b8152600401610334906125b7565b600061041b84611158565b90506001600160a01b038116156104c05760006104388385611176565b604051631434318f60e21b81529091506001600160a01b038316906350d0c63c9061046b908c908c908690600401612275565b602060405180830381600087803b15801561048557600080fd5b505af1158015610499573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bd9190612142565b50505b5050505050505050565b6104d2610d59565b6001600160a01b03166104e3610738565b6001600160a01b0316146105095760405162461bcd60e51b815260040161033490612582565b61051382826111a2565b5050565b61051f610d59565b6001600160a01b0316610530610738565b6001600160a01b0316146105565760405162461bcd60e51b815260040161033490612582565b806001600160a01b0381161580159061057c575061057c816001600160a01b0316611226565b6105985760405162461bcd60e51b815260040161033490612397565b606580546001600160a01b0319166001600160a01b0384169081179091556040517f5ce0e6b7fd36339ee97339831b6c72694ecee88c62aab49919d9cabe0a732e4190600090a25050565b6105eb610d59565b6001600160a01b03166105fc610738565b6001600160a01b0316146106225760405162461bcd60e51b815260040161033490612582565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b600054610100900460ff16806106855750610685611262565b80610693575060005460ff16155b6106af5760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff161580156106da576000805460ff1961ff0019909116610100171660011790555b6106e2611273565b80156106f4576000805461ff00191690555b50565b6106ff611ccc565b50600090815260696020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b6033546001600160a01b031690565b61074f610d59565b6001600160a01b0316610760610738565b6001600160a01b0316146107865760405162461bcd60e51b815260040161033490612582565b6001600160a01b03811660008181526067602052604080822080546001600160a01b0319169055517f87e1027e3dc61d1977f39f0dfe911b66a943946b4ceb39210dee01495621de529190a250565b6107dd610d59565b6001600160a01b03166107ee610738565b6001600160a01b0316146108145760405162461bcd60e51b815260040161033490612582565b816001600160a01b0381161580159061083a575061083a816001600160a01b0316611226565b6108565760405162461bcd60e51b815260040161033490612397565b6001600160a01b03821661087c5760405162461bcd60e51b81526004016103349061230b565b6001600160a01b0382811660008181526067602052604080822080546001600160a01b0319169488169485179055517f3b76c6366ef8a1f8d2dbb75e4be27be1e0749716fff3e6bc327da9c6158deada9190a3505050565b6108dc610d59565b6001600160a01b03166108ed610738565b6001600160a01b0316146109135760405162461bcd60e51b815260040161033490612582565b806001600160a01b038116158015906109395750610939816001600160a01b0316611226565b6109555760405162461bcd60e51b815260040161033490612397565b50606680546001600160a01b0319166001600160a01b0392909216919091179055565b610980610d59565b6001600160a01b0316610991610738565b6001600160a01b0316146109b75760405162461bcd60e51b815260040161033490612582565b6109c3848484846112f1565b50505050565b6065546001600160a01b031633146109f35760405162461bcd60e51b8152600401610334906125b7565b60006109fe83611158565b90506001600160a01b038116156104c057604051631434318f60e21b81526001600160a01b038216906350d0c63c90610a3f908b908b908790600401612275565b602060405180830381600087803b158015610a5957600080fd5b505af1158015610a6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a919190612142565b505050505050505050565b6065546001600160a01b03163314610ac65760405162461bcd60e51b8152600401610334906125b7565b6000610ad183611158565b90506001600160a01b03811615610a91576040516323632fb160e11b81526001600160a01b038216906346c65f6290610b16908a908a908a908a908990600401612224565b600060405180830381600087803b158015610b3057600080fd5b505af1158015610b44573d6000803e3d6000fd5b50505050505050505050505050565b6066546001600160a01b031681565b6065546001600160a01b03163314610b8c5760405162461bcd60e51b8152600401610334906125b7565b6103848787858585611450565b6000610ba482611158565b92915050565b610bb2610d59565b6001600160a01b0316610bc3610738565b6001600160a01b031614610be95760405162461bcd60e51b815260040161033490612582565b6001600160a01b038116610c0f5760405162461bcd60e51b81526004016103349061232e565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6065546001600160a01b03163314610c955760405162461bcd60e51b8152600401610334906125b7565b6000610ca085611158565b90506001600160a01b03811615610a91576000610cc784610cc18588611541565b90611176565b604051631434318f60e21b81529091506001600160a01b038316906350d0c63c90610cfa908d908d908690600401612275565b602060405180830381600087803b158015610d1457600080fd5b505af1158015610d28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4c9190612142565b5050505050505050505050565b3390565b6001600160a01b038316610d835760405162461bcd60e51b815260040161033490612374565b6040516370a0823160e01b815281906001600160a01b038416906370a0823190610db190309060040161219b565b60206040518083038186803b158015610dc957600080fd5b505afa158015610ddd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e019190612142565b1061034857610e1a6001600160a01b0383168483611569565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b83604051610e5d919061267c565b60405180910390a3505050565b6066546001600160a01b03848116911614610e8457610ff6565b6000610e996001600160a01b038716866115bf565b90506000610ea785856115f3565b9050600081118015610ece57506000828152606860205260409020610ecc90826116d5565b155b15610fa6576000828152606860205260409020610eeb90826116e1565b506000610ef7836116ed565b600084815260696020526040902060010154909150610f5157604080516060810182528281524360208083019182526000838501818152888252606990925293909320915182555160018201559051600290910155610fa4565b60008381526069602052604090206001810154908290554303610f90610f7882600261176d565b60008681526069602052604090206001015490611176565b600085815260696020526040902060010155505b505b846001600160a01b0316876001600160a01b03167f186ebbe503be539e070ca73b33a78f4266d96003e62b888dc31f88a39ddc9c878887604051610feb929190612685565b60405180910390a350505b5050505050565b6001600160a01b0383166110235760405162461bcd60e51b815260040161033490612374565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e9061105190859060040161267c565b60206040518083038186803b15801561106957600080fd5b505afa15801561107d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a19190611d50565b6001600160a01b03161415610348576040516323b872dd60e01b81526001600160a01b038316906323b872dd906110e0903090879086906004016121af565b600060405180830381600087803b1580156110fa57600080fd5b505af115801561110e573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b039081166000908152606760205260409020541690565b60008282018381101561119b5760405162461bcd60e51b8152600401610334906123ba565b9392505050565b6001600160a01b0382166111c85760405162461bcd60e51b815260040161033490612374565b804710610513576111e26001600160a01b0383168261179f565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd8260405161121a919061267c565b60405180910390a25050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061125a57508115155b949350505050565b600061126d3061183b565b15905090565b600054610100900460ff168061128c575061128c611262565b8061129a575060005460ff16155b6112b65760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff161580156112e1576000805460ff1961ff0019909116610100171660011790555b6112e9611841565b6106e26118c2565b6001600160a01b0384166113175760405162461bcd60e51b815260040161033490612374565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e90611345903090879060040161220b565b60206040518083038186803b15801561135d57600080fd5b505afa158015611371573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113959190612142565b106109c357604051637921219560e11b81526001600160a01b0384169063f242432a906113cc9030908890879087906004016121d3565b600060405180830381600087803b1580156113e657600080fd5b505af11580156113fa573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b84604051611442919061267c565b60405180910390a450505050565b6066546001600160a01b0384811691161461146a57610ff6565b600061147f6001600160a01b038716866115bf565b600081815260696020526040812091925061149a86866115f3565b60008481526068602052604090209091506114b5908261199c565b5060008381526068602052604081206114cd906119a8565b11156114e3576114dc836116ed565b82556114ea565b4360028301555b856001600160a01b0316886001600160a01b03167ff3cfcfc091fdd683cf6c013de9806af93f3af27b256a57cb776331291cef4085898860405161152f929190612685565b60405180910390a35050505050505050565b6000828211156115635760405162461bcd60e51b8152600401610334906123f1565b50900390565b6103488363a9059cbb60e01b848460405160240161158892919061220b565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526119b3565b600082826040516020016115d492919061215a565b60408051601f1981840301815291905280516020909101209392505050565b60008063adf8252d60e01b905060006060856001600160a01b03168386604051602401611620919061267c565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161165e919061217c565b6000604051808303816000865af19150503d806000811461169b576040519150601f19603f3d011682016040523d82523d6000602084013e6116a0565b606091505b509150915081156116c957808060200190518101906116bf9190612142565b9350505050610ba4565b60009350505050610ba4565b600061119b8383611a42565b600061119b8383611a5a565b60008181526068602052604081208190611706906119a8565b905060006032815b83811015611743576000868152606860205260409020611739906117329083611aa4565b8490611176565b925060010161170e565b6001841115611763576117606117598386611ab0565b8490611541565b92505b5090949350505050565b600080821161178e5760405162461bcd60e51b8152600401610334906124bc565b81838161179757fe5b049392505050565b804710156117bf5760405162461bcd60e51b815260040161033490612485565b6000826001600160a01b0316826040516117d890612198565b60006040518083038185875af1925050503d8060008114611815576040519150601f19603f3d011682016040523d82523d6000602084013e61181a565b606091505b50509050806103485760405162461bcd60e51b815260040161033490612428565b3b151590565b600054610100900460ff168061185a575061185a611262565b80611868575060005460ff16155b6118845760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff161580156106e2576000805460ff1961ff00199091166101001716600117905580156106f4576000805461ff001916905550565b600054610100900460ff16806118db57506118db611262565b806118e9575060005460ff16155b6119055760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff16158015611930576000805460ff1961ff0019909116610100171660011790555b600061193a610d59565b603380546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35080156106f4576000805461ff001916905550565b600061119b8383611aea565b6000610ba482611bb0565b6060611a08826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611bb49092919063ffffffff16565b8051909150156103485780806020019051810190611a26919061210a565b6103485760405162461bcd60e51b815260040161033490612611565b60009081526001919091016020526040902054151590565b6000611a668383611a42565b611a9c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ba4565b506000610ba4565b600061119b8383611bc3565b600082611abf57506000610ba4565b82820282848281611acc57fe5b041461119b5760405162461bcd60e51b815260040161033490612541565b60008181526001830160205260408120548015611ba65783546000198083019190810190600090879083908110611b1d57fe5b9060005260206000200154905080876000018481548110611b3a57fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080611b6a57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610ba4565b6000915050610ba4565b5490565b606061125a8484600085611c08565b81546000908210611be65760405162461bcd60e51b8152600401610334906122c9565b826000018281548110611bf557fe5b9060005260206000200154905092915050565b6060611c138561183b565b611c2f5760405162461bcd60e51b8152600401610334906125da565b60006060866001600160a01b03168587604051611c4c919061217c565b60006040518083038185875af1925050503d8060008114611c89576040519150601f19603f3d011682016040523d82523d6000602084013e611c8e565b606091505b50915091508115611ca257915061125a9050565b805115611cb25780518082602001fd5b8360405162461bcd60e51b81526004016103349190612296565b60405180606001604052806000815260200160008152602001600081525090565b60008083601f840112611cfe578182fd5b50813567ffffffffffffffff811115611d15578182fd5b602083019150836020828501011115611d2d57600080fd5b9250929050565b600060208284031215611d45578081fd5b813561119b816126bf565b600060208284031215611d61578081fd5b815161119b816126bf565b600080600060608486031215611d80578182fd5b8335611d8b816126bf565b92506020840135611d9b816126bf565b929592945050506040919091013590565b60008060008060808587031215611dc1578081fd5b8435611dcc816126bf565b93506020850135611ddc816126bf565b93969395505050506040820135916060013590565b60008060408385031215611e03578182fd5b8235611e0e816126bf565b946020939093013593505050565b60008060408385031215611e2e578182fd5b8235611e39816126bf565b91506020830135611e49816126bf565b809150509250929050565b60008060008060008060008060e0898b031215611e6f578384fd5b8835611e7a816126bf565b97506020890135611e8a816126bf565b96506040890135611e9a816126bf565b955060608901359450608089013567ffffffffffffffff811115611ebc578485fd5b611ec88b828c01611ced565b90955093505060a0890135611edc816126bf565b8092505060c089013590509295985092959890939650565b600080600080600080600060e0888a031215611f0e578283fd5b8735611f19816126bf565b9650602088013595506040880135611f30816126bf565b94506060880135611f40816126bf565b93506080880135925060a0880135611f57816126bf565b8092505060c0880135905092959891949750929550565b600080600080600080600060c0888a031215611f88578283fd5b8735611f93816126bf565b965060208801359550604088013567ffffffffffffffff811115611fb5578384fd5b611fc18a828b01611ced565b9096509450506060880135611fd5816126bf565b92506080880135611fe5816126bf565b8092505060a0880135905092959891949750929550565b600080600080600080600060c0888a031215612016578081fd5b8735612021816126bf565b965060208801359550604088013567ffffffffffffffff811115612043578182fd5b61204f8a828b01611ced565b9096509450506060880135612063816126bf565b969995985093969295946080840135945060a09093013592915050565b60008060008060008060008060e0898b03121561209b578182fd5b88356120a6816126bf565b975060208901359650604089013567ffffffffffffffff8111156120c8578283fd5b6120d48b828c01611ced565b90975095505060608901356120e8816126bf565b979a96995094979396956080850135955060a08501359460c001359350915050565b60006020828403121561211b578081fd5b8151801515811461119b578182fd5b60006020828403121561213b578081fd5b5035919050565b600060208284031215612153578081fd5b5051919050565b60609290921b6bffffffffffffffffffffffff19168252601482015260340190565b6000825161218e818460208701612693565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03861681526020810185905260806040820181905281018390526000838560a08401378060a0858401015260a0601f19601f86011683010190508260608301529695505050505050565b6001600160a01b039390931683526020830191909152604082015260600190565b60006020825282518060208401526122b5816040850160208701612693565b601f01601f19169190910160400192915050565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b602080825260099082015268554e493a452d34303360b81b604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b602080825260099082015268554e493a452d34313760b81b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252600990820152680aa9c92748a5a6260760bb1b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b81518152602080830151908201526040918201519181019190915260600190565b90815260200190565b918252602082015260400190565b60005b838110156126ae578181015183820152602001612696565b838111156109c35750506000910152565b6001600160a01b03811681146106f457600080fdfea264697066735822122055c84894697dd3e92642a98fce78fc85de39452936a89059494ec186a3b80f2d64736f6c634300060c0033", + "devdoc": { + "details": "Upgradeable Contract", + "kind": "dev", + "methods": { + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Charged Particles Universe Contract with Rewards Program", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 680, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 683, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 3177, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 111, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "t_address" + }, + { + "astId": 230, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 16752, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_chargedParticles", + "offset": 0, + "slot": "101", + "type": "t_address" + }, + { + "astId": 16754, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_multiplierNft", + "offset": 0, + "slot": "102", + "type": "t_address" + }, + { + "astId": 16758, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_assetRewardPrograms", + "offset": 0, + "slot": "103", + "type": "t_mapping(t_address,t_address)" + }, + { + "astId": 16762, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_multiplierNftsSet", + "offset": 0, + "slot": "104", + "type": "t_mapping(t_uint256,t_struct(UintSet)8991_storage)" + }, + { + "astId": 16766, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_nftStake", + "offset": 0, + "slot": "105", + "type": "t_mapping(t_uint256,t_struct(NftStake)29442_storage)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_address)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_uint256,t_struct(NftStake)29442_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct IUniverseRP.NftStake)", + "numberOfBytes": "32", + "value": "t_struct(NftStake)29442_storage" + }, + "t_mapping(t_uint256,t_struct(UintSet)8991_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct EnumerableSet.UintSet)", + "numberOfBytes": "32", + "value": "t_struct(UintSet)8991_storage" + }, + "t_struct(NftStake)29442_storage": { + "encoding": "inplace", + "label": "struct IUniverseRP.NftStake", + "members": [ + { + "astId": 29437, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "multiplier", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 29439, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "depositBlockNumber", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 29441, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "releaseBlockNumber", + "offset": 0, + "slot": "2", + "type": "t_uint256" + } + ], + "numberOfBytes": "96" + }, + "t_struct(Set)8702_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 8697, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 8701, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_struct(UintSet)8991_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.UintSet", + "members": [ + { + "astId": 8990, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)8702_storage" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/deployments/goerli/UniverseRP_Proxy.json b/deployments/goerli/UniverseRP_Proxy.json new file mode 100644 index 0000000..32de1b1 --- /dev/null +++ b/deployments/goerli/UniverseRP_Proxy.json @@ -0,0 +1,249 @@ +{ + "address": "0x5618Fa2E1Cb2F0F4e55db1d3F83ac3dA14BCdc4B", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xf59e7ac181a04210addd00fd6e08c4d822126361f639391b1320caa86daaa82b", + "receipt": { + "to": null, + "from": "0x6d46b37708dA7Ed4E5C4509495768Fecd3D17C01", + "contractAddress": "0x5618Fa2E1Cb2F0F4e55db1d3F83ac3dA14BCdc4B", + "transactionIndex": 18, + "gasUsed": "769740", + "logsBloom": "0x00000000000000000000000000000000400000000000000000800000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000022000001000000000000000000000000000000000000020000000000000000000800000000800000000000000010000000400000000000000000000000000000000800000000040000000400000000800000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000800000400000000000000000020000000000000000200000000000000000000000000000000000000000020000000", + "blockHash": "0x775f0bd1b1d52b62ce1280ba7a5a5a55b1f900393b54f010eda639e155d17616", + "transactionHash": "0xf59e7ac181a04210addd00fd6e08c4d822126361f639391b1320caa86daaa82b", + "logs": [ + { + "transactionIndex": 18, + "blockNumber": 9608560, + "transactionHash": "0xf59e7ac181a04210addd00fd6e08c4d822126361f639391b1320caa86daaa82b", + "address": "0x5618Fa2E1Cb2F0F4e55db1d3F83ac3dA14BCdc4B", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000bbe78410e9cf6c1d68ab99f1c9595803c795cba5" + ], + "data": "0x", + "logIndex": 27, + "blockHash": "0x775f0bd1b1d52b62ce1280ba7a5a5a55b1f900393b54f010eda639e155d17616" + }, + { + "transactionIndex": 18, + "blockNumber": 9608560, + "transactionHash": "0xf59e7ac181a04210addd00fd6e08c4d822126361f639391b1320caa86daaa82b", + "address": "0x5618Fa2E1Cb2F0F4e55db1d3F83ac3dA14BCdc4B", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000006d46b37708da7ed4e5c4509495768fecd3d17c01" + ], + "data": "0x", + "logIndex": 28, + "blockHash": "0x775f0bd1b1d52b62ce1280ba7a5a5a55b1f900393b54f010eda639e155d17616" + }, + { + "transactionIndex": 18, + "blockNumber": 9608560, + "transactionHash": "0xf59e7ac181a04210addd00fd6e08c4d822126361f639391b1320caa86daaa82b", + "address": "0x5618Fa2E1Cb2F0F4e55db1d3F83ac3dA14BCdc4B", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d34060fa3ea8ac05aba386ac8cbb019c4594b204", + "logIndex": 29, + "blockHash": "0x775f0bd1b1d52b62ce1280ba7a5a5a55b1f900393b54f010eda639e155d17616" + } + ], + "blockNumber": 9608560, + "cumulativeGasUsed": "4929378", + "status": 1, + "byzantium": true + }, + "args": [ + "0xbbe78410e9cf6C1d68AB99f1c9595803C795cBA5", + "0xd34060fa3eA8AC05abA386ac8Cbb019C4594b204", + "0x8129fc1c" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev 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\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/goerli/solcInputs/0e89febeebc7444140de8e67c9067d2c.json b/deployments/goerli/solcInputs/0e89febeebc7444140de8e67c9067d2c.json new file mode 100644 index 0000000..6eb5ed9 --- /dev/null +++ b/deployments/goerli/solcInputs/0e89febeebc7444140de8e67c9067d2c.json @@ -0,0 +1,80 @@ +{ + "language": "Solidity", + "sources": { + "solc_0.8/openzeppelin/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 (address initialOwner) {\n _transferOwnership(initialOwner);\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" + }, + "solc_0.8/openzeppelin/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" + }, + "solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"../../access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n\n constructor (address initialOwner) Ownable(initialOwner) {}\n\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(\n TransparentUpgradeableProxy proxy,\n address implementation,\n bytes memory data\n ) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(\n address _logic,\n address admin_,\n bytes memory _data\n ) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _changeAdmin(admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n _changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overriden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n" + }, + "solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view virtual returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(Address.isContract(IBeacon(newBeacon).implementation()), \"ERC1967: beacon implementation is not a contract\");\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "solc_0.8/openzeppelin/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\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 * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev 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" + }, + "solc_0.8/openzeppelin/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n assembly {\n r.slot := slot\n }\n }\n}\n" + }, + "solc_0.8/proxy/OptimizedTransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract OptimizedTransparentUpgradeableProxy is ERC1967Proxy {\n address internal immutable _ADMIN;\n\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(\n address _logic,\n address admin_,\n bytes memory _data\n ) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _ADMIN = admin_;\n\n // still store it to work with EIP-1967\n bytes32 slot = _ADMIN_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, admin_)\n }\n emit AdminChanged(address(0), admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n\n function _getAdmin() internal view virtual override returns (address) {\n return _ADMIN;\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/utils/UUPSUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../ERC1967/ERC1967Upgrade.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n *\n * _Available since v4.1._\n */\nabstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade {\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\n address private immutable __self = address(this);\n\n /**\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n * fail.\n */\n modifier onlyProxy() {\n require(address(this) != __self, \"Function must be called through delegatecall\");\n require(_getImplementation() == __self, \"Function must be called through active proxy\");\n _;\n }\n\n /**\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\n * callable on the implementing contract but not through proxies.\n */\n modifier notDelegated() {\n require(address(this) == __self, \"UUPSUpgradeable: must not be called through delegatecall\");\n _;\n }\n\n /**\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\n * implementation. It is used to validate that the this implementation remains valid after an upgrade.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\n */\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\n return _IMPLEMENTATION_SLOT;\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n */\n function upgradeTo(address newImplementation) external virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n * encoded in `data`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n */\n function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, data, true);\n }\n\n /**\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n * {upgradeTo} and {upgradeToAndCall}.\n *\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\n *\n * ```solidity\n * function _authorizeUpgrade(address) internal override onlyOwner {}\n * ```\n */\n function _authorizeUpgrade(address newImplementation) internal virtual;\n}\n" + }, + "solc_0.8/openzeppelin/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * 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 !Address.isContract(address(this));\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/beacon/UpgradeableBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/UpgradeableBeacon.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IBeacon.sol\";\nimport \"../../access/Ownable.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their\n * implementation contract, which is where they will delegate all function calls.\n *\n * An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon.\n */\ncontract UpgradeableBeacon is IBeacon, Ownable {\n address private _implementation;\n\n /**\n * @dev Emitted when the implementation returned by the beacon is changed.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Sets the address of the initial implementation, and the deployer account as the owner who can upgrade the\n * beacon.\n */\n\n constructor(address implementation_, address initialOwner) Ownable(initialOwner) {\n _setImplementation(implementation_);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function implementation() public view virtual override returns (address) {\n return _implementation;\n }\n\n /**\n * @dev Upgrades the beacon to a new implementation.\n *\n * Emits an {Upgraded} event.\n *\n * Requirements:\n *\n * - msg.sender must be the owner of the contract.\n * - `newImplementation` must be a contract.\n */\n function upgradeTo(address newImplementation) public virtual onlyOwner {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Sets the implementation contract address for this beacon\n *\n * Requirements:\n *\n * - `newImplementation` must be a contract.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableBeacon: implementation is not a contract\");\n _implementation = newImplementation;\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/beacon/BeaconProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/BeaconProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IBeacon.sol\";\nimport \"../Proxy.sol\";\nimport \"../ERC1967/ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements a proxy that gets the implementation address for each call from a {UpgradeableBeacon}.\n *\n * The beacon address is stored in storage slot `uint256(keccak256('eip1967.proxy.beacon')) - 1`, so that it doesn't\n * conflict with the storage layout of the implementation behind the proxy.\n *\n * _Available since v3.4._\n */\ncontract BeaconProxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the proxy with `beacon`.\n *\n * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This\n * will typically be an encoded function call, and allows initializating the storage of the proxy like a Solidity\n * constructor.\n *\n * Requirements:\n *\n * - `beacon` must be a contract with the interface {IBeacon}.\n */\n constructor(address beacon, bytes memory data) payable {\n assert(_BEACON_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.beacon\")) - 1));\n _upgradeBeaconToAndCall(beacon, data, false);\n }\n\n /**\n * @dev Returns the current beacon address.\n */\n function _beacon() internal view virtual returns (address) {\n return _getBeacon();\n }\n\n /**\n * @dev Returns the current implementation address of the associated beacon.\n */\n function _implementation() internal view virtual override returns (address) {\n return IBeacon(_getBeacon()).implementation();\n }\n\n /**\n * @dev Changes the proxy to use a new beacon. Deprecated: see {_upgradeBeaconToAndCall}.\n *\n * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon.\n *\n * Requirements:\n *\n * - `beacon` must be a contract.\n * - The implementation returned by `beacon` must be a contract.\n */\n function _setBeacon(address beacon, bytes memory data) internal virtual {\n _upgradeBeaconToAndCall(beacon, data, false);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "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/deployments/goerli/solcInputs/39876b9d6995fafd8c4442fb1a03f418.json b/deployments/goerli/solcInputs/39876b9d6995fafd8c4442fb1a03f418.json new file mode 100644 index 0000000..891dec4 --- /dev/null +++ b/deployments/goerli/solcInputs/39876b9d6995fafd8c4442fb1a03f418.json @@ -0,0 +1,452 @@ +{ + "language": "Solidity", + "sources": { + "@opengsn/gsn/contracts/BaseRelayRecipient.sol": { + "content": "// SPDX-License-Identifier:MIT\n// solhint-disable no-inline-assembly\npragma solidity ^0.6.2;\n\nimport \"./interfaces/IRelayRecipient.sol\";\n\n/**\n * A base contract to be inherited by any contract that want to receive relayed transactions\n * A subclass must use \"_msgSender()\" instead of \"msg.sender\"\n */\nabstract contract BaseRelayRecipient is IRelayRecipient {\n\n /*\n * Forwarder singleton we accept calls from\n */\n address public trustedForwarder;\n\n function isTrustedForwarder(address forwarder) public override view returns(bool) {\n return forwarder == trustedForwarder;\n }\n\n /**\n * return the sender of this call.\n * if the call came through our trusted forwarder, return the original sender.\n * otherwise, return `msg.sender`.\n * should be used in the contract anywhere instead of msg.sender\n */\n function _msgSender() internal override virtual view returns (address payable ret) {\n if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // so we trust that the last bytes of msg.data are the verified sender address.\n // extract sender address from the end of msg.data\n assembly {\n ret := shr(96,calldataload(sub(calldatasize(),20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n /**\n * return the msg.data of this call.\n * if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes\n * of the msg.data - so this method will strip those 20 bytes off.\n * otherwise, return `msg.data`\n * should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly\n * signing or hashing the\n */\n function _msgData() internal override virtual view returns (bytes memory ret) {\n if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // we copy the msg.data , except the last 20 bytes (and update the total length)\n assembly {\n let ptr := mload(0x40)\n // copy only size-20 bytes\n let size := sub(calldatasize(),20)\n // structure RLP data as \n mstore(ptr, 0x20)\n mstore(add(ptr,32), size)\n calldatacopy(add(ptr,64), 0, size)\n return(ptr, add(size,64))\n }\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "@opengsn/gsn/contracts/interfaces/IRelayRecipient.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.6.2;\n\n/**\n * a contract must implement this interface in order to support relayed transaction.\n * It is better to inherit the BaseRelayRecipient as its implementation.\n */\nabstract contract IRelayRecipient {\n\n /**\n * return if the forwarder is trusted to forward relayed transactions to us.\n * the forwarder is required to verify the sender's signature, and verify\n * the call is not a replay.\n */\n function isTrustedForwarder(address forwarder) public virtual view returns(bool);\n\n /**\n * return the sender of this call.\n * if the call came through our trusted forwarder, then the real sender is appended as the last 20 bytes\n * of the msg.data.\n * otherwise, return `msg.sender`\n * should be used in the contract anywhere instead of msg.sender\n */\n function _msgSender() internal virtual view returns (address payable);\n\n /**\n * return the msg.data of this call.\n * if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes\n * of the msg.data - so this method will strip those 20 bytes off.\n * otherwise, return `msg.data`\n * should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly\n * signing or hashing the\n */\n function _msgData() internal virtual view returns (bytes memory);\n\n function versionRecipient() external virtual view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\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 initializer {\n __Context_init_unchained();\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal initializer {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), 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 emit OwnershipTransferred(_owner, address(0));\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n function __ERC165_init() internal initializer {\n __ERC165_init_unchained();\n }\n\n function __ERC165_init_unchained() internal initializer {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMathUpgradeable {\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 uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\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 if (b > a) return (false, 0);\n return (true, a - b);\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 // 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 * @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 if (b == 0) return (false, 0);\n return (true, a / b);\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 if (b == 0) return (false, 0);\n return (true, a % b);\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 uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n return c;\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 require(b <= a, \"SafeMath: subtraction overflow\");\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 if (a == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n return c;\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. 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(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: division by zero\");\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 require(b > 0, \"SafeMath: modulo by zero\");\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n return a - b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a / b;\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.4.24 <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 {UpgradeableProxy-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 */\nabstract contract Initializable {\n\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 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 /// @dev Returns true if and only if the function is running in the constructor\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\n\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 )\n external\n 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 )\n external\n returns(bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC20Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../proxy/Initializable.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 guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable {\n using SafeMathUpgradeable for uint256;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal initializer {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer {\n _name = name_;\n _symbol = symbol_;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal virtual {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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(address sender, address recipient, uint256 amount) 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/ERC20/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.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 SafeERC20Upgradeable {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) 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(IERC20Upgradeable token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\n require((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(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\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(IERC20Upgradeable 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) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721MetadataUpgradeable.sol\";\nimport \"./IERC721EnumerableUpgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"../../introspection/ERC165Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/EnumerableSetUpgradeable.sol\";\nimport \"../../utils/EnumerableMapUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../proxy/Initializable.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable, IERC721EnumerableUpgradeable {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet;\n using EnumerableMapUpgradeable for EnumerableMapUpgradeable.UintToAddressMap;\n using StringsUpgradeable for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSetUpgradeable.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMapUpgradeable.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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 initializer {\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 initializer {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\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 _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\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 _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\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(_msgSender() == owner || ERC721Upgradeable.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 require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) 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(address from, address to, uint256 tokenId, bytes memory _data) 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 _tokenOwners.contains(tokenId);\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 || ERC721Upgradeable.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\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 _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(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); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(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(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721ReceiverUpgradeable(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); // internal owner\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(address from, address to, uint256 tokenId) internal virtual { }\n uint256[41] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721EnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 /**\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/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 /**\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\npragma solidity >=0.6.0 <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(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) 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 // solhint-disable-next-line avoid-low-level-calls\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(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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 // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/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 GSN 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 initializer {\n __Context_init_unchained();\n }\n\n function __Context_init_unchained() internal initializer {\n }\n function _msgSender() internal view virtual returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/EnumerableMapUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMapUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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 EnumerableSetUpgradeable {\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\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\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] = toDeleteIndex + 1; // All indexes are 1-based\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 require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\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 // 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 // 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" + }, + "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/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 initializer {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal initializer {\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 make 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/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n /**\n * @dev Converts a `uint256` to its ASCII `string` 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 uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = bytes1(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../GSN/Context.sol\";\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 */\ncontract 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 () internal {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), msgSender);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view 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 emit OwnershipTransferred(_owner, address(0));\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n" + }, + "@openzeppelin/contracts/cryptography/MerkleProof.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev These functions deal with verification of Merkle trees (hash trees),\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(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {\n bytes32 computedHash = leaf;\n\n for (uint256 i = 0; i < proof.length; i++) {\n bytes32 proofElement = proof[i];\n\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\n // Check if the computed hash (root) is equal to the provided root\n return computedHash == root;\n }\n}\n" + }, + "@openzeppelin/contracts/GSN/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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 GSN 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 payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\ncontract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () internal {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n" + }, + "@openzeppelin/contracts/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\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 uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\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 sub(a, b, \"SafeMath: subtraction overflow\");\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 * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\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 // 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) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts 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 mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\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 SafeMath for uint256;\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 * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri) public {\n _setURI(uri);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\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) external view 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 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(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\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 require(accounts[i] != address(0), \"ERC1155: batch balance query for the zero address\");\n batchBalances[i] = _balances[ids[i]][accounts[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 require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view 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 )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, 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 )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\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 _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(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 `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` 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(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, 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(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) 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 (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\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 `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, 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(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != 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, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\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 )\n internal virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).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 )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).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/token/ERC1155/ERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() public {\n _registerInterface(\n ERC1155Receiver(0).onERC1155Received.selector ^\n ERC1155Receiver(0).onERC1155BatchReceived.selector\n );\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\nimport \"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\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 )\n external\n 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 )\n external\n returns(bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.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 guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 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 {\n using SafeMath for uint256;\n using Address for address;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name, string memory symbol) public {\n _name = name;\n _symbol = symbol;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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/token/ERC20/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.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 SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\n require((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(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\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) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n\n // If there is no base URI, return the token URI.\n if (bytes(_baseURI).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(_baseURI, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(_baseURI, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_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 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 require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) 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(address from, address to, uint256 tokenId, bytes memory _data) 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 returns (bool) {\n return _tokenOwners.contains(tokenId);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = 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 d*\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\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 _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(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 = ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(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(address from, address to, uint256 tokenId) internal virtual {\n require(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 _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\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(address from, address to, uint256 tokenId) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\nimport \"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 /**\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/token/ERC721/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 /**\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/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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(address operator, address from, uint256 tokenId, bytes calldata data)\n external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 in 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 // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n return _functionCallWithValue(target, data, value, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\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 // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../math/SafeMath.sol\";\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented or decremented by one. 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 * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}\n * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never\n * directly accessed.\n */\nlibrary Counters {\n using SafeMath for uint256;\n\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 // The {SafeMath} overflow check can be skipped here, see the comment at the top\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableMap.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n return _get(map, key, \"EnumerableMap: nonexistent key\");\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(value)));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint256(value)));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint256(_get(map._inner, bytes32(key))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint256(_get(map._inner, bytes32(key), errorMessage)));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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.0.0, only sets of type `address` (`AddressSet`) and `uint256`\n * (`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\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\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] = toDeleteIndex + 1; // All indexes are 1-based\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 require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\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(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(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(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(uint256(_at(set._inner, index)));\n }\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" + }, + "@openzeppelin/contracts/utils/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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 */\ncontract 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 () internal {\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 make 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/utils/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value < 2**128, \"SafeCast: value doesn\\'t fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value < 2**64, \"SafeCast: value doesn\\'t fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value < 2**32, \"SafeCast: value doesn\\'t fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value < 2**16, \"SafeCast: value doesn\\'t fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value < 2**8, \"SafeCast: value doesn\\'t fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= -2**127 && value < 2**127, \"SafeCast: value doesn\\'t fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= -2**63 && value < 2**63, \"SafeCast: value doesn\\'t fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= -2**31 && value < 2**31, \"SafeCast: value doesn\\'t fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= -2**15 && value < 2**15, \"SafeCast: value doesn\\'t fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= -2**7 && value < 2**7, \"SafeCast: value doesn\\'t fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n require(value < 2**255, \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` 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 uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = byte(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n" + }, + "contracts/v1/ChargedManagers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Wallet-Managers Contract\n */\ncontract ChargedManagers is\n IChargedManagers,\n Initializable,\n OwnableUpgradeable,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n\n IChargedSettings internal _chargedSettings;\n IChargedState internal _chargedState;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // Wallet/Basket Managers (by Unique Manager ID)\n mapping (string => IWalletManager) internal _ftWalletManager;\n mapping (string => IBasketManager) internal _nftBasketManager;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n /// @notice Checks if an Account is the Owner of an NFT Contract\n /// When Custom Contracts are registered, only the \"owner\" or operator of the Contract\n /// is allowed to register them and define custom rules for how their tokens are \"Charged\".\n /// Otherwise, any token can be \"Charged\" according to the default rules of Charged Particles.\n /// @param contractAddress The Address to the External NFT Contract to check\n /// @param account The Account to check if it is the Owner of the specified Contract\n /// @return True if the account is the Owner of the _contract\n function isContractOwner(address contractAddress, address account) external view override virtual returns (bool) {\n return contractAddress.isContractOwner(account);\n }\n\n function isWalletManagerEnabled(string calldata walletManagerId) external virtual override view returns (bool) {\n return _isWalletManagerEnabled(walletManagerId);\n }\n\n function getWalletManager(string calldata walletManagerId) external virtual override view returns (IWalletManager) {\n return _ftWalletManager[walletManagerId];\n }\n\n function isNftBasketEnabled(string calldata basketId) external virtual override view returns (bool) {\n return _isNftBasketEnabled(basketId);\n }\n\n function getBasketManager(string calldata basketId) external virtual override view returns (IBasketManager) {\n return _nftBasketManager[basketId];\n }\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param sender The sender address to validate against\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external virtual override {\n _validateDeposit(sender, contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param sender The sender address to validate against\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external virtual override {\n _validateNftDeposit(sender, contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateDischarge(sender, contractAddress, tokenId);\n }\n\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateRelease(sender, contractAddress, tokenId);\n }\n\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateBreakBond(sender, contractAddress, tokenId);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"state\"))) {\n _chargedState = IChargedState(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n /// @dev Register Contracts as wallet managers with a unique liquidity provider ID\n function registerWalletManager(string calldata walletManagerId, address walletManager) external virtual onlyOwner {\n // Validate wallet manager\n IWalletManager newWalletMgr = IWalletManager(walletManager);\n require(newWalletMgr.isPaused() != true, \"CP:E-418\");\n\n // Register LP ID\n _ftWalletManager[walletManagerId] = newWalletMgr;\n emit WalletManagerRegistered(walletManagerId, walletManager);\n }\n\n /// @dev Register Contracts as basket managers with a unique basket ID\n function registerBasketManager(string calldata basketId, address basketManager) external virtual onlyOwner {\n // Validate basket manager\n IBasketManager newBasketMgr = IBasketManager(basketManager);\n require(newBasketMgr.isPaused() != true, \"CP:E-418\");\n\n // Register Basket ID\n _nftBasketManager[basketId] = newBasketMgr;\n emit BasketManagerRegistered(basketId, basketManager);\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev See {ChargedParticles-isWalletManagerEnabled}.\n function _isWalletManagerEnabled(string calldata walletManagerId) internal view virtual returns (bool) {\n return (address(_ftWalletManager[walletManagerId]) != address(0x0) && !_ftWalletManager[walletManagerId].isPaused());\n }\n\n /// @dev See {ChargedParticles-isNftBasketEnabled}.\n function _isNftBasketEnabled(string calldata basketId) internal view virtual returns (bool) {\n return (address(_nftBasketManager[basketId]) != address(0x0) && !_nftBasketManager[basketId].isPaused());\n }\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n internal\n virtual\n {\n if (_chargedState.isEnergizeRestricted(contractAddress, tokenId)) {\n bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender);\n require(isNFTOwnerOrOperator, \"CP:E-105\");\n }\n\n ( string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n ) = _chargedSettings.getAssetRequirements(contractAddress, assetToken);\n\n require(energizeEnabled, \"CP:E-417\");\n\n require(!invalidAsset, \"CP:E-424\");\n\n // Valid Wallet Manager?\n if (bytes(requiredWalletManager).length > 0) {\n require(keccak256(abi.encodePacked(requiredWalletManager)) == keccak256(abi.encodePacked(walletManagerId)), \"CP:E-419\");\n }\n\n // Valid Asset?\n if (restrictedAssets) {\n require(validAsset, \"CP:E-424\");\n }\n\n _validateDepositAmount(\n contractAddress,\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n depositCap,\n depositMin,\n depositMax\n );\n }\n\n /// @dev Validates a Deposit-Amount according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDepositAmount(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax\n )\n internal\n virtual\n {\n uint256 existingBalance = _ftWalletManager[walletManagerId].getPrincipal(contractAddress, tokenId, assetToken);\n uint256 newBalance = assetAmount.add(existingBalance);\n\n // Validate Deposit Cap\n if (depositCap > 0) {\n require(newBalance <= depositCap, \"CP:E-408\");\n }\n\n // Valid Amount for Deposit?\n if (depositMin > 0) {\n require(newBalance >= depositMin, \"CP:E-410\");\n }\n if (depositMax > 0) {\n require(newBalance <= depositMax, \"CP:E-410\");\n }\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n {\n // Prevent Ouroboros NFTs\n require(contractAddress.getTokenUUID(tokenId) != nftTokenAddress.getTokenUUID(nftTokenId), \"CP:E-433\");\n\n if (_chargedState.isCovalentBondRestricted(contractAddress, tokenId)) {\n bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender);\n require(isNFTOwnerOrOperator, \"CP:E-105\");\n }\n\n ( string memory requiredBasketManager,\n bool basketEnabled,\n uint256 maxNfts\n ) = _chargedSettings.getNftAssetRequirements(contractAddress, nftTokenAddress);\n\n require(basketEnabled, \"CP:E-417\");\n\n // Valid Basket Manager?\n if (bytes(requiredBasketManager).length > 0) {\n require(keccak256(abi.encodePacked(requiredBasketManager)) == keccak256(abi.encodePacked(basketManagerId)), \"CP:E-419\");\n }\n\n if (maxNfts > 0) {\n uint256 tokenCount = _nftBasketManager[basketManagerId].getTokenTotalCount(contractAddress, tokenId);\n require(maxNfts >= (tokenCount + nftTokenAmount), \"CP:E-427\");\n }\n }\n\n function _validateDischarge(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getDischargeState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateRelease(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getReleaseState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateBreakBond(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getBreakBondState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateState(\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n internal\n view\n virtual\n {\n if (!allowFromAll) {\n require(isApproved, \"CP:E-105\");\n }\n if (timelock > 0) {\n require(block.number >= timelock, \"CP:E-302\");\n }\n if (tempLockExpiry > 0) {\n require(block.number >= tempLockExpiry, \"CP:E-303\");\n }\n }\n}\n" + }, + "contracts/v1/ChargedParticles.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\n\nimport \"./interfaces/IUniverse.sol\";\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/IWalletManager.sol\";\nimport \"./interfaces/IBasketManager.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/RelayRecipient.sol\";\n\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles V2 Contract\n * @dev Upgradeable Contract\n */\ncontract ChargedParticles is\n IChargedParticles,\n Initializable,\n OwnableUpgradeable,\n ReentrancyGuardUpgradeable,\n RelayRecipient,\n IERC721ReceiverUpgradeable,\n BlackholePrevention,\n IERC1155ReceiverUpgradeable\n{\n using SafeMathUpgradeable for uint256;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using Bitwise for uint32;\n using AddressUpgradeable for address;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n //\n // Particle Terminology\n //\n // Particle - Non-fungible Token (NFT)\n // Mass - Underlying Asset of a Token (ex; DAI)\n // Charge - Accrued Interest on the Underlying Asset of a Token\n // Charged Particle - Any NFT that has a Mass and a Positive Charge\n // Neutral Particle - Any NFT that has a Mass and No Charge\n // Energize / Recharge - Deposit of an Underlying Asset into an NFT\n // Discharge - Withdraw the Accrued Interest of an NFT leaving the Particle with its initial Mass\n // Release - Withdraw the Underlying Asset & Accrued Interest of an NFT leaving the Particle with No Mass or Charge\n //\n // Proton - NFTs minted from the Charged Particle Accelerator\n // - A proton is a subatomic particle, symbol p or p⁺, with a positive electric charge of +1e elementary\n // charge and a mass slightly less than that of a neutron.\n // Ion - Platform Governance Token\n // - A charged subatomic particle. An atom or group of atoms that carries a positive or negative electric charge\n // as a result of having lost or gained one or more electrons.\n //\n\n // Linked Contracts\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n address internal _lepton;\n uint256 internal depositFee;\n ITokenInfoProxy internal _tokenInfoProxy;\n IChargedManagers internal _chargedManagers;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n __ReentrancyGuard_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getStateAddress() external view virtual override returns (address stateAddress) {\n return address(_chargedState);\n }\n\n function getSettingsAddress() external view virtual override returns (address settingsAddress) {\n return address(_chargedSettings);\n }\n\n function getManagersAddress() external view virtual override returns (address managersAddress) {\n return address(_chargedManagers);\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external virtual override returns (bytes4) {\n return IERC721ReceiverUpgradeable(0).onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external virtual override returns (bytes4) {\n return IERC1155ReceiverUpgradeable(0).onERC1155Received.selector;\n }\n\n // Unimplemented\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external virtual override returns (bytes4) {\n return \"\"; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector;\n }\n\n function supportsInterface(bytes4 /* interfaceId */) external view virtual override returns (bool) {\n return false;\n }\n\n /// @notice Calculates the amount of Fees to be paid for a specific deposit amount\n /// @param assetAmount The Amount of Assets to calculate Fees on\n /// @return protocolFee The amount of deposit fees for the protocol\n function getFeesForDeposit(\n uint256 assetAmount\n )\n external\n override\n view\n returns (uint256 protocolFee)\n {\n protocolFee = _getFeesForDeposit(assetAmount);\n }\n\n /// @notice Gets the Amount of Asset Tokens that have been Deposited into the Particle\n /// representing the Mass of the Particle.\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Asset balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The Amount of underlying Assets held within the Token\n function baseParticleMass(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _baseParticleMass(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the amount of Interest that the Particle has generated representing\n /// the Charge of the Particle\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Interest balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The amount of interest the Token has generated (in Asset Token)\n function currentParticleCharge(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _currentParticleCharge(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the amount of LP Tokens that the Particle has generated representing\n /// the Kinetics of the Particle\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Kinetics balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The amount of LP tokens that have been generated\n function currentParticleKinetics(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _currentParticleKinetics(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the total amount of ERC721 Tokens that the Particle holds\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param basketManagerId The ID of the BasketManager to check the token balance of\n /// @return The total amount of ERC721 tokens that are held within the Particle\n function currentParticleCovalentBonds(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId\n )\n external\n view\n virtual\n override\n basketEnabled(basketManagerId)\n returns (uint256)\n {\n return _currentParticleCovalentBonds(contractAddress, tokenId, basketManagerId);\n }\n\n\n /***********************************|\n | Energize Particles |\n |__________________________________*/\n\n /// @notice Fund Particle with Asset Token\n /// Must be called by the account providing the Asset\n /// Account must Approve THIS contract as Operator of Asset\n ///\n /// NOTE: DO NOT Energize an ERC20 Token, as anyone who holds any amount\n /// of the same ERC20 token could discharge or release the funds.\n /// All holders of the ERC20 token would essentially be owners of the Charged Particle.\n ///\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param walletManagerId The Asset-Pair to Energize the Token with\n /// @param assetToken The Address of the Asset Token being used\n /// @param assetAmount The Amount of Asset Token to Energize the Token with\n /// @return yieldTokensAmount The amount of Yield-bearing Tokens added to the escrow for the Token\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 yieldTokensAmount)\n {\n _validateDeposit(contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n\n // Transfer ERC20 Token from Caller to Contract (reverts on fail)\n uint256 feeAmount = _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n yieldTokensAmount = _depositIntoWalletManager(contractAddress, tokenId, walletManagerId, assetToken, assetAmount, feeAmount);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onEnergize(_msgSender(), referrer, contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n }\n\n\n /***********************************|\n | Discharge Particles |\n |__________________________________*/\n\n /// @notice Allows the owner or operator of the Token to collect or transfer the interest generated\n /// from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @return creatorAmount Amount of Asset Token discharged to the Creator\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateDischarge(contractAddress, tokenId);\n\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).discharge(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount);\n }\n }\n\n /// @notice Allows the owner or operator of the Token to collect or transfer a specific amount of the interest\n /// generated from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @param assetAmount The specific amount of Asset Token to Discharge from the Token\n /// @return creatorAmount Amount of Asset Token discharged to the Creator\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateDischarge(contractAddress, tokenId);\n\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).dischargeAmount(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n assetAmount,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount);\n }\n }\n\n /// @notice Allows the Creator of the Token to collect or transfer a their portion of the interest (if any)\n /// generated from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @param assetAmount The specific amount of Asset Token to Discharge from the Particle\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 receiverAmount)\n {\n address sender = _msgSender();\n address tokenCreator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId);\n require(sender == tokenCreator, \"CP:E-104\");\n\n receiverAmount = _chargedManagers.getWalletManager(walletManagerId).dischargeAmountForCreator(\n receiver,\n contractAddress,\n tokenId,\n sender,\n assetToken,\n assetAmount\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischargeForCreator(contractAddress, tokenId, walletManagerId, sender, assetToken, receiverAmount);\n }\n }\n\n\n /***********************************|\n | Release Particles |\n |__________________________________*/\n\n /// @notice Releases the Full amount of Asset + Interest held within the Particle by LP of the Assets\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Release\n /// @param tokenId The ID of the Token to Release\n /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token\n /// @param assetToken The Address of the Asset Token being released\n /// @return creatorAmount Amount of Asset Token released to the Creator\n /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount)\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateRelease(contractAddress, tokenId);\n\n // Release Particle to Receiver\n uint256 principalAmount;\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).release(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n }\n\n\n /// @notice Releases a partial amount of Asset + Interest held within the Particle by LP of the Assets\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Release\n /// @param tokenId The ID of the Token to Release\n /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token\n /// @param assetToken The Address of the Asset Token being released\n /// @param assetAmount The specific amount of Asset Token to Release from the Particle\n /// @return creatorAmount Amount of Asset Token released to the Creator\n /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount)\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateRelease(contractAddress, tokenId);\n\n // Release Particle to Receiver\n uint256 principalAmount;\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).releaseAmount(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n assetAmount,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n }\n\n\n /***********************************|\n | Covalent Bonding |\n |__________________________________*/\n\n /// @notice Deposit other NFT Assets into the Particle\n /// Must be called by the account providing the Asset\n /// Account must Approve THIS contract as Operator of Asset\n ///\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n basketEnabled(basketManagerId)\n nonReentrant\n returns (bool success)\n {\n _validateNftDeposit(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Transfer ERC721 Token from Caller to Contract (reverts on fail)\n _collectNftToken(_msgSender(), nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n success = _depositIntoBasketManager(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onCovalentBond(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n }\n\n /// @notice Release NFT Assets from the Particle\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Withdraw (ERC1155-specific)\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n basketEnabled(basketManagerId)\n nonReentrant\n returns (bool success)\n {\n _validateBreakBond(contractAddress, tokenId);\n\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked(\"generic\"))) {\n basketMgr.prepareTransferAmount(nftTokenAmount);\n }\n\n // Release Particle to Receiver\n success = basketMgr.removeFromBasket(\n receiver,\n contractAddress,\n tokenId,\n nftTokenAddress,\n nftTokenId\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onCovalentBreak(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"universe\"))) {\n _universe = IUniverse(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"state\"))) {\n _chargedState = IChargedState(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"managers\"))) {\n _chargedManagers = IChargedManagers(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"leptons\"))) {\n _lepton = controller;\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"forwarder\"))) {\n trustedForwarder = controller;\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n\n /***********************************|\n | Protocol Fees |\n |__________________________________*/\n\n /// @dev Setup the Base Deposit Fee for the Protocol\n function setDepositFee(uint256 fee) external onlyOwner {\n require(fee < PERCENTAGE_SCALE, \"CP:E-421\");\n depositFee = fee;\n emit DepositFeeSet(fee);\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n internal\n virtual\n {\n _chargedManagers.validateDeposit(_msgSender(), contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _validateNftDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n {\n _chargedManagers.validateNftDeposit(_msgSender(), contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function _validateDischarge(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateDischarge(_msgSender(), contractAddress, tokenId);\n }\n\n function _validateRelease(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateRelease(_msgSender(), contractAddress, tokenId);\n }\n\n function _validateBreakBond(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateBreakBond(_msgSender(), contractAddress, tokenId);\n }\n\n /// @dev Deposit Asset Tokens into an NFT via the Wallet Manager\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n /// @param feeAmount The Amount of Protocol Fees charged\n function _depositIntoWalletManager(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 feeAmount\n )\n internal\n virtual\n returns (uint256)\n {\n // Get Wallet-Manager for LP\n IWalletManager lpWalletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n address wallet = lpWalletMgr.getWalletAddressById(contractAddress, tokenId, creator, annuityPct);\n IERC20Upgradeable(assetToken).transfer(wallet, assetAmount);\n\n emit ProtocolFeesCollected(assetToken, assetAmount, feeAmount);\n\n return lpWalletMgr.energize(contractAddress, tokenId, assetToken, assetAmount);\n }\n\n /// @dev Deposit NFT Tokens into the Basket Manager\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @param basketManagerId The Wallet Manager of the Assets to Deposit\n /// @param nftTokenAddress The Address of the Asset Token to Deposit\n /// @param nftTokenId The specific amount of Asset Token to Deposit\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _depositIntoBasketManager(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n returns (bool)\n {\n // Deposit NFT Token directly into Smart Wallet (reverts on fail) and Update BasketManager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId);\n\n if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked(\"generic\"))) {\n basketMgr.prepareTransferAmount(nftTokenAmount);\n }\n\n if (_isERC1155(nftTokenAddress)) {\n if (nftTokenAmount == 0) { nftTokenAmount = 1; }\n IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(address(this), wallet, nftTokenId, nftTokenAmount, \"\");\n } else {\n IERC721Upgradeable(nftTokenAddress).transferFrom(address(this), wallet, nftTokenId);\n }\n return basketMgr.addToBasket(contractAddress, tokenId, nftTokenAddress, nftTokenId);\n }\n\n /**\n * @dev Calculates the amount of Fees to be paid for a specific deposit amount\n * Fees are calculated in Interest-Token as they are the type collected for Fees\n * @param assetAmount The Amount of Assets to calculate Fees on\n * @return protocolFee The amount of fees reserved for the protocol\n */\n function _getFeesForDeposit(\n uint256 assetAmount\n )\n internal\n view\n returns (uint256 protocolFee)\n {\n if (depositFee > 0) {\n protocolFee = assetAmount.mul(depositFee).div(PERCENTAGE_SCALE);\n }\n }\n\n /// @dev Collects the Required ERC20 Token(s) from the users wallet\n /// Be sure to Approve this Contract to transfer your Token(s)\n /// @param from The owner address to collect the tokens from\n /// @param tokenAddress The addres of the token to transfer\n /// @param tokenAmount The amount of tokens to collect\n function _collectAssetToken(address from, address tokenAddress, uint256 tokenAmount) internal virtual returns (uint256 protocolFee) {\n protocolFee = _getFeesForDeposit(tokenAmount);\n IERC20Upgradeable(tokenAddress).safeTransferFrom(from, address(this), tokenAmount.add(protocolFee));\n }\n\n /// @dev Collects the Required ERC721 Token(s) from the users wallet\n /// Be sure to Approve this Contract to transfer your Token(s)\n /// @param from The owner address to collect the tokens from\n /// @param nftTokenAddress The address of the NFT token to transfer\n /// @param nftTokenId The ID of the NFT token to transfer\n /// @param nftTokenAmount The amount of Tokens to Transfer (ERC1155-specific)\n function _collectNftToken(address from, address nftTokenAddress, uint256 nftTokenId, uint256 nftTokenAmount) internal virtual {\n if (_isERC1155(nftTokenAddress)) {\n IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId, nftTokenAmount, \"\");\n } else {\n IERC721Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId);\n }\n }\n\n /// @dev Checks if an NFT token contract supports the ERC1155 standard interface\n function _isERC1155(address nftTokenAddress) internal view virtual returns (bool) {\n bytes4 _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n return IERC165Upgradeable(nftTokenAddress).supportsInterface(_INTERFACE_ID_ERC1155);\n }\n\n /// @dev See {ChargedParticles-baseParticleMass}.\n function _baseParticleMass(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n return _chargedManagers.getWalletManager(walletManagerId).getPrincipal(contractAddress, tokenId, assetToken);\n }\n\n /// @dev See {ChargedParticles-currentParticleCharge}.\n function _currentParticleCharge(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n (, uint256 ownerInterest) = _chargedManagers.getWalletManager(walletManagerId).getInterest(contractAddress, tokenId, assetToken);\n return ownerInterest;\n }\n\n /// @dev See {ChargedParticles-currentParticleKinetics}.\n function _currentParticleKinetics(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n return _chargedManagers.getWalletManager(walletManagerId).getRewards(contractAddress, tokenId, assetToken);\n }\n\n /// @dev See {ChargedParticles-currentParticleCovalentBonds}.\n function _currentParticleCovalentBonds(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId\n )\n internal\n view\n virtual\n returns (uint256)\n {\n return _chargedManagers.getBasketManager(basketManagerId).getTokenTotalCount(contractAddress, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier managerEnabled(string calldata walletManagerId) {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"CP:E-419\");\n _;\n }\n\n modifier basketEnabled(string calldata basketManagerId) {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"CP:E-419\");\n _;\n }\n}\n" + }, + "contracts/v1/ChargedSettings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/RelayRecipient.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\nimport \"./lib/TokenInfoProxy.sol\";\n\n/**\n * @notice Charged Particles Settings Contract\n */\ncontract ChargedSettings is\n IChargedSettings,\n Initializable,\n OwnableUpgradeable,\n RelayRecipient,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using Bitwise for uint32;\n\n uint256 constant internal MAX_ANNUITIES = 1e4; // 10000 (100%)\n\n // NftSettings - actionPerms\n uint32 constant internal PERM_CHARGE_NFT = 1; // NFT Contracts that can have assets Deposited into them (Charged)\n uint32 constant internal PERM_BASKET_NFT = 2; // NFT Contracts that can have other NFTs Deposited into them\n uint32 constant internal PERM_TIMELOCK_ANY_NFT = 4; // NFT Contracts that can timelock any NFT on behalf of users (primarily used for Front-run Protection)\n uint32 constant internal PERM_TIMELOCK_OWN_NFT = 8; // NFT Contracts that can timelock their own NFTs on behalf of their users\n uint32 constant internal PERM_RESTRICTED_ASSETS = 16; // NFT Contracts that have restricted deposits to specific assets\n\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // Current Settings for External NFT Token Contracts;\n // - Any user can add any ERC721 or ERC1155 token as a Charged Particle without Limits,\n // unless the Owner of the ERC721 or ERC1155 token contract registers the token\n // and sets the Custom Settings for their token(s)\n mapping (address => uint32) internal _nftActionPerms;\n\n mapping (address => string) internal _nftRequiredWalletManager;\n mapping (address => string) internal _nftRequiredBasketManager;\n\n // ERC20\n mapping (address => mapping(address => bool)) internal _nftAllowedAssetTokens;\n mapping (address => mapping (address => uint256)) internal _nftDepositMin;\n mapping (address => mapping (address => uint256)) internal _nftDepositMax;\n\n // ERC721 / ERC1155\n mapping (address => mapping (address => uint256)) internal _nftMaxNfts; // NFT Token Address => Max\n\n // Optional Configs for individual NFTs set by NFT Creator (by Token UUID)\n mapping (uint256 => uint256) internal _creatorAnnuityPercent;\n mapping (uint256 => address) internal _creatorAnnuityRedirect;\n\n mapping (address => uint256) internal _depositCap;\n uint256 internal _tempLockExpiryBlocks;\n\n // Blacklist for non-compliant tokens\n mapping (address => bool) internal _invalidAssets;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n /// @dev Gets the amount of creator annuities reserved for the creator for the specified NFT\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @return creator The address of the creator\n /// @return annuityPct The percentage amount of annuities reserved for the creator\n function getCreatorAnnuities(\n address contractAddress,\n uint256 tokenId\n )\n external\n override\n virtual\n returns (address creator, uint256 annuityPct)\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n creator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId);\n annuityPct = _creatorAnnuityPercent[tokenUuid];\n }\n\n function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId)\n external\n view\n override\n virtual\n returns (address)\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _creatorAnnuityRedirect[tokenUuid];\n }\n\n function getTempLockExpiryBlocks() external view override virtual returns (uint256) {\n return _tempLockExpiryBlocks;\n }\n\n function getTimelockApprovals(address operator)\n external\n view\n override\n virtual\n returns (bool timelockAny, bool timelockOwn)\n {\n timelockAny = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_ANY_NFT);\n timelockOwn = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_OWN_NFT);\n }\n\n function getAssetRequirements(address contractAddress, address assetToken)\n external\n view\n override\n virtual\n returns (\n string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n )\n {\n requiredWalletManager = _nftRequiredWalletManager[contractAddress];\n energizeEnabled = _nftActionPerms[contractAddress].hasBit(PERM_CHARGE_NFT);\n restrictedAssets = _nftActionPerms[contractAddress].hasBit(PERM_RESTRICTED_ASSETS);\n validAsset = _nftAllowedAssetTokens[contractAddress][assetToken];\n depositCap = _depositCap[assetToken];\n depositMin = _nftDepositMin[contractAddress][assetToken];\n depositMax = _nftDepositMax[contractAddress][assetToken];\n invalidAsset = _invalidAssets[assetToken];\n }\n\n function getNftAssetRequirements(address contractAddress, address nftTokenAddress)\n external\n view\n override\n virtual\n returns (string memory requiredBasketManager, bool basketEnabled, uint256 maxNfts)\n {\n requiredBasketManager = _nftRequiredBasketManager[contractAddress];\n basketEnabled = _nftActionPerms[contractAddress].hasBit(PERM_BASKET_NFT);\n maxNfts = _nftMaxNfts[contractAddress][nftTokenAddress];\n }\n\n\n /***********************************|\n | Only NFT Creator |\n |__________________________________*/\n\n /// @notice Sets the Custom Configuration for Creators of Proton-based NFTs\n /// @param contractAddress The Address to the Proton-based NFT to configure\n /// @param tokenId The token ID of the Proton-based NFT to configure\n /// @param creator The creator of the Proton-based NFT\n /// @param annuityPercent The percentage of interest-annuities to reserve for the creator\n function setCreatorAnnuities(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent\n )\n external\n virtual\n override\n {\n require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), \"CP:E-104\");\n _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent);\n }\n\n /// @notice Sets a Custom Receiver Address for the Creator Annuities\n /// @param contractAddress The Address to the Proton-based NFT to configure\n /// @param tokenId The token ID of the Proton-based NFT to configure\n /// @param receiver The receiver of the Creator interest-annuities\n function setCreatorAnnuitiesRedirect(\n address contractAddress,\n uint256 tokenId,\n address receiver\n )\n external\n virtual\n override\n {\n require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), \"CP:E-104\");\n _setCreatorAnnuitiesRedirect(contractAddress, tokenId, receiver);\n }\n\n\n /***********************************|\n | Register Contract Settings |\n |(For External Contract Integration)|\n |__________________________________*/\n\n /// @notice Sets a Required Wallet-Manager for External NFT Contracts (otherwise set to \"none\" to allow any Wallet-Manager)\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param walletManager If set, will only allow deposits from this specific Wallet-Manager\n function setRequiredWalletManager(\n address contractAddress,\n string calldata walletManager\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (keccak256(bytes(walletManager)) == keccak256(bytes(\"none\"))) {\n _nftRequiredWalletManager[contractAddress] = \"\";\n } else {\n _nftRequiredWalletManager[contractAddress] = walletManager;\n }\n\n emit RequiredWalletManagerSet(\n contractAddress,\n walletManager\n );\n }\n\n /// @notice Sets a Required Basket-Manager for External NFT Contracts (otherwise set to \"none\" to allow any Basket-Manager)\n /// @param contractAddress The Address to the External Contract to configure\n /// @param basketManager If set, will only allow deposits from this specific Basket-Manager\n function setRequiredBasketManager(\n address contractAddress,\n string calldata basketManager\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (keccak256(bytes(basketManager)) == keccak256(bytes(\"none\"))) {\n _nftRequiredBasketManager[contractAddress] = \"\";\n } else {\n _nftRequiredBasketManager[contractAddress] = basketManager;\n }\n\n emit RequiredBasketManagerSet(\n contractAddress,\n basketManager\n );\n }\n\n /// @notice Enables or Disables Asset-Token Restrictions for External NFT Contracts\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param restrictionsEnabled If set, will only allow deposits from Allowed Asset Tokens\n function setAssetTokenRestrictions(\n address contractAddress,\n bool restrictionsEnabled\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (restrictionsEnabled) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_RESTRICTED_ASSETS);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_RESTRICTED_ASSETS);\n }\n\n emit AssetTokenRestrictionsSet(\n contractAddress,\n restrictionsEnabled\n );\n }\n\n /// @notice Enables or Disables Allowed Asset Tokens for External NFT Contracts\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param assetToken The Address of the Asset Token to Allow or Disallow\n /// @param isAllowed True if the Asset Token is allowed\n function setAllowedAssetToken(\n address contractAddress,\n address assetToken,\n bool isAllowed\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftAllowedAssetTokens[contractAddress][assetToken] = isAllowed;\n\n emit AllowedAssetTokenSet(\n contractAddress,\n assetToken,\n isAllowed\n );\n }\n\n /// @notice Sets the Custom Configuration for External Contracts\n /// @param contractAddress The Address to the External Contract to configure\n /// @param assetToken The address of the Asset Token to set Limits for\n /// @param depositMin If set, will define the minimum amount of Asset tokens the NFT may hold, otherwise any amount\n /// @param depositMax If set, will define the maximum amount of Asset tokens the NFT may hold, otherwise any amount\n function setAssetTokenLimits(\n address contractAddress,\n address assetToken,\n uint256 depositMin,\n uint256 depositMax\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftDepositMin[contractAddress][assetToken] = depositMin;\n _nftDepositMax[contractAddress][assetToken] = depositMax;\n\n emit AssetTokenLimitsSet(\n contractAddress,\n assetToken,\n depositMin,\n depositMax\n );\n }\n\n /// @notice Sets the Max Number of NFTs that can be held by a Charged Particle NFT\n /// @param contractAddress The Address to the External Contract to configure\n /// @param nftTokenAddress The address of the NFT Token to set a Max for\n /// @param maxNfts The maximum numbers of NFTs that can be held by a given NFT (0 = unlimited)\n function setMaxNfts(\n address contractAddress,\n address nftTokenAddress,\n uint256 maxNfts\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftMaxNfts[contractAddress][nftTokenAddress] = maxNfts;\n\n emit MaxNftsSet(\n contractAddress,\n nftTokenAddress,\n maxNfts\n );\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n function setAssetInvalidity(address assetToken, bool invalidity) external virtual override onlyOwner {\n _invalidAssets[assetToken] = invalidity;\n emit AssetInvaliditySet(assetToken, invalidity);\n }\n\n function setDepositCap(address assetToken, uint256 cap) external virtual onlyOwner {\n _depositCap[assetToken] = cap;\n emit DepositCapSet(assetToken, cap);\n }\n\n function setTempLockExpiryBlocks(uint256 numBlocks) external virtual onlyOwner {\n _tempLockExpiryBlocks = numBlocks;\n emit TempLockExpirySet(numBlocks);\n }\n\n function enableNftContracts(address[] calldata contracts) external override virtual onlyOwner {\n uint count = contracts.length;\n for (uint i = 0; i < count; i++) {\n address tokenContract = contracts[i];\n _setPermsForCharge(tokenContract, true);\n _setPermsForBasket(tokenContract, true);\n _setPermsForTimelockSelf(tokenContract, true);\n }\n }\n\n function migrateToken(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent,\n address annuityReceiver\n )\n external\n onlyOwner\n {\n _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent);\n if (annuityReceiver != address(0)) {\n _setCreatorAnnuitiesRedirect(contractAddress, tokenId, annuityReceiver);\n }\n }\n\n /// @dev Update the list of NFT contracts that can be Charged\n function setPermsForCharge(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForCharge(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can hold other NFTs\n function setPermsForBasket(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForBasket(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection\n function setPermsForTimelockAny(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForTimelockAny(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock their own tokens\n function setPermsForTimelockSelf(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForTimelockSelf(contractAddress, state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Update the list of NFT contracts that can be Charged\n function _setPermsForCharge(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_CHARGE_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_CHARGE_NFT);\n }\n emit PermsSetForCharge(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can hold other NFTs\n function _setPermsForBasket(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_BASKET_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_BASKET_NFT);\n }\n emit PermsSetForBasket(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection\n function _setPermsForTimelockAny(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_ANY_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_ANY_NFT);\n }\n emit PermsSetForTimelockAny(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock their own tokens\n function _setPermsForTimelockSelf(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_OWN_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_OWN_NFT);\n }\n emit PermsSetForTimelockSelf(contractAddress, state);\n }\n\n /// @dev see setCreatorAnnuities()\n function _setCreatorAnnuities(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent\n )\n internal\n virtual\n {\n require(annuityPercent <= MAX_ANNUITIES, \"CP:E-421\");\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Update Configs for External Token Creator\n _creatorAnnuityPercent[tokenUuid] = annuityPercent;\n\n emit TokenCreatorConfigsSet(\n contractAddress,\n tokenId,\n creator,\n annuityPercent\n );\n }\n\n /// @dev see setCreatorAnnuitiesRedirect()\n function _setCreatorAnnuitiesRedirect(\n address contractAddress,\n uint256 tokenId,\n address receiver\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _creatorAnnuityRedirect[tokenUuid] = receiver;\n emit TokenCreatorAnnuitiesRedirected(contractAddress, tokenId, receiver);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyValidExternalContract(address contractAddress) {\n require(contractAddress.isContract(), \"CP:E-420\");\n _;\n }\n\n modifier onlyContractOwnerOrAdmin(address contractAddress, address sender) {\n require(sender == owner() || contractAddress.isContractOwner(sender), \"CP:E-103\");\n _;\n }\n}\n" + }, + "contracts/v1/ChargedState.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedState.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/RelayRecipient.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Settings Contract\n */\ncontract ChargedState is\n IChargedState,\n Initializable,\n OwnableUpgradeable,\n RelayRecipient,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using Bitwise for uint32;\n\n // NftState - actionPerms\n uint32 constant internal PERM_RESTRICT_ENERGIZE_FROM_ALL = 1; // NFTs that have Restrictions on Energize\n uint32 constant internal PERM_ALLOW_DISCHARGE_FROM_ALL = 2; // NFTs that allow Discharge by anyone\n uint32 constant internal PERM_ALLOW_RELEASE_FROM_ALL = 4; // NFTs that allow Release by anyone\n uint32 constant internal PERM_RESTRICT_BOND_FROM_ALL = 8; // NFTs that have Restrictions on Covalent Bonds\n uint32 constant internal PERM_ALLOW_BREAK_BOND_FROM_ALL = 16; // NFTs that allow Breaking Covalent Bonds by anyone\n\n IChargedSettings internal _chargedSettings;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // NftTimelocks\n /// @dev discharge unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftDischargeTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftDischargeTimelockLockedBy;\n\n /// @dev release unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftReleaseTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftReleaseTimelockLockedBy;\n\n /// @dev release unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftBreakBondTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftBreakBondTimelockLockedBy;\n\n // NftState\n /// @dev maps nft by tokenId to actionPermissions uint32 which is a composite of all possible NftState - actionPerms\n mapping (uint256 => uint32) internal _nftActionPerms;\n\n /// @dev maps nft by tokenId to its tempLockExpiry\n mapping (uint256 => uint256) internal _nftTempLockExpiry;\n\n /// @dev maps tokenId to user address to operator address for approving various actions\n mapping (uint256 => mapping(address => address)) internal _nftDischargeApproval;\n mapping (uint256 => mapping(address => address)) internal _nftReleaseApproval;\n mapping (uint256 => mapping(address => address)) internal _nftBreakBondApproval;\n mapping (uint256 => mapping(address => address)) internal _nftTimelockApproval;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftDischargeTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftDischargeTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftReleaseTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftReleaseTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftBreakBondTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftBreakBondTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n\n /// @notice Checks if an operator is allowed to Discharge a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForDischarge(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Release a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForRelease(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Break Covalent Bonds on a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForBreakBond(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Timelock a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForTimelock(contractAddress, tokenId, operator);\n }\n\n\n function isEnergizeRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n }\n\n\n function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_BOND_FROM_ALL);\n }\n\n\n function getDischargeState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n isApproved = _isApprovedForDischarge(contractAddress, tokenId, sender);\n timelock = _nftDischargeTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n function getReleaseState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_RELEASE_FROM_ALL);\n isApproved = _isApprovedForRelease(contractAddress, tokenId, sender);\n timelock = _nftReleaseTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n function getBreakBondState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n isApproved = _isApprovedForBreakBond(contractAddress, tokenId, sender);\n timelock = _nftBreakBondTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n\n /***********************************|\n | Only NFT Owner/Operator |\n |__________________________________*/\n\n /// @notice Sets an Operator as Approved to Discharge a specific Token\n /// This allows an operator to withdraw the interest-portion only\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setDischargeApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Release a specific Token\n /// This allows an operator to withdraw the principal + interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setReleaseApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token\n /// This allows an operator to withdraw Basket NFTs\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setBreakBondApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Timelock a specific Token\n /// This allows an operator to timelock the principal or interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setTimelockApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Discharge/Release/Timelock a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setApprovalForAll(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @dev Updates Restrictions on Energizing an NFT\n function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForRestrictCharge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowDischarge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowRelease(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Restrictions on Covalent Bonds on an NFT\n function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForRestrictBond(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone\n function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowBreakBond(contractAddress, tokenId, state);\n }\n\n /// @notice Sets a Timelock on the ability to Discharge the Interest of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setDischargeTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftDischargeTimelockLockedBy[tokenUuid] == sender) {\n delete _nftDischargeTimelockUnlockBlock[tokenUuid];\n delete _nftDischargeTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftDischargeTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftDischargeTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftDischargeTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenDischargeTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n /// @notice Sets a Timelock on the ability to Release the Assets of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setReleaseTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftReleaseTimelockLockedBy[tokenUuid] == sender) {\n delete _nftReleaseTimelockUnlockBlock[tokenUuid];\n delete _nftReleaseTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftReleaseTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftReleaseTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftReleaseTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenReleaseTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n /// @notice Sets a Timelock on the ability to Break the Covalent Bond of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setBreakBondTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftBreakBondTimelockLockedBy[tokenUuid] == sender) {\n delete _nftBreakBondTimelockUnlockBlock[tokenUuid];\n delete _nftBreakBondTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftBreakBondTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftBreakBondTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftBreakBondTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenBreakBondTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n\n /***********************************|\n | Only NFT Contract |\n |__________________________________*/\n\n /// @notice Sets a Temporary-Lock on the ability to Release/Discharge the Assets of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param isLocked The locked state; contracts are expected to disable this lock before expiry\n function setTemporaryLock(\n address contractAddress,\n uint256 tokenId,\n bool isLocked\n )\n external\n override\n virtual\n {\n require(msg.sender == contractAddress, \"CP:E-112\");\n\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n uint256 unlockBlock;\n if (isLocked && _nftTempLockExpiry[tokenUuid] == 0) {\n unlockBlock = block.number.add(_chargedSettings.getTempLockExpiryBlocks());\n _nftTempLockExpiry[tokenUuid] = unlockBlock;\n }\n if (!isLocked) {\n _nftTempLockExpiry[tokenUuid] = 0;\n }\n\n emit TokenTempLock(contractAddress, tokenId, unlockBlock);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n function migrateToken(\n address contractAddress,\n uint256 tokenId,\n uint256 releaseTimelockExpiry,\n address releaseTimelockLockedBy,\n uint256 tempLockExpiry\n )\n external\n onlyOwner\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (releaseTimelockExpiry > block.number && releaseTimelockLockedBy != address(0)) {\n _nftReleaseTimelockUnlockBlock[tokenUuid] = releaseTimelockExpiry;\n _nftReleaseTimelockLockedBy[tokenUuid] = releaseTimelockLockedBy;\n emit TokenReleaseTimelock(contractAddress, tokenId, releaseTimelockLockedBy, releaseTimelockExpiry);\n }\n\n if (tempLockExpiry > 0) {\n _nftTempLockExpiry[tokenUuid] = tempLockExpiry;\n emit TokenTempLock(contractAddress, tokenId, tempLockExpiry);\n }\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev See {ChargedParticles-isApprovedForDischarge}.\n function _isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftDischargeApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForRelease}.\n function _isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftReleaseApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForBreakBond}.\n function _isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftBreakBondApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForTimelock}.\n function _isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n (bool timelockAny, bool timelockOwn) = _chargedSettings.getTimelockApprovals(operator);\n if (timelockAny || (timelockOwn && contractAddress == operator)) { return true; }\n\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return tokenOwner == operator || _nftTimelockApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @notice Sets an Operator as Approved to Discharge a specific Token\n /// This allows an operator to withdraw the interest-portion only\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setDischargeApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftDischargeApproval[tokenUuid][tokenOwner] = operator;\n emit DischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Release a specific Token\n /// This allows an operator to withdraw the principal + interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setReleaseApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftReleaseApproval[tokenUuid][tokenOwner] = operator;\n emit ReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token\n /// This allows an operator to withdraw Basket NFTs\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setBreakBondApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftBreakBondApproval[tokenUuid][tokenOwner] = operator;\n emit BreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Timelock a specific Token\n /// This allows an operator to timelock the principal or interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setTimelockApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftTimelockApproval[tokenUuid][tokenOwner] = operator;\n emit TimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @dev Updates Restrictions on Energizing an NFT\n function _setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n }\n emit PermsSetForRestrictCharge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function _setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n }\n emit PermsSetForAllowDischarge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function _setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_RELEASE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_RELEASE_FROM_ALL);\n }\n emit PermsSetForAllowRelease(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Restrictions on Covalent Bonds on an NFT\n function _setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_BOND_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_BOND_FROM_ALL);\n }\n emit PermsSetForRestrictBond(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone\n function _setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n }\n emit PermsSetForAllowBreakBond(contractAddress, tokenId, state);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) {\n require(_tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender), \"CP:E-105\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/CommunityVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract CommunityVault is Ownable, BlackholePrevention {\n\n IERC20 private immutable _ionx;\n\n constructor (address ionx) public {\n _ionx = IERC20(ionx);\n }\n\n event SetAllowance(address indexed caller, address indexed spender, uint256 amount);\n\n function setAllowance(address spender, uint amount) public onlyOwner {\n _ionx.approve(spender, amount);\n\n emit SetAllowance(msg.sender, spender, amount);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens other than IONX, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n require(tokenAddress != address(_ionx), \"CommunityVault: cannot withdraw IONX\");\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n}" + }, + "contracts/v1/incentives/MerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_) public {\n token = token_;\n merkleRoot = merkleRoot_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), 'MerkleDistributor: Drop already claimed.');\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), 'MerkleDistributor: Invalid proof.');\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), 'MerkleDistributor: Transfer failed.');\n\n emit Claimed(index, account, amount);\n }\n}\n" + }, + "contracts/v1/incentives/MerkleDistributor2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor2 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"MerkleDistributor2: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"MerkleDistributor2: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor2: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"MerkleDistributor2: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"MerkleDistributor2: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"MerkleDistributor2: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/MerkleDistributor3.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor3 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"MerkleDistributor3: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"MerkleDistributor3: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor3: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"MerkleDistributor3: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"MerkleDistributor3: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"MerkleDistributor3: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/RewardProgram.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// RewardProgram.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/IRewardProgram.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/introspection/IERC165.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"../interfaces/IUniverseRP.sol\";\nimport \"../interfaces/IChargedManagers.sol\";\nimport \"../interfaces/IWalletManager.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IERC20Detailed.sol\";\n\ncontract RewardProgram is\n IRewardProgram,\n BlackholePrevention,\n IERC165,\n ReentrancyGuard,\n IERC721Receiver,\n IERC1155Receiver\n{\n using SafeMath for uint256;\n using TokenInfo for address;\n using SafeERC20 for IERC20;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n\n address private _owner;\n IUniverseRP private _universe;\n IChargedManagers private _chargedManagers;\n ProgramRewardData private _programData;\n mapping(uint256 => AssetStake) private _assetStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public {}\n\n function initialize(\n address stakingToken,\n address rewardToken,\n uint256 baseMultiplier,\n address chargedManagers,\n address universe,\n address owner\n ) external override {\n require(_owner == address(0x0), \"Already initialized\");\n _owner = owner;\n\n // Prepare Reward Program\n _programData.stakingToken = stakingToken;\n _programData.rewardToken = rewardToken;\n _programData.baseMultiplier = baseMultiplier; // Basis Points\n\n // Connect to Charged Particles\n _chargedManagers = IChargedManagers(chargedManagers);\n _universe = IUniverseRP(universe);\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getProgramData() external view override returns (ProgramRewardData memory) {\n return _programData;\n }\n\n function getAssetStake(uint256 parentNftUuid) external view override returns (AssetStake memory) {\n return _assetStake[parentNftUuid];\n }\n\n function getFundBalance() external view override returns (uint256) {\n return _getFundBalance();\n }\n\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) public view override returns (uint256) {\n return _calculateRewardsEarned(parentNftUuid, interestAmount);\n }\n\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n return _assetStake[parentNftUuid].claimableRewards;\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\n return \"\";\n }\n\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(IERC165)\n returns (bool)\n {\n // default interface support\n if (\n interfaceId == type(IERC721Receiver).interfaceId ||\n interfaceId == type(IERC1155Receiver).interfaceId ||\n interfaceId == type(IERC165).interfaceId\n ) {\n return true;\n }\n }\n\n function owner() public view returns (address) {\n return _owner;\n }\n\n\n /***********************************|\n | Only Universe |\n |__________________________________*/\n\n function registerAssetDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n uint256 principalAmount\n )\n external\n override\n onlyUniverse\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n if (assetStake.start == 0) {\n assetStake.start = block.number;\n assetStake.walletManagerId = walletManagerId;\n }\n emit AssetDeposit(contractAddress, tokenId, walletManagerId, principalAmount);\n }\n\n function registerAssetRelease(\n address contractAddress,\n uint256 tokenId,\n uint256 interestAmount\n )\n external\n override\n onlyUniverse\n nonReentrant\n returns (uint256 rewards)\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n // Update Claimable Rewards\n uint256 newRewards = _calculateRewardsEarned(parentNftUuid, interestAmount);\n assetStake.claimableRewards = assetStake.claimableRewards.add(newRewards);\n\n // Reset Stake if Principal Balance falls to Zero\n IWalletManager walletMgr = _chargedManagers.getWalletManager(assetStake.walletManagerId);\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\n if (principal == 0) {\n assetStake.start = 0;\n }\n\n // Issue Rewards to NFT Owner\n rewards = _claimRewards(contractAddress, tokenId);\n\n emit AssetRelease(contractAddress, tokenId, interestAmount);\n }\n\n\n /***********************************|\n | Reward Calculation |\n |__________________________________*/\n\n function _calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) internal view returns (uint256 totalReward) {\n uint256 baseReward = _calculateBaseReward(interestAmount);\n uint256 leptonMultipliedReward = _calculateMultipliedReward(parentNftUuid, baseReward);\n totalReward = _convertDecimals(leptonMultipliedReward);\n }\n\n function _calculateBaseReward(uint256 amount) internal view returns(uint256 baseReward) {\n baseReward = amount.mul(_programData.baseMultiplier).div(PERCENTAGE_SCALE);\n }\n\n function _calculateMultipliedReward(uint256 parentNftUuid, uint256 baseReward) internal view returns(uint256) {\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n if (assetStake.start == 0) { return baseReward; }\n\n IUniverseRP.NftStake memory nftStake = _universe.getNftStake(parentNftUuid);\n uint256 multiplierBP = nftStake.multiplier;\n\n uint256 assetDepositLength = block.number.sub(assetStake.start);\n uint256 nftDepositLength = 0;\n if (nftStake.releaseBlockNumber > 0) {\n nftDepositLength = nftStake.releaseBlockNumber.sub(nftStake.depositBlockNumber);\n } else {\n nftDepositLength = block.number.sub(nftStake.depositBlockNumber);\n }\n\n if (multiplierBP == 0 || nftDepositLength == 0 || assetDepositLength == 0) {\n return baseReward;\n }\n\n if (nftDepositLength > assetDepositLength) {\n nftDepositLength = assetDepositLength;\n }\n\n // Percentage of the total program that the Multiplier Nft was deposited for\n uint256 nftRewardRatioBP = nftDepositLength.mul(PERCENTAGE_SCALE).div(assetDepositLength);\n\n // Amount of reward that the Multiplier Nft is responsible for\n uint256 amountGeneratedDuringNftDeposit = baseReward.mul(nftRewardRatioBP).div(PERCENTAGE_SCALE);\n\n // Amount of Multiplied Reward from NFT\n uint256 multipliedReward = amountGeneratedDuringNftDeposit.mul(multiplierBP.mul(LEPTON_MULTIPLIER_SCALE)).div(PERCENTAGE_SCALE);\n\n // Amount of Base Reward without Multiplied NFT Rewards\n uint256 amountGeneratedWithoutNftDeposit = baseReward.sub(amountGeneratedDuringNftDeposit);\n\n // Amount of Base Rewards + Multiplied NFT Rewards\n return amountGeneratedWithoutNftDeposit.add(multipliedReward);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function fundProgram(uint256 amount) external onlyOwner {\n require(_programData.rewardToken != address(0), \"RP:E-405\");\n IERC20(_programData.rewardToken).safeTransferFrom(msg.sender, address(this), amount);\n emit RewardProgramFunded(amount);\n }\n\n function setStakingToken(address newStakingToken) external onlyOwner {\n _programData.stakingToken = newStakingToken;\n }\n\n function setRewardToken(address newRewardToken) external onlyOwner {\n _programData.rewardToken = newRewardToken;\n }\n\n function setBaseMultiplier(uint256 newMultiplier) external onlyOwner {\n _programData.baseMultiplier = newMultiplier; // Basis Points\n }\n\n function setChargedManagers(address manager) external onlyOwner {\n _chargedManagers = IChargedManagers(manager);\n }\n\n function setUniverse(address universe) external onlyOwner {\n _universe = IUniverseRP(universe);\n }\n\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external override onlyOwner {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n\n // Initiate Asset Stake\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\n if (principal > 0) {\n _assetStake[parentNftUuid] = AssetStake(block.number, 0, walletManagerId);\n emit AssetRegistered(contractAddress, tokenId, walletManagerId, principal);\n }\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _claimRewards(\n address contractAddress,\n uint256 tokenId\n )\n internal\n returns (uint256 totalReward)\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n // Rewards Receiver\n address receiver = IERC721(contractAddress).ownerOf(tokenId);\n\n // Ensure Reward Pool has Sufficient Balance\n totalReward = assetStake.claimableRewards;\n uint256 fundBalance = _getFundBalance();\n uint256 unavailReward = totalReward > fundBalance ? totalReward.sub(fundBalance) : 0;\n\n // Determine amount of Rewards to Transfer\n if (unavailReward > 0) {\n totalReward = totalReward.sub(unavailReward);\n emit RewardProgramOutOfFunds();\n }\n\n // Update Asset Stake\n assetStake.claimableRewards = unavailReward;\n\n if (totalReward > 0) {\n // Transfer Available Rewards to Receiver\n IERC20(_programData.rewardToken).safeTransfer(receiver, totalReward);\n }\n\n emit RewardsClaimed(contractAddress, tokenId, receiver, totalReward, unavailReward);\n }\n\n function _convertDecimals(uint256 reward) internal view returns (uint256) {\n uint8 stakingTokenDecimals = IERC20Detailed(_programData.stakingToken).decimals();\n return reward.mul(10**(18 - uint256(stakingTokenDecimals)));\n }\n\n function _getFundBalance() internal view returns (uint256) {\n return IERC20Detailed(_programData.rewardToken).balanceOf(address(this));\n }\n\n\n modifier onlyOwner() {\n require(_owner == msg.sender, \"Caller is not the owner\");\n _;\n }\n\n modifier onlyUniverse() {\n require(msg.sender == address(_universe), \"RP:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/RewardProgramFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// RewardProgramFactory.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport \"./RewardProgram.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract RewardProgramFactory is BlackholePrevention, Ownable {\n event RewardProgramCreated(address indexed rewardProgram);\n\n address public _template;\n\n constructor () public {\n _template = address(new RewardProgram());\n }\n\n // function _msgSender() internal view override returns (address payable) {\n // return msg.sender;\n // }\n\n function createRewardProgram(\n address stakingToken,\n address rewardToken,\n uint256 baseMultiplier,\n address chargedManagers,\n address universe\n )\n external\n onlyOwner\n returns (address)\n {\n address newRewardProgram = _createClone(_template);\n RewardProgram rewardProgram = RewardProgram(newRewardProgram);\n rewardProgram.initialize(stakingToken, rewardToken, baseMultiplier, chargedManagers, universe, _msgSender());\n emit RewardProgramCreated(newRewardProgram);\n return newRewardProgram;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n}\n" + }, + "contracts/v1/incentives/Staking.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/Staking2.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking2 is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/Staking3.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking3 is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/YieldFarm.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/incentives/YieldFarm2.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm2 is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/incentives/YieldFarm3.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm3 is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/interfaces/IAaveBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IAaveBridge.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n\ninterface IAaveBridge {\n function getReserveInterestToken(address assetToken) external view returns (address aTokenAddress);\n function isReserveActive(address assetToken) external view returns (bool);\n\n function getTotalBalance(address account, address assetToken) external view returns (uint256);\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(address receiver, address assetToken, uint256 assetAmount) external;\n}\n" + }, + "contracts/v1/interfaces/IBaseProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IBaseProton is IERC721 {\n event PausedStateSet(bool isPaused);\n event SalePriceSet(uint256 indexed tokenId, uint256 salePrice);\n event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct);\n event FeesWithdrawn(address indexed receiver, uint256 amount);\n event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties);\n event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view returns (address);\n function getSalePrice(uint256 tokenId) external view returns (uint256);\n function getLastSellPrice(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyalties(address account) external view returns (uint256);\n function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address);\n\n function buyProton(uint256 tokenId, uint256 gasLimit) external payable returns (bool);\n function claimCreatorRoyalties() external returns (uint256);\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n ) external returns (uint256 newTokenId);\n\n function createProtons(\n address creator,\n address receiver,\n string[] calldata tokenMetaUris\n ) external returns (bool);\n\n function createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n ) external returns (bool);\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice) external;\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external;\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external;\n}" + }, + "contracts/v1/interfaces/IBasketManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Particle Basket Manager interface\n * @dev The basket-manager for underlying assets attached to Charged Particles\n * @dev Manages the link between NFTs and their respective Smart-Baskets\n */\ninterface IBasketManager {\n\n event ControllerSet(address indexed controller);\n event ExecutorSet(address indexed executor);\n event PausedStateSet(bool isPaused);\n event NewSmartBasket(address indexed contractAddress, uint256 indexed tokenId, address indexed smartBasket);\n event BasketAdd(address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\n event BasketRemove(address indexed receiver, address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\n event BasketRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\n event RewardProgramSet(address indexed rewardProgram);\n\n function isPaused() external view returns (bool);\n\n function getTokenTotalCount(address contractAddress, uint256 tokenId) external view returns (uint256);\n function getTokenCountByType(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (uint256);\n\n function prepareTransferAmount(uint256 nftTokenAmount) external;\n function addToBasket(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function getBasketAddressById(address contractAddress, uint256 tokenId) external returns (address);\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/IChargedManagers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IWalletManager.sol\";\nimport \"./IBasketManager.sol\";\n\n/**\n * @notice Interface for Charged Wallet-Managers\n */\ninterface IChargedManagers {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function isContractOwner(address contractAddress, address account) external view returns (bool);\n\n // ERC20\n function isWalletManagerEnabled(string calldata walletManagerId) external view returns (bool);\n function getWalletManager(string calldata walletManagerId) external view returns (IWalletManager);\n\n // ERC721\n function isNftBasketEnabled(string calldata basketId) external view returns (bool);\n function getBasketManager(string calldata basketId) external view returns (IBasketManager);\n\n // Validation\n function validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external;\n function validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external;\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external;\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event WalletManagerRegistered(string indexed walletManagerId, address indexed walletManager);\n event BasketManagerRegistered(string indexed basketId, address indexed basketManager);\n}\n" + }, + "contracts/v1/interfaces/IChargedParticles.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Charged Particles\n */\ninterface IChargedParticles {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getStateAddress() external view returns (address stateAddress);\n function getSettingsAddress() external view returns (address settingsAddress);\n function getManagersAddress() external view returns (address managersAddress);\n\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\n\n /***********************************|\n | Particle Mechanics |\n |__________________________________*/\n\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n ) external returns (uint256 yieldTokensAmount);\n\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 receiverAmount);\n\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositFeeSet(uint256 depositFee);\n event ProtocolFeesCollected(address indexed assetToken, uint256 depositAmount, uint256 feesCollected);\n}\n" + }, + "contracts/v1/interfaces/IChargedSettings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IWalletManager.sol\";\nimport \"./IBasketManager.sol\";\n\n/**\n * @notice Interface for Charged Settings\n */\ninterface IChargedSettings {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n // function isContractOwner(address contractAddress, address account) external view returns (bool);\n function getCreatorAnnuities(address contractAddress, uint256 tokenId) external returns (address creator, uint256 annuityPct);\n function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId) external view returns (address);\n function getTempLockExpiryBlocks() external view returns (uint256);\n function getTimelockApprovals(address operator) external view returns (bool timelockAny, bool timelockOwn);\n function getAssetRequirements(\n address contractAddress,\n address assetToken\n ) external view returns (\n string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n );\n function getNftAssetRequirements(\n address contractAddress,\n address nftTokenAddress\n ) external view returns (\n string memory requiredBasketManager,\n bool basketEnabled,\n uint256 maxNfts\n );\n\n /***********************************|\n | Only NFT Creator |\n |__________________________________*/\n\n function setCreatorAnnuities(address contractAddress, uint256 tokenId, address creator, uint256 annuityPercent) external;\n function setCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId, address receiver) external;\n\n\n /***********************************|\n | Only NFT Contract Owner |\n |__________________________________*/\n\n function setRequiredWalletManager(address contractAddress, string calldata walletManager) external;\n function setRequiredBasketManager(address contractAddress, string calldata basketManager) external;\n function setAssetTokenRestrictions(address contractAddress, bool restrictionsEnabled) external;\n function setAllowedAssetToken(address contractAddress, address assetToken, bool isAllowed) external;\n function setAssetTokenLimits(address contractAddress, address assetToken, uint256 depositMin, uint256 depositMax) external;\n function setMaxNfts(address contractAddress, address nftTokenAddress, uint256 maxNfts) external;\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAssetInvalidity(address assetToken, bool invalidity) external;\n function enableNftContracts(address[] calldata contracts) external;\n function setPermsForCharge(address contractAddress, bool state) external;\n function setPermsForBasket(address contractAddress, bool state) external;\n function setPermsForTimelockAny(address contractAddress, bool state) external;\n function setPermsForTimelockSelf(address contractAddress, bool state) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositCapSet(address assetToken, uint256 depositCap);\n event TempLockExpirySet(uint256 expiryBlocks);\n\n event RequiredWalletManagerSet(address indexed contractAddress, string walletManager);\n event RequiredBasketManagerSet(address indexed contractAddress, string basketManager);\n event AssetTokenRestrictionsSet(address indexed contractAddress, bool restrictionsEnabled);\n event AllowedAssetTokenSet(address indexed contractAddress, address assetToken, bool isAllowed);\n event AssetTokenLimitsSet(address indexed contractAddress, address assetToken, uint256 assetDepositMin, uint256 assetDepositMax);\n event MaxNftsSet(address indexed contractAddress, address indexed nftTokenAddress, uint256 maxNfts);\n event AssetInvaliditySet(address indexed assetToken, bool invalidity);\n\n event TokenCreatorConfigsSet(address indexed contractAddress, uint256 indexed tokenId, address indexed creatorAddress, uint256 annuityPercent);\n event TokenCreatorAnnuitiesRedirected(address indexed contractAddress, uint256 indexed tokenId, address indexed redirectAddress);\n\n event PermsSetForCharge(address indexed contractAddress, bool state);\n event PermsSetForBasket(address indexed contractAddress, bool state);\n event PermsSetForTimelockAny(address indexed contractAddress, bool state);\n event PermsSetForTimelockSelf(address indexed contractAddress, bool state);\n}\n" + }, + "contracts/v1/interfaces/IChargedState.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IChargedSettings.sol\";\n\n/**\n * @notice Interface for Charged State\n */\ninterface IChargedState {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n\n function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n\n function isEnergizeRestricted(address contractAddress, uint256 tokenId) external view returns (bool);\n function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external view returns (bool);\n\n function getDischargeState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n function getReleaseState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n function getBreakBondState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n\n /***********************************|\n | Only NFT Owner/Operator |\n |__________________________________*/\n\n function setDischargeApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setReleaseApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setBreakBondApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setTimelockApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setApprovalForAll(address contractAddress, uint256 tokenId, address operator) external;\n\n function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) external;\n\n function setDischargeTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n function setReleaseTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n function setBreakBondTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n /***********************************|\n | Only NFT Contract |\n |__________________________________*/\n\n function setTemporaryLock(\n address contractAddress,\n uint256 tokenId,\n bool isLocked\n ) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n\n event DischargeApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event ReleaseApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event BreakBondApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event TimelockApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n\n event TokenDischargeTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenReleaseTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenBreakBondTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenTempLock(address indexed contractAddress, uint256 indexed tokenId, uint256 unlockBlock);\n\n event PermsSetForRestrictCharge(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowDischarge(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowRelease(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForRestrictBond(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowBreakBond(address indexed contractAddress, uint256 indexed tokenId, bool state);\n}\n" + }, + "contracts/v1/interfaces/IDai.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\ninterface IDai is IERC20Upgradeable {\n // --- Approve by signature ---\n function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external;\n function transferFrom(address src, address dst, uint wad) external override returns (bool);\n}" + }, + "contracts/v1/interfaces/IERC20Detailed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Detailed {\n function decimals() external view returns (uint8);\n function symbol() external view returns (string memory);\n function name() external view returns (string memory);\n\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(address sender, address recipient, uint256 amount) 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" + }, + "contracts/v1/interfaces/IERC721Chargeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IERC721Chargeable.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\n\ninterface IERC721Chargeable is IERC165Upgradeable {\n function owner() external view returns (address);\n function creatorOf(uint256 tokenId) external view returns (address);\n function balanceOf(address tokenOwner) external view returns (uint256 balance);\n function ownerOf(uint256 tokenId) external view returns (address tokenOwner);\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n function transferFrom(address from, address to, uint256 tokenId) external;\n function approve(address to, uint256 tokenId) external;\n function getApproved(uint256 tokenId) external view returns (address operator);\n function setApprovalForAll(address operator, bool _approved) external;\n function isApprovedForAll(address tokenOwner, address operator) external view returns (bool);\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "contracts/v1/interfaces/ILepton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ILepton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Lepton Interface\n * @dev ...\n */\ninterface ILepton {\n\n struct Classification {\n string tokenUri;\n uint256 price;\n uint128 _upperBounds;\n uint32 supply;\n uint32 multiplier;\n uint32 bonus;\n }\n\n function mintLepton() external payable returns (uint256 newTokenId);\n function batchMintLepton(uint256 count) external payable;\n function getNextType() external view returns (uint256);\n function getNextPrice() external view returns (uint256);\n function getMultiplier(uint256 tokenId) external view returns (uint256);\n function getBonus(uint256 tokenId) external view returns (uint256);\n\n\n event MaxMintPerTxSet(uint256 maxAmount);\n event LeptonTypeAdded(string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\n event LeptonTypeUpdated(uint256 leptonIndex, string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\n event LeptonMinted(address indexed receiver, uint256 indexed tokenId, uint256 price, uint32 multiplier);\n event LeptonBatchMinted(address indexed receiver, uint256 indexed tokenId, uint256 count, uint256 price, uint32 multiplier);\n event PausedStateSet(bool isPaused);\n}\n" + }, + "contracts/v1/interfaces/IMerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.6.0;\n\n// Allows anyone to claim a token if they exist in a merkle root.\ninterface IMerkleDistributor {\n // Returns the address of the token distributed by this contract.\n function token() external view returns (address);\n // Returns the merkle root of the merkle tree containing account balances available to claim.\n function merkleRoot() external view returns (bytes32);\n // Returns true if the index has been marked claimed.\n function isClaimed(uint256 index) external view returns (bool);\n // Claim the given amount of the token to the given address. Reverts if the inputs are invalid.\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external;\n\n // This event is triggered whenever a call to #claim succeeds.\n event Claimed(uint256 index, address account, uint256 amount);\n}" + }, + "contracts/v1/interfaces/IParticleSplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IParticleSplitter.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Particle Splitter\n */\ninterface IParticleSplitter {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function executeForWallet(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address externalAddress,\n bytes memory encodedParams\n ) external payable returns (bytes memory);\n\n function executeForBasket(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address externalAddress,\n bytes memory encodedParams\n ) external payable returns (bytes memory);\n\n function withdrawWalletRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n ) external returns (uint256 amountWithdrawn);\n\n function withdrawBasketRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n ) external returns (uint256 amountWithdrawn);\n\n function refreshWalletPrincipal(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external;\n\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event ChargedManagersSet(address indexed chargedManagers);\n event TokenInfoProxySet(address indexed tokenInfoProxy);\n\n event ExecuteForWallet(\n address indexed contractAddress,\n uint256 tokenId,\n string walletManagerId,\n address indexed externalAddress,\n bytes encodedParams,\n uint256 ethValue\n );\n event ExecuteForBasket(\n address indexed contractAddress,\n uint256 tokenId,\n string basketManagerId,\n address indexed externalAddress,\n bytes encodedParams,\n uint256 ethValue\n );\n event PrincipalRefreshed(\n address contractAddress,\n uint256 tokenId,\n string walletManagerId,\n address assetToken\n );\n event PermsSetForExternal(\n address indexed contractAddress,\n bool state\n );\n}\n" + }, + "contracts/v1/interfaces/IProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IProton is IERC721 {\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n event PausedStateSet(bool isPaused);\n event SalePriceSet(uint256 indexed tokenId, uint256 salePrice);\n event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct);\n event FeesWithdrawn(address indexed receiver, uint256 amount);\n event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties);\n event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view returns (address);\n function getSalePrice(uint256 tokenId) external view returns (uint256);\n function getLastSellPrice(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyalties(address account) external view returns (uint256);\n function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address);\n\n function buyProton(uint256 tokenId) external payable returns (bool);\n function claimCreatorRoyalties() external returns (uint256);\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n ) external returns (uint256 newTokenId);\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n ) external returns (uint256 newTokenId);\n\n function batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n ) external;\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice) external;\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external;\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external;\n}" + }, + "contracts/v1/interfaces/IProtonB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IProtonB is IERC721 {\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n ) external returns (uint256 newTokenId);\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n}" + }, + "contracts/v1/interfaces/IRewardNft.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IRewardNft.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Reward-NFT Interface\n * @dev ...\n */\ninterface IRewardNft {\n function getMultiplier(uint256 tokenId) external view returns (uint256);\n function getBonus(uint256 tokenId) external view returns (uint256);\n}\n" + }, + "contracts/v1/interfaces/IRewardProgram.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IRewardProgram.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\ninterface IRewardProgram {\n /* admin events */\n event RewardProgramFunded(uint256 amount);\n event RewardProgramOutOfFunds();\n\n /* user events */\n event RewardsClaimed(address indexed contractAddress, uint256 tokenId, address indexed receiver, uint256 rewarded, uint256 remaining);\n\n event AssetRegistered(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\n event AssetDeposit(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\n event AssetRelease(address indexed contractAddress, uint256 tokenId, uint256 interestAmount);\n\n /* data types */\n struct ProgramRewardData {\n address stakingToken;\n address rewardToken;\n uint256 baseMultiplier; // Basis Points\n }\n\n struct AssetStake {\n uint256 start;\n uint256 claimableRewards;\n string walletManagerId;\n }\n\n function initialize(address stakingToken, address rewardToken, uint256 baseMultiplier, address chargedManagers, address universe, address owner) external;\n\n /* user functions */\n function getProgramData() external view returns (ProgramRewardData memory programData);\n function getAssetStake(uint256 uuid) external view returns (AssetStake memory);\n function getFundBalance() external view returns (uint256);\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) external view returns (uint256);\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external;\n function registerAssetDeposit(address contractAddress, uint256 tokenId, string calldata walletManagerId, uint256 principalAmount) external;\n function registerAssetRelease(address contractAddress, uint256 tokenId, uint256 interestAmount) external returns (uint256 rewards);\n}" + }, + "contracts/v1/interfaces/ISmartBasket.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartBasket.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Basket\n * @dev Manages holding and transferring NFTs within an NFT (if any),\n */\ninterface ISmartBasket {\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function addToBasket(address contractAddress, uint256 tokenId) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId) external returns (bool);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartBasketB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartBasketB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Basket \"B\"\n * @dev Manages holding and transferring NFTs within an NFT (if any),\n */\ninterface ISmartBasketB {\n function getNestedNftCount() external view returns (uint256);\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool);\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Wallet\n * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any),\n */\ninterface ISmartWallet {\n function getAssetTokenCount() external view returns (uint256);\n function getAssetTokenByIndex(uint256 index) external view returns (address);\n\n function setNftCreator(address creator, uint256 annuityPct) external;\n\n function isReserveActive(address assetToken) external view returns (bool);\n function getReserveInterestToken(address assetToken) external view returns (address);\n\n function getPrincipal(address assetToken) external returns (uint256);\n function getInterest(address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getTotal(address assetToken) external returns (uint256);\n function getRewards(address assetToken) external returns (uint256);\n\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(address receiver, address creatorRedirect, address assetToken) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function withdrawAmount(address receiver, address creatorRedirect, address assetToken, uint256 assetAmount) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function withdrawAmountForCreator(address receiver, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address assetToken) external;\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Wallet\n * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any),\n */\ninterface ISmartWalletB {\n function getAssetTokenCount() external view returns (uint256);\n function getAssetTokenByIndex(uint256 index) external view returns (address);\n\n function isReserveActive(address assetToken) external view returns (bool);\n function getReserveInterestToken(address assetToken) external view returns (address);\n\n function getPrincipal(address assetToken) external returns (uint256);\n function getInterest(address assetToken, uint256 creatorPct) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getTotal(address assetToken) external returns (uint256);\n function getRewards(address assetToken) external returns (uint256);\n\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken\n ) external returns (\n uint256 creatorAmount,\n uint256 receiverAmount\n );\n function withdrawAmount(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n ) external returns (\n uint256 creatorAmount,\n uint256 receiverAmount\n );\n function withdrawAmountForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n ) external returns (\n uint256 receiverAmount\n );\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address assetToken) external;\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/IStaking.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\ninterface IStaking {\n function manualEpochInit(address[] memory tokens, uint128 epochId) external;\n function getCurrentEpoch() external view returns (uint128);\n function getEpochId(uint timestamp) external view returns (uint); // get epoch id\n function getEpochUserBalance(address user, address token, uint128 epoch) external view returns(uint);\n function getEpochPoolSize(address token, uint128 epoch) external view returns (uint);\n function epoch1Start() external view returns (uint);\n function epochDuration() external view returns (uint);\n}" + }, + "contracts/v1/interfaces/ITokenInfoProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfoProxy.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\n\ninterface ITokenInfoProxy {\n\n event ContractFunctionSignatureSet(address indexed contractAddress, string fnName, bytes4 fnSig);\n\n struct FnSignatures {\n bytes4 ownerOf;\n bytes4 creatorOf;\n }\n\n function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external;\n function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external;\n\n function getTokenUUID(address contractAddress, uint256 tokenId) external pure returns (uint256);\n function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external returns (bool);\n function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external returns (bool);\n function getTokenOwner(address contractAddress, uint256 tokenId) external returns (address);\n function getTokenCreator(address contractAddress, uint256 tokenId) external returns (address);\n}\n" + }, + "contracts/v1/interfaces/IUniverse.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IUniverse.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Universal Controller interface\n * @dev ...\n */\ninterface IUniverse {\n\n event ChargedParticlesSet(address indexed chargedParticles);\n event PhotonSet(address indexed photonToken, uint256 maxSupply);\n event ProtonTokenSet(address indexed protonToken);\n event LeptonTokenSet(address indexed leptonToken);\n event QuarkTokenSet(address indexed quarkToken);\n event BosonTokenSet(address indexed bosonToken);\n event EsaMultiplierSet(address indexed assetToken, uint256 multiplier);\n event ElectrostaticAttraction(address indexed account, address photonSource, uint256 energy, uint256 multiplier);\n event ElectrostaticDischarge(address indexed account, address photonSource, uint256 energy);\n\n function onEnergize(\n address sender,\n address referrer,\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 assetEnergy\n ) external;\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n ) external;\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address creator,\n address assetToken,\n uint256 receiverEnergy\n ) external;\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 principalEnergy,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n ) external;\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n ) external;\n}\n" + }, + "contracts/v1/interfaces/IUniverseRP.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IUniverseRP.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport \"./IUniverse.sol\";\n\n/**\n * @title Universal Controller interface for Rewards Program\n * @dev ...\n */\ninterface IUniverseRP is IUniverse {\n event RewardProgramSet(address indexed assetToken, address indexed rewardProgram);\n event RewardProgramRemoved(address indexed assetToken);\n event NftDeposit(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\n event NftRelease(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\n\n struct NftStake {\n uint256 multiplier; // in Basis Points\n uint256 depositBlockNumber;\n uint256 releaseBlockNumber;\n }\n\n function getRewardProgram(address asset) external view returns (address);\n function getNftStake(uint256 uuid) external view returns (NftStake memory);\n}\n" + }, + "contracts/v1/interfaces/IWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Particle Wallet Manager interface\n * @dev The wallet-manager for underlying assets attached to Charged Particles\n * @dev Manages the link between NFTs and their respective Smart-Wallets\n */\ninterface IWalletManager {\n\n event ControllerSet(address indexed controller);\n event ExecutorSet(address indexed executor);\n event PausedStateSet(bool isPaused);\n event NewSmartWallet(address indexed contractAddress, uint256 indexed tokenId, address indexed smartWallet, address creator, uint256 annuityPct);\n event WalletEnergized(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 assetAmount, uint256 yieldTokensAmount);\n event WalletDischarged(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 creatorAmount, uint256 receiverAmount);\n event WalletDischargedForCreator(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, address creator, uint256 receiverAmount);\n event WalletReleased(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address assetToken, uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n event WalletRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\n\n function isPaused() external view returns (bool);\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view returns (bool);\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view returns (address);\n\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\n function getInterest(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken) external returns (uint256);\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount) external returns (uint256 yieldTokensAmount);\n function discharge(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function dischargeAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function dischargeAmountForCreator(address receiver, address contractAddress, uint256 tokenId, address creator, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\n function release(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n function releaseAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken) external;\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct) external returns (address);\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\n}\n" + }, + "contracts/v1/lib/BaseProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IBaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n/// @title Base Proton Contract for Charged Particles compatible ERC721 NFTs\n/// @dev MUST NOT be Upgradeable, as Upgradeable NFTs are incompatible with Charged Particles.\ncontract BaseProton is \n IBaseProton, \n ERC721, \n Ownable, \n RelayRecipient, \n ReentrancyGuard, \n BlackholePrevention \n{\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n event Received(address, uint);\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n /// @dev Sequential Token IDs storage\n Counters.Counter internal _tokenIds;\n\n /// @dev NFT Token Creator settings\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct;\n mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect;\n mapping (address => uint256) internal _tokenCreatorClaimableRoyalties;\n\n /// @dev NFT Token Sale settings\n mapping (uint256 => uint256) internal _tokenSalePrice;\n mapping (uint256 => uint256) internal _tokenLastSellPrice;\n\n /// @dev Whether of not the Contract is Paused\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n /// @dev Inherit from ERC721 standard\n constructor(string memory _name, string memory _symbol) public ERC721(_name, _symbol) {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n receive() external payable virtual {\n emit Received(msg.sender, msg.value);\n }\n\n /// Returns the Creator address of an NFT by Token ID\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The address of the Creator account\n function creatorOf(uint256 tokenId) external view virtual override returns (address) {\n return _tokenCreator[tokenId];\n }\n\n /// Returns the Sale Price of an NFT by Token ID\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The sale price of the NFT\n function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenSalePrice[tokenId];\n }\n\n /// Returns the Last Sale Price of an NFT by Token ID\n /// @notice This is used to determine any increase in sale price used in royalties calculations\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The last sale price of the NFT\n function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenLastSellPrice[tokenId];\n }\n\n /// Returns the Claimable Royalties for the NFT Creator\n /// @param account The address of the Creator account to lookup\n /// @return The amount of earned royalties for the creator account\n function getCreatorRoyalties(address account) external view virtual override returns (uint256) {\n return _tokenCreatorClaimableRoyalties[account];\n }\n\n /// Returns the Percentage of Royalties reserved for the NFT Creator\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The percentage of royalties reserved for the creator\n function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenCreatorRoyaltiesPct[tokenId];\n }\n\n /// Returns the Receiving address of the Creator Royalties (or Creator if not set)\n /// @dev Returns the creator address if a receiving address has not been configured\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The Receiving address of the Creator Royalties\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) {\n return _creatorRoyaltiesReceiver(tokenId);\n }\n\n /// Allows an NFT Creator to Claim any Royalties that have been earned from NFT sales\n /// @dev Must be called by the royalties receiver account (not neccessarily the creator)\n /// @return The amout of creator royalties claimed\n function claimCreatorRoyalties()\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256)\n {\n return _claimCreatorRoyalties(_msgSender());\n }\n\n\n /***********************************|\n | Create Single Protons |\n |__________________________________*/\n\n /// Creates a Basic NFT with no Royalties and no initial Sale Price\n /// @dev Royalties and Sale Price can be configured later\n /// @param creator The address of the NFT Creator (can be different from the caller)\n /// @param receiver The receiving address of the NFT (can be different from the caller)\n /// @param tokenMetaUri The unique metadata URI for the NFT\n /// @return newTokenId The newly minted NFT Token ID\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n\n /***********************************|\n | Create Multiple Protons |\n |__________________________________*/\n\n function createProtons(\n address creator,\n address receiver,\n string[] calldata tokenMetaUris\n )\n external\n virtual\n override\n whenNotPaused\n returns (bool)\n {\n _createProtons(\n creator,\n receiver,\n 0, // royaltiesPercent\n tokenMetaUris\n );\n return true;\n }\n\n function createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n external\n virtual\n override\n whenNotPaused\n returns (bool)\n {\n _createProtonsForSale(\n creator,\n receiver,\n royaltiesPercent,\n tokenMetaUris,\n salePrices\n );\n return true;\n }\n\n\n /***********************************|\n | Buy Protons |\n |__________________________________*/\n\n function buyProton(uint256 tokenId, uint256 gasLimit)\n external\n payable\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (bool)\n {\n _buyProton(tokenId, gasLimit);\n return true;\n }\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice)\n external\n virtual\n override\n whenNotPaused\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setSalePrice(tokenId, salePrice);\n }\n\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setRoyaltiesPct(tokenId, royaltiesPct);\n }\n\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n {\n _tokenCreatorRoyaltiesRedirect[tokenId] = receiver;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual {\n _tokenSalePrice[tokenId] = salePrice;\n emit SalePriceSet(tokenId, salePrice);\n }\n\n function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual {\n require(royaltiesPct <= PERCENTAGE_SCALE, \"PRT:E-421\");\n _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct;\n emit CreatorRoyaltiesSet(tokenId, royaltiesPct);\n }\n\n function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) {\n address receiver = _tokenCreatorRoyaltiesRedirect[tokenId];\n if (receiver == address(0x0)) {\n receiver = _tokenCreator[tokenId];\n }\n return receiver;\n }\n\n function _createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n _tokenIds.increment();\n\n newTokenId = _tokenIds.current();\n _safeMint(receiver, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUri);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n }\n\n function _createProtons(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris\n )\n internal\n virtual\n {\n uint256 count = tokenMetaUris.length;\n for (uint256 i; i < count; i++) {\n _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, 0);\n }\n }\n\n function _createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n internal\n virtual\n {\n require(tokenMetaUris.length == salePrices.length, \"PRT:E-202\");\n\n uint256 count = tokenMetaUris.length;\n for (uint256 i; i < count; i++) {\n _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, salePrices[i]);\n }\n }\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n contractAddress = address(this);\n tokenId = _tokenId;\n salePrice = _tokenSalePrice[_tokenId];\n require(salePrice > 0, \"PRT:E-416\");\n require(msg.value >= salePrice, \"PRT:E-414\");\n\n uint256 ownerAmount = salePrice;\n creatorAmount;\n oldOwner = ownerOf(_tokenId);\n newOwner = _msgSender();\n\n // Creator Royalties\n royaltiesReceiver = _creatorRoyaltiesReceiver(_tokenId);\n uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[_tokenId];\n uint256 lastSellPrice = _tokenLastSellPrice[_tokenId];\n if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) {\n creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE);\n ownerAmount = ownerAmount.sub(creatorAmount);\n }\n _tokenLastSellPrice[_tokenId] = salePrice;\n\n // Reserve Royalties for Creator\n if (creatorAmount > 0) {\n _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount);\n }\n\n // Transfer Token\n _transfer(oldOwner, newOwner, _tokenId);\n\n // Transfer Payment\n if (ownerAmount > 0) {\n payable(oldOwner).sendValue(ownerAmount, _gasLimit);\n }\n\n emit ProtonSold(_tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n\n _refundOverpayment(salePrice, _gasLimit);\n }\n\n /**\n * @dev Pays out the Creator Royalties of the calling account\n * @param receiver The receiver of the claimable royalties\n * @return The amount of Creator Royalties claimed\n */\n function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) {\n uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver];\n require(claimableAmount > 0, \"PRT:E-411\");\n\n delete _tokenCreatorClaimableRoyalties[receiver];\n payable(receiver).sendValue(claimableAmount, 0);\n\n emit RoyaltiesClaimed(receiver, claimableAmount);\n }\n\n /**\n * @dev Collects the Required Asset Token from the users wallet\n * @param from The owner address to collect the Assets from\n * @param assetAmount The Amount of Asset Tokens to Collect\n */\n function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual {\n uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from);\n require(assetAmount <= _userAssetBalance, \"PRT:E-411\");\n // Be sure to Approve this Contract to transfer your Asset Token\n require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), \"PRT:E-401\");\n }\n\n function _refundOverpayment(uint256 threshold, uint256 gasLimit) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage, gasLimit);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n _tokenSalePrice[tokenId] = 0;\n super._transfer(from, to, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"PRT:E-101\");\n _;\n }\n\n modifier onlyTokenOwnerOrApproved(uint256 tokenId) {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"PRT:E-105\");\n _;\n }\n\n modifier onlyTokenCreator(uint256 tokenId) {\n require(_tokenCreator[tokenId] == _msgSender(), \"PRT:E-104\");\n _;\n }\n}" + }, + "contracts/v1/lib/Bitwise.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Bitwise.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nlibrary Bitwise {\n function negate(uint32 a) internal pure returns (uint32) {\n return a ^ maxInt();\n }\n\n function shiftLeft(uint32 a, uint32 n) internal pure returns (uint32) {\n return a * uint32(2) ** n;\n }\n\n function shiftRight(uint32 a, uint32 n) internal pure returns (uint32) {\n return a / uint32(2) ** n;\n }\n\n function maxInt() internal pure returns (uint32) {\n return uint32(-1);\n }\n\n // Get bit value at position\n function hasBit(uint32 a, uint32 n) internal pure returns (bool) {\n return a & shiftLeft(0x01, n) != 0;\n }\n\n // Set bit value at position\n function setBit(uint32 a, uint32 n) internal pure returns (uint32) {\n return a | shiftLeft(0x01, n);\n }\n\n // Set the bit into state \"false\"\n function clearBit(uint32 a, uint32 n) internal pure returns (uint32) {\n uint32 mask = negate(shiftLeft(0x01, n));\n return a & mask;\n }\n}\n" + }, + "contracts/v1/lib/BlackholePrevention.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\n\n/**\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\n * the Owner/DAO to pull them out on behalf of a user\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\n */\ncontract BlackholePrevention {\n using Address for address payable;\n using SafeERC20 for IERC20;\n\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\n\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (address(this).balance >= amount) {\n receiver.sendValue(amount);\n emit WithdrawStuckEther(receiver, amount);\n }\n }\n\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\n IERC20(tokenAddress).safeTransfer(receiver, amount);\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\n }\n }\n\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\n }\n }\n\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \"\");\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\n }\n }\n}\n" + }, + "contracts/v1/lib/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/GSN/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableMap.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n /**\n * @dev Emitted when `tokenId` token is transfered from `from` to `to`.\n */\n event TransferBatch(address indexed from, address indexed to, uint256 startTokenId, uint256 count);\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721:E-403\");\n\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721:E-405\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"ERC721:E-405\");\n return _tokenURIs[tokenId];\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721:E-111\");\n\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \"ERC721:E-105\");\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view override returns (address) {\n require(_exists(tokenId), \"ERC721:E-405\");\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 require(operator != _msgSender(), \"ERC721:E-111\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721:E-402\");\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 returns (bool) {\n return _tokenOwners.contains(tokenId);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721:E-405\");\n address owner = ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721:E-402\");\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 _safeMintBatch(address to, uint256 startTokenId, uint256 count, bytes memory _data) internal virtual {\n _mintBatch(to, startTokenId, count);\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \"ERC721:E-402\");\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:E-403\");\n require(!_exists(tokenId), \"ERC721:E-407\");\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\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 _mintBatch(address to, uint256 startTokenId, uint256 count) internal virtual {\n require(to != address(0), \"ERC721:E-403\");\n require(!_exists(startTokenId), \"ERC721:E-407\");\n\n for (uint i = 0; i < count; i++) {\n uint256 tokenId = startTokenId.add(i);\n _holderTokens[to].add(tokenId);\n _tokenOwners.set(tokenId, to);\n }\n\n emit TransferBatch(address(0), to, startTokenId, count);\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(address from, address to, uint256 tokenId) internal virtual {\n require(ownerOf(tokenId) == from, \"ERC721:E-102\");\n require(to != address(0), \"ERC721:E-403\");\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721:E-405\");\n _tokenURIs[tokenId] = _tokenURI;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721:E-402\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\n }\n}\n" + }, + "contracts/v1/lib/ERC721Basic.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/GSN/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Basic is Context, ERC165, IERC721, IERC721Metadata {\n using SafeMath for uint256;\n using Address for address;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 internal constant _ERC721_RECEIVED = 0x150b7a02;\n\n // mapping from token ids to their owners\n mapping (uint256 => address) internal _tokenOwners;\n\n // mapping from owner to token balance\n mapping (address => uint256) internal _ownerBalance;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) internal _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) internal _operatorApprovals;\n\n // Token name\n string internal _name;\n\n // Token symbol\n string internal _symbol;\n\n // Token Count\n uint256 internal _tokenCount;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 internal constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 internal constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721:E-403\");\n return _ownerBalance[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners[tokenId];\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view 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 return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721:E-111\");\n\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \"ERC721:E-105\");\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view override returns (address) {\n require(_exists(tokenId), \"ERC721:E-405\");\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721:E-111\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721:E-402\");\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 returns (bool) {\n return _tokenOwners[tokenId] != address(0x0);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721:E-405\");\n address owner = ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\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(address to, bytes memory _data) internal virtual returns (uint256) {\n uint256 tokenId = _mint(to);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721:E-402\");\n return 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 _safeMintBatch(address to, uint256 count, bytes memory _data) internal virtual {\n uint256 startTokenId = _mintBatch(to, count);\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \"ERC721:E-402\");\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) internal virtual returns (uint256) {\n require(to != address(0), \"ERC721:E-403\");\n\n _tokenCount = _tokenCount.add(1);\n uint256 tokenId = _tokenCount;\n require(!_exists(tokenId), \"ERC721:E-407\");\n\n _tokenOwners[tokenId] = to;\n _ownerBalance[to] = _ownerBalance[to].add(1);\n\n emit Transfer(address(0), to, tokenId);\n return tokenId;\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 _mintBatch(address to, uint256 count) internal virtual returns (uint256) {\n require(to != address(0), \"ERC721:E-403\");\n\n uint256 startTokenId = _tokenCount.add(1);\n for (uint i = 1; i <= count; i++) {\n uint256 tokenId = _tokenCount.add(i);\n _tokenOwners[tokenId] = to;\n emit Transfer(address(0), to, tokenId);\n }\n\n _tokenCount = _tokenCount.add(count);\n _ownerBalance[to] = _ownerBalance[to].add(count);\n return startTokenId;\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(address from, address to, uint256 tokenId) internal virtual {\n require(ownerOf(tokenId) == from, \"ERC721:E-102\");\n require(to != address(0), \"ERC721:E-403\");\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _tokenOwners[tokenId] = to;\n _ownerBalance[from] = _ownerBalance[from].sub(1);\n _ownerBalance[to] = _ownerBalance[to].add(1);\n\n emit Transfer(from, to, tokenId);\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(address from, address to, uint256 tokenId, bytes memory _data)\n internal returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721:E-402\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) internal {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\n }\n}\n" + }, + "contracts/v1/lib/IERC5192.sol": { + "content": "// SPDX-License-Identifier: CC0-1.0\npragma solidity ^0.6.0;\n\ninterface IERC5192 {\n /// @notice Emitted when the locking status is changed to locked.\n /// @dev If a token is minted and the status is locked, this event should be emitted.\n /// @param tokenId The identifier for a token.\n event Locked(uint256 tokenId);\n\n /// @notice Emitted when the locking status is changed to unlocked.\n /// @dev If a token is minted and the status is unlocked, this event should be emitted.\n /// @param tokenId The identifier for a token.\n event Unlocked(uint256 tokenId);\n\n /// @notice Returns the locking status of an Soulbound Token\n /// @dev SBTs assigned to zero address are considered invalid, and queries\n /// about them do throw.\n /// @param tokenId The identifier for an SBT.\n function locked(uint256 tokenId) external view returns (bool);\n}\n" + }, + "contracts/v1/lib/NftTokenType.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// NftTokenType.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/introspection/IERC165.sol\";\n\nlibrary NftTokenType {\n bytes4 constant internal INTERFACE_SIGNATURE_ERC721 = 0x80ac58cd;\n bytes4 constant internal INTERFACE_SIGNATURE_ERC1155 = 0xd9b67a26;\n\n uint256 constant internal TYPE_MASK = uint256(uint128(~0)) << 128;\n uint256 constant internal TYPE_NFT_BIT = 1 << 255;\n\n function isERC721(address contractAddress) internal view returns (bool) {\n return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC721);\n }\n\n function isERC1155(address contractAddress) internal view returns (bool) {\n return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC1155);\n }\n\n function getTokenType(address contractAddress, uint256 tokenId) internal view returns (uint256) {\n IERC165 tokenInterface = IERC165(contractAddress);\n bool is1155 = tokenInterface.supportsInterface(INTERFACE_SIGNATURE_ERC1155);\n\n if (!is1155 || (tokenId & TYPE_NFT_BIT != TYPE_NFT_BIT)) { return 0; }\n\n return tokenId & TYPE_MASK;\n }\n}\n" + }, + "contracts/v1/lib/ReentrancyGuard.sol": { + "content": "pragma solidity 0.6.12;\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 () public {\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 _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\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 /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}" + }, + "contracts/v1/lib/RelayRecipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0;\n\nimport \"@opengsn/gsn/contracts/BaseRelayRecipient.sol\";\n\ncontract RelayRecipient is BaseRelayRecipient {\n function versionRecipient() external override view returns (string memory) {\n return \"1.0.0-beta.1/charged-particles.relay.recipient\";\n }\n}\n" + }, + "contracts/v1/lib/SmartWalletBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// SmartWalletBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../interfaces/ISmartWallet.sol\";\nimport \"./BlackholePrevention.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract SmartWalletBase is ISmartWallet, BlackholePrevention {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n address internal _walletManager;\n\n address internal nftCreator;\n uint256 internal nftCreatorAnnuityPct;\n uint256 internal nftCreatorAmountDischarged;\n\n EnumerableSet.AddressSet internal _assetTokens;\n\n // Asset Token => Principal Balance\n mapping (address => uint256) internal _assetPrincipalBalance;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initializeBase() public {\n require(_walletManager == address(0x0), \"SWB:E-002\");\n _walletManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getAssetTokenCount() external view virtual override returns (uint256) {\n return _assetTokens.length();\n }\n\n function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) {\n if (index >= _assetTokens.length()) {\n return address(0);\n }\n return _assetTokens.at(index);\n }\n\n function setNftCreator(address creator, uint256 annuityPct) external virtual override onlyWalletManager {\n nftCreator = creator;\n nftCreatorAnnuityPct = annuityPct;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyWalletManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n function refreshPrincipal(address assetToken)\n external\n virtual\n override\n onlyWalletManager\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getPrincipal(address assetToken) internal view virtual returns (uint256) {\n return _assetPrincipalBalance[assetToken];\n }\n\n function _trackAssetToken(address assetToken) internal virtual {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n }\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the wallet manager\n modifier onlyWalletManager() {\n require(_walletManager == msg.sender, \"SWB:E-109\");\n _;\n }\n}" + }, + "contracts/v1/lib/SmartWalletBaseB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// SmartWalletBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../interfaces/ISmartWalletB.sol\";\nimport \"./BlackholePrevention.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract SmartWalletBaseB is ISmartWalletB, BlackholePrevention {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n address internal _walletManager;\n\n EnumerableSet.AddressSet internal _assetTokens;\n\n // Asset Token => Principal Balance\n mapping (address => uint256) internal _assetPrincipalBalance;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initializeBase() public {\n require(_walletManager == address(0x0), \"SWB:E-002\");\n _walletManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getAssetTokenCount() external view virtual override returns (uint256) {\n return _assetTokens.length();\n }\n\n function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) {\n if (index >= _assetTokens.length()) {\n return address(0);\n }\n return _assetTokens.at(index);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyWalletManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getPrincipal(address assetToken) internal view virtual returns (uint256) {\n return _assetPrincipalBalance[assetToken];\n }\n\n function _trackAssetToken(address assetToken) internal virtual {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n }\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the wallet manager\n modifier onlyWalletManager() {\n require(_walletManager == msg.sender, \"SWB:E-109\");\n _;\n }\n}" + }, + "contracts/v1/lib/Soul.sol": { + "content": "// SPDX-License-Identifier: CC0-1.0\npragma solidity ^0.6.12;\n\nimport \"./IERC5192.sol\";\n\ncontract Soul is IERC5192 {\n \n mapping (uint256 => bool) public lockedTokens;\n\n function _lockToken(uint256 tokenId) internal {\n lockedTokens[tokenId] = true;\n emit Locked(tokenId);\n }\n\n function _unlockToken(uint256 tokenId) internal {\n lockedTokens[tokenId] = false;\n emit Unlocked(tokenId);\n }\n\n function locked(uint256 tokenId)\n external\n view\n override(IERC5192)\n returns (bool)\n {\n return lockedTokens[tokenId];\n }\n}\n" + }, + "contracts/v1/lib/TokenInfo.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfo.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"../interfaces/IERC721Chargeable.sol\";\n\nlibrary TokenInfo {\n function getTokenUUID(address contractAddress, uint256 tokenId) internal pure virtual returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n function getTokenOwner(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n return tokenInterface.ownerOf(tokenId);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n function getTokenCreator(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n return tokenInterface.creatorOf(tokenId);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Owner of an External NFT contract\n /// @param contractAddress The Address to the Contract of the NFT to check\n /// @param account The Address of the Account to check\n /// @return True if the account owns the contract\n function isContractOwner(address contractAddress, address account) internal view virtual returns (bool) {\n address contractOwner = IERC721Chargeable(contractAddress).owner();\n return contractOwner != address(0x0) && contractOwner == account;\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Creator of a Proton-based NFT\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the Proton-based NFT\n function isTokenCreator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenCreator = tokenInterface.creatorOf(tokenId);\n return (sender == tokenCreator);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the Proton-based NFT or the Contract itself\n function isTokenContractOrCreator(address contractAddress, uint256 tokenId, address creator, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenCreator = tokenInterface.creatorOf(tokenId);\n if (sender == contractAddress && creator == tokenCreator) { return true; }\n return (sender == tokenCreator);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Owner or Operator of an External NFT\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the Owner or Operator of the External NFT\n function isErc721OwnerOrOperator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenOwner = tokenInterface.ownerOf(tokenId);\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\n }\n\n /**\n * @dev Returns true if `account` is a contract.\n * @dev Taken from OpenZeppelin library\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\n // for accounts without code, i.e. `keccak256('')`\n bytes32 codehash;\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n // solhint-disable-next-line no-inline-assembly\n assembly { codehash := extcodehash(account) }\n return (codehash != accountHash && codehash != 0x0);\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 * @dev Taken from OpenZeppelin library\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, uint256 gasLimit) internal {\n require(address(this).balance >= amount, \"TokenInfo: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = (gasLimit > 0)\n ? recipient.call{ value: amount, gas: gasLimit }(\"\")\n : recipient.call{ value: amount }(\"\");\n require(success, \"TokenInfo: unable to send value, recipient may have reverted\");\n }\n}\n" + }, + "contracts/v1/lib/TokenInfoProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfoProxy.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../interfaces/ITokenInfoProxy.sol\";\nimport \"../interfaces/IERC721Chargeable.sol\";\n\n\ncontract TokenInfoProxy is ITokenInfoProxy, Ownable {\n using Address for address;\n\n mapping (address => FnSignatures) internal _remappedFnSigs;\n\n function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner {\n _remappedFnSigs[contractAddress].ownerOf = fnSig;\n emit ContractFunctionSignatureSet(contractAddress, \"ownerOf\", fnSig);\n }\n\n function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner {\n _remappedFnSigs[contractAddress].creatorOf = fnSig;\n emit ContractFunctionSignatureSet(contractAddress, \"creatorOf\", fnSig);\n }\n\n\n function getTokenUUID(address contractAddress, uint256 tokenId) external pure virtual override returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n function getTokenOwner(address contractAddress, uint256 tokenId) external virtual override returns (address) {\n return _getTokenOwner(contractAddress, tokenId);\n }\n\n function getTokenCreator(address contractAddress, uint256 tokenId) external virtual override returns (address) {\n return _getTokenCreator(contractAddress, tokenId);\n }\n\n function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenOwner = _getTokenOwner(contractAddress, tokenId);\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\n }\n\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the NFT or the Contract itself\n function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) {\n address tokenCreator = _getTokenCreator(contractAddress, tokenId);\n return (sender == tokenCreator || sender == contractAddress);\n }\n\n\n\n function _getTokenCreator(address contractAddress, uint256 tokenId) internal returns (address) {\n bytes4 fnSig = IERC721Chargeable.creatorOf.selector;\n if (_remappedFnSigs[contractAddress].creatorOf != bytes4(0)) {\n fnSig = _remappedFnSigs[contractAddress].creatorOf;\n }\n\n // solhint-disable-next-line\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n if (success) {\n return abi.decode(returnData, (address));\n } else {\n return address(0x0);\n }\n }\n\n function _getTokenOwner(address contractAddress, uint256 tokenId) internal returns (address) {\n bytes4 fnSig = IERC721Chargeable.ownerOf.selector;\n if (_remappedFnSigs[contractAddress].ownerOf != bytes4(0)) {\n fnSig = _remappedFnSigs[contractAddress].ownerOf;\n }\n\n // solhint-disable-next-line\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n if (success) {\n return abi.decode(returnData, (address));\n } else {\n return address(0x0);\n }\n }\n}\n" + }, + "contracts/v1/lib/WalletManagerBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// WalletManagerBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IWalletManager.sol\";\nimport \"../interfaces/ISmartWallet.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"./BlackholePrevention.sol\";\n\n\n/**\n * @notice Wallet-Manager Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract WalletManagerBase is Ownable, BlackholePrevention, IWalletManager {\n using TokenInfo for address;\n\n // The Controller Contract Address\n address internal _controller;\n\n // The Executor Contract Address\n address internal _executor;\n\n // Template Contract for creating Token Smart-Wallet Bridges\n address internal _walletTemplate;\n\n // TokenID => Token Smart-Wallet Address\n mapping (uint256 => address) internal _wallets;\n\n // State of Wallet Manager\n bool internal _paused;\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Wallet Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n /**\n * @dev Connects to the ExecForAccount Controller\n */\n function setExecutor(address executor) external onlyOwner {\n _executor = executor;\n emit ExecutorSet(executor);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartWallet(wallet).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartWallet(wallet).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartWallet(wallet).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Executor contract\n modifier onlyExecutor() {\n require(_executor == msg.sender, \"WMB:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Controller or Executor contract\n modifier onlyControllerOrExecutor() {\n require(_executor == msg.sender || _controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"WMB:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/ParticleSplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ParticleSplitter.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"./interfaces/IParticleSplitter.sol\";\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IWalletManager.sol\";\nimport \"./interfaces/IBasketManager.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Contract\n * @dev Upgradeable Contract\n */\ncontract ParticleSplitter is IParticleSplitter, Ownable, ReentrancyGuard, BlackholePrevention\n{\n IChargedManagers internal _chargedManagers;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n mapping (address => bool) internal _externalAddressesAllowed;\n\n\n /***********************************|\n | Execute for Account |\n |__________________________________*/\n\n /// @notice Executes an arbitrary command on an NFT Wallet\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Wallet Manager controlling the NFT Wallet to execute on\n /// @param externalAddress The Address of the External Contract to execute on\n /// @param encodedParams The encoded function call to execute\n function executeForWallet(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address externalAddress,\n bytes memory encodedParams\n )\n external\n payable\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (bytes memory)\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n require(_externalAddressesAllowed[externalAddress], \"PS:E-117\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Wallet Manager\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n // Get Address of Wallet to send any ETH into\n if (msg.value > 0) {\n address wallet = walletMgr.getWalletAddressById(contractAddress, tokenId, address(0), 0);\n payable(wallet).sendValue(msg.value);\n }\n\n emit ExecuteForWallet(contractAddress, tokenId, walletManagerId, externalAddress, encodedParams, msg.value);\n\n // Execute command for NFT Wallet\n return walletMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams);\n }\n\n /// @notice Executes an arbitrary command on an NFT Basket\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param basketManagerId The Basket Manager controlling the NFT Wallet to execute on\n /// @param externalAddress The Address of the External Contract to execute on\n /// @param encodedParams The encoded function call to execute\n function executeForBasket(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address externalAddress,\n bytes memory encodedParams\n )\n external\n payable\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (bytes memory)\n {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"PS:E-419\");\n require(_externalAddressesAllowed[externalAddress], \"PS:E-117\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Basket Manager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n\n // Get Address of Wallet to send any ETH into\n if (msg.value > 0) {\n address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId);\n payable(wallet).sendValue(msg.value);\n }\n\n emit ExecuteForBasket(contractAddress, tokenId, basketManagerId, externalAddress, encodedParams, msg.value);\n\n // Execute command for NFT Wallet\n return basketMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams);\n }\n\n function withdrawWalletRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (uint256 amountWithdrawn)\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Wallet Manager\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n // Withdraw Rewards for NFT Wallet\n return walletMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount);\n }\n\n function withdrawBasketRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (uint256 amountWithdrawn)\n {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"PS:E-419\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Basket Manager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n\n // Withdraw Rewards for NFT Basket\n return basketMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount);\n }\n\n function refreshWalletPrincipal(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n walletMgr.refreshPrincipal(contractAddress, tokenId, assetToken);\n\n emit PrincipalRefreshed(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedManagers Interface\n */\n function setChargedManagers(address chargedManagers) external virtual onlyOwner {\n _chargedManagers = IChargedManagers(chargedManagers);\n emit ChargedManagersSet(chargedManagers);\n }\n\n /**\n * @dev Setup the ChargedManagers Interface\n */\n function setTokenInfoProxy(address tokenInfoProxy) external virtual onlyOwner {\n _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy);\n emit TokenInfoProxySet(tokenInfoProxy);\n }\n\n /**\n * @dev Allows/Disallows execute from on specific contracts\n */\n function setExternalContracts(address[] calldata contracts, bool state) external onlyOwner {\n uint count = contracts.length;\n for (uint i; i < count; i++) {\n address externalContract = contracts[i];\n _externalAddressesAllowed[externalContract] = state;\n emit PermsSetForExternal(externalContract, state);\n }\n }\n\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyTokenOwner(address contractAddress, uint256 tokenId) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(msg.sender == tokenOwner, \"PS:E-102\");\n _;\n }\n}\n" + }, + "contracts/v1/test/Dai.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"../interfaces/IDai.sol\";\n\ncontract Dai is IDai {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (uint256 chainId_) public {\n string memory version = \"1\";\n\n _name = \"Dai Stablecoin\";\n _symbol = \"DAI\";\n _decimals = 18;\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(_name)),\n keccak256(bytes(version)),\n chainId_,\n address(this)\n )\n );\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view 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(msg.sender, 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(msg.sender, 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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(msg.sender, spender, _allowances[msg.sender][spender].add(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 _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20:E-403\");\n require(recipient != address(0), \"ERC20:E-403\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20:E-403\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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:E-403\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20:E-403\");\n require(spender != address(0), \"ERC20:E-403\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n\n mapping (address => uint) public nonces;\n\n // --- EIP712 niceties ---\n bytes32 public DOMAIN_SEPARATOR;\n // bytes32 public constant PERMIT_TYPEHASH = keccak256(\"Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)\");\n bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;\n\n // --- Approve by signature ---\n function permit(\n address holder, address spender, uint256 nonce, uint256 expiry,\n bool allowed, uint8 v, bytes32 r, bytes32 s) external override\n {\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n holder,\n spender,\n nonce,\n expiry,\n allowed\n )\n )\n )\n );\n\n require(holder != address(0), \"Dai/invalid-address-0\");\n require(holder == ecrecover(digest, v, r, s), \"Dai/invalid-permit\");\n require(expiry == 0 || now <= expiry, \"Dai/permit-expired\");\n require(nonce == nonces[holder]++, \"Dai/invalid-nonce\");\n uint wad = allowed ? uint(-1) : 0;\n _allowances[holder][spender] = wad;\n emit Approval(holder, spender, wad);\n }\n\n function mint(address to, uint256 amount) external {\n _mint(to, amount);\n }\n}" + }, + "contracts/v1/test/ERC20Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.7.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/**\n * @dev Extension of {ERC20} that adds a set of accounts with the {MinterRole},\n * which have permission to mint (create) new tokens as they see fit.\n *\n * At construction, the deployer of the contract is the only minter.\n */\ncontract ERC20Mintable is ERC20Upgradeable {\n\n constructor(string memory _name, string memory _symbol) public {\n __ERC20_init(_name, _symbol);\n }\n\n /**\n * @dev See {ERC20-_mint}.\n *\n * Requirements:\n *\n * - the caller must have the {MinterRole}.\n */\n function mint(address account, uint256 amount) public returns (bool) {\n _mint(account, amount);\n return true;\n }\n\n function burn(address account, uint256 amount) public returns (bool) {\n _burn(account, amount);\n return true;\n }\n}" + }, + "contracts/v1/test/ERC721Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.7.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\n\n/**\n * @dev Extension of {ERC721} for Minting/Burning\n */\ncontract ERC721Mintable is ERC721Upgradeable {\n\n constructor () public {\n __ERC721_init(\"ERC 721\", \"NFT\");\n }\n\n /**\n * @dev See {ERC721-_mint}.\n */\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n\n /**\n * @dev See {ERC721-_burn}.\n */\n function burn(uint256 tokenId) public {\n _burn(tokenId);\n }\n}\n" + }, + "contracts/v1/tokens/ExternalERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ExternalERC721.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\n\ncontract ExternalERC721 is ERC721 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n\n constructor() public ERC721(\"Charged Particles - ExternalERC721\", \"ExNFT\") {}\n\n function mintNft(address receiver, string memory tokenUri) external returns (uint256 newTokenId) {\n return _mintNft(receiver, tokenUri);\n }\n\n function _mintNft(address receiver, string memory tokenUri) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n\n _safeMint(receiver, newTokenId, \"\");\n\n _setTokenURI(newTokenId, tokenUri);\n }\n}\n" + }, + "contracts/v1/tokens/FungibleERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// FungibleERC1155.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract FungibleERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n\n constructor() public ERC1155(\"https://staging.app.charged.fi/erc1155/metadata.json\") {}\n\n function mintNft(address receiver, uint256 amount) external returns (uint256 newTokenId) {\n return _mintNft(receiver, amount);\n }\n\n function _mintNft(address receiver, uint256 amount) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n _mint(receiver, newTokenId, amount, \"\");\n }\n}\n" + }, + "contracts/v1/tokens/Ionx.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Ionx.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"erc20permit/contracts/ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\n\ncontract Ionx is ERC20Permit, Ownable, BlackholePrevention {\n using SafeMath for uint256;\n\n /// @notice An event thats emitted when the minter address is changed\n event MinterChanged(address minter, address newMinter);\n\n /// @notice Total number of tokens in circulation\n uint256 constant public INITIAL_SUPPLY = 1e8 ether;\n\n /// @notice Minimum time between mints\n uint32 public constant INFLATION_EPOCH = 1 days * 365;\n\n /// @notice Cap on the percentage of totalSupply that can be minted at each mint\n uint8 public constant INFLATION_CAP = 2;\n\n /// @notice Address which may mint new tokens\n address public minter;\n\n /// @notice The timestamp after which minting may occur\n uint256 public mintingAllowedAfter;\n\n\n constructor() public ERC20Permit(\"Charged Particles - IONX\", \"IONX\") {}\n\n\n /**\n * @notice Change the minter address\n * @param newMinter The address of the new minter\n */\n function setMinter(address newMinter) external onlyOwner {\n emit MinterChanged(minter, newMinter);\n minter = newMinter;\n }\n\n /**\n * @notice Mint new tokens\n * @param receiver The address of the destination account\n * @param amount The number of tokens to be minted\n */\n function mint(address receiver, uint256 amount) external onlyMinter {\n require(block.timestamp >= mintingAllowedAfter, \"Ionx:E-114\");\n require(receiver != address(0), \"Ionx:E-403\");\n\n uint256 amountToMint = amount;\n uint256 _totalSupply = totalSupply();\n\n // From Inflationary Supply\n if (_totalSupply >= INITIAL_SUPPLY) {\n mintingAllowedAfter = mintingAllowedAfter.add(INFLATION_EPOCH);\n amountToMint = _totalSupply.mul(INFLATION_CAP).div(100);\n }\n\n // From Initial Supply\n else {\n if (_totalSupply.add(amountToMint) > INITIAL_SUPPLY) {\n amountToMint = INITIAL_SUPPLY.sub(_totalSupply);\n }\n if (_totalSupply.add(amountToMint) == INITIAL_SUPPLY) {\n mintingAllowedAfter = block.timestamp.add(INFLATION_EPOCH);\n }\n }\n\n // transfer the amount to the recipient\n _mint(receiver, amountToMint);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n modifier onlyMinter() {\n require(msg.sender == minter, \"Ionx:E-113\");\n _;\n }\n}\n" + }, + "contracts/v1/tokens/Lepton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Lepton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/ILepton.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\n\ncontract Lepton is ILepton, ERC721, Ownable, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenIds;\n Classification[] internal _leptonTypes;\n mapping (uint256 => Classification) internal _leptonData;\n\n uint256 internal _typeIndex;\n uint256 internal _maxSupply;\n uint256 internal _maxMintPerTx;\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721(\"Charged Particles - Lepton\", \"LEPTON\") {\n _paused = true;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function mintLepton() external payable virtual override nonReentrant whenNotPaused returns (uint256 newTokenId) {\n newTokenId = _mintLepton(msg.sender);\n }\n\n function batchMintLepton(uint256 count) external payable virtual override nonReentrant whenNotPaused {\n _batchMintLepton(msg.sender, count);\n }\n\n function getNextType() external view virtual override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _typeIndex;\n }\n\n function getNextPrice() external view virtual override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _leptonTypes[_typeIndex].price;\n }\n\n function getMultiplier(uint256 tokenId) external view virtual override returns (uint256) {\n return _leptonData[tokenId].multiplier;\n }\n\n function getBonus(uint256 tokenId) external view virtual override returns (uint256) {\n return _leptonData[tokenId].bonus;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function addLeptonType(\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n virtual\n onlyOwner\n {\n _maxSupply = _maxSupply.add(uint256(supply));\n\n Classification memory lepton = Classification({\n tokenUri: tokenUri,\n price: price,\n supply: supply,\n multiplier: multiplier,\n bonus: bonus,\n _upperBounds: uint128(_maxSupply)\n });\n _leptonTypes.push(lepton);\n\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function updateLeptonType(\n uint256 leptonIndex,\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n virtual\n onlyOwner\n {\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\n _leptonTypes[leptonIndex].price = price;\n _leptonTypes[leptonIndex].supply = supply;\n _leptonTypes[leptonIndex].multiplier = multiplier;\n _leptonTypes[leptonIndex].bonus = bonus;\n\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function setMaxMintPerTx(uint256 maxAmount) external virtual onlyOwner {\n _maxMintPerTx = maxAmount;\n emit MaxMintPerTxSet(maxAmount);\n }\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _mintLepton(address receiver) internal virtual returns (uint256 newTokenId) {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n require(msg.value >= lepton.price, \"LPT:E-414\");\n\n _tokenIds.increment();\n newTokenId = _tokenIds.current();\n\n _leptonData[newTokenId] = lepton;\n _safeMint(receiver, newTokenId, \"\");\n _setTokenURI(newTokenId, lepton.tokenUri);\n\n // Distribute Next Type\n if (newTokenId == lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n emit LeptonMinted(receiver, newTokenId, lepton.price, lepton.multiplier);\n\n _refundOverpayment(lepton.price);\n }\n\n\n function _batchMintLepton(address receiver, uint256 count) internal virtual {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \"LPT:E-429\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n\n uint256 startTokenId = _tokenIds.current();\n uint256 endTokenId = startTokenId.add(count);\n if (endTokenId > lepton._upperBounds) {\n count = count.sub(endTokenId.sub(lepton._upperBounds));\n }\n\n uint256 salePrice = lepton.price.mul(count);\n require(msg.value >= salePrice, \"LPT:E-414\");\n\n _safeMintBatch(receiver, startTokenId.add(1), count, \"\");\n\n for (uint i = 0; i < count; i++) {\n _tokenIds.increment();\n startTokenId = _tokenIds.current();\n\n _leptonData[startTokenId] = lepton;\n _setTokenURI(startTokenId, lepton.tokenUri);\n }\n\n // Distribute Next Type\n if (startTokenId >= lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n emit LeptonBatchMinted(receiver, startTokenId, count, lepton.price, lepton.multiplier);\n\n _refundOverpayment(salePrice);\n }\n\n function _refundOverpayment(uint256 threshold) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"LPT:E-101\");\n _;\n }\n}" + }, + "contracts/v1/tokens/Lepton2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Lepton2.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"../lib/ERC721Basic.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\n\nimport \"../interfaces/ILepton.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Lepton2 is ILepton, ERC721Basic, Ownable, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n\n Classification[] internal _leptonTypes;\n\n uint256 internal _typeIndex;\n uint256 internal _maxSupply;\n uint256 internal _maxMintPerTx;\n uint256 internal _migratedCount;\n\n bool internal _paused;\n bool internal _migrationComplete;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721Basic(\"Charged Particles - Lepton2\", \"LEPTON2\") {\n _paused = true;\n _migrationComplete = false;\n _migratedCount = 0;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function mintLepton() external payable override nonReentrant whenNotPaused returns (uint256 newTokenId) {\n newTokenId = _mintLepton(msg.sender);\n }\n\n function batchMintLepton(uint256 count) external payable override nonReentrant whenNotPaused {\n _batchMintLepton(msg.sender, count);\n }\n\n function totalSupply() public view returns (uint256) {\n return _tokenCount;\n }\n\n function maxSupply() external view returns (uint256) {\n return _maxSupply;\n }\n\n function getNextType() external view override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _typeIndex;\n }\n\n function getNextPrice() external view override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _leptonTypes[_typeIndex].price;\n }\n\n function getMultiplier(uint256 tokenId) external view override returns (uint256) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).multiplier;\n }\n\n function getBonus(uint256 tokenId) external view override returns (uint256) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).bonus;\n }\n\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).tokenUri;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function addLeptonType(\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n onlyOwner\n {\n _maxSupply = _maxSupply.add(uint256(supply));\n\n Classification memory lepton = Classification({\n tokenUri: tokenUri,\n price: price,\n supply: supply,\n multiplier: multiplier,\n bonus: bonus,\n _upperBounds: uint128(_maxSupply)\n });\n _leptonTypes.push(lepton);\n\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function updateLeptonType(\n uint256 leptonIndex,\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n onlyOwner\n {\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\n _leptonTypes[leptonIndex].price = price;\n _leptonTypes[leptonIndex].supply = supply;\n _leptonTypes[leptonIndex].multiplier = multiplier;\n _leptonTypes[leptonIndex].bonus = bonus;\n\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function setMaxMintPerTx(uint256 maxAmount) external onlyOwner {\n _maxMintPerTx = maxAmount;\n emit MaxMintPerTxSet(maxAmount);\n }\n\n function setPausedState(bool state) external onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function migrateAccounts(address oldLeptonContract, uint256 count) external onlyOwner whenNotMigrated {\n uint256 oldSupply = IERC721Enumerable(oldLeptonContract).totalSupply();\n require(oldSupply == 0 || oldSupply > _migratedCount, \"LPT:E-004\");\n\n if (oldSupply > 0) {\n uint256 endTokenId = _migratedCount.add(count);\n if (endTokenId > oldSupply) {\n count = count.sub(endTokenId.sub(oldSupply));\n }\n\n for (uint256 i = 1; i <= count; i++) {\n uint256 tokenId = _migratedCount.add(i);\n address tokenOwner = IERC721(oldLeptonContract).ownerOf(tokenId);\n _mint(tokenOwner);\n }\n _migratedCount = _migratedCount.add(count);\n }\n\n if (oldSupply == _migratedCount) {\n _finalizeMigration();\n }\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getLepton(uint256 tokenId) internal view returns (Classification memory) {\n uint256 types = _leptonTypes.length;\n for (uint256 i = 0; i < types; i++) {\n Classification memory lepton = _leptonTypes[i];\n if (tokenId <= lepton._upperBounds) {\n return lepton;\n }\n }\n }\n\n function _mintLepton(address receiver) internal returns (uint256 newTokenId) {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n require(msg.value >= lepton.price, \"LPT:E-414\");\n\n newTokenId = _safeMint(receiver, \"\");\n\n // Determine Next Type\n if (newTokenId == lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n _refundOverpayment(lepton.price);\n }\n\n function _batchMintLepton(address receiver, uint256 count) internal {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \"LPT:E-429\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n\n uint256 endTokenId = _tokenCount.add(count);\n if (endTokenId > lepton._upperBounds) {\n count = count.sub(endTokenId.sub(lepton._upperBounds));\n }\n\n uint256 salePrice = lepton.price.mul(count);\n require(msg.value >= salePrice, \"LPT:E-414\");\n\n _safeMintBatch(receiver, count, \"\");\n\n // Determine Next Type\n if (endTokenId >= lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n _refundOverpayment(salePrice);\n }\n\n function _refundOverpayment(uint256 threshold) internal {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n function _finalizeMigration() internal {\n // Determine Next Type\n _typeIndex = 0;\n for (uint256 i = 0; i < _leptonTypes.length; i++) {\n Classification memory lepton = _leptonTypes[i];\n if (_migratedCount >= lepton._upperBounds) {\n _typeIndex = i + 1;\n }\n }\n _migrationComplete = true;\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotMigrated() {\n require(!_migrationComplete, \"LPT:E-004\");\n _;\n }\n\n modifier whenNotPaused() {\n require(!_paused, \"LPT:E-101\");\n _;\n }\n}" + }, + "contracts/v1/tokens/NonFungibleERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// NonFungibleERC1155.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract NonFungibleERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => address) internal _tokenOwner;\n\n constructor() public ERC1155(\"https://staging.app.charged.fi/erc1155/metadata.json\") {}\n\n function creatorOf(uint256 tokenId) external view returns (address) {\n return _tokenCreator[tokenId];\n }\n\n function ownerOf(uint256 tokenId) external view returns (address) {\n return _tokenOwner[tokenId];\n }\n\n function mintNft(address receiver) external returns (uint256 newTokenId) {\n return _mintNft(msg.sender, receiver);\n }\n\n function _mintNft(address creator, address receiver) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n\n _mint(receiver, newTokenId, 1, \"\");\n _tokenCreator[newTokenId] = creator;\n _tokenOwner[newTokenId] = receiver;\n }\n}\n" + }, + "contracts/v1/tokens/Proton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IProton.sol\";\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ncontract Proton is IProton, ERC721, Ownable, RelayRecipient, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n using Counters for Counters.Counter;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n uint256 constant internal MAX_ROYALTIES = 8e3; // 8000 (80%)\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n Counters.Counter internal _tokenIds;\n\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct;\n mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect;\n mapping (address => uint256) internal _tokenCreatorClaimableRoyalties;\n\n mapping (uint256 => uint256) internal _tokenSalePrice;\n mapping (uint256 => uint256) internal _tokenLastSellPrice;\n\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721(\"Charged Particles - Proton\", \"PROTON\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view virtual override returns (address) {\n return _tokenCreator[tokenId];\n }\n\n function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenSalePrice[tokenId];\n }\n\n function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenLastSellPrice[tokenId];\n }\n\n function getCreatorRoyalties(address account) external view virtual override returns (uint256) {\n return _tokenCreatorClaimableRoyalties[account];\n }\n\n function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenCreatorRoyaltiesPct[tokenId];\n }\n\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) {\n return _creatorRoyaltiesReceiver(tokenId);\n }\n\n function claimCreatorRoyalties()\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256)\n {\n return _claimCreatorRoyalties(_msgSender());\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // annuityPercent,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n royaltiesPercent,\n salePrice\n );\n }\n\n function batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n external\n virtual\n override\n whenNotPaused\n {\n _batchProtonsForSale(\n creator,\n annuityPercent,\n royaltiesPercent,\n tokenMetaUris,\n salePrices\n );\n }\n\n function buyProton(uint256 tokenId)\n external\n payable\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (bool)\n {\n return _buyProton(tokenId);\n }\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice)\n external\n virtual\n override\n whenNotPaused\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setSalePrice(tokenId, salePrice);\n }\n\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setRoyaltiesPct(tokenId, royaltiesPct);\n }\n\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n {\n _tokenCreatorRoyaltiesRedirect[tokenId] = receiver;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual {\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n\n _tokenSalePrice[tokenId] = salePrice;\n emit SalePriceSet(tokenId, salePrice);\n }\n\n function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual {\n require(royaltiesPct <= MAX_ROYALTIES, \"PRT:E-421\");\n _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct;\n emit CreatorRoyaltiesSet(tokenId, royaltiesPct);\n }\n\n function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) {\n address receiver = _tokenCreatorRoyaltiesRedirect[tokenId];\n if (receiver == address(0x0)) {\n receiver = _tokenCreator[tokenId];\n }\n return receiver;\n }\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, annuityPercent, 0, 0);\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n _tokenIds.increment();\n\n newTokenId = _tokenIds.current();\n _safeMint(receiver, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUri);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function _batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n internal\n virtual\n {\n require(tokenMetaUris.length == salePrices.length, \"PRT:E-202\");\n address self = address(this);\n\n uint256 count = tokenMetaUris.length;\n for (uint256 i = 0; i < count; i++) {\n _tokenIds.increment();\n uint256 newTokenId = _tokenIds.current();\n\n _safeMint(creator, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUris[i]);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n uint256 salePrice = salePrices[i];\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n self,\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n function _buyProton(uint256 tokenId)\n internal\n virtual\n returns (bool)\n {\n uint256 salePrice = _tokenSalePrice[tokenId];\n require(salePrice > 0, \"PRT:E-416\");\n require(msg.value >= salePrice, \"PRT:E-414\");\n\n uint256 ownerAmount = salePrice;\n uint256 creatorAmount;\n address oldOwner = ownerOf(tokenId);\n address newOwner = _msgSender();\n\n // Creator Royalties\n address royaltiesReceiver = _creatorRoyaltiesReceiver(tokenId);\n uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[tokenId];\n uint256 lastSellPrice = _tokenLastSellPrice[tokenId];\n if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) {\n creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE);\n ownerAmount = ownerAmount.sub(creatorAmount);\n }\n _tokenLastSellPrice[tokenId] = salePrice;\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(address(this), tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n\n // Reserve Royalties for Creator\n if (creatorAmount > 0) {\n _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount);\n }\n\n // Transfer Token\n _transfer(oldOwner, newOwner, tokenId);\n\n // Transfer Payment\n payable(oldOwner).sendValue(ownerAmount);\n\n emit ProtonSold(tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n\n _refundOverpayment(salePrice);\n return true;\n }\n\n /**\n * @dev Pays out the Creator Royalties of the calling account\n * @param receiver The receiver of the claimable royalties\n * @return The amount of Creator Royalties claimed\n */\n function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) {\n uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver];\n require(claimableAmount > 0, \"PRT:E-411\");\n\n delete _tokenCreatorClaimableRoyalties[receiver];\n payable(receiver).sendValue(claimableAmount);\n\n emit RoyaltiesClaimed(receiver, claimableAmount);\n }\n\n /**\n * @dev Collects the Required Asset Token from the users wallet\n * @param from The owner address to collect the Assets from\n * @param assetAmount The Amount of Asset Tokens to Collect\n */\n function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual {\n uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from);\n require(assetAmount <= _userAssetBalance, \"PRT:E-411\");\n // Be sure to Approve this Contract to transfer your Asset Token\n require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), \"PRT:E-401\");\n }\n\n function _refundOverpayment(uint256 threshold) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n _tokenSalePrice[tokenId] = 0;\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n super._transfer(from, to, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"PRT:E-101\");\n _;\n }\n\n modifier onlyTokenOwnerOrApproved(uint256 tokenId) {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"PRT:E-105\");\n _;\n }\n\n modifier onlyTokenCreator(uint256 tokenId) {\n require(_tokenCreator[tokenId] == _msgSender(), \"PRT:E-104\");\n _;\n }\n}" + }, + "contracts/v1/tokens/ProtonB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\nimport \"../interfaces/IProtonB.sol\";\n\nimport \"../lib/BaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ncontract ProtonB is BaseProton, IProtonB {\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public BaseProton(\"Charged Particles - ProtonB\", \"PROTON.B\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n external\n virtual\n override\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n royaltiesPercent,\n salePrice\n );\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n /// @dev for backwards compatibility with v1\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0);\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n\n /***********************************|\n | Function Overrides |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override {\n super._setSalePrice(tokenId, salePrice);\n\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n }\n\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n override\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n }\n\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n // Unlock NFT\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n\n super._transfer(from, to, tokenId);\n }\n}" + }, + "contracts/v1/tokens/ProtonC.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\nimport \"../lib/Soul.sol\";\n\n\ncontract ProtonC is BaseProton, Soul {\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public BaseProton(\"Charged Particles - ProtonC\", \"PROTON.C\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createBondedToken(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent\n )\n external\n virtual\n payable\n returns (uint256 newTokenId)\n {\n uint256 tokenId = createProtonForSale(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n royaltiesPercent,\n 0\n );\n lockToken(tokenId);\n\n return tokenId;\n }\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n public \n virtual\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n royaltiesPercent,\n salePrice\n );\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n nonReentrant\n whenNotPaused\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n /// @dev for backwards compatibility with v1\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n whenNotPaused\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function burn(uint256 tokenId) public {\n requireTokenOwner(tokenId); \n _burn(tokenId);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n function requireTokenOwner(uint256 tokenId) public view {\n require(ownerOf(tokenId) == msg.sender, \"Only token owner\");\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0);\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n function _burn(uint256 tokenId) internal {\n _unlockToken(tokenId);\n _transfer(ownerOf(tokenId), address(0x000000000000000000000000000000000000dEaD), tokenId);\n }\n\n /***********************************|\n | Soul bounded |\n |__________________________________*/\n\n function lockToken(uint256 tokenId) public {\n requireTokenOwner(tokenId);\n _lockToken(tokenId);\n }\n\n /***********************************|\n | Function Overrides |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override {\n super._setSalePrice(tokenId, salePrice);\n\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n }\n\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n override\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n require(lockedTokens[tokenId] == false, \"BondedToken: Token is locked\");\n\n // Unlock NFT\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n\n super._transfer(from, to, tokenId);\n }\n}" + }, + "contracts/v1/Universe.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\n\nimport \"./interfaces/IUniverse.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n\n/**\n * @notice Charged Particles Universe Contract\n * @dev Upgradeable Contract\n */\ncontract Universe is IUniverse, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n // The ChargedParticles Contract Address\n address public chargedParticles;\n address public proton;\n address public lepton;\n address public quark;\n address public boson;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // Positive Charge\n uint256 internal photonMaxSupply;\n uint256 internal totalPhotonDischarged;\n\n // Source of Positive Charge\n IERC20Upgradeable public photonSource;\n\n // Asset Token => Electrostatic Attraction Multiplier\n mapping (address => uint256) internal esaMultiplier;\n\n // Account => Electrostatic Attraction Levels\n mapping (address => uint256) internal esaLevel;\n\n // Energizing Account => Referral Source\n mapping (address => address) internal referralSource;\n\n // NFT Token UUID => Bonded Lepton Mass\n mapping (uint256 => uint256) internal bondedLeptonMass;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getStaticCharge(address /* account */) external pure virtual returns (uint256 positiveEnergy) {\n return 0;\n }\n\n function conductElectrostaticDischarge(address /* account */, uint256 /* amount */) external pure virtual returns (uint256 positiveEnergy) {\n return 0;\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n onlyProton\n {\n // no-op\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(controller)\n {\n chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setPhoton(\n address token,\n uint256 maxSupply\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n photonSource = IERC20Upgradeable(token);\n photonMaxSupply = maxSupply;\n emit PhotonSet(token, maxSupply);\n }\n\n function setProtonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n proton = token;\n emit ProtonTokenSet(token);\n }\n\n function setLeptonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n lepton = token;\n emit LeptonTokenSet(token);\n }\n\n function setQuarkToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n quark = token;\n emit QuarkTokenSet(token);\n }\n\n function setBosonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n boson = token;\n emit BosonTokenSet(token);\n }\n\n function setEsaMultiplier(\n address assetToken,\n uint256 multiplier\n )\n external\n virtual\n onlyOwner\n {\n esaMultiplier[assetToken] = multiplier;\n emit EsaMultiplierSet(assetToken, multiplier);\n }\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _electrostaticAttraction(uint256 tokenUuid, address receiver, address assetToken, uint256 baseAmount) internal virtual {\n }\n\n function _conductElectrostaticDischarge(address /* account */, uint256 /* energy */) internal virtual pure returns (uint256) {\n return 0;\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Proton NFT contract\n modifier onlyProton() {\n require(proton == msg.sender, \"UNI:E-110\");\n _;\n }\n}\n" + }, + "contracts/v1/UniverseRP.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"./interfaces/IUniverseRP.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./interfaces/IRewardNft.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\nimport \"./interfaces/IRewardProgram.sol\";\n\n/**\n * @notice Charged Particles Universe Contract with Rewards Program\n * @dev Upgradeable Contract\n */\ncontract UniverseRP is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // The ChargedParticles Contract Address\n address public _chargedParticles;\n\n // The Lepton NFT Contract Address\n address public _multiplierNft;\n\n // Asset Token => Reward Program\n mapping (address => address) internal _assetRewardPrograms;\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\n\n // Token UUID => NFT Staking Data\n mapping (uint256 => NftStake) private _nftStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n function getRewardProgram(address asset) external view override returns (address) {\n return _getRewardProgram(asset);\n }\n\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\n return _nftStake[uuid];\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetDeposit(\n contractAddress,\n tokenId,\n walletManagerId,\n assetAmount\n );\n }\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\n }\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n // \"receiverEnergy\" includes the \"principalAmount\"\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n onlyOwner\n onlyValidContractAddress(controller)\n {\n _chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setMultiplierNft(address nftTokenAddress)\n external\n onlyOwner\n onlyValidContractAddress(nftTokenAddress)\n {\n _multiplierNft = nftTokenAddress;\n }\n\n function setRewardProgram(\n address rewardProgam,\n address assetToken\n )\n external\n onlyOwner\n onlyValidContractAddress(rewardProgam)\n {\n require(assetToken != address(0x0), \"UNI:E-403\");\n _assetRewardPrograms[assetToken] = rewardProgam;\n emit RewardProgramSet(assetToken, rewardProgam);\n }\n\n function removeRewardProgram(address assetToken) external onlyOwner {\n delete _assetRewardPrograms[assetToken];\n emit RewardProgramRemoved(assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getRewardProgram(address assetToken) internal view returns (address) {\n return _assetRewardPrograms[assetToken];\n }\n\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != depositNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n uint256 multiplier = _getNftMultiplier(depositNftAddress, depositNftTokenId);\n\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\n // Add to Multipliers Set\n _multiplierNftsSet[parentNftUuid].add(multiplier);\n\n // Update NFT Stake\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\n } else {\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\n }\n }\n\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\n }\n\n function _registerNftRelease(\n address contractAddress,\n uint256 tokenId,\n address releaseNftAddress,\n uint256 releaseNftTokenId,\n uint256 /* nftTokenAmount */\n )\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != releaseNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n NftStake storage nftStake = _nftStake[parentNftUuid];\n\n // Remove from Multipliers Set\n uint256 multiplier = _getNftMultiplier(releaseNftAddress, releaseNftTokenId);\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\n\n // Determine New Multiplier or Mark as Released\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\n } else {\n nftStake.releaseBlockNumber = block.number;\n }\n\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\n }\n\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\n uint256 multiplier = 0;\n uint256 loss = 50;\n uint256 i = 0;\n\n for (; i < len; i++) {\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\n }\n if (len > 1) {\n multiplier = multiplier.sub(loss.mul(len));\n }\n return multiplier;\n }\n\n function _getNftMultiplier(address contractAddress, uint256 tokenId) internal returns (uint256) {\n bytes4 fnSig = IRewardNft.getMultiplier.selector;\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n\n if (success) {\n return abi.decode(returnData, (uint256));\n } else {\n return 0;\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(_chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/vesting/VestingClaim7.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract VestingClaim7 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"VestingClaim7: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"VestingClaim7: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"VestingClaim7: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"VestingClaim7: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"VestingClaim7: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"VestingClaim7: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveSmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\nimport \"../../interfaces/IAaveBridge.sol\";\nimport \"../../lib/SmartWalletBase.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet for Aave Assets\n * @dev Non-upgradeable Contract\n */\ncontract AaveSmartWallet is SmartWalletBase {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 constant internal RAY = 1e27;\n\n IAaveBridge internal _bridge;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(\n address aaveBridge\n )\n public\n {\n SmartWalletBase.initializeBase();\n _bridge = IAaveBridge(aaveBridge);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _bridge.isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address) {\n return _bridge.getReserveInterestToken(assetToken);\n }\n\n function getPrincipal(address assetToken) external override returns (uint256) {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address assetToken) external override returns (uint256 creatorInterest, uint256 ownerInterest) {\n return _getInterest(assetToken);\n }\n\n function getTotal(address assetToken) external override returns (uint256) {\n return _getTotal(assetToken);\n }\n\n function getRewards(address rewardToken) external override returns (uint256) {\n return IERC20(rewardToken).balanceOf(address(this));\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _deposit(assetToken, assetAmount, referralCode);\n }\n\n\n function withdraw(\n address receiver,\n address creatorRedirect,\n address assetToken\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (, uint256 ownerInterest) = _getInterest(assetToken);\n return _withdraw(receiver, creatorRedirect, assetToken, walletPrincipal.add(ownerInterest));\n }\n\n function withdrawAmount(\n address receiver,\n address creatorRedirect,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return _withdraw(receiver, creatorRedirect, assetToken, assetAmount);\n }\n\n function withdrawAmountForCreator(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return _withdrawForCreator(receiver, assetToken, assetAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _withdrawRewards(receiver, rewardsToken, rewardsAmount);\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n internal\n returns (uint256)\n {\n _trackAssetToken(assetToken);\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n\n // Deposit Assets into Aave (reverts on fail)\n _sendToken(address(_bridge), assetToken, assetAmount);\n uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function _withdraw(\n address receiver,\n address creatorRedirect,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken);\n\n // Withdraw from Interest only\n if (assetAmount < ownerInterest) {\n if (creatorInterest > 0) {\n uint256 ratio = assetAmount.mul(RAY).div(ownerInterest);\n creatorAmount = creatorInterest.add(nftCreatorAmountDischarged).mul(ratio).div(RAY);\n\n if (creatorAmount <= nftCreatorAmountDischarged) {\n nftCreatorAmountDischarged = nftCreatorAmountDischarged.sub(creatorAmount);\n creatorAmount = 0;\n }\n\n else {\n creatorAmount = creatorAmount.sub(nftCreatorAmountDischarged);\n nftCreatorAmountDischarged = 0;\n }\n }\n receiverAmount = assetAmount;\n }\n\n // Withdraw from Interest + Principal\n else {\n uint256 fromPrincipal = assetAmount.sub(ownerInterest);\n if (fromPrincipal > walletPrincipal) {\n fromPrincipal = walletPrincipal.sub(ownerInterest);\n }\n\n creatorAmount = creatorInterest;\n receiverAmount = ownerInterest.add(fromPrincipal);\n nftCreatorAmountDischarged = 0;\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal);\n }\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount));\n\n // Withdraw Assets for Creator\n if (creatorAmount > 0) {\n address receivesForCreator = (creatorRedirect != address(0x0)) ? creatorRedirect : nftCreator;\n _bridge.withdraw(receivesForCreator, assetToken, creatorAmount);\n }\n\n // Withdraw Assets for Receiver\n _bridge.withdraw(receiver, assetToken, receiverAmount);\n }\n\n function _withdrawForCreator(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 receiverAmount)\n {\n (uint256 creatorInterest,) = _getInterest(assetToken);\n if (creatorInterest == 0) { return 0; }\n if (assetAmount > creatorInterest) {\n assetAmount = creatorInterest;\n }\n\n nftCreatorAmountDischarged = nftCreatorAmountDischarged.add(assetAmount);\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, assetAmount);\n\n // Withdraw Assets for Receiver on behalf of Creator\n _bridge.withdraw(receiver, assetToken, assetAmount);\n }\n\n function _withdrawRewards(\n address receiver,\n address rewardsTokenAddress,\n uint256 rewardsAmount\n )\n internal\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"ASW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function _getTotal(address assetToken) internal view returns (uint256) {\n return _bridge.getTotalBalance(address(this), assetToken);\n }\n\n function _getInterest(address assetToken) internal view returns (uint256 creatorInterest, uint256 ownerInterest) {\n uint256 total = _getTotal(assetToken);\n uint256 principal = _getPrincipal(assetToken);\n uint256 interest = total.sub(principal);\n\n // Creator Royalties\n if (nftCreatorAnnuityPct > 0) {\n\n // Interest too small to calculate percentage;\n if (interest <= PERCENTAGE_SCALE) {\n // creatorInterest = interest.div(2); // split evenly?\n creatorInterest = 0; // All to owner\n }\n\n // Calculate percentage for Creator\n else {\n creatorInterest = interest\n .add(nftCreatorAmountDischarged)\n .mul(nftCreatorAnnuityPct)\n .div(PERCENTAGE_SCALE)\n .sub(nftCreatorAmountDischarged);\n }\n }\n\n // Owner Portion\n ownerInterest = interest.sub(creatorInterest);\n }\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveSmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\nimport \"../../interfaces/IAaveBridge.sol\";\nimport \"../../lib/SmartWalletBaseB.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet for Aave Assets\n * @dev Non-upgradeable Contract\n */\ncontract AaveSmartWalletB is SmartWalletBaseB {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 constant internal RAY = 1e27;\n\n IAaveBridge internal _bridge;\n\n uint256 internal _nftCreatorAmountDischarged;\n\n mapping (address => address) internal _assetATokens;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(\n address aaveBridge\n )\n public\n {\n SmartWalletBaseB.initializeBase();\n _bridge = IAaveBridge(aaveBridge);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _bridge.isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address) {\n return _bridge.getReserveInterestToken(assetToken);\n }\n\n function getPrincipal(address assetToken) external override returns (uint256) {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address assetToken, uint256 creatorPct) external override returns (uint256 creatorInterest, uint256 ownerInterest) {\n return _getInterest(assetToken, creatorPct);\n }\n\n function getTotal(address assetToken) external override returns (uint256) {\n return _getTotal(assetToken);\n }\n\n function getRewards(address rewardToken) external override returns (uint256) {\n return IERC20(rewardToken).balanceOf(address(this));\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _deposit(assetToken, assetAmount, referralCode);\n }\n\n\n function withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (, uint256 ownerInterest) = _getInterest(assetToken, creatorPct);\n return _withdraw(receiver, creator, creatorPct, assetToken, walletPrincipal.add(ownerInterest));\n }\n\n function withdrawAmount(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return _withdraw(receiver, creator, creatorPct, assetToken, assetAmount);\n }\n\n function withdrawAmountForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return _withdrawForCreator(receiver, creatorPct, assetToken, assetAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _withdrawRewards(receiver, rewardsToken, rewardsAmount);\n }\n\n function refreshPrincipal(address assetToken) external virtual override onlyWalletManager {\n uint256 aTokenBalance = IERC20(_assetATokens[assetToken]).balanceOf(address(this));\n if (_assetPrincipalBalance[assetToken] > aTokenBalance) {\n _assetPrincipalBalance[assetToken] = aTokenBalance;\n }\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n internal\n returns (uint256)\n {\n _trackAssetToken(assetToken);\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n\n // Deposit Assets into Aave (reverts on fail)\n _sendToken(address(_bridge), assetToken, assetAmount);\n uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function _withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken, creatorPct);\n\n // Withdraw from Interest only\n if (assetAmount < ownerInterest) {\n if (creatorInterest > 0) {\n uint256 ratio = assetAmount.mul(RAY).div(ownerInterest);\n creatorAmount = creatorInterest.add(_nftCreatorAmountDischarged).mul(ratio).div(RAY);\n\n if (creatorAmount <= _nftCreatorAmountDischarged) {\n _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.sub(creatorAmount);\n creatorAmount = 0;\n }\n else {\n creatorAmount = creatorAmount.sub(_nftCreatorAmountDischarged);\n _nftCreatorAmountDischarged = 0;\n }\n }\n receiverAmount = assetAmount;\n }\n\n // Withdraw from Interest + Principal\n else {\n uint256 fromPrincipal = assetAmount.sub(ownerInterest);\n if (fromPrincipal > walletPrincipal) {\n fromPrincipal = walletPrincipal.sub(ownerInterest);\n }\n\n creatorAmount = creatorInterest;\n receiverAmount = ownerInterest.add(fromPrincipal);\n _nftCreatorAmountDischarged = 0;\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal);\n }\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount));\n\n // Withdraw Assets for Creator\n if (creatorAmount > 0) {\n if (creator != address(0)) {\n _bridge.withdraw(creator, assetToken, creatorAmount);\n } else {\n receiverAmount = receiverAmount.add(creatorAmount);\n creatorAmount = 0;\n }\n }\n\n // Withdraw Assets for Receiver\n _bridge.withdraw(receiver, assetToken, receiverAmount);\n }\n\n function _withdrawForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 receiverAmount)\n {\n (uint256 creatorInterest,) = _getInterest(assetToken, creatorPct);\n if (creatorInterest == 0) { return 0; }\n if (assetAmount > creatorInterest) {\n assetAmount = creatorInterest;\n }\n\n _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.add(assetAmount);\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, assetAmount);\n\n // Withdraw Assets for Receiver on behalf of Creator\n _bridge.withdraw(receiver, assetToken, assetAmount);\n }\n\n function _withdrawRewards(\n address receiver,\n address rewardsTokenAddress,\n uint256 rewardsAmount\n )\n internal\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"ASW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function _getTotal(address assetToken) internal view returns (uint256) {\n return _bridge.getTotalBalance(address(this), assetToken);\n }\n\n function _getInterest(address assetToken, uint256 creatorPct) internal view returns (uint256 creatorInterest, uint256 ownerInterest) {\n uint256 total = _getTotal(assetToken);\n uint256 principal = _getPrincipal(assetToken);\n uint256 interest = total.sub(principal);\n\n // Creator Royalties\n if (creatorPct > 0) {\n\n // Interest too small to calculate percentage;\n if (interest <= PERCENTAGE_SCALE) {\n // creatorInterest = interest.div(2); // split evenly?\n creatorInterest = 0; // All to owner\n }\n\n // Calculate percentage for Creator\n else {\n creatorInterest = interest\n .add(_nftCreatorAmountDischarged)\n .mul(creatorPct)\n .div(PERCENTAGE_SCALE)\n .sub(_nftCreatorAmountDischarged);\n }\n }\n\n // Owner Portion\n ownerInterest = interest.sub(creatorInterest);\n }\n\n function _trackAssetToken(address assetToken) internal override {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _assetATokens[assetToken] = aTokenAddress;\n }\n }\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../lib/WalletManagerBase.sol\";\n\nimport \"./AaveSmartWallet.sol\";\n\n/**\n * @notice Wallet Manager for Aave\n * @dev Non-upgradeable Contract\n */\ncontract AaveWalletManager is WalletManagerBase {\n using SafeMath for uint256;\n\n event AaveBridgeSet(address indexed aaveBridge);\n event ValidRewardsTokenSet(address indexed rewardsToken, bool state);\n\n address internal _aaveBridge;\n uint256 internal _referralCode;\n\n mapping (address => bool) public rewardsTokenWhitelist;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new AaveSmartWallet());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return AaveSmartWallet(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return AaveSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return AaveSmartWallet(_wallets[uuid]).getInterest(assetToken);\n }\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getTotal(assetToken);\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getRewards(_rewardToken);\n }\n\n\n /***********************************|\n | Only Controller |\n |__________________________________*/\n\n function energize(\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = AaveSmartWallet(wallet).deposit(assetToken, assetAmount, _referralCode);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(ownerInterest > 0, \"AWM:E-412\");\n\n // Discharge the full amount of interest\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, ownerInterest);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(assetAmount > 0 && ownerInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmountForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address creator,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (uint256 creatorInterest,) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(assetAmount > 0 && creatorInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n receiverAmount = AaveSmartWallet(wallet).withdrawAmountForCreator(receiver, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount);\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = AaveSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0;\n\n // Release from interest first + principal if needed\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n require(rewardsTokenWhitelist[rewardsToken], \"AWM:E-423\");\n\n // Withdraw Rewards to Receiver\n amount = AaveSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 tokenId,\n address externalAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return AaveSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n // no-op\n }\n\n function getWalletAddressById(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPct\n )\n external\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n\n if (creator != address(0x0)) {\n AaveSmartWallet(wallet).setNftCreator(creator, annuityPct);\n }\n\n emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAaveBridge(address aaveBridge) external onlyOwner {\n require(aaveBridge != address(0x0), \"AWM:E-403\");\n _aaveBridge = aaveBridge;\n emit AaveBridgeSet(aaveBridge);\n }\n\n // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool\n function setReferralCode(uint256 referralCode) external onlyOwner {\n _referralCode = referralCode;\n }\n\n function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner {\n rewardsTokenWhitelist[rewardsToken] = state;\n emit ValidRewardsTokenSet(rewardsToken, state);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n AaveSmartWallet(newWallet).initialize(_aaveBridge);\n return newWallet;\n }\n}" + }, + "contracts/v1/yield/aave/AaveWalletManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../lib/WalletManagerBase.sol\";\nimport \"../../interfaces/IChargedSettings.sol\";\nimport \"./AaveSmartWalletB.sol\";\n\n/**\n * @notice Wallet Manager for Aave\n * @dev Non-upgradeable Contract\n */\ncontract AaveWalletManagerB is WalletManagerBase {\n using SafeMath for uint256;\n\n event AaveBridgeSet(address indexed aaveBridge);\n event ChargedSettingsSet(address indexed settings);\n event ValidRewardsTokenSet(address indexed rewardsToken, bool state);\n\n IChargedSettings internal _chargedSettings;\n\n address internal _aaveBridge;\n uint256 internal _referralCode;\n\n mapping (address => bool) public _rewardsTokenWhitelist;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new AaveSmartWalletB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return AaveSmartWalletB(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return AaveSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n return AaveSmartWalletB(_wallets[uuid]).getInterest(assetToken, annuityPct);\n }\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getTotal(assetToken);\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getRewards(_rewardToken);\n }\n\n\n /***********************************|\n | Only Controller |\n |__________________________________*/\n\n function energize(\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = AaveSmartWalletB(wallet).deposit(assetToken, assetAmount, _referralCode);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(ownerInterest > 0, \"AWM:E-412\");\n\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Discharge the full amount of interest\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, ownerInterest);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(assetAmount > 0 && ownerInterest >= assetAmount, \"AWM:E-412\");\n\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Discharge a portion of the interest\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmountForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address creator,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (uint256 creatorInterest,) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(assetAmount > 0 && creatorInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n receiverAmount = AaveSmartWalletB(wallet).withdrawAmountForCreator(receiver, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount);\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Release Principal + Interest\n principalAmount = AaveSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdraw(receiver, creator, annuityPct, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0;\n\n // Release from interest first + principal if needed\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n require(_rewardsTokenWhitelist[rewardsToken], \"AWM:E-423\");\n\n // Withdraw Rewards to Receiver\n amount = AaveSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 tokenId,\n address externalAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return AaveSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n AaveSmartWalletB(wallet).refreshPrincipal(assetToken);\n }\n\n function getWalletAddressById(\n address contractAddress,\n uint256 tokenId,\n address /* creator */,\n uint256 /* annuityPct */\n )\n external\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAaveBridge(address aaveBridge) external onlyOwner {\n require(aaveBridge != address(0x0), \"AWM:E-403\");\n _aaveBridge = aaveBridge;\n emit AaveBridgeSet(aaveBridge);\n }\n\n function setChargedSettings(address settings) external onlyOwner {\n require(settings != address(0x0), \"AWM:E-403\");\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool\n function setReferralCode(uint256 referralCode) external onlyOwner {\n _referralCode = referralCode;\n }\n\n function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner {\n _rewardsTokenWhitelist[rewardsToken] = state;\n emit ValidRewardsTokenSet(rewardsToken, state);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n AaveSmartWalletB(newWallet).initialize(_aaveBridge);\n return newWallet;\n }\n}" + }, + "contracts/v1/yield/aave/v2/AaveBridgeV2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveBridgeV2.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/SafeCast.sol\";\n\nimport \"./IATokenV2.sol\";\nimport \"./ILendingPoolV2.sol\";\nimport \"./ILendingPoolAddressesProviderV2.sol\";\n\nimport \"../../../interfaces/IAaveBridge.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\n\ncontract AaveBridgeV2 is Ownable, IAaveBridge, BlackholePrevention {\n using SafeMath for uint256;\n using SafeCast for uint256;\n using SafeERC20 for IERC20;\n using ReserveLogic for ReserveLogic.ReserveData;\n\n ILendingPoolAddressesProviderV2 public provider;\n ILendingPoolV2 public lendingPool;\n\n constructor (address lendingPoolProvider) public {\n provider = ILendingPoolAddressesProviderV2(lendingPoolProvider);\n lendingPool = ILendingPoolV2(provider.getLendingPool());\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address aTokenAddress) {\n return _getReserveInterestToken(assetToken);\n }\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _isReserveActive(assetToken);\n }\n\n function getTotalBalance(address account, address assetToken) external view override returns (uint256) {\n address aTokenAddress = _getReserveInterestToken(assetToken);\n if (aTokenAddress == address(0x0)) { return 0; }\n return IATokenV2(aTokenAddress).balanceOf(account);\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n returns (uint256)\n {\n address self = address(this);\n address aTokenAddress = _getReserveInterestToken(assetToken);\n require(_isReserveActive(assetToken), \"ABV2:E-424\");\n\n IERC20 token = IERC20(assetToken);\n IATokenV2 aToken = IATokenV2(aTokenAddress);\n\n if (token.allowance(address(this), address(lendingPool)) < assetAmount) {\n token.approve(address(lendingPool), uint256(-1));\n }\n\n // Deposit Assets into Aave\n uint256 preBalance = aToken.balanceOf(self);\n lendingPool.deposit(assetToken, assetAmount, self, referralCode.toUint16());\n uint256 postBalance = aToken.balanceOf(self);\n uint256 aTokensAmount = postBalance.sub(preBalance);\n\n // Transfer back the Interest Tokens\n _sendToken(msg.sender, aTokenAddress, aTokensAmount);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function withdraw(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n {\n address self = address(this);\n require(_isReserveActive(assetToken), \"ABV2:E-424\");\n\n // Redeem aTokens for Asset Tokens\n lendingPool.withdraw(assetToken, assetAmount, self);\n\n // Transfer back the Asset Tokens\n _sendToken(receiver, assetToken, assetAmount);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n\n function _getReserveInterestToken(address assetToken) internal view returns (address aTokenAddress) {\n ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken);\n return config.aTokenAddress;\n }\n\n function _isReserveActive(address assetToken) internal view returns (bool) {\n ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken);\n uint256 isActiveFlag = 2 ** 56; // bit 56: reserve is active\n return (config.configuration.data & isActiveFlag) == isActiveFlag;\n }\n}\n" + }, + "contracts/v1/yield/aave/v2/IATokenV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\n\ninterface IATokenV2 {\n function balanceOf(address account) external view returns (uint256);\n}\n" + }, + "contracts/v1/yield/aave/v2/ILendingPoolAddressesProviderV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\n\ninterface ILendingPoolAddressesProviderV2 {\n function getLendingPool() external view returns (address);\n}" + }, + "contracts/v1/yield/aave/v2/ILendingPoolV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport \"./ILendingPoolAddressesProviderV2.sol\";\n\nlibrary ReserveConfiguration {\n struct Map {\n uint256 data;\n }\n}\n\nlibrary ReserveLogic {\n struct ReserveData {\n ReserveConfiguration.Map configuration;\n uint128 liquidityIndex;\n uint128 variableBorrowIndex;\n uint128 currentLiquidityRate;\n uint128 currentVariableBorrowRate;\n uint128 currentStableBorrowRate;\n uint40 lastUpdateTimestamp;\n address aTokenAddress;\n address stableDebtTokenAddress;\n address variableDebtTokenAddress;\n address interestRateStrategyAddress;\n uint8 id;\n }\n}\n\ninterface ILendingPoolV2 {\n function deposit(address reserve, uint256 amount, address onBehalfOf, uint16 referralCode) external;\n function withdraw(address reserve, uint256 amount, address to) external;\n function getReserveData(address asset) external view returns (ReserveLogic.ReserveData memory);\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericSmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"../../../lib/SmartWalletBase.sol\";\n\n\n/**\n * @notice Generic ERC20-Token Smart-Wallet Bridge\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartWallet is SmartWalletBase {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize()\n public\n {\n SmartWalletBase.initializeBase();\n }\n\n function isReserveActive(address assetToken)\n external\n override\n view\n returns (bool)\n {\n return _getPrincipal(assetToken) == 0;\n }\n\n function getReserveInterestToken(address assetToken)\n external\n override\n view\n returns (address)\n {\n return assetToken;\n }\n\n function getPrincipal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address /* assetToken */)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n return (0, 0);\n }\n\n function getTotal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getRewards(address assetToken)\n external\n override\n returns (uint256)\n {\n return IERC20(assetToken).balanceOf(address(this));\n }\n\n function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n // Track Principal\n _trackAssetToken(assetToken);\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n }\n\n function withdraw(address receiver, address /* creatorRedirect */, address assetToken)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmount(address receiver, address /* creatorRedirect */, address assetToken, uint256 assetAmount)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n if (receiverAmount >= assetAmount) {\n receiverAmount = assetAmount;\n }\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmountForCreator(\n address /* receiver */,\n address /* assetToken */,\n uint256 /* assetID */\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericSmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWalletB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"../../../lib/SmartWalletBaseB.sol\";\n\n\n/**\n * @notice Generic ERC20-Token Smart-Wallet Bridge\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartWalletB is SmartWalletBaseB {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize()\n public\n {\n SmartWalletBaseB.initializeBase();\n }\n\n function isReserveActive(address assetToken)\n external\n override\n view\n returns (bool)\n {\n return _getPrincipal(assetToken) == 0;\n }\n\n function getReserveInterestToken(address assetToken)\n external\n override\n view\n returns (address)\n {\n return assetToken;\n }\n\n function getPrincipal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address /* assetToken */, uint256 /* creatorPct */)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n return (0, 0);\n }\n\n function getTotal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getRewards(address assetToken)\n external\n override\n returns (uint256)\n {\n return IERC20(assetToken).balanceOf(address(this));\n }\n\n function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n // Track Principal\n _trackAssetToken(assetToken);\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n }\n\n function withdraw(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmount(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken, uint256 assetAmount)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n if (receiverAmount >= assetAmount) {\n receiverAmount = assetAmount;\n }\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmountForCreator(\n address /* receiver */,\n uint256 /* creatorPct */,\n address /* assetToken */,\n uint256 /* assetID */\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function refreshPrincipal(address assetToken) external virtual override onlyWalletManager {\n _assetPrincipalBalance[assetToken] = IERC20(assetToken).balanceOf(address(this));\n }\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../../lib/WalletManagerBase.sol\";\nimport \"./GenericSmartWallet.sol\";\n\n/**\n * @notice Generic ERC20 Wallet Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericWalletManager is WalletManagerBase {\n using SafeMath for uint256;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new GenericSmartWallet());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return GenericSmartWallet(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return GenericSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getTotal(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return GenericSmartWallet(_wallets[uuid]).getInterest(assetToken);\n }\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getRewards(rewardToken);\n }\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount)\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = GenericSmartWallet(wallet).deposit(assetToken, assetAmount, 0);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmountForCreator(\n address /* receiver */,\n address /* contractAddress */,\n uint256 /* tokenId */,\n address /* creator */,\n address /* assetToken */,\n uint256 /* assetAmount */\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release from interest first + principal if needed\n principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n external\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return GenericSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n // no-op\n }\n\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct)\n external\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n\n if (creator != address(0x0)) {\n GenericSmartWallet(wallet).setNftCreator(creator, annuityPct);\n }\n\n emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n GenericSmartWallet(newWallet).initialize();\n return newWallet;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericWalletManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericWalletManagerB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../../lib/WalletManagerBase.sol\";\nimport \"./GenericSmartWalletB.sol\";\n\n/**\n * @notice Generic ERC20 Wallet Manager B\n * @dev Non-upgradeable Contract\n */\ncontract GenericWalletManagerB is WalletManagerBase {\n using SafeMath for uint256;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new GenericSmartWalletB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return GenericSmartWalletB(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return GenericSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getTotal(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return GenericSmartWalletB(_wallets[uuid]).getInterest(assetToken, 0);\n }\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getRewards(rewardToken);\n }\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount)\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = GenericSmartWalletB(wallet).deposit(assetToken, assetAmount, 0);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmountForCreator(\n address /* receiver */,\n address /* contractAddress */,\n uint256 /* tokenId */,\n address /* creator */,\n address /* assetToken */,\n uint256 /* assetAmount */\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdraw(receiver, creatorRedirect, 0, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release from interest first + principal if needed\n principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdrawAmount(receiver, creatorRedirect, 0, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyControllerOrExecutor\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n external\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return GenericSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n GenericSmartWalletB(wallet).refreshPrincipal(assetToken);\n }\n\n function getWalletAddressById(address contractAddress, uint256 tokenId, address /* creator */, uint256 /* annuityPct */)\n external\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n GenericSmartWalletB(newWallet).initialize();\n return newWallet;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericBasketManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"../../../interfaces/IBasketManager.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"./GenericSmartBasket.sol\";\n\n/**\n * @notice Generic ERC721 Basket Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericBasketManager is Ownable, BlackholePrevention, IBasketManager {\n using Counters for Counters.Counter;\n using TokenInfo for address;\n\n // The Controller Contract Address\n address internal _controller;\n\n // Template Contract for creating Token Smart-Baskets\n address internal _basketTemplate;\n\n // TokenID => Token Smart-Basket Address\n mapping (uint256 => address) internal _baskets;\n\n mapping (uint256 => Counters.Counter) internal _totalTokens;\n\n // State of Basket Manager\n bool internal _paused;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _basketTemplate = address(new GenericSmartBasket());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n function getTokenTotalCount(\n address contractAddress,\n uint256 tokenId\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n return _totalTokens[uuid].current();\n }\n\n function getTokenCountByType(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n external\n override\n returns (uint256)\n {\n address basket = getBasketAddressById(contractAddress, tokenId);\n return GenericSmartBasket(basket).getTokenCountByType(basketTokenAddress, basketTokenId);\n }\n\n function prepareTransferAmount(uint256 /* nftTokenAmount */) external override onlyController {\n // no-op\n }\n\n function addToBasket(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n whenNotPaused\n returns (bool added)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n added = GenericSmartBasket(basket).addToBasket(basketTokenAddress, basketTokenId);\n\n // Log Event\n if (added) {\n _totalTokens[uuid].increment();\n emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, 1);\n }\n }\n\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n returns (bool removed)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n removed = GenericSmartBasket(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId);\n\n // Log Event\n if (removed) {\n _totalTokens[uuid].decrement();\n emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, 1);\n }\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyController\n returns (uint256 amount)\n {\n // no-op\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n public\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n return GenericSmartBasket(basket).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function getBasketAddressById(address contractAddress, uint256 tokenId)\n public\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n // Create Smart-Basket if none exists\n if (basket == address(0x0)) {\n basket = _createBasket();\n _baskets[uuid] = basket;\n\n emit NewSmartBasket(contractAddress, tokenId, basket);\n }\n\n return basket;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Basket Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartBasket(basket).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n function _createBasket()\n internal\n returns (address)\n {\n address newBasket = _createClone(_basketTemplate);\n GenericSmartBasket(newBasket).initialize();\n return newBasket;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"GBM:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"GBM:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericBasketManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport \"../../../interfaces/IBasketManager.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../interfaces/ITokenInfoProxy.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"../../../lib/NftTokenType.sol\";\nimport \"./GenericSmartBasketB.sol\";\n\n/**\n * @notice Generic ERC721 Basket Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericBasketManagerB is Ownable, BlackholePrevention, IBasketManager {\n using Counters for Counters.Counter;\n using TokenInfo for address;\n using NftTokenType for address;\n\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // The Controller Contract Address\n address internal _controller;\n\n // The Executor Contract Address\n address internal _executor;\n\n // Template Contract for creating Token Smart-Baskets\n address internal _basketTemplate;\n\n // TokenID => Token Smart-Basket Address\n mapping (uint256 => address) internal _baskets;\n\n // Prepared Amount\n uint256 internal _preparedAmount;\n\n // State of Basket Manager\n bool internal _paused;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _basketTemplate = address(new GenericSmartBasketB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n function getTokenTotalCount(\n address contractAddress,\n uint256 tokenId\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n if (basket == address(0)) { return 0; }\n return GenericSmartBasketB(basket).getNestedNftCount();\n }\n\n function getTokenCountByType(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n if (basket == address(0)) { return 0; }\n return GenericSmartBasketB(basket).getTokenCountByType(basketTokenAddress, basketTokenId);\n }\n\n function prepareTransferAmount(uint256 nftTokenAmount) external override onlyController {\n _preparedAmount = nftTokenAmount;\n }\n\n function addToBasket(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n whenNotPaused\n returns (bool added)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n uint256 nftTokenAmount = 1;\n if (_preparedAmount > 0) {\n nftTokenAmount = _preparedAmount;\n _preparedAmount = 0;\n }\n\n added = GenericSmartBasketB(basket).addToBasket(basketTokenAddress, basketTokenId, nftTokenAmount);\n if (added) {\n emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount);\n }\n }\n\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n returns (bool removed)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n uint256 nftTokenAmount = 1;\n if (_preparedAmount > 0) {\n nftTokenAmount = _preparedAmount;\n _preparedAmount = 0;\n }\n\n removed = GenericSmartBasketB(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId, nftTokenAmount);\n if (removed) {\n emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount);\n }\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyControllerOrExecutor\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartBasketB(basket).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit BasketRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n public\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n return GenericSmartBasketB(basket).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function getBasketAddressById(address contractAddress, uint256 tokenId)\n public\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n // Create Smart-Basket if none exists\n if (basket == address(0x0)) {\n basket = _createBasket();\n _baskets[uuid] = basket;\n\n emit NewSmartBasket(contractAddress, tokenId, basket);\n }\n\n return basket;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Basket Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n /**\n * @dev Connects to the ExecForAccount Controller\n */\n function setExecutor(address executor) external onlyOwner {\n _executor = executor;\n emit ExecutorSet(executor);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setTokenInfoProxy(address tokenInfoProxy) external onlyOwner {\n _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartBasket(basket).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createBasket()\n internal\n returns (address)\n {\n address newBasket = _createClone(_basketTemplate);\n GenericSmartBasketB(newBasket).initialize(_tokenInfoProxy);\n return newBasket;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"GBM:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Controller or Executor contract\n modifier onlyControllerOrExecutor() {\n require(_executor == msg.sender || _controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"GBM:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericSmartBasket.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/NftTokenType.sol\";\n\n\n/**\n * @notice Generic ERC721-Token Smart-Basket\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartBasket is ISmartBasket, BlackholePrevention, IERC721Receiver {\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableSet for EnumerableSet.AddressSet;\n using NftTokenType for address;\n\n address internal _basketManager;\n\n // NFT contract address => Token Ids in Basket\n mapping (address => mapping(uint256 => EnumerableSet.UintSet)) internal _nftContractTokens;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public {\n require(_basketManager == address(0x0), \"GSB:E-002\");\n _basketManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n return _nftContractTokens[contractAddress][nftType].length();\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver(0).onERC721Received.selector;\n }\n\n function addToBasket(address contractAddress, uint256 tokenId)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n require(!_nftContractTokens[contractAddress][nftType].contains(tokenId), \"GSB:E-425\");\n\n bool added = _nftContractTokens[contractAddress][nftType].add(tokenId);\n if (added) {\n // NFT should have been Transferred into here via Charged-Particles\n added = (IERC721(contractAddress).ownerOf(tokenId) == address(this));\n }\n return added;\n }\n\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n require(_nftContractTokens[contractAddress][nftType].contains(tokenId), \"GSB:E-426\");\n\n bool removed = _nftContractTokens[contractAddress][nftType].remove(tokenId);\n if (removed) {\n IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId);\n }\n return removed;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyBasketManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the basket manager\n modifier onlyBasketManager() {\n require(_basketManager == msg.sender, \"GSB:E-109\");\n _;\n }\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericSmartBasketB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155Receiver.sol\";\nimport \"../../../interfaces/ISmartBasketB.sol\";\nimport \"../../../interfaces/ITokenInfoProxy.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"../../../lib/NftTokenType.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\n\n/**\n * @notice Generic ERC721-Token Smart-Basket\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartBasketB is ISmartBasketB, BlackholePrevention, IERC721Receiver, ERC1155Receiver {\n using TokenInfo for address;\n using NftTokenType for address;\n\n address internal _basketManager;\n\n // NFT TokenUUID => ERC1155 Balance\n mapping (uint256 => uint256) internal _nftContractTokenBalance;\n uint256 internal _nestedNftCount;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(ITokenInfoProxy /* tokenInfoProxy */) public {\n require(_basketManager == address(0x0), \"GSB:E-002\");\n _basketManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getNestedNftCount() external view override returns (uint256) {\n return _nestedNftCount;\n }\n\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n return _nftContractTokenBalance[contractAddress.getTokenUUID(tokenId)];\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver(0).onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\n return IERC1155Receiver(0).onERC1155Received.selector;\n }\n\n // Unimplemented\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\n return \"\"; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector;\n }\n\n function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n _nftContractTokenBalance[uuid] += nftTokenAmount;\n _nestedNftCount += nftTokenAmount;\n return true;\n }\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n uint256 nftTokenAmount\n )\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n _nftContractTokenBalance[uuid] -= nftTokenAmount;\n _nestedNftCount -= nftTokenAmount;\n\n if (contractAddress.isERC1155()) {\n IERC1155(contractAddress).safeTransferFrom(address(this), receiver, tokenId, nftTokenAmount, \"\");\n } else {\n IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId);\n }\n return true;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyBasketManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSB:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyBasketManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the basket manager\n modifier onlyBasketManager() {\n require(_basketManager == msg.sender, \"GSB:E-109\");\n _;\n }\n}\n" + }, + "erc20permit/contracts/ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"./IERC2612.sol\";\n\n/**\n * @author Georgios Konstantopoulos\n * @dev Extension of {ERC20} that allows token holders to use their tokens\n * without sending any transactions by setting {IERC20-allowance} with a\n * signature using the {permit} method, and then spend them via\n * {IERC20-transferFrom}.\n *\n * The {permit} signature mechanism conforms to the {IERC2612} interface.\n */\nabstract contract ERC20Permit is ERC20, IERC2612 {\n mapping (address => uint256) public override nonces;\n\n bytes32 public immutable PERMIT_TYPEHASH = keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public immutable DOMAIN_SEPARATOR;\n\n constructor(string memory name_, string memory symbol_) internal ERC20(name_, symbol_) {\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name_)),\n keccak256(bytes(\"1\")),\n chainId,\n address(this)\n )\n );\n }\n\n /**\n * @dev See {IERC2612-permit}.\n *\n * In cases where the free option is not a concern, deadline can simply be\n * set to uint(-1), so it should be seen as an optional parameter\n */\n function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {\n require(deadline >= block.timestamp, \"ERC20Permit: expired deadline\");\n\n bytes32 hashStruct = keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n amount,\n nonces[owner]++,\n deadline\n )\n );\n\n bytes32 hash = keccak256(\n abi.encodePacked(\n '\\x19\\x01',\n DOMAIN_SEPARATOR,\n hashStruct\n )\n );\n\n address signer = ecrecover(hash, v, r, s);\n require(\n signer != address(0) && signer == owner,\n \"ERC20Permit: invalid signature\"\n );\n\n _approve(owner, spender, amount);\n }\n}\n" + }, + "erc20permit/contracts/IERC2612.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC2612 standard as defined in the EIP.\n *\n * Adds the {permit} method, which can be used to change one's\n * {IERC20-allowance} without having to send a transaction, by signing a\n * message. This allows users to spend tokens without having to hold Ether.\n *\n * See https://eips.ethereum.org/EIPS/eip-2612.\n */\ninterface IERC2612 {\n /**\n * @dev Sets `amount` 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 * - `owner` cannot be the zero address.\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(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n /**\n * @dev Returns the current ERC2612 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" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "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/deployments/mainnet/.chainId b/deployments/mainnet/.chainId new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/deployments/mainnet/.chainId @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/deployments/mainnet/DefaultProxyAdmin.json b/deployments/mainnet/DefaultProxyAdmin.json new file mode 100644 index 0000000..1457106 --- /dev/null +++ b/deployments/mainnet/DefaultProxyAdmin.json @@ -0,0 +1,259 @@ +{ + "address": "0x4ccD62462070C8B8AB1614E0Ca1Ec449108B7f65", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "initialOwner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "upgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ], + "transactionHash": "0x9452f5fdd960092278bf5f194c741537a50beb4b347ef5a3e6d4271800e18b60", + "receipt": { + "to": null, + "from": "0xb8D175F16742395F530e0b3bC1d30BD06B78CdA9", + "contractAddress": "0x4ccD62462070C8B8AB1614E0Ca1Ec449108B7f65", + "transactionIndex": 68, + "gasUsed": "644163", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000800000000000000000000000000000400000000000000000000000000000000000000000000000000000000001000000000000000000000000008000000000020000000000000000000800000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000010000000000000000000002000000", + "blockHash": "0x60e4836ad49339c9f4127cdc8167912f1aba074627839c5f8d29ae733ef7cc7a", + "transactionHash": "0x9452f5fdd960092278bf5f194c741537a50beb4b347ef5a3e6d4271800e18b60", + "logs": [ + { + "transactionIndex": 68, + "blockNumber": 18042834, + "transactionHash": "0x9452f5fdd960092278bf5f194c741537a50beb4b347ef5a3e6d4271800e18b60", + "address": "0x4ccD62462070C8B8AB1614E0Ca1Ec449108B7f65", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000b8d175f16742395f530e0b3bc1d30bd06b78cda9" + ], + "data": "0x", + "logIndex": 159, + "blockHash": "0x60e4836ad49339c9f4127cdc8167912f1aba074627839c5f8d29ae733ef7cc7a" + } + ], + "blockNumber": 18042834, + "cumulativeGasUsed": "11878320", + "status": 1, + "byzantium": true + }, + "args": [ + "0xb8D175F16742395F530e0b3bC1d30BD06B78CdA9" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"initialOwner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\",\"kind\":\"dev\",\"methods\":{\"changeProxyAdmin(address,address)\":{\"details\":\"Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`.\"},\"getProxyAdmin(address)\":{\"details\":\"Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"getProxyImplementation(address)\":{\"details\":\"Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"upgrade(address,address)\":{\"details\":\"Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`.\"},\"upgradeAndCall(address,address,bytes)\":{\"details\":\"Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol\":\"ProxyAdmin\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/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 (address initialOwner) {\\n _transferOwnership(initialOwner);\\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\",\"keccak256\":\"0x9b2bbba5bb04f53f277739c1cdff896ba8b3bf591cfc4eab2098c655e8ac251e\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./TransparentUpgradeableProxy.sol\\\";\\nimport \\\"../../access/Ownable.sol\\\";\\n\\n/**\\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\\n */\\ncontract ProxyAdmin is Ownable {\\n\\n constructor (address initialOwner) Ownable(initialOwner) {}\\n\\n /**\\n * @dev Returns the current implementation of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"implementation()\\\")) == 0x5c60da1b\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"5c60da1b\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Returns the current admin of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"admin()\\\")) == 0xf851a440\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"f851a440\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Changes the admin of `proxy` to `newAdmin`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the current admin of `proxy`.\\n */\\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\\n proxy.changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\\n proxy.upgradeTo(implementation);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgradeAndCall(\\n TransparentUpgradeableProxy proxy,\\n address implementation,\\n bytes memory data\\n ) public payable virtual onlyOwner {\\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\\n }\\n}\\n\",\"keccak256\":\"0x754888b9c9ab5525343460b0a4fa2e2f4fca9b6a7e0e7ddea4154e2b1182a45d\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev 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\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/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\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50604051610b17380380610b1783398101604081905261002f91610090565b8061003981610040565b50506100c0565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156100a257600080fd5b81516001600160a01b03811681146100b957600080fd5b9392505050565b610a48806100cf6000396000f3fe60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461012b57806399a88ec41461013e578063f2fde38b1461015e578063f3b7dead1461017e57600080fd5b8063204e1c7a14610080578063715018a6146100c95780637eff275e146100e05780638da5cb5b14610100575b600080fd5b34801561008c57600080fd5b506100a061009b3660046107e4565b61019e565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d557600080fd5b506100de610255565b005b3480156100ec57600080fd5b506100de6100fb366004610808565b6102e7565b34801561010c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100a0565b6100de610139366004610870565b6103ee565b34801561014a57600080fd5b506100de610159366004610808565b6104fc565b34801561016a57600080fd5b506100de6101793660046107e4565b6105d1565b34801561018a57600080fd5b506100a06101993660046107e4565b610701565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b600060405180830381855afa9150503d8060008114610225576040519150601f19603f3d011682016040523d82523d6000602084013e61022a565b606091505b50915091508161023957600080fd5b8080602001905181019061024d9190610964565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6102e5600061074d565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610368576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b600060405180830381600087803b1580156103d257600080fd5b505af11580156103e6573d6000803e3d6000fd5b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461046f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef2869034906104c59086908690600401610981565b6000604051808303818588803b1580156104de57600080fd5b505af11580156104f2573d6000803e3d6000fd5b5050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461057d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016103b8565b60005473ffffffffffffffffffffffffffffffffffffffff163314610652576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b73ffffffffffffffffffffffffffffffffffffffff81166106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102d2565b6106fe8161074d565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146106fe57600080fd5b6000602082840312156107f657600080fd5b8135610801816107c2565b9392505050565b6000806040838503121561081b57600080fd5b8235610826816107c2565b91506020830135610836816107c2565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561088557600080fd5b8335610890816107c2565b925060208401356108a0816107c2565b9150604084013567ffffffffffffffff808211156108bd57600080fd5b818601915086601f8301126108d157600080fd5b8135818111156108e3576108e3610841565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561092957610929610841565b8160405282815289602084870101111561094257600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561097657600080fd5b8151610801816107c2565b73ffffffffffffffffffffffffffffffffffffffff8316815260006020604081840152835180604085015260005b818110156109cb578581018301518582016060015282016109af565b818111156109dd576000606083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160600194935050505056fea2646970667358221220bd6c09ab03bfaf9ec60a4bf8cd98903cecb891974e17e2d76a3b2002c97eeb8964736f6c634300080a0033", + "deployedBytecode": "0x60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461012b57806399a88ec41461013e578063f2fde38b1461015e578063f3b7dead1461017e57600080fd5b8063204e1c7a14610080578063715018a6146100c95780637eff275e146100e05780638da5cb5b14610100575b600080fd5b34801561008c57600080fd5b506100a061009b3660046107e4565b61019e565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d557600080fd5b506100de610255565b005b3480156100ec57600080fd5b506100de6100fb366004610808565b6102e7565b34801561010c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100a0565b6100de610139366004610870565b6103ee565b34801561014a57600080fd5b506100de610159366004610808565b6104fc565b34801561016a57600080fd5b506100de6101793660046107e4565b6105d1565b34801561018a57600080fd5b506100a06101993660046107e4565b610701565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b600060405180830381855afa9150503d8060008114610225576040519150601f19603f3d011682016040523d82523d6000602084013e61022a565b606091505b50915091508161023957600080fd5b8080602001905181019061024d9190610964565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6102e5600061074d565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610368576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b600060405180830381600087803b1580156103d257600080fd5b505af11580156103e6573d6000803e3d6000fd5b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461046f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef2869034906104c59086908690600401610981565b6000604051808303818588803b1580156104de57600080fd5b505af11580156104f2573d6000803e3d6000fd5b5050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461057d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016103b8565b60005473ffffffffffffffffffffffffffffffffffffffff163314610652576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b73ffffffffffffffffffffffffffffffffffffffff81166106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102d2565b6106fe8161074d565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146106fe57600080fd5b6000602082840312156107f657600080fd5b8135610801816107c2565b9392505050565b6000806040838503121561081b57600080fd5b8235610826816107c2565b91506020830135610836816107c2565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561088557600080fd5b8335610890816107c2565b925060208401356108a0816107c2565b9150604084013567ffffffffffffffff808211156108bd57600080fd5b818601915086601f8301126108d157600080fd5b8135818111156108e3576108e3610841565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561092957610929610841565b8160405282815289602084870101111561094257600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561097657600080fd5b8151610801816107c2565b73ffffffffffffffffffffffffffffffffffffffff8316815260006020604081840152835180604085015260005b818110156109cb578581018301518582016060015282016109af565b818111156109dd576000606083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160600194935050505056fea2646970667358221220bd6c09ab03bfaf9ec60a4bf8cd98903cecb891974e17e2d76a3b2002c97eeb8964736f6c634300080a0033", + "devdoc": { + "details": "This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.", + "kind": "dev", + "methods": { + "changeProxyAdmin(address,address)": { + "details": "Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`." + }, + "getProxyAdmin(address)": { + "details": "Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`." + }, + "getProxyImplementation(address)": { + "details": "Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`." + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + }, + "upgrade(address,address)": { + "details": "Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`." + }, + "upgradeAndCall(address,address,bytes)": { + "details": "Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 7, + "contract": "solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol:ProxyAdmin", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + } + } + } +} \ No newline at end of file diff --git a/deployments/mainnet/LeptonsStore.json b/deployments/mainnet/LeptonsStore.json new file mode 100644 index 0000000..2186281 --- /dev/null +++ b/deployments/mainnet/LeptonsStore.json @@ -0,0 +1,632 @@ +{ + "address": "0x7Bf70a3DC2d5Da7c924ce3E414E14C4564A59b1b", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_lepton", + "type": "address" + }, + { + "internalType": "address", + "name": "_ionx", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_ionxPerLepton", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "buyer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "price", + "type": "uint256" + } + ], + "name": "SoldLepton", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "leptonAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "buyWithIonx", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getIonxBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getLeptonBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ionx", + "outputs": [ + { + "internalType": "contract Ionx", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ionxPerLepton", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lepton", + "outputs": [ + { + "internalType": "contract Lepton2", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "load", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "nextTokenId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "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": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_ionx", + "type": "address" + } + ], + "name": "setIonx", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "ionxAmount", + "type": "uint256" + } + ], + "name": "setIonxPerLepton", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_lepton", + "type": "address" + } + ], + "name": "setLepton", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "setNextTokenId", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xfd93351d808a919195332d3fc3533bdf24fe0f9b9b59fc696310ee15e084feec", + "receipt": { + "to": null, + "from": "0xb8D175F16742395F530e0b3bC1d30BD06B78CdA9", + "contractAddress": "0x7Bf70a3DC2d5Da7c924ce3E414E14C4564A59b1b", + "transactionIndex": 82, + "gasUsed": "1605291", + "logsBloom": "0x00000000000000000000000000000000000000000000100000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000040000000000800000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000020000000000000000000000000000000000000010000000000000000000002000000", + "blockHash": "0x9ec3db50b19e1bac6ba718a9166054aa50768e7c2a07e1a3c04d8f92909ac518", + "transactionHash": "0xfd93351d808a919195332d3fc3533bdf24fe0f9b9b59fc696310ee15e084feec", + "logs": [ + { + "transactionIndex": 82, + "blockNumber": 19636578, + "transactionHash": "0xfd93351d808a919195332d3fc3533bdf24fe0f9b9b59fc696310ee15e084feec", + "address": "0x7Bf70a3DC2d5Da7c924ce3E414E14C4564A59b1b", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000b8d175f16742395f530e0b3bc1d30bd06b78cda9" + ], + "data": "0x", + "logIndex": 238, + "blockHash": "0x9ec3db50b19e1bac6ba718a9166054aa50768e7c2a07e1a3c04d8f92909ac518" + } + ], + "blockNumber": 19636578, + "cumulativeGasUsed": "9365242", + "status": 1, + "byzantium": true + }, + "args": [ + "0x3Cd2410EAa9c2dCE50aF6CCAb72Dc93879a09c1F", + "0x02D3A27Ac3f55d5D91Fb0f52759842696a864217", + "15000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "e9994e7fbdc698929d4e56cc732a0db2", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_lepton\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_ionx\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_ionxPerLepton\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"buyer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"}],\"name\":\"SoldLepton\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC1155\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckEther\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"leptonAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"buyWithIonx\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getIonxBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLeptonBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ionx\",\"outputs\":[{\"internalType\":\"contract Ionx\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ionxPerLepton\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lepton\",\"outputs\":[{\"internalType\":\"contract Lepton2\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"load\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nextTokenId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"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\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_ionx\",\"type\":\"address\"}],\"name\":\"setIonx\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"ionxAmount\",\"type\":\"uint256\"}],\"name\":\"setIonxPerLepton\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_lepton\",\"type\":\"address\"}],\"name\":\"setLepton\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"setNextTokenId\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC1155\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawErc20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawEther\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/v1/leptons/store.sol\":\"LeptonsStore\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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 GSN 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 payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xdb26cbf4d028490f49831a7865c2fe1b28db44b535ca8d343785a3b768aae183\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"../GSN/Context.sol\\\";\\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 */\\ncontract 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 () internal {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view 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 emit OwnershipTransferred(_owner, address(0));\\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x4bd6402ca6b3419008c2b482aff54e66836e8cb4eba2680e42ac5884ae6424fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts may inherit from this and call {_registerInterface} to declare\\n * their support of an interface.\\n */\\ncontract ERC165 is IERC165 {\\n /*\\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\\n */\\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\\n\\n /**\\n * @dev Mapping of interface ids to whether or not it's supported.\\n */\\n mapping(bytes4 => bool) private _supportedInterfaces;\\n\\n constructor () internal {\\n // Derived contracts need only register support for their own interfaces,\\n // we register support for ERC165 itself here\\n _registerInterface(_INTERFACE_ID_ERC165);\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n *\\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) public view override returns (bool) {\\n return _supportedInterfaces[interfaceId];\\n }\\n\\n /**\\n * @dev Registers the contract as an implementer of the interface defined by\\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\\n * registering its interface id is not required.\\n *\\n * See {IERC165-supportsInterface}.\\n *\\n * Requirements:\\n *\\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\\n */\\n function _registerInterface(bytes4 interfaceId) internal virtual {\\n require(interfaceId != 0xffffffff, \\\"ERC165: invalid interface id\\\");\\n _supportedInterfaces[interfaceId] = true;\\n }\\n}\\n\",\"keccak256\":\"0xb046d18f9d09683ca1c0ed6d80c61da8a8a7d9b30bad70a17b898538683eff74\",\"license\":\"MIT\"},\"@openzeppelin/contracts/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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\",\"keccak256\":\"0xfa152b6e88a1dc50780e8f1580426dc23ad2e1e2c2f086a088adf206a202f453\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\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 uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\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 sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\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 * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\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 // 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) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts 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 mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9a9cf02622cd7a64261b10534fc3260449da25c98c9e96d1b4ae8110a20e5806\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x31691ad0817f8cb338531b78d2ab2989027d9f27e6f8e62492b754fed9429b10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"../../GSN/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.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 guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 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 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\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 uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name, string memory symbol) public {\\n _name = name;\\n _symbol = symbol;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view 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 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 {_setupDecimals} is\\n * called.\\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 returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal {\\n _decimals = decimals_;\\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 to 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(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0x91e0bd6a6762d2a1700dab0849de8422611355100576c4beef1e80d82a4104a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0x5c26b39d26f7ed489e555d955dcd3e01872972e71fdd1528e93ec164e4f23385\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.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 SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf3b30f8a49631420635a8c35daacfcaa338012755f18a76fdd118730256f9a27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0xaf936da92f3a9a4f98b237323b5eb1d813fb86c4d07a184beba7027cf0509ba3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 /**\\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\",\"keccak256\":\"0x3636662804cd8f474536b2875a9038a4c3fb91879f1bbff48af5c3f140fcd2f0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 /**\\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\",\"keccak256\":\"0xe7f984cedc00a138dc27f263c73c32ba9a4b2fd23b6c34ac46f46c074b943538\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address operator, address from, uint256 tokenId, bytes calldata data)\\n external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x321ee37ef4925020aa818a03ec7fe48e057561f65ab009a84f6c20c86026ade7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 in 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 // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n return _functionCallWithValue(target, data, value, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\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 // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf5fa8cbdffa5ef8be49b246b5628facc30b71707e78a45d80d93b64eff3fe390\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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 */\\ncontract 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 () internal {\\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 make 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\",\"keccak256\":\"0x7ff0067f2d7df4187eaa1cb4800949b929602c9d9cb20fcaee6922a7613ef2fb\",\"license\":\"MIT\"},\"contracts/v1/interfaces/ILepton.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// ILepton.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Charged Particles Lepton Interface\\n * @dev ...\\n */\\ninterface ILepton {\\n\\n struct Classification {\\n string tokenUri;\\n uint256 price;\\n uint128 _upperBounds;\\n uint32 supply;\\n uint32 multiplier;\\n uint32 bonus;\\n }\\n\\n function mintLepton() external payable returns (uint256 newTokenId);\\n function batchMintLepton(uint256 count) external payable;\\n function getNextType() external view returns (uint256);\\n function getNextPrice() external view returns (uint256);\\n function getMultiplier(uint256 tokenId) external view returns (uint256);\\n function getBonus(uint256 tokenId) external view returns (uint256);\\n\\n\\n event MaxMintPerTxSet(uint256 maxAmount);\\n event LeptonTypeAdded(string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\\n event LeptonTypeUpdated(uint256 leptonIndex, string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\\n event LeptonMinted(address indexed receiver, uint256 indexed tokenId, uint256 price, uint32 multiplier);\\n event LeptonBatchMinted(address indexed receiver, uint256 indexed tokenId, uint256 count, uint256 price, uint32 multiplier);\\n event PausedStateSet(bool isPaused);\\n}\\n\",\"keccak256\":\"0x4903085427fa5dbee690fe79854fba60afaf21189957406ade55f6fc12556a01\",\"license\":\"MIT\"},\"contracts/v1/leptons/store.sol\":{\"content\":\"pragma solidity 0.6.12;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"../lib/BlackholePrevention.sol\\\";\\nimport \\\"../tokens/Ionx.sol\\\";\\nimport \\\"../tokens/Lepton2.sol\\\";\\n\\ninterface ILepsonsStore {\\n function getLeptonBalance() external view returns (uint256);\\n function getIonxBalance() external view returns (uint256);\\n function buyWithIonx(uint256 leptonAmount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\\n\\n function load(uint256 amount) external payable;\\n function setNextTokenId(uint256 tokenId) external;\\n function setLepton(address _lepton) external;\\n function setIonx(address _ionx) external;\\n function setIonxPerLepton(uint256 ionxAmount) external;\\n}\\n\\ncontract LeptonsStore is ILepsonsStore, IERC721Receiver, Ownable, BlackholePrevention {\\n using SafeMath for uint256;\\n\\n event SoldLepton(address indexed buyer, uint256 amount, uint256 price);\\n\\n Lepton2 public lepton;\\n Ionx public ionx;\\n\\n uint256 public nextTokenId;\\n uint256 public ionxPerLepton;\\n\\n constructor(address _lepton, address _ionx, uint256 _ionxPerLepton) public {\\n lepton = Lepton2(_lepton);\\n ionx = Ionx(_ionx);\\n ionxPerLepton = _ionxPerLepton;\\n }\\n\\n function getLeptonBalance() external view override returns (uint256) {\\n return lepton.balanceOf(address(this));\\n }\\n\\n function getIonxBalance() external view override returns (uint256) {\\n return ionx.balanceOf(address(this));\\n }\\n\\n function buyWithIonx(\\n uint256 leptonAmount,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external override {\\n uint256 ionxAmount = leptonAmount * ionxPerLepton;\\n require(ionx.balanceOf(msg.sender) >= ionxAmount, \\\"Insufficient IONX balance\\\");\\n require(lepton.balanceOf(address(this)) >= leptonAmount, \\\"Insufficient Lepton balance\\\");\\n\\n ionx.permit(msg.sender, address(this), ionxAmount, deadline, v, r, s);\\n ionx.transferFrom(msg.sender, address(this), ionxAmount);\\n\\n for (uint256 i = 0; i < leptonAmount; ++i) {\\n uint256 tokenId = nextTokenId;\\n nextTokenId = nextTokenId.add(1);\\n\\n lepton.safeTransferFrom(address(this), msg.sender, tokenId);\\n }\\n\\n emit SoldLepton(msg.sender, leptonAmount, ionxAmount);\\n }\\n\\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\\n return IERC721Receiver.onERC721Received.selector;\\n }\\n\\n /***********************************|\\n | Only Admin/DAO |\\n |__________________________________*/\\n\\n function load(uint256 amount) external payable override onlyOwner {\\n lepton.batchMintLepton{ value: msg.value }(amount);\\n }\\n\\n function setNextTokenId(uint256 tokenId) external override onlyOwner {\\n nextTokenId = (tokenId == 0) ? lepton.totalSupply().add(1) : tokenId;\\n }\\n\\n function setLepton(address _lepton) external override onlyOwner {\\n require(_lepton != address(0), \\\"Invalid address\\\");\\n lepton = Lepton2(_lepton);\\n }\\n\\n function setIonx(address _ionx) external override onlyOwner {\\n require(_ionx != address(0), \\\"Invalid address\\\");\\n ionx = Ionx(_ionx);\\n }\\n\\n function setIonxPerLepton(uint256 ionxAmount) external override onlyOwner {\\n ionxPerLepton = ionxAmount;\\n }\\n\\n /***********************************|\\n | Only Admin/DAO |\\n | (blackhole prevention) |\\n |__________________________________*/\\n\\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n}\",\"keccak256\":\"0x04d24263642b0f72ba7937dad9d7b6d5bda7e2139833e669a527eaaa6c324107\"},\"contracts/v1/lib/BlackholePrevention.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\\\";\\n\\n/**\\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\\n * the Owner/DAO to pull them out on behalf of a user\\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\\n */\\ncontract BlackholePrevention {\\n using Address for address payable;\\n using SafeERC20 for IERC20;\\n\\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\\n\\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (address(this).balance >= amount) {\\n receiver.sendValue(amount);\\n emit WithdrawStuckEther(receiver, amount);\\n }\\n }\\n\\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\\n IERC20(tokenAddress).safeTransfer(receiver, amount);\\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\\n }\\n }\\n\\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\\n }\\n }\\n\\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \\\"\\\");\\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6a664c8a1c1d7fb32ade2c11f75756b1fdb4c489daa32c1d58e6b867ea2ba8d6\",\"license\":\"MIT\"},\"contracts/v1/lib/ERC721Basic.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/GSN/Context.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/introspection/ERC165.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\n/**\\n * @title ERC721 Non-Fungible Token Standard basic implementation\\n * @dev see https://eips.ethereum.org/EIPS/eip-721\\n */\\ncontract ERC721Basic is Context, ERC165, IERC721, IERC721Metadata {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n // Equals to `bytes4(keccak256(\\\"onERC721Received(address,address,uint256,bytes)\\\"))`\\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\\n bytes4 internal constant _ERC721_RECEIVED = 0x150b7a02;\\n\\n // mapping from token ids to their owners\\n mapping (uint256 => address) internal _tokenOwners;\\n\\n // mapping from owner to token balance\\n mapping (address => uint256) internal _ownerBalance;\\n\\n // Mapping from token ID to approved address\\n mapping (uint256 => address) internal _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping (address => mapping (address => bool)) internal _operatorApprovals;\\n\\n // Token name\\n string internal _name;\\n\\n // Token symbol\\n string internal _symbol;\\n\\n // Token Count\\n uint256 internal _tokenCount;\\n\\n /*\\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\\n *\\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\\n */\\n bytes4 internal constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\\n\\n /*\\n * bytes4(keccak256('name()')) == 0x06fdde03\\n * bytes4(keccak256('symbol()')) == 0x95d89b41\\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\\n *\\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\\n */\\n bytes4 internal constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\\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) public {\\n _name = name;\\n _symbol = symbol;\\n\\n // register the supported interfaces to conform to ERC721 via ERC165\\n _registerInterface(_INTERFACE_ID_ERC721);\\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view override returns (uint256) {\\n require(owner != address(0), \\\"ERC721:E-403\\\");\\n return _ownerBalance[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view override returns (address) {\\n return _tokenOwners[tokenId];\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view 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 return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ownerOf(tokenId);\\n require(to != owner, \\\"ERC721:E-111\\\");\\n\\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \\\"ERC721:E-105\\\");\\n\\n _approve(to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-getApproved}.\\n */\\n function getApproved(uint256 tokenId) public view override returns (address) {\\n require(_exists(tokenId), \\\"ERC721:E-405\\\");\\n return _tokenApprovals[tokenId];\\n }\\n\\n /**\\n * @dev See {IERC721-setApprovalForAll}.\\n */\\n function setApprovalForAll(address operator, bool approved) public virtual override {\\n require(operator != _msgSender(), \\\"ERC721:E-111\\\");\\n\\n _operatorApprovals[_msgSender()][operator] = approved;\\n emit ApprovalForAll(_msgSender(), operator, approved);\\n }\\n\\n /**\\n * @dev See {IERC721-isApprovedForAll}.\\n */\\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\\n return _operatorApprovals[owner][operator];\\n }\\n\\n /**\\n * @dev See {IERC721-transferFrom}.\\n */\\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721:E-105\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721:E-105\\\");\\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\\n _transfer(from, to, tokenId);\\n require(_checkOnERC721Received(from, to, tokenId, _data), \\\"ERC721:E-402\\\");\\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 returns (bool) {\\n return _tokenOwners[tokenId] != address(0x0);\\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 returns (bool) {\\n require(_exists(tokenId), \\\"ERC721:E-405\\\");\\n address owner = ownerOf(tokenId);\\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\\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(address to, bytes memory _data) internal virtual returns (uint256) {\\n uint256 tokenId = _mint(to);\\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \\\"ERC721:E-402\\\");\\n return 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 _safeMintBatch(address to, uint256 count, bytes memory _data) internal virtual {\\n uint256 startTokenId = _mintBatch(to, count);\\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \\\"ERC721:E-402\\\");\\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) internal virtual returns (uint256) {\\n require(to != address(0), \\\"ERC721:E-403\\\");\\n\\n _tokenCount = _tokenCount.add(1);\\n uint256 tokenId = _tokenCount;\\n require(!_exists(tokenId), \\\"ERC721:E-407\\\");\\n\\n _tokenOwners[tokenId] = to;\\n _ownerBalance[to] = _ownerBalance[to].add(1);\\n\\n emit Transfer(address(0), to, tokenId);\\n return tokenId;\\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 _mintBatch(address to, uint256 count) internal virtual returns (uint256) {\\n require(to != address(0), \\\"ERC721:E-403\\\");\\n\\n uint256 startTokenId = _tokenCount.add(1);\\n for (uint i = 1; i <= count; i++) {\\n uint256 tokenId = _tokenCount.add(i);\\n _tokenOwners[tokenId] = to;\\n emit Transfer(address(0), to, tokenId);\\n }\\n\\n _tokenCount = _tokenCount.add(count);\\n _ownerBalance[to] = _ownerBalance[to].add(count);\\n return startTokenId;\\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(address from, address to, uint256 tokenId) internal virtual {\\n require(ownerOf(tokenId) == from, \\\"ERC721:E-102\\\");\\n require(to != address(0), \\\"ERC721:E-403\\\");\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _tokenOwners[tokenId] = to;\\n _ownerBalance[from] = _ownerBalance[from].sub(1);\\n _ownerBalance[to] = _ownerBalance[to].add(1);\\n\\n emit Transfer(from, to, tokenId);\\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(address from, address to, uint256 tokenId, bytes memory _data)\\n internal returns (bool)\\n {\\n if (!to.isContract()) {\\n return true;\\n }\\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\\n IERC721Receiver(to).onERC721Received.selector,\\n _msgSender(),\\n from,\\n tokenId,\\n _data\\n ), \\\"ERC721:E-402\\\");\\n bytes4 retval = abi.decode(returndata, (bytes4));\\n return (retval == _ERC721_RECEIVED);\\n }\\n\\n function _approve(address to, uint256 tokenId) internal {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ownerOf(tokenId), to, tokenId);\\n }\\n}\\n\",\"keccak256\":\"0x4b9f68ff101017027a7d963c7ab888d126c3e5f10fb5dd28daba08d49d9bd291\",\"license\":\"MIT\"},\"contracts/v1/tokens/Ionx.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// Ionx.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\n\\nimport \\\"erc20permit/contracts/ERC20Permit.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"../lib/BlackholePrevention.sol\\\";\\n\\n\\ncontract Ionx is ERC20Permit, Ownable, BlackholePrevention {\\n using SafeMath for uint256;\\n\\n /// @notice An event thats emitted when the minter address is changed\\n event MinterChanged(address minter, address newMinter);\\n\\n /// @notice Total number of tokens in circulation\\n uint256 constant public INITIAL_SUPPLY = 1e8 ether;\\n\\n /// @notice Minimum time between mints\\n uint32 public constant INFLATION_EPOCH = 1 days * 365;\\n\\n /// @notice Cap on the percentage of totalSupply that can be minted at each mint\\n uint8 public constant INFLATION_CAP = 2;\\n\\n /// @notice Address which may mint new tokens\\n address public minter;\\n\\n /// @notice The timestamp after which minting may occur\\n uint256 public mintingAllowedAfter;\\n\\n\\n constructor() public ERC20Permit(\\\"Charged Particles - IONX\\\", \\\"IONX\\\") {}\\n\\n\\n /**\\n * @notice Change the minter address\\n * @param newMinter The address of the new minter\\n */\\n function setMinter(address newMinter) external onlyOwner {\\n emit MinterChanged(minter, newMinter);\\n minter = newMinter;\\n }\\n\\n /**\\n * @notice Mint new tokens\\n * @param receiver The address of the destination account\\n * @param amount The number of tokens to be minted\\n */\\n function mint(address receiver, uint256 amount) external onlyMinter {\\n require(block.timestamp >= mintingAllowedAfter, \\\"Ionx:E-114\\\");\\n require(receiver != address(0), \\\"Ionx:E-403\\\");\\n\\n uint256 amountToMint = amount;\\n uint256 _totalSupply = totalSupply();\\n\\n // From Inflationary Supply\\n if (_totalSupply >= INITIAL_SUPPLY) {\\n mintingAllowedAfter = mintingAllowedAfter.add(INFLATION_EPOCH);\\n amountToMint = _totalSupply.mul(INFLATION_CAP).div(100);\\n }\\n\\n // From Initial Supply\\n else {\\n if (_totalSupply.add(amountToMint) > INITIAL_SUPPLY) {\\n amountToMint = INITIAL_SUPPLY.sub(_totalSupply);\\n }\\n if (_totalSupply.add(amountToMint) == INITIAL_SUPPLY) {\\n mintingAllowedAfter = block.timestamp.add(INFLATION_EPOCH);\\n }\\n }\\n\\n // transfer the amount to the recipient\\n _mint(receiver, amountToMint);\\n }\\n\\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n modifier onlyMinter() {\\n require(msg.sender == minter, \\\"Ionx:E-113\\\");\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x248e7f30883795c45e37a90aa8e7cd94cd09fb618122b09d83fd98d2d63fd37d\",\"license\":\"MIT\"},\"contracts/v1/tokens/Lepton2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// Lepton2.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\n\\nimport \\\"../lib/ERC721Basic.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/ReentrancyGuard.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\\\";\\n\\nimport \\\"../interfaces/ILepton.sol\\\";\\nimport \\\"../lib/BlackholePrevention.sol\\\";\\n\\ncontract Lepton2 is ILepton, ERC721Basic, Ownable, ReentrancyGuard, BlackholePrevention {\\n using SafeMath for uint256;\\n using Address for address payable;\\n\\n Classification[] internal _leptonTypes;\\n\\n uint256 internal _typeIndex;\\n uint256 internal _maxSupply;\\n uint256 internal _maxMintPerTx;\\n uint256 internal _migratedCount;\\n\\n bool internal _paused;\\n bool internal _migrationComplete;\\n\\n\\n /***********************************|\\n | Initialization |\\n |__________________________________*/\\n\\n constructor() public ERC721Basic(\\\"Charged Particles - Lepton2\\\", \\\"LEPTON2\\\") {\\n _paused = true;\\n _migrationComplete = false;\\n _migratedCount = 0;\\n }\\n\\n\\n /***********************************|\\n | Public |\\n |__________________________________*/\\n\\n function mintLepton() external payable override nonReentrant whenNotPaused returns (uint256 newTokenId) {\\n newTokenId = _mintLepton(msg.sender);\\n }\\n\\n function batchMintLepton(uint256 count) external payable override nonReentrant whenNotPaused {\\n _batchMintLepton(msg.sender, count);\\n }\\n\\n function totalSupply() public view returns (uint256) {\\n return _tokenCount;\\n }\\n\\n function maxSupply() external view returns (uint256) {\\n return _maxSupply;\\n }\\n\\n function getNextType() external view override returns (uint256) {\\n if (_typeIndex >= _leptonTypes.length) { return 0; }\\n return _typeIndex;\\n }\\n\\n function getNextPrice() external view override returns (uint256) {\\n if (_typeIndex >= _leptonTypes.length) { return 0; }\\n return _leptonTypes[_typeIndex].price;\\n }\\n\\n function getMultiplier(uint256 tokenId) external view override returns (uint256) {\\n require(_exists(tokenId), \\\"LPT:E-405\\\");\\n return _getLepton(tokenId).multiplier;\\n }\\n\\n function getBonus(uint256 tokenId) external view override returns (uint256) {\\n require(_exists(tokenId), \\\"LPT:E-405\\\");\\n return _getLepton(tokenId).bonus;\\n }\\n\\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\\n require(_exists(tokenId), \\\"LPT:E-405\\\");\\n return _getLepton(tokenId).tokenUri;\\n }\\n\\n /***********************************|\\n | Only Admin/DAO |\\n |__________________________________*/\\n\\n function addLeptonType(\\n string calldata tokenUri,\\n uint256 price,\\n uint32 supply,\\n uint32 multiplier,\\n uint32 bonus\\n )\\n external\\n onlyOwner\\n {\\n _maxSupply = _maxSupply.add(uint256(supply));\\n\\n Classification memory lepton = Classification({\\n tokenUri: tokenUri,\\n price: price,\\n supply: supply,\\n multiplier: multiplier,\\n bonus: bonus,\\n _upperBounds: uint128(_maxSupply)\\n });\\n _leptonTypes.push(lepton);\\n\\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\\n }\\n\\n function updateLeptonType(\\n uint256 leptonIndex,\\n string calldata tokenUri,\\n uint256 price,\\n uint32 supply,\\n uint32 multiplier,\\n uint32 bonus\\n )\\n external\\n onlyOwner\\n {\\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\\n _leptonTypes[leptonIndex].price = price;\\n _leptonTypes[leptonIndex].supply = supply;\\n _leptonTypes[leptonIndex].multiplier = multiplier;\\n _leptonTypes[leptonIndex].bonus = bonus;\\n\\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\\n }\\n\\n function setMaxMintPerTx(uint256 maxAmount) external onlyOwner {\\n _maxMintPerTx = maxAmount;\\n emit MaxMintPerTxSet(maxAmount);\\n }\\n\\n function setPausedState(bool state) external onlyOwner {\\n _paused = state;\\n emit PausedStateSet(state);\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n | (blackhole prevention) |\\n |__________________________________*/\\n\\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n function migrateAccounts(address oldLeptonContract, uint256 count) external onlyOwner whenNotMigrated {\\n uint256 oldSupply = IERC721Enumerable(oldLeptonContract).totalSupply();\\n require(oldSupply == 0 || oldSupply > _migratedCount, \\\"LPT:E-004\\\");\\n\\n if (oldSupply > 0) {\\n uint256 endTokenId = _migratedCount.add(count);\\n if (endTokenId > oldSupply) {\\n count = count.sub(endTokenId.sub(oldSupply));\\n }\\n\\n for (uint256 i = 1; i <= count; i++) {\\n uint256 tokenId = _migratedCount.add(i);\\n address tokenOwner = IERC721(oldLeptonContract).ownerOf(tokenId);\\n _mint(tokenOwner);\\n }\\n _migratedCount = _migratedCount.add(count);\\n }\\n\\n if (oldSupply == _migratedCount) {\\n _finalizeMigration();\\n }\\n }\\n\\n /***********************************|\\n | Private Functions |\\n |__________________________________*/\\n\\n function _getLepton(uint256 tokenId) internal view returns (Classification memory) {\\n uint256 types = _leptonTypes.length;\\n for (uint256 i = 0; i < types; i++) {\\n Classification memory lepton = _leptonTypes[i];\\n if (tokenId <= lepton._upperBounds) {\\n return lepton;\\n }\\n }\\n }\\n\\n function _mintLepton(address receiver) internal returns (uint256 newTokenId) {\\n require(_typeIndex < _leptonTypes.length, \\\"LPT:E-408\\\");\\n\\n Classification memory lepton = _leptonTypes[_typeIndex];\\n require(msg.value >= lepton.price, \\\"LPT:E-414\\\");\\n\\n newTokenId = _safeMint(receiver, \\\"\\\");\\n\\n // Determine Next Type\\n if (newTokenId == lepton._upperBounds) {\\n _typeIndex = _typeIndex.add(1);\\n }\\n\\n _refundOverpayment(lepton.price);\\n }\\n\\n function _batchMintLepton(address receiver, uint256 count) internal {\\n require(_typeIndex < _leptonTypes.length, \\\"LPT:E-408\\\");\\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \\\"LPT:E-429\\\");\\n\\n Classification memory lepton = _leptonTypes[_typeIndex];\\n\\n uint256 endTokenId = _tokenCount.add(count);\\n if (endTokenId > lepton._upperBounds) {\\n count = count.sub(endTokenId.sub(lepton._upperBounds));\\n }\\n\\n uint256 salePrice = lepton.price.mul(count);\\n require(msg.value >= salePrice, \\\"LPT:E-414\\\");\\n\\n _safeMintBatch(receiver, count, \\\"\\\");\\n\\n // Determine Next Type\\n if (endTokenId >= lepton._upperBounds) {\\n _typeIndex = _typeIndex.add(1);\\n }\\n\\n _refundOverpayment(salePrice);\\n }\\n\\n function _refundOverpayment(uint256 threshold) internal {\\n uint256 overage = msg.value.sub(threshold);\\n if (overage > 0) {\\n payable(_msgSender()).sendValue(overage);\\n }\\n }\\n\\n function _finalizeMigration() internal {\\n // Determine Next Type\\n _typeIndex = 0;\\n for (uint256 i = 0; i < _leptonTypes.length; i++) {\\n Classification memory lepton = _leptonTypes[i];\\n if (_migratedCount >= lepton._upperBounds) {\\n _typeIndex = i + 1;\\n }\\n }\\n _migrationComplete = true;\\n }\\n\\n\\n /***********************************|\\n | Modifiers |\\n |__________________________________*/\\n\\n modifier whenNotMigrated() {\\n require(!_migrationComplete, \\\"LPT:E-004\\\");\\n _;\\n }\\n\\n modifier whenNotPaused() {\\n require(!_paused, \\\"LPT:E-101\\\");\\n _;\\n }\\n}\",\"keccak256\":\"0x308d33f8e4c5dbc7fa986fd93e3f760f8f81c14e0915af9ba9ab9cd5509fae6d\",\"license\":\"MIT\"},\"erc20permit/contracts/ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\\npragma solidity ^0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"./IERC2612.sol\\\";\\n\\n/**\\n * @author Georgios Konstantopoulos\\n * @dev Extension of {ERC20} that allows token holders to use their tokens\\n * without sending any transactions by setting {IERC20-allowance} with a\\n * signature using the {permit} method, and then spend them via\\n * {IERC20-transferFrom}.\\n *\\n * The {permit} signature mechanism conforms to the {IERC2612} interface.\\n */\\nabstract contract ERC20Permit is ERC20, IERC2612 {\\n mapping (address => uint256) public override nonces;\\n\\n bytes32 public immutable PERMIT_TYPEHASH = keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n bytes32 public immutable DOMAIN_SEPARATOR;\\n\\n constructor(string memory name_, string memory symbol_) internal ERC20(name_, symbol_) {\\n uint256 chainId;\\n assembly {\\n chainId := chainid()\\n }\\n\\n DOMAIN_SEPARATOR = keccak256(\\n abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"),\\n keccak256(bytes(name_)),\\n keccak256(bytes(\\\"1\\\")),\\n chainId,\\n address(this)\\n )\\n );\\n }\\n\\n /**\\n * @dev See {IERC2612-permit}.\\n *\\n * In cases where the free option is not a concern, deadline can simply be\\n * set to uint(-1), so it should be seen as an optional parameter\\n */\\n function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {\\n require(deadline >= block.timestamp, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 hashStruct = keccak256(\\n abi.encode(\\n PERMIT_TYPEHASH,\\n owner,\\n spender,\\n amount,\\n nonces[owner]++,\\n deadline\\n )\\n );\\n\\n bytes32 hash = keccak256(\\n abi.encodePacked(\\n '\\\\x19\\\\x01',\\n DOMAIN_SEPARATOR,\\n hashStruct\\n )\\n );\\n\\n address signer = ecrecover(hash, v, r, s);\\n require(\\n signer != address(0) && signer == owner,\\n \\\"ERC20Permit: invalid signature\\\"\\n );\\n\\n _approve(owner, spender, amount);\\n }\\n}\\n\",\"keccak256\":\"0x2207175c262cdffe2f4e0a31d0c35e02a0ebf2528f21009be6b7743eeb474eaa\",\"license\":\"GPL-3.0-or-later\"},\"erc20permit/contracts/IERC2612.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n// Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Interface of the ERC2612 standard as defined in the EIP.\\n *\\n * Adds the {permit} method, which can be used to change one's\\n * {IERC20-allowance} without having to send a transaction, by signing a\\n * message. This allows users to spend tokens without having to hold Ether.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2612.\\n */\\ninterface IERC2612 {\\n /**\\n * @dev Sets `amount` 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 * - `owner` cannot be the zero address.\\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(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\\n\\n /**\\n * @dev Returns the current ERC2612 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\",\"keccak256\":\"0xe79dd739aaa881172ede4d81472ded9db3a0b4183573c0c01541b4084033b222\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50604051611b40380380611b408339818101604052606081101561003357600080fd5b5080516020820151604090920151909190600061004e6100d0565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600180546001600160a01b039485166001600160a01b03199182161790915560028054939094169216919091179091556004556100d4565b3390565b611a5d806100e36000396000f3fe60806040526004361061011f5760003560e01c80638da5cb5b116100a0578063c29ccc1511610064578063c29ccc1514610438578063d2a126731461044d578063e27e1b0814610492578063efeab4ab146104c5578063f2fde38b146104da5761011f565b80638da5cb5b1461036057806399d548aa146103755780639a20f66514610392578063a0edb48b146103bc578063b8d820f8146104055761011f565b80635a362235116100e75780635a362235146102c6578063715018a6146102db57806375794a3c146102f05780637d0e13a51461030557806383e3500f146103365761011f565b8063150b7a02146101245780631593dee1146101de5780634025feb2146102235780634cf65a4814610266578063522f68151461028d575b600080fd5b34801561013057600080fd5b506101c16004803603608081101561014757600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561018257600080fd5b82018360208201111561019457600080fd5b803590602001918460018302840111640100000000831117156101b657600080fd5b50909250905061050d565b604080516001600160e01b03199092168252519081900360200190f35b3480156101ea57600080fd5b506102216004803603606081101561020157600080fd5b506001600160a01b0381358116916020810135909116906040013561051e565b005b34801561022f57600080fd5b506102216004803603606081101561024657600080fd5b506001600160a01b03813581169160208101359091169060400135610586565b34801561027257600080fd5b5061027b6105e9565b60408051918252519081900360200190f35b34801561029957600080fd5b50610221600480360360408110156102b057600080fd5b506001600160a01b0381351690602001356105ef565b3480156102d257600080fd5b5061027b610655565b3480156102e757600080fd5b506102216106d1565b3480156102fc57600080fd5b5061027b610773565b34801561031157600080fd5b5061031a610779565b604080516001600160a01b039092168252519081900360200190f35b34801561034257600080fd5b506102216004803603602081101561035957600080fd5b5035610788565b34801561036c57600080fd5b5061031a61086c565b6102216004803603602081101561038b57600080fd5b503561087b565b34801561039e57600080fd5b50610221600480360360208110156103b557600080fd5b503561093d565b3480156103c857600080fd5b50610221600480360360808110156103df57600080fd5b506001600160a01b0381358116916020810135909116906040810135906060013561099a565b34801561041157600080fd5b506102216004803603602081101561042857600080fd5b50356001600160a01b0316610a04565b34801561044457600080fd5b5061027b610acb565b34801561045957600080fd5b50610221600480360360a081101561047057600080fd5b5080359060208101359060ff6040820135169060608101359060800135610b16565b34801561049e57600080fd5b50610221600480360360208110156104b557600080fd5b50356001600160a01b0316610ea6565b3480156104d157600080fd5b5061031a610f6d565b3480156104e657600080fd5b50610221600480360360208110156104fd57600080fd5b50356001600160a01b0316610f7c565b630a85bd0160e11b95945050505050565b610526611074565b6000546001600160a01b03908116911614610576576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b610581838383611078565b505050565b61058e611074565b6000546001600160a01b039081169116146105de576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b6105818383836111a2565b60045481565b6105f7611074565b6000546001600160a01b03908116911614610647576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b6106518282611328565b5050565b600154604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156106a057600080fd5b505afa1580156106b4573d6000803e3d6000fd5b505050506040513d60208110156106ca57600080fd5b5051905090565b6106d9611074565b6000546001600160a01b03908116911614610729576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60035481565b6001546001600160a01b031681565b610790611074565b6000546001600160a01b039081169116146107e0576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b80156107ec5780610866565b60018054604080516318160ddd60e01b8152905161086693926001600160a01b0316916318160ddd916004808301926020929190829003018186803b15801561083457600080fd5b505afa158015610848573d6000803e3d6000fd5b505050506040513d602081101561085e57600080fd5b5051906113cb565b60035550565b6000546001600160a01b031690565b610883611074565b6000546001600160a01b039081169116146108d3576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b60015460408051630afd902b60e01b81526004810184905290516001600160a01b0390921691630afd902b913491602480830192600092919082900301818588803b15801561092157600080fd5b505af1158015610935573d6000803e3d6000fd5b505050505050565b610945611074565b6000546001600160a01b03908116911614610995576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b600455565b6109a2611074565b6000546001600160a01b039081169116146109f2576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b6109fe8484848461142c565b50505050565b610a0c611074565b6000546001600160a01b03908116911614610a5c576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b6001600160a01b038116610aa9576040805162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b600254604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156106a057600080fd5b60048054600254604080516370a0823160e01b81523394810194909452519188029283926001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015610b6c57600080fd5b505afa158015610b80573d6000803e3d6000fd5b505050506040513d6020811015610b9657600080fd5b50511015610beb576040805162461bcd60e51b815260206004820152601960248201527f496e73756666696369656e7420494f4e582062616c616e636500000000000000604482015290519081900360640190fd5b600154604080516370a0823160e01b8152306004820152905188926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015610c3557600080fd5b505afa158015610c49573d6000803e3d6000fd5b505050506040513d6020811015610c5f57600080fd5b50511015610cb4576040805162461bcd60e51b815260206004820152601b60248201527f496e73756666696369656e74204c6570746f6e2062616c616e63650000000000604482015290519081900360640190fd5b6002546040805163d505accf60e01b8152336004820152306024820152604481018490526064810188905260ff8716608482015260a4810186905260c4810185905290516001600160a01b039092169163d505accf9160e48082019260009290919082900301818387803b158015610d2b57600080fd5b505af1158015610d3f573d6000803e3d6000fd5b5050600254604080516323b872dd60e01b81523360048201523060248201526044810186905290516001600160a01b0390921693506323b872dd92506064808201926020929091908290030181600087803b158015610d9d57600080fd5b505af1158015610db1573d6000803e3d6000fd5b505050506040513d6020811015610dc757600080fd5b50600090505b86811015610e6357600354610de38160016113cb565b60035560015460408051632142170760e11b81523060048201523360248201526044810184905290516001600160a01b03909216916342842e0e9160648082019260009290919082900301818387803b158015610e3f57600080fd5b505af1158015610e53573d6000803e3d6000fd5b5050505050806001019050610dcd565b506040805187815260208101839052815133927f56d4a3892345beae7b80a9cb4d571ef4929baf938bc67960aa0f17606a934bc0928290030190a2505050505050565b610eae611074565b6000546001600160a01b03908116911614610efe576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b6001600160a01b038116610f4b576040805162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015290519081900360640190fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031681565b610f84611074565b6000546001600160a01b03908116911614610fd4576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b6001600160a01b0381166110195760405162461bcd60e51b815260040180806020018281038252602681526020018061197e6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b0383166110bf576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b80826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561110d57600080fd5b505afa158015611121573d6000803e3d6000fd5b505050506040513d602081101561113757600080fd5b505110610581576111526001600160a01b03831684836115cd565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b836040518082815260200191505060405180910390a3505050565b6001600160a01b0383166111e9576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b306001600160a01b0316826001600160a01b0316636352211e836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561123757600080fd5b505afa15801561124b573d6000803e3d6000fd5b505050506040513d602081101561126157600080fd5b50516001600160a01b0316141561058157604080516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018490529151918416916323b872dd9160648082019260009290919082900301818387803b1580156112ca57600080fd5b505af11580156112de573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b03821661136f576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b804710610651576113896001600160a01b0383168261161f565b6040805182815290516001600160a01b038416917eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd919081900360200190a25050565b600082820183811015611425576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038416611473576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b80836001600160a01b031662fdd58e30856040518363ffffffff1660e01b815260040180836001600160a01b031681526020018281526020019250505060206040518083038186803b1580156114c857600080fd5b505afa1580156114dc573d6000803e3d6000fd5b505050506040513d60208110156114f257600080fd5b5051106109fe5760408051637921219560e11b81523060048201526001600160a01b038681166024830152604482018590526064820184905260a06084830152600060a4830181905292519086169263f242432a9260e4808201939182900301818387803b15801561156357600080fd5b505af1158015611577573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b846040518082815260200191505060405180910390a450505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610581908490611704565b80471015611674576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015290519081900360640190fd5b6040516000906001600160a01b0384169083908381818185875af1925050503d80600081146116bf576040519150601f19603f3d011682016040523d82523d6000602084013e6116c4565b606091505b50509050806105815760405162461bcd60e51b815260040180806020018281038252603a8152602001806119a4603a913960400191505060405180910390fd5b6060611759826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166117b59092919063ffffffff16565b8051909150156105815780806020019051602081101561177857600080fd5b50516105815760405162461bcd60e51b815260040180806020018281038252602a8152602001806119fe602a913960400191505060405180910390fd5b60606117c484846000856117cc565b949350505050565b60606117d785611977565b611828576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106118675780518252601f199092019160209182019101611848565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146118c9576040519150601f19603f3d011682016040523d82523d6000602084013e6118ce565b606091505b509150915081156118e25791506117c49050565b8051156118f25780518082602001fd5b8360405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561193c578181015183820152602001611924565b50505050905090810190601f1680156119695780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b3b15159056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373416464726573733a20756e61626c6520746f2073656e642076616c75652c20726563697069656e74206d617920686176652072657665727465644f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a264697066735822122052c6f5dca3cb93f92d58411ee76c0d6fd159b06b263d0ec3fbf23b02e261cb1a64736f6c634300060c0033", + "deployedBytecode": "0x60806040526004361061011f5760003560e01c80638da5cb5b116100a0578063c29ccc1511610064578063c29ccc1514610438578063d2a126731461044d578063e27e1b0814610492578063efeab4ab146104c5578063f2fde38b146104da5761011f565b80638da5cb5b1461036057806399d548aa146103755780639a20f66514610392578063a0edb48b146103bc578063b8d820f8146104055761011f565b80635a362235116100e75780635a362235146102c6578063715018a6146102db57806375794a3c146102f05780637d0e13a51461030557806383e3500f146103365761011f565b8063150b7a02146101245780631593dee1146101de5780634025feb2146102235780634cf65a4814610266578063522f68151461028d575b600080fd5b34801561013057600080fd5b506101c16004803603608081101561014757600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561018257600080fd5b82018360208201111561019457600080fd5b803590602001918460018302840111640100000000831117156101b657600080fd5b50909250905061050d565b604080516001600160e01b03199092168252519081900360200190f35b3480156101ea57600080fd5b506102216004803603606081101561020157600080fd5b506001600160a01b0381358116916020810135909116906040013561051e565b005b34801561022f57600080fd5b506102216004803603606081101561024657600080fd5b506001600160a01b03813581169160208101359091169060400135610586565b34801561027257600080fd5b5061027b6105e9565b60408051918252519081900360200190f35b34801561029957600080fd5b50610221600480360360408110156102b057600080fd5b506001600160a01b0381351690602001356105ef565b3480156102d257600080fd5b5061027b610655565b3480156102e757600080fd5b506102216106d1565b3480156102fc57600080fd5b5061027b610773565b34801561031157600080fd5b5061031a610779565b604080516001600160a01b039092168252519081900360200190f35b34801561034257600080fd5b506102216004803603602081101561035957600080fd5b5035610788565b34801561036c57600080fd5b5061031a61086c565b6102216004803603602081101561038b57600080fd5b503561087b565b34801561039e57600080fd5b50610221600480360360208110156103b557600080fd5b503561093d565b3480156103c857600080fd5b50610221600480360360808110156103df57600080fd5b506001600160a01b0381358116916020810135909116906040810135906060013561099a565b34801561041157600080fd5b506102216004803603602081101561042857600080fd5b50356001600160a01b0316610a04565b34801561044457600080fd5b5061027b610acb565b34801561045957600080fd5b50610221600480360360a081101561047057600080fd5b5080359060208101359060ff6040820135169060608101359060800135610b16565b34801561049e57600080fd5b50610221600480360360208110156104b557600080fd5b50356001600160a01b0316610ea6565b3480156104d157600080fd5b5061031a610f6d565b3480156104e657600080fd5b50610221600480360360208110156104fd57600080fd5b50356001600160a01b0316610f7c565b630a85bd0160e11b95945050505050565b610526611074565b6000546001600160a01b03908116911614610576576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b610581838383611078565b505050565b61058e611074565b6000546001600160a01b039081169116146105de576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b6105818383836111a2565b60045481565b6105f7611074565b6000546001600160a01b03908116911614610647576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b6106518282611328565b5050565b600154604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156106a057600080fd5b505afa1580156106b4573d6000803e3d6000fd5b505050506040513d60208110156106ca57600080fd5b5051905090565b6106d9611074565b6000546001600160a01b03908116911614610729576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60035481565b6001546001600160a01b031681565b610790611074565b6000546001600160a01b039081169116146107e0576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b80156107ec5780610866565b60018054604080516318160ddd60e01b8152905161086693926001600160a01b0316916318160ddd916004808301926020929190829003018186803b15801561083457600080fd5b505afa158015610848573d6000803e3d6000fd5b505050506040513d602081101561085e57600080fd5b5051906113cb565b60035550565b6000546001600160a01b031690565b610883611074565b6000546001600160a01b039081169116146108d3576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b60015460408051630afd902b60e01b81526004810184905290516001600160a01b0390921691630afd902b913491602480830192600092919082900301818588803b15801561092157600080fd5b505af1158015610935573d6000803e3d6000fd5b505050505050565b610945611074565b6000546001600160a01b03908116911614610995576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b600455565b6109a2611074565b6000546001600160a01b039081169116146109f2576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b6109fe8484848461142c565b50505050565b610a0c611074565b6000546001600160a01b03908116911614610a5c576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b6001600160a01b038116610aa9576040805162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b600254604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156106a057600080fd5b60048054600254604080516370a0823160e01b81523394810194909452519188029283926001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015610b6c57600080fd5b505afa158015610b80573d6000803e3d6000fd5b505050506040513d6020811015610b9657600080fd5b50511015610beb576040805162461bcd60e51b815260206004820152601960248201527f496e73756666696369656e7420494f4e582062616c616e636500000000000000604482015290519081900360640190fd5b600154604080516370a0823160e01b8152306004820152905188926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015610c3557600080fd5b505afa158015610c49573d6000803e3d6000fd5b505050506040513d6020811015610c5f57600080fd5b50511015610cb4576040805162461bcd60e51b815260206004820152601b60248201527f496e73756666696369656e74204c6570746f6e2062616c616e63650000000000604482015290519081900360640190fd5b6002546040805163d505accf60e01b8152336004820152306024820152604481018490526064810188905260ff8716608482015260a4810186905260c4810185905290516001600160a01b039092169163d505accf9160e48082019260009290919082900301818387803b158015610d2b57600080fd5b505af1158015610d3f573d6000803e3d6000fd5b5050600254604080516323b872dd60e01b81523360048201523060248201526044810186905290516001600160a01b0390921693506323b872dd92506064808201926020929091908290030181600087803b158015610d9d57600080fd5b505af1158015610db1573d6000803e3d6000fd5b505050506040513d6020811015610dc757600080fd5b50600090505b86811015610e6357600354610de38160016113cb565b60035560015460408051632142170760e11b81523060048201523360248201526044810184905290516001600160a01b03909216916342842e0e9160648082019260009290919082900301818387803b158015610e3f57600080fd5b505af1158015610e53573d6000803e3d6000fd5b5050505050806001019050610dcd565b506040805187815260208101839052815133927f56d4a3892345beae7b80a9cb4d571ef4929baf938bc67960aa0f17606a934bc0928290030190a2505050505050565b610eae611074565b6000546001600160a01b03908116911614610efe576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b6001600160a01b038116610f4b576040805162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015290519081900360640190fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031681565b610f84611074565b6000546001600160a01b03908116911614610fd4576040805162461bcd60e51b815260206004820181905260248201526000805160206119de833981519152604482015290519081900360640190fd5b6001600160a01b0381166110195760405162461bcd60e51b815260040180806020018281038252602681526020018061197e6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b0383166110bf576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b80826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561110d57600080fd5b505afa158015611121573d6000803e3d6000fd5b505050506040513d602081101561113757600080fd5b505110610581576111526001600160a01b03831684836115cd565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b836040518082815260200191505060405180910390a3505050565b6001600160a01b0383166111e9576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b306001600160a01b0316826001600160a01b0316636352211e836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561123757600080fd5b505afa15801561124b573d6000803e3d6000fd5b505050506040513d602081101561126157600080fd5b50516001600160a01b0316141561058157604080516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018490529151918416916323b872dd9160648082019260009290919082900301818387803b1580156112ca57600080fd5b505af11580156112de573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b03821661136f576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b804710610651576113896001600160a01b0383168261161f565b6040805182815290516001600160a01b038416917eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd919081900360200190a25050565b600082820183811015611425576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038416611473576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b80836001600160a01b031662fdd58e30856040518363ffffffff1660e01b815260040180836001600160a01b031681526020018281526020019250505060206040518083038186803b1580156114c857600080fd5b505afa1580156114dc573d6000803e3d6000fd5b505050506040513d60208110156114f257600080fd5b5051106109fe5760408051637921219560e11b81523060048201526001600160a01b038681166024830152604482018590526064820184905260a06084830152600060a4830181905292519086169263f242432a9260e4808201939182900301818387803b15801561156357600080fd5b505af1158015611577573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b846040518082815260200191505060405180910390a450505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610581908490611704565b80471015611674576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015290519081900360640190fd5b6040516000906001600160a01b0384169083908381818185875af1925050503d80600081146116bf576040519150601f19603f3d011682016040523d82523d6000602084013e6116c4565b606091505b50509050806105815760405162461bcd60e51b815260040180806020018281038252603a8152602001806119a4603a913960400191505060405180910390fd5b6060611759826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166117b59092919063ffffffff16565b8051909150156105815780806020019051602081101561177857600080fd5b50516105815760405162461bcd60e51b815260040180806020018281038252602a8152602001806119fe602a913960400191505060405180910390fd5b60606117c484846000856117cc565b949350505050565b60606117d785611977565b611828576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106118675780518252601f199092019160209182019101611848565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146118c9576040519150601f19603f3d011682016040523d82523d6000602084013e6118ce565b606091505b509150915081156118e25791506117c49050565b8051156118f25780518082602001fd5b8360405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561193c578181015183820152602001611924565b50505050905090810190601f1680156119695780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b3b15159056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373416464726573733a20756e61626c6520746f2073656e642076616c75652c20726563697069656e74206d617920686176652072657665727465644f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a264697066735822122052c6f5dca3cb93f92d58411ee76c0d6fd159b06b263d0ec3fbf23b02e261cb1a64736f6c634300060c0033", + "devdoc": { + "kind": "dev", + "methods": { + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 4406, + "contract": "contracts/v1/leptons/store.sol:LeptonsStore", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 30802, + "contract": "contracts/v1/leptons/store.sol:LeptonsStore", + "label": "lepton", + "offset": 0, + "slot": "1", + "type": "t_contract(Lepton2)38485" + }, + { + "astId": 30804, + "contract": "contracts/v1/leptons/store.sol:LeptonsStore", + "label": "ionx", + "offset": 0, + "slot": "2", + "type": "t_contract(Ionx)37047" + }, + { + "astId": 30806, + "contract": "contracts/v1/leptons/store.sol:LeptonsStore", + "label": "nextTokenId", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 30808, + "contract": "contracts/v1/leptons/store.sol:LeptonsStore", + "label": "ionxPerLepton", + "offset": 0, + "slot": "4", + "type": "t_uint256" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_contract(Ionx)37047": { + "encoding": "inplace", + "label": "contract Ionx", + "numberOfBytes": "20" + }, + "t_contract(Lepton2)38485": { + "encoding": "inplace", + "label": "contract Lepton2", + "numberOfBytes": "20" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/deployments/mainnet/RewardProgramDAI.json b/deployments/mainnet/RewardProgramDAI.json new file mode 100644 index 0000000..f02f785 --- /dev/null +++ b/deployments/mainnet/RewardProgramDAI.json @@ -0,0 +1,814 @@ +{ + "address": "0xf85695Cab8842eb283E5d85b5210e995537f0fA5", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "AssetDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "AssetRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "AssetRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardProgramFunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "RewardProgramOutOfFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewarded", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remaining", + "type": "uint256" + } + ], + "name": "RewardsClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "parentNftUuid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "calculateRewardsEarned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "fundProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "parentNftUuid", + "type": "uint256" + } + ], + "name": "getAssetStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimableRewards", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + } + ], + "internalType": "struct IRewardProgram.AssetStake", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getClaimableRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFundBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProgramData", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + } + ], + "internalType": "struct IRewardProgram.ProgramRewardData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + }, + { + "internalType": "address", + "name": "chargedManagers", + "type": "address" + }, + { + "internalType": "address", + "name": "universe", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "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": "nonpayable", + "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": "nonpayable", + "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": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "registerAssetDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "registerAssetRelease", + "outputs": [ + { + "internalType": "uint256", + "name": "rewards", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + } + ], + "name": "registerExistingDeposits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newMultiplier", + "type": "uint256" + } + ], + "name": "setBaseMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "setChargedManagers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newRewardToken", + "type": "address" + } + ], + "name": "setRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newStakingToken", + "type": "address" + } + ], + "name": "setStakingToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "universe", + "type": "address" + } + ], + "name": "setUniverse", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xc352e40af8bca5bc88cad535f5a0a9df8283eb3b5154704deb1ce5a00bde503e", + "numDeployments": 1 +} \ No newline at end of file diff --git a/deployments/mainnet/RewardProgramFactory.json b/deployments/mainnet/RewardProgramFactory.json new file mode 100644 index 0000000..ab614fd --- /dev/null +++ b/deployments/mainnet/RewardProgramFactory.json @@ -0,0 +1,403 @@ +{ + "address": "0x696a1b75a93fE7f28CFaE616cCd391690acE7c3d", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "rewardProgram", + "type": "address" + } + ], + "name": "RewardProgramCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [], + "name": "_template", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + }, + { + "internalType": "address", + "name": "chargedManagers", + "type": "address" + }, + { + "internalType": "address", + "name": "universe", + "type": "address" + } + ], + "name": "createRewardProgram", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xd6e3dfc8ba873940b4c5250f1df35260ab5882f3f2f08e8f739202273f02f861", + "receipt": { + "to": null, + "from": "0xb8D175F16742395F530e0b3bC1d30BD06B78CdA9", + "contractAddress": "0x696a1b75a93fE7f28CFaE616cCd391690acE7c3d", + "transactionIndex": 77, + "gasUsed": "3261080", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000400001000000000000000000000000000000000000020008000000000000000800000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000010000000000000000000002000000", + "blockHash": "0x5aee80ffe669e67df2dfb3381efe9c8ca672d5e92c43342fd8e850262c15b6f2", + "transactionHash": "0xd6e3dfc8ba873940b4c5250f1df35260ab5882f3f2f08e8f739202273f02f861", + "logs": [ + { + "transactionIndex": 77, + "blockNumber": 18063736, + "transactionHash": "0xd6e3dfc8ba873940b4c5250f1df35260ab5882f3f2f08e8f739202273f02f861", + "address": "0x696a1b75a93fE7f28CFaE616cCd391690acE7c3d", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000b8d175f16742395f530e0b3bc1d30bd06b78cda9" + ], + "data": "0x", + "logIndex": 223, + "blockHash": "0x5aee80ffe669e67df2dfb3381efe9c8ca672d5e92c43342fd8e850262c15b6f2" + } + ], + "blockNumber": 18063736, + "cumulativeGasUsed": "10655284", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "39876b9d6995fafd8c4442fb1a03f418", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"rewardProgram\",\"type\":\"address\"}],\"name\":\"RewardProgramCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC1155\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckEther\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"_template\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"stakingToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rewardToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"baseMultiplier\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"chargedManagers\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"universe\",\"type\":\"address\"}],\"name\":\"createRewardProgram\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC1155\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawErc20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawEther\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/v1/incentives/RewardProgramFactory.sol\":\"RewardProgramFactory\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <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\",\"keccak256\":\"0x4784c3f8a520a739dd25d76f514833a653990902d0e21601aed45bda44c87524\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0xa1931c47a617014f858580db625aa0dcf343796f39acd4b5b51effc092a1f0a9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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 GSN 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 payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xdb26cbf4d028490f49831a7865c2fe1b28db44b535ca8d343785a3b768aae183\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"../GSN/Context.sol\\\";\\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 */\\ncontract 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 () internal {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view 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 emit OwnershipTransferred(_owner, address(0));\\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x4bd6402ca6b3419008c2b482aff54e66836e8cb4eba2680e42ac5884ae6424fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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\",\"keccak256\":\"0xfa152b6e88a1dc50780e8f1580426dc23ad2e1e2c2f086a088adf206a202f453\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\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 uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\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 sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\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 * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\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 // 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) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts 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 mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9a9cf02622cd7a64261b10534fc3260449da25c98c9e96d1b4ae8110a20e5806\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x31691ad0817f8cb338531b78d2ab2989027d9f27e6f8e62492b754fed9429b10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"../../introspection/IERC165.sol\\\";\\n\\n/**\\n * _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n\\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 )\\n external\\n 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 )\\n external\\n returns(bytes4);\\n}\\n\",\"keccak256\":\"0x0bc1d0b8fa3b262a6fb98b88dceab8b3348903b95dcc5909b9074fb19a3d2da5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0x5c26b39d26f7ed489e555d955dcd3e01872972e71fdd1528e93ec164e4f23385\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.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 SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf3b30f8a49631420635a8c35daacfcaa338012755f18a76fdd118730256f9a27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0xaf936da92f3a9a4f98b237323b5eb1d813fb86c4d07a184beba7027cf0509ba3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 /**\\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\",\"keccak256\":\"0x3636662804cd8f474536b2875a9038a4c3fb91879f1bbff48af5c3f140fcd2f0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address operator, address from, uint256 tokenId, bytes calldata data)\\n external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x321ee37ef4925020aa818a03ec7fe48e057561f65ab009a84f6c20c86026ade7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 in 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 // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n return _functionCallWithValue(target, data, value, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\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 // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf5fa8cbdffa5ef8be49b246b5628facc30b71707e78a45d80d93b64eff3fe390\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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.0.0, only sets of type `address` (`AddressSet`) and `uint256`\\n * (`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\\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\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] = toDeleteIndex + 1; // All indexes are 1-based\\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 require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\n return set._values[index];\\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(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(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(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(uint256(_at(set._inner, index)));\\n }\\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\",\"keccak256\":\"0xb2a11b236f073662f5a196995863f51c11d006bf7c3de158b316dfa1506c4b79\",\"license\":\"MIT\"},\"contracts/v1/incentives/RewardProgram.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// RewardProgram.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../interfaces/IRewardProgram.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/introspection/IERC165.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/EnumerableSet.sol\\\";\\n\\nimport \\\"../interfaces/IUniverseRP.sol\\\";\\nimport \\\"../interfaces/IChargedManagers.sol\\\";\\nimport \\\"../interfaces/IWalletManager.sol\\\";\\nimport \\\"../lib/TokenInfo.sol\\\";\\nimport \\\"../lib/ReentrancyGuard.sol\\\";\\nimport \\\"../lib/BlackholePrevention.sol\\\";\\nimport \\\"../interfaces/IERC20Detailed.sol\\\";\\n\\ncontract RewardProgram is\\n IRewardProgram,\\n BlackholePrevention,\\n IERC165,\\n ReentrancyGuard,\\n IERC721Receiver,\\n IERC1155Receiver\\n{\\n using SafeMath for uint256;\\n using TokenInfo for address;\\n using SafeERC20 for IERC20;\\n using EnumerableSet for EnumerableSet.UintSet;\\n\\n uint256 constant private PERCENTAGE_SCALE = 1e4; // 10000 (100%)\\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\\n\\n address private _owner;\\n IUniverseRP private _universe;\\n IChargedManagers private _chargedManagers;\\n ProgramRewardData private _programData;\\n mapping(uint256 => AssetStake) private _assetStake;\\n\\n\\n /***********************************|\\n | Initialization |\\n |__________________________________*/\\n\\n constructor() public {}\\n\\n function initialize(\\n address stakingToken,\\n address rewardToken,\\n uint256 baseMultiplier,\\n address chargedManagers,\\n address universe,\\n address owner\\n ) external override {\\n require(_owner == address(0x0), \\\"Already initialized\\\");\\n _owner = owner;\\n\\n // Prepare Reward Program\\n _programData.stakingToken = stakingToken;\\n _programData.rewardToken = rewardToken;\\n _programData.baseMultiplier = baseMultiplier; // Basis Points\\n\\n // Connect to Charged Particles\\n _chargedManagers = IChargedManagers(chargedManagers);\\n _universe = IUniverseRP(universe);\\n }\\n\\n\\n /***********************************|\\n | Public Functions |\\n |__________________________________*/\\n\\n function getProgramData() external view override returns (ProgramRewardData memory) {\\n return _programData;\\n }\\n\\n function getAssetStake(uint256 parentNftUuid) external view override returns (AssetStake memory) {\\n return _assetStake[parentNftUuid];\\n }\\n\\n function getFundBalance() external view override returns (uint256) {\\n return _getFundBalance();\\n }\\n\\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) public view override returns (uint256) {\\n return _calculateRewardsEarned(parentNftUuid, interestAmount);\\n }\\n\\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view override returns (uint256) {\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n return _assetStake[parentNftUuid].claimableRewards;\\n }\\n\\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\\n return IERC721Receiver.onERC721Received.selector;\\n }\\n\\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\\n return IERC1155Receiver.onERC1155BatchReceived.selector;\\n }\\n\\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\\n return \\\"\\\";\\n }\\n\\n function supportsInterface(bytes4 interfaceId)\\n public\\n view\\n virtual\\n override(IERC165)\\n returns (bool)\\n {\\n // default interface support\\n if (\\n interfaceId == type(IERC721Receiver).interfaceId ||\\n interfaceId == type(IERC1155Receiver).interfaceId ||\\n interfaceId == type(IERC165).interfaceId\\n ) {\\n return true;\\n }\\n }\\n\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n\\n /***********************************|\\n | Only Universe |\\n |__________________________________*/\\n\\n function registerAssetDeposit(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n uint256 principalAmount\\n )\\n external\\n override\\n onlyUniverse\\n {\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n AssetStake storage assetStake = _assetStake[parentNftUuid];\\n\\n if (assetStake.start == 0) {\\n assetStake.start = block.number;\\n assetStake.walletManagerId = walletManagerId;\\n }\\n emit AssetDeposit(contractAddress, tokenId, walletManagerId, principalAmount);\\n }\\n\\n function registerAssetRelease(\\n address contractAddress,\\n uint256 tokenId,\\n uint256 interestAmount\\n )\\n external\\n override\\n onlyUniverse\\n nonReentrant\\n returns (uint256 rewards)\\n {\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n AssetStake storage assetStake = _assetStake[parentNftUuid];\\n\\n // Update Claimable Rewards\\n uint256 newRewards = _calculateRewardsEarned(parentNftUuid, interestAmount);\\n assetStake.claimableRewards = assetStake.claimableRewards.add(newRewards);\\n\\n // Reset Stake if Principal Balance falls to Zero\\n IWalletManager walletMgr = _chargedManagers.getWalletManager(assetStake.walletManagerId);\\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\\n if (principal == 0) {\\n assetStake.start = 0;\\n }\\n\\n // Issue Rewards to NFT Owner\\n rewards = _claimRewards(contractAddress, tokenId);\\n\\n emit AssetRelease(contractAddress, tokenId, interestAmount);\\n }\\n\\n\\n /***********************************|\\n | Reward Calculation |\\n |__________________________________*/\\n\\n function _calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) internal view returns (uint256 totalReward) {\\n uint256 baseReward = _calculateBaseReward(interestAmount);\\n uint256 leptonMultipliedReward = _calculateMultipliedReward(parentNftUuid, baseReward);\\n totalReward = _convertDecimals(leptonMultipliedReward);\\n }\\n\\n function _calculateBaseReward(uint256 amount) internal view returns(uint256 baseReward) {\\n baseReward = amount.mul(_programData.baseMultiplier).div(PERCENTAGE_SCALE);\\n }\\n\\n function _calculateMultipliedReward(uint256 parentNftUuid, uint256 baseReward) internal view returns(uint256) {\\n AssetStake storage assetStake = _assetStake[parentNftUuid];\\n if (assetStake.start == 0) { return baseReward; }\\n\\n IUniverseRP.NftStake memory nftStake = _universe.getNftStake(parentNftUuid);\\n uint256 multiplierBP = nftStake.multiplier;\\n\\n uint256 assetDepositLength = block.number.sub(assetStake.start);\\n uint256 nftDepositLength = 0;\\n if (nftStake.releaseBlockNumber > 0) {\\n nftDepositLength = nftStake.releaseBlockNumber.sub(nftStake.depositBlockNumber);\\n } else {\\n nftDepositLength = block.number.sub(nftStake.depositBlockNumber);\\n }\\n\\n if (multiplierBP == 0 || nftDepositLength == 0 || assetDepositLength == 0) {\\n return baseReward;\\n }\\n\\n if (nftDepositLength > assetDepositLength) {\\n nftDepositLength = assetDepositLength;\\n }\\n\\n // Percentage of the total program that the Multiplier Nft was deposited for\\n uint256 nftRewardRatioBP = nftDepositLength.mul(PERCENTAGE_SCALE).div(assetDepositLength);\\n\\n // Amount of reward that the Multiplier Nft is responsible for\\n uint256 amountGeneratedDuringNftDeposit = baseReward.mul(nftRewardRatioBP).div(PERCENTAGE_SCALE);\\n\\n // Amount of Multiplied Reward from NFT\\n uint256 multipliedReward = amountGeneratedDuringNftDeposit.mul(multiplierBP.mul(LEPTON_MULTIPLIER_SCALE)).div(PERCENTAGE_SCALE);\\n\\n // Amount of Base Reward without Multiplied NFT Rewards\\n uint256 amountGeneratedWithoutNftDeposit = baseReward.sub(amountGeneratedDuringNftDeposit);\\n\\n // Amount of Base Rewards + Multiplied NFT Rewards\\n return amountGeneratedWithoutNftDeposit.add(multipliedReward);\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n |__________________________________*/\\n\\n function fundProgram(uint256 amount) external onlyOwner {\\n require(_programData.rewardToken != address(0), \\\"RP:E-405\\\");\\n IERC20(_programData.rewardToken).safeTransferFrom(msg.sender, address(this), amount);\\n emit RewardProgramFunded(amount);\\n }\\n\\n function setStakingToken(address newStakingToken) external onlyOwner {\\n _programData.stakingToken = newStakingToken;\\n }\\n\\n function setRewardToken(address newRewardToken) external onlyOwner {\\n _programData.rewardToken = newRewardToken;\\n }\\n\\n function setBaseMultiplier(uint256 newMultiplier) external onlyOwner {\\n _programData.baseMultiplier = newMultiplier; // Basis Points\\n }\\n\\n function setChargedManagers(address manager) external onlyOwner {\\n _chargedManagers = IChargedManagers(manager);\\n }\\n\\n function setUniverse(address universe) external onlyOwner {\\n _universe = IUniverseRP(universe);\\n }\\n\\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external override onlyOwner {\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n\\n // Initiate Asset Stake\\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\\n if (principal > 0) {\\n _assetStake[parentNftUuid] = AssetStake(block.number, 0, walletManagerId);\\n emit AssetRegistered(contractAddress, tokenId, walletManagerId, principal);\\n }\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n | (blackhole prevention) |\\n |__________________________________*/\\n\\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n\\n\\n /***********************************|\\n | Private Functions |\\n |__________________________________*/\\n\\n function _claimRewards(\\n address contractAddress,\\n uint256 tokenId\\n )\\n internal\\n returns (uint256 totalReward)\\n {\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n AssetStake storage assetStake = _assetStake[parentNftUuid];\\n\\n // Rewards Receiver\\n address receiver = IERC721(contractAddress).ownerOf(tokenId);\\n\\n // Ensure Reward Pool has Sufficient Balance\\n totalReward = assetStake.claimableRewards;\\n uint256 fundBalance = _getFundBalance();\\n uint256 unavailReward = totalReward > fundBalance ? totalReward.sub(fundBalance) : 0;\\n\\n // Determine amount of Rewards to Transfer\\n if (unavailReward > 0) {\\n totalReward = totalReward.sub(unavailReward);\\n emit RewardProgramOutOfFunds();\\n }\\n\\n // Update Asset Stake\\n assetStake.claimableRewards = unavailReward;\\n\\n if (totalReward > 0) {\\n // Transfer Available Rewards to Receiver\\n IERC20(_programData.rewardToken).safeTransfer(receiver, totalReward);\\n }\\n\\n emit RewardsClaimed(contractAddress, tokenId, receiver, totalReward, unavailReward);\\n }\\n\\n function _convertDecimals(uint256 reward) internal view returns (uint256) {\\n uint8 stakingTokenDecimals = IERC20Detailed(_programData.stakingToken).decimals();\\n return reward.mul(10**(18 - uint256(stakingTokenDecimals)));\\n }\\n\\n function _getFundBalance() internal view returns (uint256) {\\n return IERC20Detailed(_programData.rewardToken).balanceOf(address(this));\\n }\\n\\n\\n modifier onlyOwner() {\\n require(_owner == msg.sender, \\\"Caller is not the owner\\\");\\n _;\\n }\\n\\n modifier onlyUniverse() {\\n require(msg.sender == address(_universe), \\\"RP:E-108\\\");\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x2c6b66490dda8cea12387706aa49742f7d8c90ff3b699abd3c84dae227277e3f\",\"license\":\"MIT\"},\"contracts/v1/incentives/RewardProgramFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// RewardProgramFactory.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\nimport \\\"./RewardProgram.sol\\\";\\nimport \\\"../lib/BlackholePrevention.sol\\\";\\n\\ncontract RewardProgramFactory is BlackholePrevention, Ownable {\\n event RewardProgramCreated(address indexed rewardProgram);\\n\\n address public _template;\\n\\n constructor () public {\\n _template = address(new RewardProgram());\\n }\\n\\n // function _msgSender() internal view override returns (address payable) {\\n // return msg.sender;\\n // }\\n\\n function createRewardProgram(\\n address stakingToken,\\n address rewardToken,\\n uint256 baseMultiplier,\\n address chargedManagers,\\n address universe\\n )\\n external\\n onlyOwner\\n returns (address)\\n {\\n address newRewardProgram = _createClone(_template);\\n RewardProgram rewardProgram = RewardProgram(newRewardProgram);\\n rewardProgram.initialize(stakingToken, rewardToken, baseMultiplier, chargedManagers, universe, _msgSender());\\n emit RewardProgramCreated(newRewardProgram);\\n return newRewardProgram;\\n }\\n\\n /**\\n * @dev Creates Contracts from a Template via Cloning\\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\\n */\\n function _createClone(address target) internal returns (address result) {\\n bytes20 targetBytes = bytes20(target);\\n assembly {\\n let clone := mload(0x40)\\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\\n mstore(add(clone, 0x14), targetBytes)\\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\\n result := create(0, clone, 0x37)\\n }\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n | (blackhole prevention) |\\n |__________________________________*/\\n\\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n}\\n\",\"keccak256\":\"0x5a3692f0c9dee582d05013bc2f808cca4e7257756ed8125d81586d674c166559\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IBasketManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IBasketManager.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Particle Basket Manager interface\\n * @dev The basket-manager for underlying assets attached to Charged Particles\\n * @dev Manages the link between NFTs and their respective Smart-Baskets\\n */\\ninterface IBasketManager {\\n\\n event ControllerSet(address indexed controller);\\n event ExecutorSet(address indexed executor);\\n event PausedStateSet(bool isPaused);\\n event NewSmartBasket(address indexed contractAddress, uint256 indexed tokenId, address indexed smartBasket);\\n event BasketAdd(address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\\n event BasketRemove(address indexed receiver, address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\\n event BasketRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\\n event RewardProgramSet(address indexed rewardProgram);\\n\\n function isPaused() external view returns (bool);\\n\\n function getTokenTotalCount(address contractAddress, uint256 tokenId) external view returns (uint256);\\n function getTokenCountByType(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (uint256);\\n\\n function prepareTransferAmount(uint256 nftTokenAmount) external;\\n function addToBasket(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\\n function getBasketAddressById(address contractAddress, uint256 tokenId) external returns (address);\\n\\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount) external;\\n}\\n\",\"keccak256\":\"0x20367a08a95c30ed283f46877bef9c5f1ccd0f07409fe632f4f82a5d33b6a0c3\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IChargedManagers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"./IWalletManager.sol\\\";\\nimport \\\"./IBasketManager.sol\\\";\\n\\n/**\\n * @notice Interface for Charged Wallet-Managers\\n */\\ninterface IChargedManagers {\\n\\n /***********************************|\\n | Public API |\\n |__________________________________*/\\n\\n function isContractOwner(address contractAddress, address account) external view returns (bool);\\n\\n // ERC20\\n function isWalletManagerEnabled(string calldata walletManagerId) external view returns (bool);\\n function getWalletManager(string calldata walletManagerId) external view returns (IWalletManager);\\n\\n // ERC721\\n function isNftBasketEnabled(string calldata basketId) external view returns (bool);\\n function getBasketManager(string calldata basketId) external view returns (IBasketManager);\\n\\n // Validation\\n function validateDeposit(\\n address sender,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external;\\n function validateNftDeposit(\\n address sender,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external;\\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external;\\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external;\\n\\n /***********************************|\\n | Particle Events |\\n |__________________________________*/\\n\\n event Initialized(address indexed initiator);\\n event ControllerSet(address indexed controllerAddress, string controllerId);\\n event WalletManagerRegistered(string indexed walletManagerId, address indexed walletManager);\\n event BasketManagerRegistered(string indexed basketId, address indexed basketManager);\\n}\\n\",\"keccak256\":\"0x98103c0832064c1e446dcfebfdeeec1a9189675e9cf630f568c65c16c94d5478\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IERC20Detailed.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Detailed {\\n function decimals() external view returns (uint8);\\n function symbol() external view returns (string memory);\\n function name() external view returns (string memory);\\n\\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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0x96b8e4b6723a052ec16a1a729854532c953fb2eb758a0e01f75a3eafe242ccd8\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IERC721Chargeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IERC721Chargeable.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\\\";\\n\\ninterface IERC721Chargeable is IERC165Upgradeable {\\n function owner() external view returns (address);\\n function creatorOf(uint256 tokenId) external view returns (address);\\n function balanceOf(address tokenOwner) external view returns (uint256 balance);\\n function ownerOf(uint256 tokenId) external view returns (address tokenOwner);\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n function transferFrom(address from, address to, uint256 tokenId) external;\\n function approve(address to, uint256 tokenId) external;\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n function setApprovalForAll(address operator, bool _approved) external;\\n function isApprovedForAll(address tokenOwner, address operator) external view returns (bool);\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x459e57b2d35c7cd78e6c3d47eb9f3e981529a18c89e2c318b10fe369c479c737\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IRewardProgram.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IRewardProgram.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\npragma experimental ABIEncoderV2;\\n\\ninterface IRewardProgram {\\n /* admin events */\\n event RewardProgramFunded(uint256 amount);\\n event RewardProgramOutOfFunds();\\n\\n /* user events */\\n event RewardsClaimed(address indexed contractAddress, uint256 tokenId, address indexed receiver, uint256 rewarded, uint256 remaining);\\n\\n event AssetRegistered(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\\n event AssetDeposit(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\\n event AssetRelease(address indexed contractAddress, uint256 tokenId, uint256 interestAmount);\\n\\n /* data types */\\n struct ProgramRewardData {\\n address stakingToken;\\n address rewardToken;\\n uint256 baseMultiplier; // Basis Points\\n }\\n\\n struct AssetStake {\\n uint256 start;\\n uint256 claimableRewards;\\n string walletManagerId;\\n }\\n\\n function initialize(address stakingToken, address rewardToken, uint256 baseMultiplier, address chargedManagers, address universe, address owner) external;\\n\\n /* user functions */\\n function getProgramData() external view returns (ProgramRewardData memory programData);\\n function getAssetStake(uint256 uuid) external view returns (AssetStake memory);\\n function getFundBalance() external view returns (uint256);\\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) external view returns (uint256);\\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view returns (uint256);\\n\\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external;\\n function registerAssetDeposit(address contractAddress, uint256 tokenId, string calldata walletManagerId, uint256 principalAmount) external;\\n function registerAssetRelease(address contractAddress, uint256 tokenId, uint256 interestAmount) external returns (uint256 rewards);\\n}\",\"keccak256\":\"0xe0f4076a4b001856c54cb8a63decedc81ca34c71708f8cbe9b3a26603dc9c050\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IUniverse.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IUniverse.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Universal Controller interface\\n * @dev ...\\n */\\ninterface IUniverse {\\n\\n event ChargedParticlesSet(address indexed chargedParticles);\\n event PhotonSet(address indexed photonToken, uint256 maxSupply);\\n event ProtonTokenSet(address indexed protonToken);\\n event LeptonTokenSet(address indexed leptonToken);\\n event QuarkTokenSet(address indexed quarkToken);\\n event BosonTokenSet(address indexed bosonToken);\\n event EsaMultiplierSet(address indexed assetToken, uint256 multiplier);\\n event ElectrostaticAttraction(address indexed account, address photonSource, uint256 energy, uint256 multiplier);\\n event ElectrostaticDischarge(address indexed account, address photonSource, uint256 energy);\\n\\n function onEnergize(\\n address sender,\\n address referrer,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 assetEnergy\\n ) external;\\n\\n function onDischarge(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onDischargeForCreator(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address creator,\\n address assetToken,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onRelease(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 principalEnergy,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onCovalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n\\n function onCovalentBreak(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n\\n function onProtonSale(\\n address contractAddress,\\n uint256 tokenId,\\n address oldOwner,\\n address newOwner,\\n uint256 salePrice,\\n address creator,\\n uint256 creatorRoyalties\\n ) external;\\n}\\n\",\"keccak256\":\"0x6cebb97ce4d32c61afc746e4a6538eb605bb01276dfa66fa4bd6f63362bdc9ef\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IUniverseRP.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IUniverseRP.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"./IUniverse.sol\\\";\\n\\n/**\\n * @title Universal Controller interface for Rewards Program\\n * @dev ...\\n */\\ninterface IUniverseRP is IUniverse {\\n event RewardProgramSet(address indexed assetToken, address indexed rewardProgram);\\n event RewardProgramRemoved(address indexed assetToken);\\n event NftDeposit(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\\n event NftRelease(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\\n\\n struct NftStake {\\n uint256 multiplier; // in Basis Points\\n uint256 depositBlockNumber;\\n uint256 releaseBlockNumber;\\n }\\n\\n function getRewardProgram(address asset) external view returns (address);\\n function getNftStake(uint256 uuid) external view returns (NftStake memory);\\n}\\n\",\"keccak256\":\"0xd9c5a996bbb7f2a27bb85dde52587f7368c7b6512fc1064821a3975acdf4b7db\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IWalletManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IWalletManager.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Particle Wallet Manager interface\\n * @dev The wallet-manager for underlying assets attached to Charged Particles\\n * @dev Manages the link between NFTs and their respective Smart-Wallets\\n */\\ninterface IWalletManager {\\n\\n event ControllerSet(address indexed controller);\\n event ExecutorSet(address indexed executor);\\n event PausedStateSet(bool isPaused);\\n event NewSmartWallet(address indexed contractAddress, uint256 indexed tokenId, address indexed smartWallet, address creator, uint256 annuityPct);\\n event WalletEnergized(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 assetAmount, uint256 yieldTokensAmount);\\n event WalletDischarged(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 creatorAmount, uint256 receiverAmount);\\n event WalletDischargedForCreator(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, address creator, uint256 receiverAmount);\\n event WalletReleased(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address assetToken, uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\\n event WalletRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\\n\\n function isPaused() external view returns (bool);\\n\\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view returns (bool);\\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view returns (address);\\n\\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\\n function getInterest(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken) external returns (uint256);\\n\\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount) external returns (uint256 yieldTokensAmount);\\n function discharge(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n function dischargeAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n function dischargeAmountForCreator(address receiver, address contractAddress, uint256 tokenId, address creator, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\\n function release(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\\n function releaseAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken) external;\\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct) external returns (address);\\n\\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\\n}\\n\",\"keccak256\":\"0xb03ee0e216d7444e72af388814d219ad9aa87006ec96d660b45dcad0875ef0d7\",\"license\":\"MIT\"},\"contracts/v1/lib/BlackholePrevention.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\\\";\\n\\n/**\\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\\n * the Owner/DAO to pull them out on behalf of a user\\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\\n */\\ncontract BlackholePrevention {\\n using Address for address payable;\\n using SafeERC20 for IERC20;\\n\\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\\n\\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (address(this).balance >= amount) {\\n receiver.sendValue(amount);\\n emit WithdrawStuckEther(receiver, amount);\\n }\\n }\\n\\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\\n IERC20(tokenAddress).safeTransfer(receiver, amount);\\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\\n }\\n }\\n\\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\\n }\\n }\\n\\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \\\"\\\");\\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6a664c8a1c1d7fb32ade2c11f75756b1fdb4c489daa32c1d58e6b867ea2ba8d6\",\"license\":\"MIT\"},\"contracts/v1/lib/ReentrancyGuard.sol\":{\"content\":\"pragma solidity 0.6.12;\\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 () public {\\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 _nonReentrantBefore();\\n _;\\n _nonReentrantAfter();\\n }\\n\\n function _nonReentrantBefore() private {\\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n }\\n\\n function _nonReentrantAfter() private {\\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 /**\\n * @dev Returns true if the reentrancy guard is currently set to \\\"entered\\\", which indicates there is a\\n * `nonReentrant` function in the call stack.\\n */\\n function _reentrancyGuardEntered() internal view returns (bool) {\\n return _status == _ENTERED;\\n }\\n}\",\"keccak256\":\"0x4897c6fee5e1601d203efa54d29b2cef20825cab134b8e63b0b13ee9603642ad\"},\"contracts/v1/lib/TokenInfo.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// TokenInfo.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport \\\"../interfaces/IERC721Chargeable.sol\\\";\\n\\nlibrary TokenInfo {\\n function getTokenUUID(address contractAddress, uint256 tokenId) internal pure virtual returns (uint256) {\\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n function getTokenOwner(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n return tokenInterface.ownerOf(tokenId);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n function getTokenCreator(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n return tokenInterface.creatorOf(tokenId);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Owner of an External NFT contract\\n /// @param contractAddress The Address to the Contract of the NFT to check\\n /// @param account The Address of the Account to check\\n /// @return True if the account owns the contract\\n function isContractOwner(address contractAddress, address account) internal view virtual returns (bool) {\\n address contractOwner = IERC721Chargeable(contractAddress).owner();\\n return contractOwner != address(0x0) && contractOwner == account;\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Creator of a Proton-based NFT\\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\\n /// @param tokenId The Token ID of the Proton-based NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the creator of the Proton-based NFT\\n function isTokenCreator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenCreator = tokenInterface.creatorOf(tokenId);\\n return (sender == tokenCreator);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\\n /// @param tokenId The Token ID of the Proton-based NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the creator of the Proton-based NFT or the Contract itself\\n function isTokenContractOrCreator(address contractAddress, uint256 tokenId, address creator, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenCreator = tokenInterface.creatorOf(tokenId);\\n if (sender == contractAddress && creator == tokenCreator) { return true; }\\n return (sender == tokenCreator);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Owner or Operator of an External NFT\\n /// @param contractAddress The Address to the Contract of the External NFT to check\\n /// @param tokenId The Token ID of the External NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the Owner or Operator of the External NFT\\n function isErc721OwnerOrOperator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenOwner = tokenInterface.ownerOf(tokenId);\\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\\n }\\n\\n /**\\n * @dev Returns true if `account` is a contract.\\n * @dev Taken from OpenZeppelin library\\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { codehash := extcodehash(account) }\\n return (codehash != accountHash && codehash != 0x0);\\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 * @dev Taken from OpenZeppelin library\\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, uint256 gasLimit) internal {\\n require(address(this).balance >= amount, \\\"TokenInfo: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = (gasLimit > 0)\\n ? recipient.call{ value: amount, gas: gasLimit }(\\\"\\\")\\n : recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"TokenInfo: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0xbc78c6173db068d95084288246642402d0f4af399e1eb754182cae2d9173af5e\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50600061001b6100b3565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350604051610071906100b7565b604051809103906000f08015801561008d573d6000803e3d6000fd5b50600180546001600160a01b0319166001600160a01b03929092169190911790556100c4565b3390565b6127bd8061115483390190565b611081806100d36000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c80636fe6fabb116100665780636fe6fabb146100fc578063715018a6146101045780638da5cb5b1461010c578063a0edb48b14610114578063f2fde38b1461012757610093565b80631593dee1146100985780634025feb2146100ad578063522f6815146100c05780636f9d5f78146100d3575b600080fd5b6100ab6100a6366004610be7565b61013a565b005b6100ab6100bb366004610be7565b610188565b6100ab6100ce366004610c6c565b6101c8565b6100e66100e1366004610c97565b61020b565b6040516100f39190610d55565b60405180910390f35b6100e661030b565b6100ab61031a565b6100e6610399565b6100ab610122366004610c27565b6103a8565b6100ab610135366004610ba8565b6103ef565b6101426104a5565b6000546001600160a01b039081169116146101785760405162461bcd60e51b815260040161016f90610f48565b60405180910390fd5b6101838383836104a9565b505050565b6101906104a5565b6000546001600160a01b039081169116146101bd5760405162461bcd60e51b815260040161016f90610f48565b6101838383836105b6565b6101d06104a5565b6000546001600160a01b039081169116146101fd5760405162461bcd60e51b815260040161016f90610f48565b6102078282610711565b5050565b60006102156104a5565b6000546001600160a01b039081169116146102425760405162461bcd60e51b815260040161016f90610f48565b60015460009061025a906001600160a01b0316610795565b9050806001600160a01b03811663ff9935cb89898989896102796104a5565b6040518763ffffffff1660e01b815260040161029a96959493929190610dc5565b600060405180830381600087803b1580156102b457600080fd5b505af11580156102c8573d6000803e3d6000fd5b50506040516001600160a01b03851692507f6ecb2838bef4560681475e8bb5e7feccefe33df915df2d6757024bc6fe4c616a9150600090a2509695505050505050565b6001546001600160a01b031681565b6103226104a5565b6000546001600160a01b0390811691161461034f5760405162461bcd60e51b815260040161016f90610f48565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b6103b06104a5565b6000546001600160a01b039081169116146103dd5760405162461bcd60e51b815260040161016f90610f48565b6103e9848484846107e7565b50505050565b6103f76104a5565b6000546001600160a01b039081169116146104245760405162461bcd60e51b815260040161016f90610f48565b6001600160a01b03811661044a5760405162461bcd60e51b815260040161016f90610e4b565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b0383166104cf5760405162461bcd60e51b815260040161016f90610e91565b6040516370a0823160e01b815281906001600160a01b038416906370a08231906104fd903090600401610d55565b60206040518083038186803b15801561051557600080fd5b505afa158015610529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061054d9190610d1e565b10610183576105666001600160a01b0383168483610946565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b836040516105a99190610ffe565b60405180910390a3505050565b6001600160a01b0383166105dc5760405162461bcd60e51b815260040161016f90610e91565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e9061060a908590600401610ffe565b60206040518083038186803b15801561062257600080fd5b505afa158015610636573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065a9190610bcb565b6001600160a01b03161415610183576040516323b872dd60e01b81526001600160a01b038316906323b872dd9061069990309087908690600401610d69565b600060405180830381600087803b1580156106b357600080fd5b505af11580156106c7573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b0382166107375760405162461bcd60e51b815260040161016f90610e91565b804710610207576107516001600160a01b0383168261099c565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd826040516107899190610ffe565b60405180910390a25050565b6000808260601b9050604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528160148201526e5af43d82803e903d91602b57fd5bf360881b60288201526037816000f0949350505050565b6001600160a01b03841661080d5760405162461bcd60e51b815260040161016f90610e91565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e9061083b9030908790600401610dff565b60206040518083038186803b15801561085357600080fd5b505afa158015610867573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088b9190610d1e565b106103e957604051637921219560e11b81526001600160a01b0384169063f242432a906108c2903090889087908790600401610d8d565b600060405180830381600087803b1580156108dc57600080fd5b505af11580156108f0573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b846040516109389190610ffe565b60405180910390a450505050565b6101838363a9059cbb60e01b8484604051602401610965929190610dff565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610a38565b804710156109bc5760405162461bcd60e51b815260040161016f90610f11565b6000826001600160a01b0316826040516109d590610d52565b60006040518083038185875af1925050503d8060008114610a12576040519150601f19603f3d011682016040523d82523d6000602084013e610a17565b606091505b50509050806101835760405162461bcd60e51b815260040161016f90610eb4565b6060610a8d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610ac79092919063ffffffff16565b8051909150156101835780806020019051810190610aab9190610cfe565b6101835760405162461bcd60e51b815260040161016f90610fb4565b6060610ad68484600085610ade565b949350505050565b6060610ae985610ba2565b610b055760405162461bcd60e51b815260040161016f90610f7d565b60006060866001600160a01b03168587604051610b229190610d36565b60006040518083038185875af1925050503d8060008114610b5f576040519150601f19603f3d011682016040523d82523d6000602084013e610b64565b606091505b50915091508115610b78579150610ad69050565b805115610b885780518082602001fd5b8360405162461bcd60e51b815260040161016f9190610e18565b3b151590565b600060208284031215610bb9578081fd5b8135610bc481611033565b9392505050565b600060208284031215610bdc578081fd5b8151610bc481611033565b600080600060608486031215610bfb578182fd5b8335610c0681611033565b92506020840135610c1681611033565b929592945050506040919091013590565b60008060008060808587031215610c3c578081fd5b8435610c4781611033565b93506020850135610c5781611033565b93969395505050506040820135916060013590565b60008060408385031215610c7e578182fd5b8235610c8981611033565b946020939093013593505050565b600080600080600060a08688031215610cae578081fd5b8535610cb981611033565b94506020860135610cc981611033565b9350604086013592506060860135610ce081611033565b91506080860135610cf081611033565b809150509295509295909350565b600060208284031215610d0f578081fd5b81518015158114610bc4578182fd5b600060208284031215610d2f578081fd5b5051919050565b60008251610d48818460208701611007565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b0396871681529486166020860152604085019390935290841660608401528316608083015290911660a082015260c00190565b6001600160a01b03929092168252602082015260400190565b6000602082528251806020840152610e37816040850160208701611007565b601f01601f19169190910160400192915050565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b90815260200190565b60005b8381101561102257818101518382015260200161100a565b838111156103e95750506000910152565b6001600160a01b038116811461104857600080fd5b5056fea2646970667358221220260383f23709db660967a522664682b39439430262c686f1ff999462e44f3aff64736f6c634300060c0033608060405234801561001057600080fd5b506001600055612798806100256000396000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c8063533f852e116100c3578063ae9704cd1161007c578063ae9704cd146102f6578063bc197c8114610309578063dae9e3791461031c578063e3043ee814610324578063f23a6e6114610337578063ff9935cb1461034a57610158565b8063533f852e1461027557806370d2e5cd14610288578063784483491461029b5780638aee8127146102bb5780638da5cb5b146102ce578063a0edb48b146102e357610158565b8063352685bc11610115578063352685bc146101f65780634025feb21461020957806346c65f621461021c578063494b01001461022f57806350d0c63c14610242578063522f68151461026257610158565b806301ffc9a71461015d57806314e5f66814610186578063150b7a021461019b5780631593dee1146101bb5780631e9b12ef146101d05780631f5b149f146101e3575b600080fd5b61017061016b3660046120c8565b61035d565b60405161017d91906122fc565b60405180910390f35b61018e6103b7565b60405161017d919061268b565b6101ae6101a9366004611ecd565b6103f0565b60405161017d9190612307565b6101ce6101c9366004611cea565b610401565b005b6101ce6101de366004611cb2565b610444565b6101ce6101f1366004611cb2565b610490565b6101ce610204366004612147565b6104dc565b6101ce610217366004611cea565b610580565b6101ce61022a366004612012565b6105b5565b6101ce61023d366004611fb8565b61066f565b610255610250366004612074565b61089f565b60405161017d91906126ba565b6101ce610270366004611d6f565b610a9a565b610255610283366004611d6f565b610ad2565b6101ce610296366004612147565b610b04565b6102ae6102a9366004612147565b610b33565b60405161017d919061265c565b6101ce6102c9366004611cb2565b610c16565b6102d6610c62565b60405161017d9190612250565b6101ce6102f1366004611d2a565b610c71565b6101ce610304366004611cb2565b610cad565b6101ae610317366004611d9a565b610cf9565b610255610d07565b610255610332366004612177565b610d16565b6101ae610345366004611f3e565b610d22565b6101ce610358366004611e55565b610d34565b60006001600160e01b03198216630a85bd0160e11b148061038e57506001600160e01b03198216630271189760e51b145b806103a957506001600160e01b031982166301ffc9a760e01b145b156103b2575060015b919050565b6103bf611ac6565b50604080516060810182526004546001600160a01b0390811682526005541660208201526006549181019190915290565b630a85bd0160e11b95945050505050565b6001546001600160a01b031633146104345760405162461bcd60e51b815260040161042b906123cd565b60405180910390fd5b61043f838383610dbf565b505050565b6001546001600160a01b0316331461046e5760405162461bcd60e51b815260040161042b906123cd565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633146104ba5760405162461bcd60e51b815260040161042b906123cd565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633146105065760405162461bcd60e51b815260040161042b906123cd565b6005546001600160a01b031661052e5760405162461bcd60e51b815260040161042b90612514565b600554610546906001600160a01b0316333084610ecc565b7fcbd64454da4b3587b11b8f8170d7656cbe58e29ee18fd715b0e79ad85edb6e5d8160405161057591906126ba565b60405180910390a150565b6001546001600160a01b031633146105aa5760405162461bcd60e51b815260040161042b906123cd565b61043f838383610f24565b6002546001600160a01b031633146105df5760405162461bcd60e51b815260040161042b906124f2565b60006105f46001600160a01b0387168661107f565b600081815260076020526040902080549192509061061f5743815561061d600282018686611ae6565b505b866001600160a01b03167f30d53e48465c48642e346a636a4eef45c72095b65bef5825308376e2f59f09e28787878760405161065e94939291906126c3565b60405180910390a250505050505050565b6001546001600160a01b031633146106995760405162461bcd60e51b815260040161042b906123cd565b60006106ae6001600160a01b0386168561107f565b6003546040516334b7328d60e01b81529192506000916001600160a01b03909116906334b7328d906106e6908790879060040161231c565b60206040518083038186803b1580156106fe57600080fd5b505afa158015610712573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107369190611cce565b60048054604051632da9ef8160e01b81529293506000926001600160a01b0380861693632da9ef8193610770938d938d93921691016122d9565b602060405180830381600087803b15801561078a57600080fd5b505af115801561079e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c2919061215f565b905080156108965760405180606001604052804381526020016000815260200186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093909452505085815260076020908152604091829020845181558482015160018201559184015180519293506108539260028501929190910190611b64565b50905050866001600160a01b03167fdd1b8616b3983aa94529955a2f7d0dd75e5a93e53875372ea41a9eab5e3ef3268787878560405161065e94939291906126c3565b50505050505050565b6002546000906001600160a01b031633146108cc5760405162461bcd60e51b815260040161042b906124f2565b6108d46110b3565b60006108e96001600160a01b0386168561107f565b600081815260076020526040812091925061090483866110dd565b6001830154909150610916908261110b565b60018301556003546040516334b7328d60e01b81526000916001600160a01b0316906334b7328d9061094f906002870190600401612343565b60206040518083038186803b15801561096757600080fd5b505afa15801561097b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099f9190611cce565b60048054604051632da9ef8160e01b81529293506000926001600160a01b0380861693632da9ef81936109d9938f938f93921691016122d9565b602060405180830381600087803b1580156109f357600080fd5b505af1158015610a07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2b919061215f565b905080610a3757600084555b610a418989611130565b9550886001600160a01b03167f8abeaea5da22bf1966530d4f970ac7c71ae0999eb1d2181afaeff8b56c394f3f8989604051610a7e9291906126ee565b60405180910390a25050505050610a936112c0565b9392505050565b6001546001600160a01b03163314610ac45760405162461bcd60e51b815260040161042b906123cd565b610ace82826112c7565b5050565b600080610ae86001600160a01b0385168461107f565b6000908152600760205260409020600101549150505b92915050565b6001546001600160a01b03163314610b2e5760405162461bcd60e51b815260040161042b906123cd565b600655565b610b3b611bd2565b600760008381526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610c065780601f10610bdb57610100808354040283529160200191610c06565b820191906000526020600020905b815481529060010190602001808311610be957829003601f168201915b5050505050815250509050919050565b6001546001600160a01b03163314610c405760405162461bcd60e51b815260040161042b906123cd565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031690565b6001546001600160a01b03163314610c9b5760405162461bcd60e51b815260040161042b906123cd565b610ca78484848461134b565b50505050565b6001546001600160a01b03163314610cd75760405162461bcd60e51b815260040161042b906123cd565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b600098975050505050505050565b6000610d116114aa565b905090565b6000610a9383836110dd565b63bc197c8160e01b9695505050505050565b6001546001600160a01b031615610d5d5760405162461bcd60e51b815260040161042b906125ae565b600180546001600160a01b03199081166001600160a01b03938416179091556004805482169783169790971790965560058054871695821695909517909455600692909255600380548516918416919091179055600280549093169116179055565b6001600160a01b038316610de55760405162461bcd60e51b815260040161042b90612404565b6040516370a0823160e01b815281906001600160a01b038416906370a0823190610e13903090600401612250565b60206040518083038186803b158015610e2b57600080fd5b505afa158015610e3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e63919061215f565b1061043f57610e7c6001600160a01b038316848361152b565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b83604051610ebf91906126ba565b60405180910390a3505050565b610ca7846323b872dd60e01b858585604051602401610eed93929190612264565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261154a565b6001600160a01b038316610f4a5760405162461bcd60e51b815260040161042b90612404565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e90610f789085906004016126ba565b60206040518083038186803b158015610f9057600080fd5b505afa158015610fa4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc89190611cce565b6001600160a01b0316141561043f576040516323b872dd60e01b81526001600160a01b038316906323b872dd9061100790309087908690600401612264565b600060405180830381600087803b15801561102157600080fd5b505af1158015611035573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6000828260405160200161109492919061220f565b60408051601f1981840301815291905280516020909101209392505050565b600260005414156110d65760405162461bcd60e51b815260040161042b90612625565b6002600055565b6000806110e9836115d9565b905060006110f785836115ff565b905061110281611797565b95945050505050565b600082820183811015610a935760405162461bcd60e51b815260040161042b90612427565b6000806111466001600160a01b0385168461107f565b60008181526007602052604080822090516331a9108f60e11b8152929350916001600160a01b03871690636352211e906111849088906004016126ba565b60206040518083038186803b15801561119c57600080fd5b505afa1580156111b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d49190611cce565b90508160010154935060006111e76114aa565b905060008186116111f9576000611203565b6112038683611828565b90508015611242576112158682611828565b6040519096507f9fc735fd421d3eb45362ea6d0d94945975bce33842b1bc94840719e66d937e4790600090a15b60018401819055851561126657600554611266906001600160a01b0316848861152b565b826001600160a01b0316886001600160a01b03167fb918e5bcd5ce5aadd59ae96fe4c568669afc7af190dbf16061540816cb407c738989856040516112ad939291906126fc565b60405180910390a3505050505092915050565b6001600055565b6001600160a01b0382166112ed5760405162461bcd60e51b815260040161042b90612404565b804710610ace576113076001600160a01b0383168261186a565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd8260405161133f91906126ba565b60405180910390a25050565b6001600160a01b0384166113715760405162461bcd60e51b815260040161042b90612404565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e9061139f90309087906004016122c0565b60206040518083038186803b1580156113b757600080fd5b505afa1580156113cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ef919061215f565b10610ca757604051637921219560e11b81526001600160a01b0384169063f242432a90611426903090889087908790600401612288565b600060405180830381600087803b15801561144057600080fd5b505af1158015611454573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b8460405161149c91906126ba565b60405180910390a450505050565b6005546040516370a0823160e01b81526000916001600160a01b0316906370a08231906114db903090600401612250565b60206040518083038186803b1580156114f357600080fd5b505afa158015611507573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d11919061215f565b61043f8363a9059cbb60e01b8484604051602401610eed9291906122c0565b606061159f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166119069092919063ffffffff16565b80519091501561043f57808060200190518101906115bd91906120a8565b61043f5760405162461bcd60e51b815260040161042b906125db565b6000610afe6127106115f96004600201548561191d90919063ffffffff16565b90611957565b6000828152600760205260408120805461161c5782915050610afe565b611624611bf3565b60025460405163836c478d60e01b81526001600160a01b039091169063836c478d906116549088906004016126ba565b60606040518083038186803b15801561166c57600080fd5b505afa158015611680573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a491906120f0565b80518354919250906000906116ba904390611828565b9050600080846040015111156116e457602084015160408501516116dd91611828565b90506116f7565b60208401516116f4904390611828565b90505b821580611702575080155b8061170b575081155b1561171d578695505050505050610afe565b818111156117285750805b600061173a836115f98461271061191d565b9050600061174e6127106115f98b8561191d565b9050600061176d6127106115f961176689606461191d565b859061191d565b9050600061177b8b84611828565b9050611787818361110b565b9c9b505050505050505050505050565b600480546040805163313ce56760e01b8152905160009384936001600160a01b03169263313ce5679281830192602092829003018186803b1580156117db57600080fd5b505afa1580156117ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118139190612198565b9050610a938360ff8316601203600a0a61191d565b6000610a9383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611999565b8047101561188a5760405162461bcd60e51b815260040161042b906124bb565b6000826001600160a01b0316826040516118a39061224d565b60006040518083038185875af1925050503d80600081146118e0576040519150601f19603f3d011682016040523d82523d6000602084013e6118e5565b606091505b505090508061043f5760405162461bcd60e51b815260040161042b9061245e565b606061191584846000856119c5565b949350505050565b60008261192c57506000610afe565b8282028284828161193957fe5b0414610a935760405162461bcd60e51b815260040161042b90612536565b6000610a9383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611a89565b600081848411156119bd5760405162461bcd60e51b815260040161042b9190612330565b505050900390565b60606119d085611ac0565b6119ec5760405162461bcd60e51b815260040161042b90612577565b60006060866001600160a01b03168587604051611a099190612231565b60006040518083038185875af1925050503d8060008114611a46576040519150601f19603f3d011682016040523d82523d6000602084013e611a4b565b606091505b50915091508115611a5f5791506119159050565b805115611a6f5780518082602001fd5b8360405162461bcd60e51b815260040161042b9190612330565b60008183611aaa5760405162461bcd60e51b815260040161042b9190612330565b506000838581611ab657fe5b0495945050505050565b3b151590565b604080516060810182526000808252602082018190529181019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611b275782800160ff19823516178555611b54565b82800160010185558215611b54579182015b82811115611b54578235825591602001919060010190611b39565b50611b60929150611c14565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611ba557805160ff1916838001178555611b54565b82800160010185558215611b54579182015b82811115611b54578251825591602001919060010190611bb7565b60405180606001604052806000815260200160008152602001606081525090565b60405180606001604052806000815260200160008152602001600081525090565b5b80821115611b605760008155600101611c15565b60008083601f840112611c3a578182fd5b50813567ffffffffffffffff811115611c51578182fd5b6020830191508360208083028501011115611c6b57600080fd5b9250929050565b60008083601f840112611c83578182fd5b50813567ffffffffffffffff811115611c9a578182fd5b602083019150836020828501011115611c6b57600080fd5b600060208284031215611cc3578081fd5b8135610a938161274a565b600060208284031215611cdf578081fd5b8151610a938161274a565b600080600060608486031215611cfe578182fd5b8335611d098161274a565b92506020840135611d198161274a565b929592945050506040919091013590565b60008060008060808587031215611d3f578081fd5b8435611d4a8161274a565b93506020850135611d5a8161274a565b93969395505050506040820135916060013590565b60008060408385031215611d81578182fd5b8235611d8c8161274a565b946020939093013593505050565b60008060008060008060008060a0898b031215611db5578384fd5b8835611dc08161274a565b97506020890135611dd08161274a565b9650604089013567ffffffffffffffff80821115611dec578586fd5b611df88c838d01611c29565b909850965060608b0135915080821115611e10578586fd5b611e1c8c838d01611c29565b909650945060808b0135915080821115611e34578384fd5b50611e418b828c01611c72565b999c989b5096995094979396929594505050565b60008060008060008060c08789031215611e6d578182fd5b8635611e788161274a565b95506020870135611e888161274a565b9450604087013593506060870135611e9f8161274a565b92506080870135611eaf8161274a565b915060a0870135611ebf8161274a565b809150509295509295509295565b600080600080600060808688031215611ee4578081fd5b8535611eef8161274a565b94506020860135611eff8161274a565b935060408601359250606086013567ffffffffffffffff811115611f21578182fd5b611f2d88828901611c72565b969995985093965092949392505050565b60008060008060008060a08789031215611f56578384fd5b8635611f618161274a565b95506020870135611f718161274a565b94506040870135935060608701359250608087013567ffffffffffffffff811115611f9a578283fd5b611fa689828a01611c72565b979a9699509497509295939492505050565b60008060008060608587031215611fcd578182fd5b8435611fd88161274a565b935060208501359250604085013567ffffffffffffffff811115611ffa578283fd5b61200687828801611c72565b95989497509550505050565b600080600080600060808688031215612029578283fd5b85356120348161274a565b945060208601359350604086013567ffffffffffffffff811115612056578384fd5b61206288828901611c72565b96999598509660600135949350505050565b600080600060608486031215612088578081fd5b83356120938161274a565b95602085013595506040909401359392505050565b6000602082840312156120b9578081fd5b81518015158114610a93578182fd5b6000602082840312156120d9578081fd5b81356001600160e01b031981168114610a93578182fd5b600060608284031215612101578081fd5b6040516060810181811067ffffffffffffffff82111715612120578283fd5b80604052508251815260208301516020820152604083015160408201528091505092915050565b600060208284031215612158578081fd5b5035919050565b600060208284031215612170578081fd5b5051919050565b60008060408385031215612189578182fd5b50508035926020909101359150565b6000602082840312156121a9578081fd5b815160ff81168114610a93578182fd5b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526121fb81602086016020860161271e565b601f01601f19169290920160200192915050565b60609290921b6bffffffffffffffffffffffff19168252601482015260340190565b6000825161224381846020870161271e565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b901515815260200190565b6001600160e01b031991909116815260200190565b6000602082526119156020830184866121b9565b600060208252610a9360208301846121e3565b6000602080830181845282855460018082166000811461236a5760018114612388576123c0565b60028304607f16855260ff19831660408901526060880193506123c0565b600283048086526123988a612712565b885b828110156123b65781548b82016040015290840190880161239a565b8a01604001955050505b5091979650505050505050565b60208082526017908201527f43616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252600890820152670a4a0748a5a6260760c31b604082015260600190565b60208082526008908201526752503a452d34303560c01b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b602080825260139082015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6000602082528251602083015260208301516040830152604083015160608084015261191560808401826121e3565b81516001600160a01b039081168252602080840151909116908201526040918201519181019190915260600190565b90815260200190565b6000858252606060208301526126dd6060830185876121b9565b905082604083015295945050505050565b918252602082015260400190565b9283526020830191909152604082015260600190565b60009081526020902090565b60005b83811015612739578181015183820152602001612721565b83811115610ca75750506000910152565b6001600160a01b038116811461275f57600080fd5b5056fea264697066735822122089923bf05c0e88235caef82d9eb9c338dbdb5c9a300cc0b182773089e351721e64736f6c634300060c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100935760003560e01c80636fe6fabb116100665780636fe6fabb146100fc578063715018a6146101045780638da5cb5b1461010c578063a0edb48b14610114578063f2fde38b1461012757610093565b80631593dee1146100985780634025feb2146100ad578063522f6815146100c05780636f9d5f78146100d3575b600080fd5b6100ab6100a6366004610be7565b61013a565b005b6100ab6100bb366004610be7565b610188565b6100ab6100ce366004610c6c565b6101c8565b6100e66100e1366004610c97565b61020b565b6040516100f39190610d55565b60405180910390f35b6100e661030b565b6100ab61031a565b6100e6610399565b6100ab610122366004610c27565b6103a8565b6100ab610135366004610ba8565b6103ef565b6101426104a5565b6000546001600160a01b039081169116146101785760405162461bcd60e51b815260040161016f90610f48565b60405180910390fd5b6101838383836104a9565b505050565b6101906104a5565b6000546001600160a01b039081169116146101bd5760405162461bcd60e51b815260040161016f90610f48565b6101838383836105b6565b6101d06104a5565b6000546001600160a01b039081169116146101fd5760405162461bcd60e51b815260040161016f90610f48565b6102078282610711565b5050565b60006102156104a5565b6000546001600160a01b039081169116146102425760405162461bcd60e51b815260040161016f90610f48565b60015460009061025a906001600160a01b0316610795565b9050806001600160a01b03811663ff9935cb89898989896102796104a5565b6040518763ffffffff1660e01b815260040161029a96959493929190610dc5565b600060405180830381600087803b1580156102b457600080fd5b505af11580156102c8573d6000803e3d6000fd5b50506040516001600160a01b03851692507f6ecb2838bef4560681475e8bb5e7feccefe33df915df2d6757024bc6fe4c616a9150600090a2509695505050505050565b6001546001600160a01b031681565b6103226104a5565b6000546001600160a01b0390811691161461034f5760405162461bcd60e51b815260040161016f90610f48565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b6103b06104a5565b6000546001600160a01b039081169116146103dd5760405162461bcd60e51b815260040161016f90610f48565b6103e9848484846107e7565b50505050565b6103f76104a5565b6000546001600160a01b039081169116146104245760405162461bcd60e51b815260040161016f90610f48565b6001600160a01b03811661044a5760405162461bcd60e51b815260040161016f90610e4b565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b0383166104cf5760405162461bcd60e51b815260040161016f90610e91565b6040516370a0823160e01b815281906001600160a01b038416906370a08231906104fd903090600401610d55565b60206040518083038186803b15801561051557600080fd5b505afa158015610529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061054d9190610d1e565b10610183576105666001600160a01b0383168483610946565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b836040516105a99190610ffe565b60405180910390a3505050565b6001600160a01b0383166105dc5760405162461bcd60e51b815260040161016f90610e91565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e9061060a908590600401610ffe565b60206040518083038186803b15801561062257600080fd5b505afa158015610636573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065a9190610bcb565b6001600160a01b03161415610183576040516323b872dd60e01b81526001600160a01b038316906323b872dd9061069990309087908690600401610d69565b600060405180830381600087803b1580156106b357600080fd5b505af11580156106c7573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b0382166107375760405162461bcd60e51b815260040161016f90610e91565b804710610207576107516001600160a01b0383168261099c565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd826040516107899190610ffe565b60405180910390a25050565b6000808260601b9050604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528160148201526e5af43d82803e903d91602b57fd5bf360881b60288201526037816000f0949350505050565b6001600160a01b03841661080d5760405162461bcd60e51b815260040161016f90610e91565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e9061083b9030908790600401610dff565b60206040518083038186803b15801561085357600080fd5b505afa158015610867573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088b9190610d1e565b106103e957604051637921219560e11b81526001600160a01b0384169063f242432a906108c2903090889087908790600401610d8d565b600060405180830381600087803b1580156108dc57600080fd5b505af11580156108f0573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b846040516109389190610ffe565b60405180910390a450505050565b6101838363a9059cbb60e01b8484604051602401610965929190610dff565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610a38565b804710156109bc5760405162461bcd60e51b815260040161016f90610f11565b6000826001600160a01b0316826040516109d590610d52565b60006040518083038185875af1925050503d8060008114610a12576040519150601f19603f3d011682016040523d82523d6000602084013e610a17565b606091505b50509050806101835760405162461bcd60e51b815260040161016f90610eb4565b6060610a8d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610ac79092919063ffffffff16565b8051909150156101835780806020019051810190610aab9190610cfe565b6101835760405162461bcd60e51b815260040161016f90610fb4565b6060610ad68484600085610ade565b949350505050565b6060610ae985610ba2565b610b055760405162461bcd60e51b815260040161016f90610f7d565b60006060866001600160a01b03168587604051610b229190610d36565b60006040518083038185875af1925050503d8060008114610b5f576040519150601f19603f3d011682016040523d82523d6000602084013e610b64565b606091505b50915091508115610b78579150610ad69050565b805115610b885780518082602001fd5b8360405162461bcd60e51b815260040161016f9190610e18565b3b151590565b600060208284031215610bb9578081fd5b8135610bc481611033565b9392505050565b600060208284031215610bdc578081fd5b8151610bc481611033565b600080600060608486031215610bfb578182fd5b8335610c0681611033565b92506020840135610c1681611033565b929592945050506040919091013590565b60008060008060808587031215610c3c578081fd5b8435610c4781611033565b93506020850135610c5781611033565b93969395505050506040820135916060013590565b60008060408385031215610c7e578182fd5b8235610c8981611033565b946020939093013593505050565b600080600080600060a08688031215610cae578081fd5b8535610cb981611033565b94506020860135610cc981611033565b9350604086013592506060860135610ce081611033565b91506080860135610cf081611033565b809150509295509295909350565b600060208284031215610d0f578081fd5b81518015158114610bc4578182fd5b600060208284031215610d2f578081fd5b5051919050565b60008251610d48818460208701611007565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b0396871681529486166020860152604085019390935290841660608401528316608083015290911660a082015260c00190565b6001600160a01b03929092168252602082015260400190565b6000602082528251806020840152610e37816040850160208701611007565b601f01601f19169190910160400192915050565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b90815260200190565b60005b8381101561102257818101518382015260200161100a565b838111156103e95750506000910152565b6001600160a01b038116811461104857600080fd5b5056fea2646970667358221220260383f23709db660967a522664682b39439430262c686f1ff999462e44f3aff64736f6c634300060c0033", + "devdoc": { + "kind": "dev", + "methods": { + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 4406, + "contract": "contracts/v1/incentives/RewardProgramFactory.sol:RewardProgramFactory", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 19454, + "contract": "contracts/v1/incentives/RewardProgramFactory.sol:RewardProgramFactory", + "label": "_template", + "offset": 0, + "slot": "1", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + } + } + } +} \ No newline at end of file diff --git a/deployments/mainnet/RewardProgramSUSD.json b/deployments/mainnet/RewardProgramSUSD.json new file mode 100644 index 0000000..87a143c --- /dev/null +++ b/deployments/mainnet/RewardProgramSUSD.json @@ -0,0 +1,814 @@ +{ + "address": "0x9090EFbe2688F05E1D1af77C4F68Adc9b6E077C4", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "AssetDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "AssetRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "AssetRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardProgramFunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "RewardProgramOutOfFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewarded", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remaining", + "type": "uint256" + } + ], + "name": "RewardsClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "parentNftUuid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "calculateRewardsEarned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "fundProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "parentNftUuid", + "type": "uint256" + } + ], + "name": "getAssetStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimableRewards", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + } + ], + "internalType": "struct IRewardProgram.AssetStake", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getClaimableRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFundBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProgramData", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + } + ], + "internalType": "struct IRewardProgram.ProgramRewardData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + }, + { + "internalType": "address", + "name": "chargedManagers", + "type": "address" + }, + { + "internalType": "address", + "name": "universe", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "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": "nonpayable", + "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": "nonpayable", + "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": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "registerAssetDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "registerAssetRelease", + "outputs": [ + { + "internalType": "uint256", + "name": "rewards", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + } + ], + "name": "registerExistingDeposits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newMultiplier", + "type": "uint256" + } + ], + "name": "setBaseMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "setChargedManagers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newRewardToken", + "type": "address" + } + ], + "name": "setRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newStakingToken", + "type": "address" + } + ], + "name": "setStakingToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "universe", + "type": "address" + } + ], + "name": "setUniverse", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x1fc82cb56a8a61526643e0f65031cb76a259337f99b183b2e6559b33cf70e548", + "numDeployments": 1 +} \ No newline at end of file diff --git a/deployments/mainnet/RewardProgramUSDC.json b/deployments/mainnet/RewardProgramUSDC.json new file mode 100644 index 0000000..6712f56 --- /dev/null +++ b/deployments/mainnet/RewardProgramUSDC.json @@ -0,0 +1,814 @@ +{ + "address": "0xeF7E9e26878e09B02B7B3E323FCC80b800722Aa6", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "AssetDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "AssetRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "AssetRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardProgramFunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "RewardProgramOutOfFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewarded", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remaining", + "type": "uint256" + } + ], + "name": "RewardsClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "parentNftUuid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "calculateRewardsEarned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "fundProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "parentNftUuid", + "type": "uint256" + } + ], + "name": "getAssetStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimableRewards", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + } + ], + "internalType": "struct IRewardProgram.AssetStake", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getClaimableRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFundBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProgramData", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + } + ], + "internalType": "struct IRewardProgram.ProgramRewardData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + }, + { + "internalType": "address", + "name": "chargedManagers", + "type": "address" + }, + { + "internalType": "address", + "name": "universe", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "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": "nonpayable", + "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": "nonpayable", + "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": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "registerAssetDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "registerAssetRelease", + "outputs": [ + { + "internalType": "uint256", + "name": "rewards", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + } + ], + "name": "registerExistingDeposits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newMultiplier", + "type": "uint256" + } + ], + "name": "setBaseMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "setChargedManagers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newRewardToken", + "type": "address" + } + ], + "name": "setRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newStakingToken", + "type": "address" + } + ], + "name": "setStakingToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "universe", + "type": "address" + } + ], + "name": "setUniverse", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xa80d08eaa6a65d1a8a4c915699860e6d2017f207fc2d92ba897253075b023edf", + "numDeployments": 1 +} \ No newline at end of file diff --git a/deployments/mainnet/RewardProgramUSDT.json b/deployments/mainnet/RewardProgramUSDT.json new file mode 100644 index 0000000..6067444 --- /dev/null +++ b/deployments/mainnet/RewardProgramUSDT.json @@ -0,0 +1,814 @@ +{ + "address": "0x3426219C2a1557E2BBd5A1201F0d29CA1BB7CfF2", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "AssetDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "AssetRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "AssetRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardProgramFunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "RewardProgramOutOfFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewarded", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remaining", + "type": "uint256" + } + ], + "name": "RewardsClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "parentNftUuid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "calculateRewardsEarned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "fundProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "parentNftUuid", + "type": "uint256" + } + ], + "name": "getAssetStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimableRewards", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + } + ], + "internalType": "struct IRewardProgram.AssetStake", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getClaimableRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFundBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProgramData", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + } + ], + "internalType": "struct IRewardProgram.ProgramRewardData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + }, + { + "internalType": "address", + "name": "chargedManagers", + "type": "address" + }, + { + "internalType": "address", + "name": "universe", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "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": "nonpayable", + "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": "nonpayable", + "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": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "registerAssetDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "registerAssetRelease", + "outputs": [ + { + "internalType": "uint256", + "name": "rewards", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + } + ], + "name": "registerExistingDeposits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newMultiplier", + "type": "uint256" + } + ], + "name": "setBaseMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "setChargedManagers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newRewardToken", + "type": "address" + } + ], + "name": "setRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newStakingToken", + "type": "address" + } + ], + "name": "setStakingToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "universe", + "type": "address" + } + ], + "name": "setUniverse", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xfcafce2640a7ae03dee0b83f61adfa8d608e719706fa5bad09e7989adfaaf0ab", + "numDeployments": 1 +} \ No newline at end of file diff --git a/deployments/mainnet/UniverseRP.json b/deployments/mainnet/UniverseRP.json new file mode 100644 index 0000000..b359390 --- /dev/null +++ b/deployments/mainnet/UniverseRP.json @@ -0,0 +1,1177 @@ +{ + "address": "0xD4bd60c64586AEEdA6923F6547E6DF478a2EF686", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bosonToken", + "type": "address" + } + ], + "name": "BosonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "chargedParticles", + "type": "address" + } + ], + "name": "ChargedParticlesSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "photonSource", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "energy", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "ElectrostaticAttraction", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "photonSource", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "energy", + "type": "uint256" + } + ], + "name": "ElectrostaticDischarge", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "EsaMultiplierSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "leptonToken", + "type": "address" + } + ], + "name": "LeptonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + } + ], + "name": "NftDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + } + ], + "name": "NftRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "photonToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxSupply", + "type": "uint256" + } + ], + "name": "PhotonSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "protonToken", + "type": "address" + } + ], + "name": "ProtonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "quarkToken", + "type": "address" + } + ], + "name": "QuarkTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "RewardProgramRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardProgram", + "type": "address" + } + ], + "name": "RewardProgramSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [], + "name": "_chargedParticles", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_multiplierNft", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "uuid", + "type": "uint256" + } + ], + "name": "getNftStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositBlockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "releaseBlockNumber", + "type": "uint256" + } + ], + "internalType": "struct IUniverseRP.NftStake", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getRewardProgram", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nftTokenAmount", + "type": "uint256" + } + ], + "name": "onCovalentBond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nftTokenAmount", + "type": "uint256" + } + ], + "name": "onCovalentBreak", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creatorEnergy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onDischarge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onDischargeForCreator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assetAmount", + "type": "uint256" + } + ], + "name": "onEnergize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "newOwner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "salePrice", + "type": "uint256" + }, + { + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creatorRoyalties", + "type": "uint256" + } + ], + "name": "onProtonSale", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "creatorEnergy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onRelease", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "removeRewardProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "controller", + "type": "address" + } + ], + "name": "setChargedParticles", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + } + ], + "name": "setMultiplierNft", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "rewardProgam", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "setRewardProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x611d292e3d0e87224b233d83aba772f9c4f78f4d4329d5804264539daf69357d", + "receipt": { + "to": null, + "from": "0xb8D175F16742395F530e0b3bC1d30BD06B78CdA9", + "contractAddress": "0xD4bd60c64586AEEdA6923F6547E6DF478a2EF686", + "transactionIndex": 44, + "gasUsed": "769740", + "logsBloom": "0x00000008000000000000000000000000400000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000001000000000000000000000000002000000000020000000000000000000800000000800000000000000000000000400000000040000000000000020000000000000000000000000000000000800000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000080400000000000000000020000000200000000000000000000000000000010000000000000000000002000000", + "blockHash": "0x815871f14c64d7ca174bf05aeb38b084c275f973f794e9bf4fd0f9715a48f920", + "transactionHash": "0x611d292e3d0e87224b233d83aba772f9c4f78f4d4329d5804264539daf69357d", + "logs": [ + { + "transactionIndex": 44, + "blockNumber": 18063735, + "transactionHash": "0x611d292e3d0e87224b233d83aba772f9c4f78f4d4329d5804264539daf69357d", + "address": "0xD4bd60c64586AEEdA6923F6547E6DF478a2EF686", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000cd5032c531c4ba324f2e4747f84a15c88e31a92e" + ], + "data": "0x", + "logIndex": 102, + "blockHash": "0x815871f14c64d7ca174bf05aeb38b084c275f973f794e9bf4fd0f9715a48f920" + }, + { + "transactionIndex": 44, + "blockNumber": 18063735, + "transactionHash": "0x611d292e3d0e87224b233d83aba772f9c4f78f4d4329d5804264539daf69357d", + "address": "0xD4bd60c64586AEEdA6923F6547E6DF478a2EF686", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000b8d175f16742395f530e0b3bc1d30bd06b78cda9" + ], + "data": "0x", + "logIndex": 103, + "blockHash": "0x815871f14c64d7ca174bf05aeb38b084c275f973f794e9bf4fd0f9715a48f920" + }, + { + "transactionIndex": 44, + "blockNumber": 18063735, + "transactionHash": "0x611d292e3d0e87224b233d83aba772f9c4f78f4d4329d5804264539daf69357d", + "address": "0xD4bd60c64586AEEdA6923F6547E6DF478a2EF686", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004ccd62462070c8b8ab1614e0ca1ec449108b7f65", + "logIndex": 104, + "blockHash": "0x815871f14c64d7ca174bf05aeb38b084c275f973f794e9bf4fd0f9715a48f920" + } + ], + "blockNumber": 18063735, + "cumulativeGasUsed": "6179446", + "status": 1, + "byzantium": true + }, + "args": [ + "0xCD5032c531c4Ba324f2E4747F84A15C88E31A92E", + "0x4ccD62462070C8B8AB1614E0Ca1Ec449108B7f65", + "0x8129fc1c" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev 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\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "execute": { + "methodName": "initialize", + "args": [] + }, + "implementation": "0xCD5032c531c4Ba324f2E4747F84A15C88E31A92E", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/mainnet/UniverseRP_Implementation.json b/deployments/mainnet/UniverseRP_Implementation.json new file mode 100644 index 0000000..d33f915 --- /dev/null +++ b/deployments/mainnet/UniverseRP_Implementation.json @@ -0,0 +1,1193 @@ +{ + "address": "0xCD5032c531c4Ba324f2E4747F84A15C88E31A92E", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bosonToken", + "type": "address" + } + ], + "name": "BosonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "chargedParticles", + "type": "address" + } + ], + "name": "ChargedParticlesSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "photonSource", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "energy", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "ElectrostaticAttraction", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "photonSource", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "energy", + "type": "uint256" + } + ], + "name": "ElectrostaticDischarge", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "EsaMultiplierSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "leptonToken", + "type": "address" + } + ], + "name": "LeptonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + } + ], + "name": "NftDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + } + ], + "name": "NftRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "photonToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxSupply", + "type": "uint256" + } + ], + "name": "PhotonSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "protonToken", + "type": "address" + } + ], + "name": "ProtonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "quarkToken", + "type": "address" + } + ], + "name": "QuarkTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "RewardProgramRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardProgram", + "type": "address" + } + ], + "name": "RewardProgramSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [], + "name": "_chargedParticles", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_multiplierNft", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "uuid", + "type": "uint256" + } + ], + "name": "getNftStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositBlockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "releaseBlockNumber", + "type": "uint256" + } + ], + "internalType": "struct IUniverseRP.NftStake", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getRewardProgram", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nftTokenAmount", + "type": "uint256" + } + ], + "name": "onCovalentBond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nftTokenAmount", + "type": "uint256" + } + ], + "name": "onCovalentBreak", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creatorEnergy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onDischarge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onDischargeForCreator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assetAmount", + "type": "uint256" + } + ], + "name": "onEnergize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "newOwner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "salePrice", + "type": "uint256" + }, + { + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creatorRoyalties", + "type": "uint256" + } + ], + "name": "onProtonSale", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "creatorEnergy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onRelease", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "removeRewardProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "controller", + "type": "address" + } + ], + "name": "setChargedParticles", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + } + ], + "name": "setMultiplierNft", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "rewardProgam", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "setRewardProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x003a2eb4d2f15b50721c34e3be06df07b00d8aca77c2c8488be9370cea7aa9ec", + "receipt": { + "to": null, + "from": "0xb8D175F16742395F530e0b3bC1d30BD06B78CdA9", + "contractAddress": "0xCD5032c531c4Ba324f2E4747F84A15C88E31A92E", + "transactionIndex": 73, + "gasUsed": "2212048", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x68828585ade97ee8ce57510817a804477ec7084daa5ce448c749bdb1ac17a237", + "transactionHash": "0x003a2eb4d2f15b50721c34e3be06df07b00d8aca77c2c8488be9370cea7aa9ec", + "logs": [], + "blockNumber": 18063734, + "cumulativeGasUsed": "8278096", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "39876b9d6995fafd8c4442fb1a03f418", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bosonToken\",\"type\":\"address\"}],\"name\":\"BosonTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"chargedParticles\",\"type\":\"address\"}],\"name\":\"ChargedParticlesSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"photonSource\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"energy\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"multiplier\",\"type\":\"uint256\"}],\"name\":\"ElectrostaticAttraction\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"photonSource\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"energy\",\"type\":\"uint256\"}],\"name\":\"ElectrostaticDischarge\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"multiplier\",\"type\":\"uint256\"}],\"name\":\"EsaMultiplierSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"leptonToken\",\"type\":\"address\"}],\"name\":\"LeptonTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"}],\"name\":\"NftDeposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"}],\"name\":\"NftRelease\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"photonToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxSupply\",\"type\":\"uint256\"}],\"name\":\"PhotonSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"protonToken\",\"type\":\"address\"}],\"name\":\"ProtonTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"quarkToken\",\"type\":\"address\"}],\"name\":\"QuarkTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"RewardProgramRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"rewardProgram\",\"type\":\"address\"}],\"name\":\"RewardProgramSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC1155\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckEther\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"_chargedParticles\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"_multiplierNft\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"uuid\",\"type\":\"uint256\"}],\"name\":\"getNftStake\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"multiplier\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"depositBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"releaseBlockNumber\",\"type\":\"uint256\"}],\"internalType\":\"struct IUniverseRP.NftStake\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"getRewardProgram\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"onCovalentBond\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"onCovalentBreak\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"creatorEnergy\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverEnergy\",\"type\":\"uint256\"}],\"name\":\"onDischarge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"receiverEnergy\",\"type\":\"uint256\"}],\"name\":\"onDischargeForCreator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"}],\"name\":\"onEnergize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"salePrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"creatorRoyalties\",\"type\":\"uint256\"}],\"name\":\"onProtonSale\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"principalAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creatorEnergy\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverEnergy\",\"type\":\"uint256\"}],\"name\":\"onRelease\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"removeRewardProgram\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"controller\",\"type\":\"address\"}],\"name\":\"setChargedParticles\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"}],\"name\":\"setMultiplierNft\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rewardProgam\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"setRewardProgram\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC1155\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawErc20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawEther\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Upgradeable Contract\",\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Charged Particles Universe Contract with Rewards Program\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/v1/UniverseRP.sol\":\"UniverseRP\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/Initializable.sol\\\";\\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 initializer {\\n __Context_init_unchained();\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal initializer {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), 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 emit OwnershipTransferred(_owner, address(0));\\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xb419e68addcb82ecda3ad3974b0d2db76435ce9b08435a04d5b119a0c5d45ea5\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <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\",\"keccak256\":\"0x4784c3f8a520a739dd25d76f514833a653990902d0e21601aed45bda44c87524\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMathUpgradeable {\\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 uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\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 if (b > a) return (false, 0);\\n return (true, a - b);\\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 // 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 * @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 if (b == 0) return (false, 0);\\n return (true, a / b);\\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 if (b == 0) return (false, 0);\\n return (true, a % b);\\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 uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\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 require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\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 if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\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. 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(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\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 require(b > 0, \\\"SafeMath: modulo by zero\\\");\\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x0dd1e9b19801e3e7d900fbf4182d81e1afd23ad7be39504e33df6bbcba91d724\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// solhint-disable-next-line compiler-version\\npragma solidity >=0.4.24 <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 {UpgradeableProxy-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 */\\nabstract contract Initializable {\\n\\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 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 /// @dev Returns true if and only if the function is running in the constructor\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0xd8e4eb08dcc1d1860fb347ba5ffd595242b9a1b66d49a47f2b4cb51c3f35017e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0xa1931c47a617014f858580db625aa0dcf343796f39acd4b5b51effc092a1f0a9\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"../../math/SafeMathUpgradeable.sol\\\";\\nimport \\\"../../utils/AddressUpgradeable.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 SafeERC20Upgradeable {\\n using SafeMathUpgradeable for uint256;\\n using AddressUpgradeable for address;\\n\\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) 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(IERC20Upgradeable token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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(IERC20Upgradeable 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) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x8457e15aa90badabe0d6ef6f572f1ebd47bebf156921c825ae6e009dda15b706\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.2 <0.8.0;\\n\\nimport \\\"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x3dab19bb4a63bcbda1ee153ca291694f92f9009fad28626126b15a8503b0e5ff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.2 <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 // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) 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 // solhint-disable-next-line avoid-low-level-calls\\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(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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 // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfc5ea91fa9ceb1961023b2a6c978b902888c52b90847ac7813fe3b79524165f6\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\nimport \\\"../proxy/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 GSN 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 initializer {\\n __Context_init_unchained();\\n }\\n\\n function __Context_init_unchained() internal initializer {\\n }\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xbbf8a21b9a66c48d45ff771b8563c6df19ba451d63dfb8380a865c1e1f29d1a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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\",\"keccak256\":\"0xfa152b6e88a1dc50780e8f1580426dc23ad2e1e2c2f086a088adf206a202f453\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\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 uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\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 sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\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 * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\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 // 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) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts 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 mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9a9cf02622cd7a64261b10534fc3260449da25c98c9e96d1b4ae8110a20e5806\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x31691ad0817f8cb338531b78d2ab2989027d9f27e6f8e62492b754fed9429b10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0x5c26b39d26f7ed489e555d955dcd3e01872972e71fdd1528e93ec164e4f23385\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.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 SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf3b30f8a49631420635a8c35daacfcaa338012755f18a76fdd118730256f9a27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0xaf936da92f3a9a4f98b237323b5eb1d813fb86c4d07a184beba7027cf0509ba3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 in 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 // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n return _functionCallWithValue(target, data, value, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\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 // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf5fa8cbdffa5ef8be49b246b5628facc30b71707e78a45d80d93b64eff3fe390\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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.0.0, only sets of type `address` (`AddressSet`) and `uint256`\\n * (`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\\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\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] = toDeleteIndex + 1; // All indexes are 1-based\\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 require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\n return set._values[index];\\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(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(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(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(uint256(_at(set._inner, index)));\\n }\\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\",\"keccak256\":\"0xb2a11b236f073662f5a196995863f51c11d006bf7c3de158b316dfa1506c4b79\",\"license\":\"MIT\"},\"contracts/v1/UniverseRP.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// Universe.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/EnumerableSet.sol\\\";\\n\\nimport \\\"./interfaces/IUniverseRP.sol\\\";\\nimport \\\"./interfaces/IChargedParticles.sol\\\";\\nimport \\\"./interfaces/ILepton.sol\\\";\\nimport \\\"./interfaces/IRewardNft.sol\\\";\\nimport \\\"./lib/TokenInfo.sol\\\";\\nimport \\\"./lib/BlackholePrevention.sol\\\";\\nimport \\\"./interfaces/IRewardProgram.sol\\\";\\n\\n/**\\n * @notice Charged Particles Universe Contract with Rewards Program\\n * @dev Upgradeable Contract\\n */\\ncontract UniverseRP is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\\n using SafeMathUpgradeable for uint256;\\n using TokenInfo for address;\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n using EnumerableSet for EnumerableSet.UintSet;\\n\\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\\n\\n // The ChargedParticles Contract Address\\n address public _chargedParticles;\\n\\n // The Lepton NFT Contract Address\\n address public _multiplierNft;\\n\\n // Asset Token => Reward Program\\n mapping (address => address) internal _assetRewardPrograms;\\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\\n\\n // Token UUID => NFT Staking Data\\n mapping (uint256 => NftStake) private _nftStake;\\n\\n\\n /***********************************|\\n | Initialization |\\n |__________________________________*/\\n\\n function initialize() public initializer {\\n __Ownable_init();\\n }\\n\\n function getRewardProgram(address asset) external view override returns (address) {\\n return _getRewardProgram(asset);\\n }\\n\\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\\n return _nftStake[uuid];\\n }\\n\\n /***********************************|\\n | Only Charged Particles |\\n |__________________________________*/\\n\\n function onEnergize(\\n address /* sender */,\\n address /* referrer */,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n address rewardProgram = _getRewardProgram(assetToken);\\n if (rewardProgram != address(0)) {\\n IRewardProgram(rewardProgram).registerAssetDeposit(\\n contractAddress,\\n tokenId,\\n walletManagerId,\\n assetAmount\\n );\\n }\\n }\\n\\n function onDischarge(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* walletManagerId */,\\n address assetToken,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n address rewardProgram = _getRewardProgram(assetToken);\\n if (rewardProgram != address(0)) {\\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\\n }\\n }\\n\\n function onDischargeForCreator(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* walletManagerId */,\\n address /* creator */,\\n address assetToken,\\n uint256 receiverEnergy\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n address rewardProgram = _getRewardProgram(assetToken);\\n if (rewardProgram != address(0)) {\\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\\n }\\n }\\n\\n function onRelease(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* walletManagerId */,\\n address assetToken,\\n uint256 principalAmount,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n address rewardProgram = _getRewardProgram(assetToken);\\n if (rewardProgram != address(0)) {\\n // \\\"receiverEnergy\\\" includes the \\\"principalAmount\\\"\\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\\n }\\n }\\n\\n function onCovalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* managerId */,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\\n }\\n\\n function onCovalentBreak(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* managerId */,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\\n }\\n\\n function onProtonSale(\\n address contractAddress,\\n uint256 tokenId,\\n address oldOwner,\\n address newOwner,\\n uint256 salePrice,\\n address creator,\\n uint256 creatorRoyalties\\n )\\n external\\n virtual\\n override\\n {\\n // no-op\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n |__________________________________*/\\n\\n function setChargedParticles(\\n address controller\\n )\\n external\\n onlyOwner\\n onlyValidContractAddress(controller)\\n {\\n _chargedParticles = controller;\\n emit ChargedParticlesSet(controller);\\n }\\n\\n function setMultiplierNft(address nftTokenAddress)\\n external\\n onlyOwner\\n onlyValidContractAddress(nftTokenAddress)\\n {\\n _multiplierNft = nftTokenAddress;\\n }\\n\\n function setRewardProgram(\\n address rewardProgam,\\n address assetToken\\n )\\n external\\n onlyOwner\\n onlyValidContractAddress(rewardProgam)\\n {\\n require(assetToken != address(0x0), \\\"UNI:E-403\\\");\\n _assetRewardPrograms[assetToken] = rewardProgam;\\n emit RewardProgramSet(assetToken, rewardProgam);\\n }\\n\\n function removeRewardProgram(address assetToken) external onlyOwner {\\n delete _assetRewardPrograms[assetToken];\\n emit RewardProgramRemoved(assetToken);\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n | (blackhole prevention) |\\n |__________________________________*/\\n\\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n\\n\\n /***********************************|\\n | Private Functions |\\n |__________________________________*/\\n\\n function _getRewardProgram(address assetToken) internal view returns (address) {\\n return _assetRewardPrograms[assetToken];\\n }\\n\\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\\n internal\\n {\\n // We only care about the Multiplier NFT\\n if (_multiplierNft != depositNftAddress) { return; }\\n\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n uint256 multiplier = _getNftMultiplier(depositNftAddress, depositNftTokenId);\\n\\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\\n // Add to Multipliers Set\\n _multiplierNftsSet[parentNftUuid].add(multiplier);\\n\\n // Update NFT Stake\\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\\n } else {\\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\\n }\\n }\\n\\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\\n }\\n\\n function _registerNftRelease(\\n address contractAddress,\\n uint256 tokenId,\\n address releaseNftAddress,\\n uint256 releaseNftTokenId,\\n uint256 /* nftTokenAmount */\\n )\\n internal\\n {\\n // We only care about the Multiplier NFT\\n if (_multiplierNft != releaseNftAddress) { return; }\\n\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n NftStake storage nftStake = _nftStake[parentNftUuid];\\n\\n // Remove from Multipliers Set\\n uint256 multiplier = _getNftMultiplier(releaseNftAddress, releaseNftTokenId);\\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\\n\\n // Determine New Multiplier or Mark as Released\\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\\n } else {\\n nftStake.releaseBlockNumber = block.number;\\n }\\n\\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\\n }\\n\\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\\n uint256 multiplier = 0;\\n uint256 loss = 50;\\n uint256 i = 0;\\n\\n for (; i < len; i++) {\\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\\n }\\n if (len > 1) {\\n multiplier = multiplier.sub(loss.mul(len));\\n }\\n return multiplier;\\n }\\n\\n function _getNftMultiplier(address contractAddress, uint256 tokenId) internal returns (uint256) {\\n bytes4 fnSig = IRewardNft.getMultiplier.selector;\\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\\n\\n if (success) {\\n return abi.decode(returnData, (uint256));\\n } else {\\n return 0;\\n }\\n }\\n\\n\\n /***********************************|\\n | Modifiers |\\n |__________________________________*/\\n\\n /// @dev Throws if called by any non-account\\n modifier onlyValidContractAddress(address account) {\\n require(account != address(0x0) && account.isContract(), \\\"UNI:E-417\\\");\\n _;\\n }\\n\\n /// @dev Throws if called by any account other than the Charged Particles contract\\n modifier onlyChargedParticles() {\\n require(_chargedParticles == msg.sender, \\\"UNI:E-108\\\");\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x5ec2e8a1bbcbb7cc8bb11a500e29df20aaa34c76a3c6963b508a377da076ba0b\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IChargedParticles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @notice Interface for Charged Particles\\n */\\ninterface IChargedParticles {\\n\\n /***********************************|\\n | Public API |\\n |__________________________________*/\\n\\n function getStateAddress() external view returns (address stateAddress);\\n function getSettingsAddress() external view returns (address settingsAddress);\\n function getManagersAddress() external view returns (address managersAddress);\\n\\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\\n\\n /***********************************|\\n | Particle Mechanics |\\n |__________________________________*/\\n\\n function energizeParticle(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount,\\n address referrer\\n ) external returns (uint256 yieldTokensAmount);\\n\\n function dischargeParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function dischargeParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function dischargeParticleForCreator(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 receiverAmount);\\n\\n function releaseParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function releaseParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function covalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success);\\n\\n function breakCovalentBond(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success);\\n\\n /***********************************|\\n | Particle Events |\\n |__________________________________*/\\n\\n event Initialized(address indexed initiator);\\n event ControllerSet(address indexed controllerAddress, string controllerId);\\n event DepositFeeSet(uint256 depositFee);\\n event ProtocolFeesCollected(address indexed assetToken, uint256 depositAmount, uint256 feesCollected);\\n}\\n\",\"keccak256\":\"0x37104c629e40193ddc8677af8a632adf53754e7915f055a5a14861cd9b417729\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IERC721Chargeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IERC721Chargeable.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\\\";\\n\\ninterface IERC721Chargeable is IERC165Upgradeable {\\n function owner() external view returns (address);\\n function creatorOf(uint256 tokenId) external view returns (address);\\n function balanceOf(address tokenOwner) external view returns (uint256 balance);\\n function ownerOf(uint256 tokenId) external view returns (address tokenOwner);\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n function transferFrom(address from, address to, uint256 tokenId) external;\\n function approve(address to, uint256 tokenId) external;\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n function setApprovalForAll(address operator, bool _approved) external;\\n function isApprovedForAll(address tokenOwner, address operator) external view returns (bool);\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x459e57b2d35c7cd78e6c3d47eb9f3e981529a18c89e2c318b10fe369c479c737\",\"license\":\"MIT\"},\"contracts/v1/interfaces/ILepton.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// ILepton.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Charged Particles Lepton Interface\\n * @dev ...\\n */\\ninterface ILepton {\\n\\n struct Classification {\\n string tokenUri;\\n uint256 price;\\n uint128 _upperBounds;\\n uint32 supply;\\n uint32 multiplier;\\n uint32 bonus;\\n }\\n\\n function mintLepton() external payable returns (uint256 newTokenId);\\n function batchMintLepton(uint256 count) external payable;\\n function getNextType() external view returns (uint256);\\n function getNextPrice() external view returns (uint256);\\n function getMultiplier(uint256 tokenId) external view returns (uint256);\\n function getBonus(uint256 tokenId) external view returns (uint256);\\n\\n\\n event MaxMintPerTxSet(uint256 maxAmount);\\n event LeptonTypeAdded(string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\\n event LeptonTypeUpdated(uint256 leptonIndex, string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\\n event LeptonMinted(address indexed receiver, uint256 indexed tokenId, uint256 price, uint32 multiplier);\\n event LeptonBatchMinted(address indexed receiver, uint256 indexed tokenId, uint256 count, uint256 price, uint32 multiplier);\\n event PausedStateSet(bool isPaused);\\n}\\n\",\"keccak256\":\"0x4903085427fa5dbee690fe79854fba60afaf21189957406ade55f6fc12556a01\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IRewardNft.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IRewardNft.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Charged Particles Reward-NFT Interface\\n * @dev ...\\n */\\ninterface IRewardNft {\\n function getMultiplier(uint256 tokenId) external view returns (uint256);\\n function getBonus(uint256 tokenId) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x51a5666003af460a55356974a286dde959c5f166104c75b4d563e8294a90b07a\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IRewardProgram.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IRewardProgram.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\npragma experimental ABIEncoderV2;\\n\\ninterface IRewardProgram {\\n /* admin events */\\n event RewardProgramFunded(uint256 amount);\\n event RewardProgramOutOfFunds();\\n\\n /* user events */\\n event RewardsClaimed(address indexed contractAddress, uint256 tokenId, address indexed receiver, uint256 rewarded, uint256 remaining);\\n\\n event AssetRegistered(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\\n event AssetDeposit(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\\n event AssetRelease(address indexed contractAddress, uint256 tokenId, uint256 interestAmount);\\n\\n /* data types */\\n struct ProgramRewardData {\\n address stakingToken;\\n address rewardToken;\\n uint256 baseMultiplier; // Basis Points\\n }\\n\\n struct AssetStake {\\n uint256 start;\\n uint256 claimableRewards;\\n string walletManagerId;\\n }\\n\\n function initialize(address stakingToken, address rewardToken, uint256 baseMultiplier, address chargedManagers, address universe, address owner) external;\\n\\n /* user functions */\\n function getProgramData() external view returns (ProgramRewardData memory programData);\\n function getAssetStake(uint256 uuid) external view returns (AssetStake memory);\\n function getFundBalance() external view returns (uint256);\\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) external view returns (uint256);\\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view returns (uint256);\\n\\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external;\\n function registerAssetDeposit(address contractAddress, uint256 tokenId, string calldata walletManagerId, uint256 principalAmount) external;\\n function registerAssetRelease(address contractAddress, uint256 tokenId, uint256 interestAmount) external returns (uint256 rewards);\\n}\",\"keccak256\":\"0xe0f4076a4b001856c54cb8a63decedc81ca34c71708f8cbe9b3a26603dc9c050\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IUniverse.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IUniverse.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Universal Controller interface\\n * @dev ...\\n */\\ninterface IUniverse {\\n\\n event ChargedParticlesSet(address indexed chargedParticles);\\n event PhotonSet(address indexed photonToken, uint256 maxSupply);\\n event ProtonTokenSet(address indexed protonToken);\\n event LeptonTokenSet(address indexed leptonToken);\\n event QuarkTokenSet(address indexed quarkToken);\\n event BosonTokenSet(address indexed bosonToken);\\n event EsaMultiplierSet(address indexed assetToken, uint256 multiplier);\\n event ElectrostaticAttraction(address indexed account, address photonSource, uint256 energy, uint256 multiplier);\\n event ElectrostaticDischarge(address indexed account, address photonSource, uint256 energy);\\n\\n function onEnergize(\\n address sender,\\n address referrer,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 assetEnergy\\n ) external;\\n\\n function onDischarge(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onDischargeForCreator(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address creator,\\n address assetToken,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onRelease(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 principalEnergy,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onCovalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n\\n function onCovalentBreak(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n\\n function onProtonSale(\\n address contractAddress,\\n uint256 tokenId,\\n address oldOwner,\\n address newOwner,\\n uint256 salePrice,\\n address creator,\\n uint256 creatorRoyalties\\n ) external;\\n}\\n\",\"keccak256\":\"0x6cebb97ce4d32c61afc746e4a6538eb605bb01276dfa66fa4bd6f63362bdc9ef\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IUniverseRP.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IUniverseRP.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"./IUniverse.sol\\\";\\n\\n/**\\n * @title Universal Controller interface for Rewards Program\\n * @dev ...\\n */\\ninterface IUniverseRP is IUniverse {\\n event RewardProgramSet(address indexed assetToken, address indexed rewardProgram);\\n event RewardProgramRemoved(address indexed assetToken);\\n event NftDeposit(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\\n event NftRelease(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\\n\\n struct NftStake {\\n uint256 multiplier; // in Basis Points\\n uint256 depositBlockNumber;\\n uint256 releaseBlockNumber;\\n }\\n\\n function getRewardProgram(address asset) external view returns (address);\\n function getNftStake(uint256 uuid) external view returns (NftStake memory);\\n}\\n\",\"keccak256\":\"0xd9c5a996bbb7f2a27bb85dde52587f7368c7b6512fc1064821a3975acdf4b7db\",\"license\":\"MIT\"},\"contracts/v1/lib/BlackholePrevention.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\\\";\\n\\n/**\\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\\n * the Owner/DAO to pull them out on behalf of a user\\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\\n */\\ncontract BlackholePrevention {\\n using Address for address payable;\\n using SafeERC20 for IERC20;\\n\\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\\n\\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (address(this).balance >= amount) {\\n receiver.sendValue(amount);\\n emit WithdrawStuckEther(receiver, amount);\\n }\\n }\\n\\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\\n IERC20(tokenAddress).safeTransfer(receiver, amount);\\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\\n }\\n }\\n\\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\\n }\\n }\\n\\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \\\"\\\");\\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6a664c8a1c1d7fb32ade2c11f75756b1fdb4c489daa32c1d58e6b867ea2ba8d6\",\"license\":\"MIT\"},\"contracts/v1/lib/TokenInfo.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// TokenInfo.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport \\\"../interfaces/IERC721Chargeable.sol\\\";\\n\\nlibrary TokenInfo {\\n function getTokenUUID(address contractAddress, uint256 tokenId) internal pure virtual returns (uint256) {\\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n function getTokenOwner(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n return tokenInterface.ownerOf(tokenId);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n function getTokenCreator(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n return tokenInterface.creatorOf(tokenId);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Owner of an External NFT contract\\n /// @param contractAddress The Address to the Contract of the NFT to check\\n /// @param account The Address of the Account to check\\n /// @return True if the account owns the contract\\n function isContractOwner(address contractAddress, address account) internal view virtual returns (bool) {\\n address contractOwner = IERC721Chargeable(contractAddress).owner();\\n return contractOwner != address(0x0) && contractOwner == account;\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Creator of a Proton-based NFT\\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\\n /// @param tokenId The Token ID of the Proton-based NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the creator of the Proton-based NFT\\n function isTokenCreator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenCreator = tokenInterface.creatorOf(tokenId);\\n return (sender == tokenCreator);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\\n /// @param tokenId The Token ID of the Proton-based NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the creator of the Proton-based NFT or the Contract itself\\n function isTokenContractOrCreator(address contractAddress, uint256 tokenId, address creator, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenCreator = tokenInterface.creatorOf(tokenId);\\n if (sender == contractAddress && creator == tokenCreator) { return true; }\\n return (sender == tokenCreator);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Owner or Operator of an External NFT\\n /// @param contractAddress The Address to the Contract of the External NFT to check\\n /// @param tokenId The Token ID of the External NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the Owner or Operator of the External NFT\\n function isErc721OwnerOrOperator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenOwner = tokenInterface.ownerOf(tokenId);\\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\\n }\\n\\n /**\\n * @dev Returns true if `account` is a contract.\\n * @dev Taken from OpenZeppelin library\\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { codehash := extcodehash(account) }\\n return (codehash != accountHash && codehash != 0x0);\\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 * @dev Taken from OpenZeppelin library\\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, uint256 gasLimit) internal {\\n require(address(this).balance >= amount, \\\"TokenInfo: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = (gasLimit > 0)\\n ? recipient.call{ value: amount, gas: gasLimit }(\\\"\\\")\\n : recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"TokenInfo: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0xbc78c6173db068d95084288246642402d0f4af399e1eb754182cae2d9173af5e\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061270a806100206000396000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c80638da5cb5b116100c3578063b9e09b4b1161007c578063b9e09b4b1461028e578063bbf1da84146102a1578063bea38be0146102a9578063c5d1d706146102bc578063f2fde38b146102cf578063fbf5ca14146102e25761014d565b80638da5cb5b14610227578063945233e21461022f57806395469dfc146102425780639a87c0de14610255578063a0edb48b14610268578063aa29542d1461027b5761014d565b8063522f681511610115578063522f6815146101be5780636e5559fd146101d1578063715018a6146101e45780638129fc1c146101ec578063836c478d146101f45780638b9309b2146102145761014d565b80631593dee1146101525780632bdbb77f1461016757806330219ef41461017a5780634025feb21461019857806341db85d6146101ab575b600080fd5b610165610160366004611d6c565b6102f5565b005b610165610175366004611ffc565b61034d565b61018261038d565b60405161018f919061219b565b60405180910390f35b6101656101a6366004611d6c565b61039c565b6101656101b9366004611ffc565b6103e6565b6101656101cc366004611df1565b6104ca565b6101656101df366004611d34565b610517565b6101656105e3565b61016561066c565b61020761020236600461212a565b6106f7565b60405161018f919061265b565b610165610222366004611ef4565b610384565b610182610738565b61016561023d366004611d34565b610747565b610165610250366004611e1c565b6107d5565b610165610263366004611d34565b6108d4565b610165610276366004611dac565b610978565b610165610289366004611f6e565b6109c9565b61016561029c366004611e54565b610a9c565b610182610b53565b6101656102b7366004611ffc565b610b62565b6101826102ca366004611d34565b610b99565b6101656102dd366004611d34565b610baa565b6101656102f0366004612080565b610c6b565b6102fd610d59565b6001600160a01b031661030e610738565b6001600160a01b03161461033d5760405162461bcd60e51b815260040161033490612582565b60405180910390fd5b610348838383610d5d565b505050565b6065546001600160a01b031633146103775760405162461bcd60e51b8152600401610334906125b7565b6103848787858585610e6a565b50505050505050565b6065546001600160a01b031681565b6103a4610d59565b6001600160a01b03166103b5610738565b6001600160a01b0316146103db5760405162461bcd60e51b815260040161033490612582565b610348838383610ffd565b6065546001600160a01b031633146104105760405162461bcd60e51b8152600401610334906125b7565b600061041b84611158565b90506001600160a01b038116156104c05760006104388385611176565b604051631434318f60e21b81529091506001600160a01b038316906350d0c63c9061046b908c908c908690600401612275565b602060405180830381600087803b15801561048557600080fd5b505af1158015610499573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bd9190612142565b50505b5050505050505050565b6104d2610d59565b6001600160a01b03166104e3610738565b6001600160a01b0316146105095760405162461bcd60e51b815260040161033490612582565b61051382826111a2565b5050565b61051f610d59565b6001600160a01b0316610530610738565b6001600160a01b0316146105565760405162461bcd60e51b815260040161033490612582565b806001600160a01b0381161580159061057c575061057c816001600160a01b0316611226565b6105985760405162461bcd60e51b815260040161033490612397565b606580546001600160a01b0319166001600160a01b0384169081179091556040517f5ce0e6b7fd36339ee97339831b6c72694ecee88c62aab49919d9cabe0a732e4190600090a25050565b6105eb610d59565b6001600160a01b03166105fc610738565b6001600160a01b0316146106225760405162461bcd60e51b815260040161033490612582565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b600054610100900460ff16806106855750610685611262565b80610693575060005460ff16155b6106af5760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff161580156106da576000805460ff1961ff0019909116610100171660011790555b6106e2611273565b80156106f4576000805461ff00191690555b50565b6106ff611ccc565b50600090815260696020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b6033546001600160a01b031690565b61074f610d59565b6001600160a01b0316610760610738565b6001600160a01b0316146107865760405162461bcd60e51b815260040161033490612582565b6001600160a01b03811660008181526067602052604080822080546001600160a01b0319169055517f87e1027e3dc61d1977f39f0dfe911b66a943946b4ceb39210dee01495621de529190a250565b6107dd610d59565b6001600160a01b03166107ee610738565b6001600160a01b0316146108145760405162461bcd60e51b815260040161033490612582565b816001600160a01b0381161580159061083a575061083a816001600160a01b0316611226565b6108565760405162461bcd60e51b815260040161033490612397565b6001600160a01b03821661087c5760405162461bcd60e51b81526004016103349061230b565b6001600160a01b0382811660008181526067602052604080822080546001600160a01b0319169488169485179055517f3b76c6366ef8a1f8d2dbb75e4be27be1e0749716fff3e6bc327da9c6158deada9190a3505050565b6108dc610d59565b6001600160a01b03166108ed610738565b6001600160a01b0316146109135760405162461bcd60e51b815260040161033490612582565b806001600160a01b038116158015906109395750610939816001600160a01b0316611226565b6109555760405162461bcd60e51b815260040161033490612397565b50606680546001600160a01b0319166001600160a01b0392909216919091179055565b610980610d59565b6001600160a01b0316610991610738565b6001600160a01b0316146109b75760405162461bcd60e51b815260040161033490612582565b6109c3848484846112f1565b50505050565b6065546001600160a01b031633146109f35760405162461bcd60e51b8152600401610334906125b7565b60006109fe83611158565b90506001600160a01b038116156104c057604051631434318f60e21b81526001600160a01b038216906350d0c63c90610a3f908b908b908790600401612275565b602060405180830381600087803b158015610a5957600080fd5b505af1158015610a6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a919190612142565b505050505050505050565b6065546001600160a01b03163314610ac65760405162461bcd60e51b8152600401610334906125b7565b6000610ad183611158565b90506001600160a01b03811615610a91576040516323632fb160e11b81526001600160a01b038216906346c65f6290610b16908a908a908a908a908990600401612224565b600060405180830381600087803b158015610b3057600080fd5b505af1158015610b44573d6000803e3d6000fd5b50505050505050505050505050565b6066546001600160a01b031681565b6065546001600160a01b03163314610b8c5760405162461bcd60e51b8152600401610334906125b7565b6103848787858585611450565b6000610ba482611158565b92915050565b610bb2610d59565b6001600160a01b0316610bc3610738565b6001600160a01b031614610be95760405162461bcd60e51b815260040161033490612582565b6001600160a01b038116610c0f5760405162461bcd60e51b81526004016103349061232e565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6065546001600160a01b03163314610c955760405162461bcd60e51b8152600401610334906125b7565b6000610ca085611158565b90506001600160a01b03811615610a91576000610cc784610cc18588611541565b90611176565b604051631434318f60e21b81529091506001600160a01b038316906350d0c63c90610cfa908d908d908690600401612275565b602060405180830381600087803b158015610d1457600080fd5b505af1158015610d28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4c9190612142565b5050505050505050505050565b3390565b6001600160a01b038316610d835760405162461bcd60e51b815260040161033490612374565b6040516370a0823160e01b815281906001600160a01b038416906370a0823190610db190309060040161219b565b60206040518083038186803b158015610dc957600080fd5b505afa158015610ddd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e019190612142565b1061034857610e1a6001600160a01b0383168483611569565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b83604051610e5d919061267c565b60405180910390a3505050565b6066546001600160a01b03848116911614610e8457610ff6565b6000610e996001600160a01b038716866115bf565b90506000610ea785856115f3565b9050600081118015610ece57506000828152606860205260409020610ecc90826116d5565b155b15610fa6576000828152606860205260409020610eeb90826116e1565b506000610ef7836116ed565b600084815260696020526040902060010154909150610f5157604080516060810182528281524360208083019182526000838501818152888252606990925293909320915182555160018201559051600290910155610fa4565b60008381526069602052604090206001810154908290554303610f90610f7882600261176d565b60008681526069602052604090206001015490611176565b600085815260696020526040902060010155505b505b846001600160a01b0316876001600160a01b03167f186ebbe503be539e070ca73b33a78f4266d96003e62b888dc31f88a39ddc9c878887604051610feb929190612685565b60405180910390a350505b5050505050565b6001600160a01b0383166110235760405162461bcd60e51b815260040161033490612374565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e9061105190859060040161267c565b60206040518083038186803b15801561106957600080fd5b505afa15801561107d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a19190611d50565b6001600160a01b03161415610348576040516323b872dd60e01b81526001600160a01b038316906323b872dd906110e0903090879086906004016121af565b600060405180830381600087803b1580156110fa57600080fd5b505af115801561110e573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b039081166000908152606760205260409020541690565b60008282018381101561119b5760405162461bcd60e51b8152600401610334906123ba565b9392505050565b6001600160a01b0382166111c85760405162461bcd60e51b815260040161033490612374565b804710610513576111e26001600160a01b0383168261179f565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd8260405161121a919061267c565b60405180910390a25050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061125a57508115155b949350505050565b600061126d3061183b565b15905090565b600054610100900460ff168061128c575061128c611262565b8061129a575060005460ff16155b6112b65760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff161580156112e1576000805460ff1961ff0019909116610100171660011790555b6112e9611841565b6106e26118c2565b6001600160a01b0384166113175760405162461bcd60e51b815260040161033490612374565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e90611345903090879060040161220b565b60206040518083038186803b15801561135d57600080fd5b505afa158015611371573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113959190612142565b106109c357604051637921219560e11b81526001600160a01b0384169063f242432a906113cc9030908890879087906004016121d3565b600060405180830381600087803b1580156113e657600080fd5b505af11580156113fa573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b84604051611442919061267c565b60405180910390a450505050565b6066546001600160a01b0384811691161461146a57610ff6565b600061147f6001600160a01b038716866115bf565b600081815260696020526040812091925061149a86866115f3565b60008481526068602052604090209091506114b5908261199c565b5060008381526068602052604081206114cd906119a8565b11156114e3576114dc836116ed565b82556114ea565b4360028301555b856001600160a01b0316886001600160a01b03167ff3cfcfc091fdd683cf6c013de9806af93f3af27b256a57cb776331291cef4085898860405161152f929190612685565b60405180910390a35050505050505050565b6000828211156115635760405162461bcd60e51b8152600401610334906123f1565b50900390565b6103488363a9059cbb60e01b848460405160240161158892919061220b565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526119b3565b600082826040516020016115d492919061215a565b60408051601f1981840301815291905280516020909101209392505050565b60008063adf8252d60e01b905060006060856001600160a01b03168386604051602401611620919061267c565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161165e919061217c565b6000604051808303816000865af19150503d806000811461169b576040519150601f19603f3d011682016040523d82523d6000602084013e6116a0565b606091505b509150915081156116c957808060200190518101906116bf9190612142565b9350505050610ba4565b60009350505050610ba4565b600061119b8383611a42565b600061119b8383611a5a565b60008181526068602052604081208190611706906119a8565b905060006032815b83811015611743576000868152606860205260409020611739906117329083611aa4565b8490611176565b925060010161170e565b6001841115611763576117606117598386611ab0565b8490611541565b92505b5090949350505050565b600080821161178e5760405162461bcd60e51b8152600401610334906124bc565b81838161179757fe5b049392505050565b804710156117bf5760405162461bcd60e51b815260040161033490612485565b6000826001600160a01b0316826040516117d890612198565b60006040518083038185875af1925050503d8060008114611815576040519150601f19603f3d011682016040523d82523d6000602084013e61181a565b606091505b50509050806103485760405162461bcd60e51b815260040161033490612428565b3b151590565b600054610100900460ff168061185a575061185a611262565b80611868575060005460ff16155b6118845760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff161580156106e2576000805460ff1961ff00199091166101001716600117905580156106f4576000805461ff001916905550565b600054610100900460ff16806118db57506118db611262565b806118e9575060005460ff16155b6119055760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff16158015611930576000805460ff1961ff0019909116610100171660011790555b600061193a610d59565b603380546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35080156106f4576000805461ff001916905550565b600061119b8383611aea565b6000610ba482611bb0565b6060611a08826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611bb49092919063ffffffff16565b8051909150156103485780806020019051810190611a26919061210a565b6103485760405162461bcd60e51b815260040161033490612611565b60009081526001919091016020526040902054151590565b6000611a668383611a42565b611a9c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ba4565b506000610ba4565b600061119b8383611bc3565b600082611abf57506000610ba4565b82820282848281611acc57fe5b041461119b5760405162461bcd60e51b815260040161033490612541565b60008181526001830160205260408120548015611ba65783546000198083019190810190600090879083908110611b1d57fe5b9060005260206000200154905080876000018481548110611b3a57fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080611b6a57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610ba4565b6000915050610ba4565b5490565b606061125a8484600085611c08565b81546000908210611be65760405162461bcd60e51b8152600401610334906122c9565b826000018281548110611bf557fe5b9060005260206000200154905092915050565b6060611c138561183b565b611c2f5760405162461bcd60e51b8152600401610334906125da565b60006060866001600160a01b03168587604051611c4c919061217c565b60006040518083038185875af1925050503d8060008114611c89576040519150601f19603f3d011682016040523d82523d6000602084013e611c8e565b606091505b50915091508115611ca257915061125a9050565b805115611cb25780518082602001fd5b8360405162461bcd60e51b81526004016103349190612296565b60405180606001604052806000815260200160008152602001600081525090565b60008083601f840112611cfe578182fd5b50813567ffffffffffffffff811115611d15578182fd5b602083019150836020828501011115611d2d57600080fd5b9250929050565b600060208284031215611d45578081fd5b813561119b816126bf565b600060208284031215611d61578081fd5b815161119b816126bf565b600080600060608486031215611d80578182fd5b8335611d8b816126bf565b92506020840135611d9b816126bf565b929592945050506040919091013590565b60008060008060808587031215611dc1578081fd5b8435611dcc816126bf565b93506020850135611ddc816126bf565b93969395505050506040820135916060013590565b60008060408385031215611e03578182fd5b8235611e0e816126bf565b946020939093013593505050565b60008060408385031215611e2e578182fd5b8235611e39816126bf565b91506020830135611e49816126bf565b809150509250929050565b60008060008060008060008060e0898b031215611e6f578384fd5b8835611e7a816126bf565b97506020890135611e8a816126bf565b96506040890135611e9a816126bf565b955060608901359450608089013567ffffffffffffffff811115611ebc578485fd5b611ec88b828c01611ced565b90955093505060a0890135611edc816126bf565b8092505060c089013590509295985092959890939650565b600080600080600080600060e0888a031215611f0e578283fd5b8735611f19816126bf565b9650602088013595506040880135611f30816126bf565b94506060880135611f40816126bf565b93506080880135925060a0880135611f57816126bf565b8092505060c0880135905092959891949750929550565b600080600080600080600060c0888a031215611f88578283fd5b8735611f93816126bf565b965060208801359550604088013567ffffffffffffffff811115611fb5578384fd5b611fc18a828b01611ced565b9096509450506060880135611fd5816126bf565b92506080880135611fe5816126bf565b8092505060a0880135905092959891949750929550565b600080600080600080600060c0888a031215612016578081fd5b8735612021816126bf565b965060208801359550604088013567ffffffffffffffff811115612043578182fd5b61204f8a828b01611ced565b9096509450506060880135612063816126bf565b969995985093969295946080840135945060a09093013592915050565b60008060008060008060008060e0898b03121561209b578182fd5b88356120a6816126bf565b975060208901359650604089013567ffffffffffffffff8111156120c8578283fd5b6120d48b828c01611ced565b90975095505060608901356120e8816126bf565b979a96995094979396956080850135955060a08501359460c001359350915050565b60006020828403121561211b578081fd5b8151801515811461119b578182fd5b60006020828403121561213b578081fd5b5035919050565b600060208284031215612153578081fd5b5051919050565b60609290921b6bffffffffffffffffffffffff19168252601482015260340190565b6000825161218e818460208701612693565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03861681526020810185905260806040820181905281018390526000838560a08401378060a0858401015260a0601f19601f86011683010190508260608301529695505050505050565b6001600160a01b039390931683526020830191909152604082015260600190565b60006020825282518060208401526122b5816040850160208701612693565b601f01601f19169190910160400192915050565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b602080825260099082015268554e493a452d34303360b81b604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b602080825260099082015268554e493a452d34313760b81b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252600990820152680aa9c92748a5a6260760bb1b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b81518152602080830151908201526040918201519181019190915260600190565b90815260200190565b918252602082015260400190565b60005b838110156126ae578181015183820152602001612696565b838111156109c35750506000910152565b6001600160a01b03811681146106f457600080fdfea264697066735822122055c84894697dd3e92642a98fce78fc85de39452936a89059494ec186a3b80f2d64736f6c634300060c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061014d5760003560e01c80638da5cb5b116100c3578063b9e09b4b1161007c578063b9e09b4b1461028e578063bbf1da84146102a1578063bea38be0146102a9578063c5d1d706146102bc578063f2fde38b146102cf578063fbf5ca14146102e25761014d565b80638da5cb5b14610227578063945233e21461022f57806395469dfc146102425780639a87c0de14610255578063a0edb48b14610268578063aa29542d1461027b5761014d565b8063522f681511610115578063522f6815146101be5780636e5559fd146101d1578063715018a6146101e45780638129fc1c146101ec578063836c478d146101f45780638b9309b2146102145761014d565b80631593dee1146101525780632bdbb77f1461016757806330219ef41461017a5780634025feb21461019857806341db85d6146101ab575b600080fd5b610165610160366004611d6c565b6102f5565b005b610165610175366004611ffc565b61034d565b61018261038d565b60405161018f919061219b565b60405180910390f35b6101656101a6366004611d6c565b61039c565b6101656101b9366004611ffc565b6103e6565b6101656101cc366004611df1565b6104ca565b6101656101df366004611d34565b610517565b6101656105e3565b61016561066c565b61020761020236600461212a565b6106f7565b60405161018f919061265b565b610165610222366004611ef4565b610384565b610182610738565b61016561023d366004611d34565b610747565b610165610250366004611e1c565b6107d5565b610165610263366004611d34565b6108d4565b610165610276366004611dac565b610978565b610165610289366004611f6e565b6109c9565b61016561029c366004611e54565b610a9c565b610182610b53565b6101656102b7366004611ffc565b610b62565b6101826102ca366004611d34565b610b99565b6101656102dd366004611d34565b610baa565b6101656102f0366004612080565b610c6b565b6102fd610d59565b6001600160a01b031661030e610738565b6001600160a01b03161461033d5760405162461bcd60e51b815260040161033490612582565b60405180910390fd5b610348838383610d5d565b505050565b6065546001600160a01b031633146103775760405162461bcd60e51b8152600401610334906125b7565b6103848787858585610e6a565b50505050505050565b6065546001600160a01b031681565b6103a4610d59565b6001600160a01b03166103b5610738565b6001600160a01b0316146103db5760405162461bcd60e51b815260040161033490612582565b610348838383610ffd565b6065546001600160a01b031633146104105760405162461bcd60e51b8152600401610334906125b7565b600061041b84611158565b90506001600160a01b038116156104c05760006104388385611176565b604051631434318f60e21b81529091506001600160a01b038316906350d0c63c9061046b908c908c908690600401612275565b602060405180830381600087803b15801561048557600080fd5b505af1158015610499573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bd9190612142565b50505b5050505050505050565b6104d2610d59565b6001600160a01b03166104e3610738565b6001600160a01b0316146105095760405162461bcd60e51b815260040161033490612582565b61051382826111a2565b5050565b61051f610d59565b6001600160a01b0316610530610738565b6001600160a01b0316146105565760405162461bcd60e51b815260040161033490612582565b806001600160a01b0381161580159061057c575061057c816001600160a01b0316611226565b6105985760405162461bcd60e51b815260040161033490612397565b606580546001600160a01b0319166001600160a01b0384169081179091556040517f5ce0e6b7fd36339ee97339831b6c72694ecee88c62aab49919d9cabe0a732e4190600090a25050565b6105eb610d59565b6001600160a01b03166105fc610738565b6001600160a01b0316146106225760405162461bcd60e51b815260040161033490612582565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b600054610100900460ff16806106855750610685611262565b80610693575060005460ff16155b6106af5760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff161580156106da576000805460ff1961ff0019909116610100171660011790555b6106e2611273565b80156106f4576000805461ff00191690555b50565b6106ff611ccc565b50600090815260696020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b6033546001600160a01b031690565b61074f610d59565b6001600160a01b0316610760610738565b6001600160a01b0316146107865760405162461bcd60e51b815260040161033490612582565b6001600160a01b03811660008181526067602052604080822080546001600160a01b0319169055517f87e1027e3dc61d1977f39f0dfe911b66a943946b4ceb39210dee01495621de529190a250565b6107dd610d59565b6001600160a01b03166107ee610738565b6001600160a01b0316146108145760405162461bcd60e51b815260040161033490612582565b816001600160a01b0381161580159061083a575061083a816001600160a01b0316611226565b6108565760405162461bcd60e51b815260040161033490612397565b6001600160a01b03821661087c5760405162461bcd60e51b81526004016103349061230b565b6001600160a01b0382811660008181526067602052604080822080546001600160a01b0319169488169485179055517f3b76c6366ef8a1f8d2dbb75e4be27be1e0749716fff3e6bc327da9c6158deada9190a3505050565b6108dc610d59565b6001600160a01b03166108ed610738565b6001600160a01b0316146109135760405162461bcd60e51b815260040161033490612582565b806001600160a01b038116158015906109395750610939816001600160a01b0316611226565b6109555760405162461bcd60e51b815260040161033490612397565b50606680546001600160a01b0319166001600160a01b0392909216919091179055565b610980610d59565b6001600160a01b0316610991610738565b6001600160a01b0316146109b75760405162461bcd60e51b815260040161033490612582565b6109c3848484846112f1565b50505050565b6065546001600160a01b031633146109f35760405162461bcd60e51b8152600401610334906125b7565b60006109fe83611158565b90506001600160a01b038116156104c057604051631434318f60e21b81526001600160a01b038216906350d0c63c90610a3f908b908b908790600401612275565b602060405180830381600087803b158015610a5957600080fd5b505af1158015610a6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a919190612142565b505050505050505050565b6065546001600160a01b03163314610ac65760405162461bcd60e51b8152600401610334906125b7565b6000610ad183611158565b90506001600160a01b03811615610a91576040516323632fb160e11b81526001600160a01b038216906346c65f6290610b16908a908a908a908a908990600401612224565b600060405180830381600087803b158015610b3057600080fd5b505af1158015610b44573d6000803e3d6000fd5b50505050505050505050505050565b6066546001600160a01b031681565b6065546001600160a01b03163314610b8c5760405162461bcd60e51b8152600401610334906125b7565b6103848787858585611450565b6000610ba482611158565b92915050565b610bb2610d59565b6001600160a01b0316610bc3610738565b6001600160a01b031614610be95760405162461bcd60e51b815260040161033490612582565b6001600160a01b038116610c0f5760405162461bcd60e51b81526004016103349061232e565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6065546001600160a01b03163314610c955760405162461bcd60e51b8152600401610334906125b7565b6000610ca085611158565b90506001600160a01b03811615610a91576000610cc784610cc18588611541565b90611176565b604051631434318f60e21b81529091506001600160a01b038316906350d0c63c90610cfa908d908d908690600401612275565b602060405180830381600087803b158015610d1457600080fd5b505af1158015610d28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4c9190612142565b5050505050505050505050565b3390565b6001600160a01b038316610d835760405162461bcd60e51b815260040161033490612374565b6040516370a0823160e01b815281906001600160a01b038416906370a0823190610db190309060040161219b565b60206040518083038186803b158015610dc957600080fd5b505afa158015610ddd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e019190612142565b1061034857610e1a6001600160a01b0383168483611569565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b83604051610e5d919061267c565b60405180910390a3505050565b6066546001600160a01b03848116911614610e8457610ff6565b6000610e996001600160a01b038716866115bf565b90506000610ea785856115f3565b9050600081118015610ece57506000828152606860205260409020610ecc90826116d5565b155b15610fa6576000828152606860205260409020610eeb90826116e1565b506000610ef7836116ed565b600084815260696020526040902060010154909150610f5157604080516060810182528281524360208083019182526000838501818152888252606990925293909320915182555160018201559051600290910155610fa4565b60008381526069602052604090206001810154908290554303610f90610f7882600261176d565b60008681526069602052604090206001015490611176565b600085815260696020526040902060010155505b505b846001600160a01b0316876001600160a01b03167f186ebbe503be539e070ca73b33a78f4266d96003e62b888dc31f88a39ddc9c878887604051610feb929190612685565b60405180910390a350505b5050505050565b6001600160a01b0383166110235760405162461bcd60e51b815260040161033490612374565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e9061105190859060040161267c565b60206040518083038186803b15801561106957600080fd5b505afa15801561107d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a19190611d50565b6001600160a01b03161415610348576040516323b872dd60e01b81526001600160a01b038316906323b872dd906110e0903090879086906004016121af565b600060405180830381600087803b1580156110fa57600080fd5b505af115801561110e573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b039081166000908152606760205260409020541690565b60008282018381101561119b5760405162461bcd60e51b8152600401610334906123ba565b9392505050565b6001600160a01b0382166111c85760405162461bcd60e51b815260040161033490612374565b804710610513576111e26001600160a01b0383168261179f565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd8260405161121a919061267c565b60405180910390a25050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061125a57508115155b949350505050565b600061126d3061183b565b15905090565b600054610100900460ff168061128c575061128c611262565b8061129a575060005460ff16155b6112b65760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff161580156112e1576000805460ff1961ff0019909116610100171660011790555b6112e9611841565b6106e26118c2565b6001600160a01b0384166113175760405162461bcd60e51b815260040161033490612374565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e90611345903090879060040161220b565b60206040518083038186803b15801561135d57600080fd5b505afa158015611371573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113959190612142565b106109c357604051637921219560e11b81526001600160a01b0384169063f242432a906113cc9030908890879087906004016121d3565b600060405180830381600087803b1580156113e657600080fd5b505af11580156113fa573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b84604051611442919061267c565b60405180910390a450505050565b6066546001600160a01b0384811691161461146a57610ff6565b600061147f6001600160a01b038716866115bf565b600081815260696020526040812091925061149a86866115f3565b60008481526068602052604090209091506114b5908261199c565b5060008381526068602052604081206114cd906119a8565b11156114e3576114dc836116ed565b82556114ea565b4360028301555b856001600160a01b0316886001600160a01b03167ff3cfcfc091fdd683cf6c013de9806af93f3af27b256a57cb776331291cef4085898860405161152f929190612685565b60405180910390a35050505050505050565b6000828211156115635760405162461bcd60e51b8152600401610334906123f1565b50900390565b6103488363a9059cbb60e01b848460405160240161158892919061220b565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526119b3565b600082826040516020016115d492919061215a565b60408051601f1981840301815291905280516020909101209392505050565b60008063adf8252d60e01b905060006060856001600160a01b03168386604051602401611620919061267c565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161165e919061217c565b6000604051808303816000865af19150503d806000811461169b576040519150601f19603f3d011682016040523d82523d6000602084013e6116a0565b606091505b509150915081156116c957808060200190518101906116bf9190612142565b9350505050610ba4565b60009350505050610ba4565b600061119b8383611a42565b600061119b8383611a5a565b60008181526068602052604081208190611706906119a8565b905060006032815b83811015611743576000868152606860205260409020611739906117329083611aa4565b8490611176565b925060010161170e565b6001841115611763576117606117598386611ab0565b8490611541565b92505b5090949350505050565b600080821161178e5760405162461bcd60e51b8152600401610334906124bc565b81838161179757fe5b049392505050565b804710156117bf5760405162461bcd60e51b815260040161033490612485565b6000826001600160a01b0316826040516117d890612198565b60006040518083038185875af1925050503d8060008114611815576040519150601f19603f3d011682016040523d82523d6000602084013e61181a565b606091505b50509050806103485760405162461bcd60e51b815260040161033490612428565b3b151590565b600054610100900460ff168061185a575061185a611262565b80611868575060005460ff16155b6118845760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff161580156106e2576000805460ff1961ff00199091166101001716600117905580156106f4576000805461ff001916905550565b600054610100900460ff16806118db57506118db611262565b806118e9575060005460ff16155b6119055760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff16158015611930576000805460ff1961ff0019909116610100171660011790555b600061193a610d59565b603380546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35080156106f4576000805461ff001916905550565b600061119b8383611aea565b6000610ba482611bb0565b6060611a08826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611bb49092919063ffffffff16565b8051909150156103485780806020019051810190611a26919061210a565b6103485760405162461bcd60e51b815260040161033490612611565b60009081526001919091016020526040902054151590565b6000611a668383611a42565b611a9c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ba4565b506000610ba4565b600061119b8383611bc3565b600082611abf57506000610ba4565b82820282848281611acc57fe5b041461119b5760405162461bcd60e51b815260040161033490612541565b60008181526001830160205260408120548015611ba65783546000198083019190810190600090879083908110611b1d57fe5b9060005260206000200154905080876000018481548110611b3a57fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080611b6a57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610ba4565b6000915050610ba4565b5490565b606061125a8484600085611c08565b81546000908210611be65760405162461bcd60e51b8152600401610334906122c9565b826000018281548110611bf557fe5b9060005260206000200154905092915050565b6060611c138561183b565b611c2f5760405162461bcd60e51b8152600401610334906125da565b60006060866001600160a01b03168587604051611c4c919061217c565b60006040518083038185875af1925050503d8060008114611c89576040519150601f19603f3d011682016040523d82523d6000602084013e611c8e565b606091505b50915091508115611ca257915061125a9050565b805115611cb25780518082602001fd5b8360405162461bcd60e51b81526004016103349190612296565b60405180606001604052806000815260200160008152602001600081525090565b60008083601f840112611cfe578182fd5b50813567ffffffffffffffff811115611d15578182fd5b602083019150836020828501011115611d2d57600080fd5b9250929050565b600060208284031215611d45578081fd5b813561119b816126bf565b600060208284031215611d61578081fd5b815161119b816126bf565b600080600060608486031215611d80578182fd5b8335611d8b816126bf565b92506020840135611d9b816126bf565b929592945050506040919091013590565b60008060008060808587031215611dc1578081fd5b8435611dcc816126bf565b93506020850135611ddc816126bf565b93969395505050506040820135916060013590565b60008060408385031215611e03578182fd5b8235611e0e816126bf565b946020939093013593505050565b60008060408385031215611e2e578182fd5b8235611e39816126bf565b91506020830135611e49816126bf565b809150509250929050565b60008060008060008060008060e0898b031215611e6f578384fd5b8835611e7a816126bf565b97506020890135611e8a816126bf565b96506040890135611e9a816126bf565b955060608901359450608089013567ffffffffffffffff811115611ebc578485fd5b611ec88b828c01611ced565b90955093505060a0890135611edc816126bf565b8092505060c089013590509295985092959890939650565b600080600080600080600060e0888a031215611f0e578283fd5b8735611f19816126bf565b9650602088013595506040880135611f30816126bf565b94506060880135611f40816126bf565b93506080880135925060a0880135611f57816126bf565b8092505060c0880135905092959891949750929550565b600080600080600080600060c0888a031215611f88578283fd5b8735611f93816126bf565b965060208801359550604088013567ffffffffffffffff811115611fb5578384fd5b611fc18a828b01611ced565b9096509450506060880135611fd5816126bf565b92506080880135611fe5816126bf565b8092505060a0880135905092959891949750929550565b600080600080600080600060c0888a031215612016578081fd5b8735612021816126bf565b965060208801359550604088013567ffffffffffffffff811115612043578182fd5b61204f8a828b01611ced565b9096509450506060880135612063816126bf565b969995985093969295946080840135945060a09093013592915050565b60008060008060008060008060e0898b03121561209b578182fd5b88356120a6816126bf565b975060208901359650604089013567ffffffffffffffff8111156120c8578283fd5b6120d48b828c01611ced565b90975095505060608901356120e8816126bf565b979a96995094979396956080850135955060a08501359460c001359350915050565b60006020828403121561211b578081fd5b8151801515811461119b578182fd5b60006020828403121561213b578081fd5b5035919050565b600060208284031215612153578081fd5b5051919050565b60609290921b6bffffffffffffffffffffffff19168252601482015260340190565b6000825161218e818460208701612693565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03861681526020810185905260806040820181905281018390526000838560a08401378060a0858401015260a0601f19601f86011683010190508260608301529695505050505050565b6001600160a01b039390931683526020830191909152604082015260600190565b60006020825282518060208401526122b5816040850160208701612693565b601f01601f19169190910160400192915050565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b602080825260099082015268554e493a452d34303360b81b604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b602080825260099082015268554e493a452d34313760b81b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252600990820152680aa9c92748a5a6260760bb1b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b81518152602080830151908201526040918201519181019190915260600190565b90815260200190565b918252602082015260400190565b60005b838110156126ae578181015183820152602001612696565b838111156109c35750506000910152565b6001600160a01b03811681146106f457600080fdfea264697066735822122055c84894697dd3e92642a98fce78fc85de39452936a89059494ec186a3b80f2d64736f6c634300060c0033", + "devdoc": { + "details": "Upgradeable Contract", + "kind": "dev", + "methods": { + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Charged Particles Universe Contract with Rewards Program", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 680, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 683, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 3177, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 111, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "t_address" + }, + { + "astId": 230, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 16752, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_chargedParticles", + "offset": 0, + "slot": "101", + "type": "t_address" + }, + { + "astId": 16754, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_multiplierNft", + "offset": 0, + "slot": "102", + "type": "t_address" + }, + { + "astId": 16758, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_assetRewardPrograms", + "offset": 0, + "slot": "103", + "type": "t_mapping(t_address,t_address)" + }, + { + "astId": 16762, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_multiplierNftsSet", + "offset": 0, + "slot": "104", + "type": "t_mapping(t_uint256,t_struct(UintSet)8991_storage)" + }, + { + "astId": 16766, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_nftStake", + "offset": 0, + "slot": "105", + "type": "t_mapping(t_uint256,t_struct(NftStake)29442_storage)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_address)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_uint256,t_struct(NftStake)29442_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct IUniverseRP.NftStake)", + "numberOfBytes": "32", + "value": "t_struct(NftStake)29442_storage" + }, + "t_mapping(t_uint256,t_struct(UintSet)8991_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct EnumerableSet.UintSet)", + "numberOfBytes": "32", + "value": "t_struct(UintSet)8991_storage" + }, + "t_struct(NftStake)29442_storage": { + "encoding": "inplace", + "label": "struct IUniverseRP.NftStake", + "members": [ + { + "astId": 29437, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "multiplier", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 29439, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "depositBlockNumber", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 29441, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "releaseBlockNumber", + "offset": 0, + "slot": "2", + "type": "t_uint256" + } + ], + "numberOfBytes": "96" + }, + "t_struct(Set)8702_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 8697, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 8701, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_struct(UintSet)8991_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.UintSet", + "members": [ + { + "astId": 8990, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)8702_storage" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/deployments/mainnet/UniverseRP_Proxy.json b/deployments/mainnet/UniverseRP_Proxy.json new file mode 100644 index 0000000..92fa29d --- /dev/null +++ b/deployments/mainnet/UniverseRP_Proxy.json @@ -0,0 +1,249 @@ +{ + "address": "0xD4bd60c64586AEEdA6923F6547E6DF478a2EF686", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x611d292e3d0e87224b233d83aba772f9c4f78f4d4329d5804264539daf69357d", + "receipt": { + "to": null, + "from": "0xb8D175F16742395F530e0b3bC1d30BD06B78CdA9", + "contractAddress": "0xD4bd60c64586AEEdA6923F6547E6DF478a2EF686", + "transactionIndex": 44, + "gasUsed": "769740", + "logsBloom": "0x00000008000000000000000000000000400000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000001000000000000000000000000002000000000020000000000000000000800000000800000000000000000000000400000000040000000000000020000000000000000000000000000000000800000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000080400000000000000000020000000200000000000000000000000000000010000000000000000000002000000", + "blockHash": "0x815871f14c64d7ca174bf05aeb38b084c275f973f794e9bf4fd0f9715a48f920", + "transactionHash": "0x611d292e3d0e87224b233d83aba772f9c4f78f4d4329d5804264539daf69357d", + "logs": [ + { + "transactionIndex": 44, + "blockNumber": 18063735, + "transactionHash": "0x611d292e3d0e87224b233d83aba772f9c4f78f4d4329d5804264539daf69357d", + "address": "0xD4bd60c64586AEEdA6923F6547E6DF478a2EF686", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000cd5032c531c4ba324f2e4747f84a15c88e31a92e" + ], + "data": "0x", + "logIndex": 102, + "blockHash": "0x815871f14c64d7ca174bf05aeb38b084c275f973f794e9bf4fd0f9715a48f920" + }, + { + "transactionIndex": 44, + "blockNumber": 18063735, + "transactionHash": "0x611d292e3d0e87224b233d83aba772f9c4f78f4d4329d5804264539daf69357d", + "address": "0xD4bd60c64586AEEdA6923F6547E6DF478a2EF686", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000b8d175f16742395f530e0b3bc1d30bd06b78cda9" + ], + "data": "0x", + "logIndex": 103, + "blockHash": "0x815871f14c64d7ca174bf05aeb38b084c275f973f794e9bf4fd0f9715a48f920" + }, + { + "transactionIndex": 44, + "blockNumber": 18063735, + "transactionHash": "0x611d292e3d0e87224b233d83aba772f9c4f78f4d4329d5804264539daf69357d", + "address": "0xD4bd60c64586AEEdA6923F6547E6DF478a2EF686", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000004ccd62462070c8b8ab1614e0ca1ec449108b7f65", + "logIndex": 104, + "blockHash": "0x815871f14c64d7ca174bf05aeb38b084c275f973f794e9bf4fd0f9715a48f920" + } + ], + "blockNumber": 18063735, + "cumulativeGasUsed": "6179446", + "status": 1, + "byzantium": true + }, + "args": [ + "0xCD5032c531c4Ba324f2E4747F84A15C88E31A92E", + "0x4ccD62462070C8B8AB1614E0Ca1Ec449108B7f65", + "0x8129fc1c" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev 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\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/mainnet/solcInputs/0e89febeebc7444140de8e67c9067d2c.json b/deployments/mainnet/solcInputs/0e89febeebc7444140de8e67c9067d2c.json new file mode 100644 index 0000000..6eb5ed9 --- /dev/null +++ b/deployments/mainnet/solcInputs/0e89febeebc7444140de8e67c9067d2c.json @@ -0,0 +1,80 @@ +{ + "language": "Solidity", + "sources": { + "solc_0.8/openzeppelin/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 (address initialOwner) {\n _transferOwnership(initialOwner);\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" + }, + "solc_0.8/openzeppelin/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" + }, + "solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"../../access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n\n constructor (address initialOwner) Ownable(initialOwner) {}\n\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(\n TransparentUpgradeableProxy proxy,\n address implementation,\n bytes memory data\n ) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(\n address _logic,\n address admin_,\n bytes memory _data\n ) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _changeAdmin(admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n _changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overriden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n" + }, + "solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view virtual returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(Address.isContract(IBeacon(newBeacon).implementation()), \"ERC1967: beacon implementation is not a contract\");\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "solc_0.8/openzeppelin/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\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 * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev 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" + }, + "solc_0.8/openzeppelin/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n assembly {\n r.slot := slot\n }\n }\n}\n" + }, + "solc_0.8/proxy/OptimizedTransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract OptimizedTransparentUpgradeableProxy is ERC1967Proxy {\n address internal immutable _ADMIN;\n\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(\n address _logic,\n address admin_,\n bytes memory _data\n ) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _ADMIN = admin_;\n\n // still store it to work with EIP-1967\n bytes32 slot = _ADMIN_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, admin_)\n }\n emit AdminChanged(address(0), admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n\n function _getAdmin() internal view virtual override returns (address) {\n return _ADMIN;\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/utils/UUPSUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../ERC1967/ERC1967Upgrade.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n *\n * _Available since v4.1._\n */\nabstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade {\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\n address private immutable __self = address(this);\n\n /**\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n * fail.\n */\n modifier onlyProxy() {\n require(address(this) != __self, \"Function must be called through delegatecall\");\n require(_getImplementation() == __self, \"Function must be called through active proxy\");\n _;\n }\n\n /**\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\n * callable on the implementing contract but not through proxies.\n */\n modifier notDelegated() {\n require(address(this) == __self, \"UUPSUpgradeable: must not be called through delegatecall\");\n _;\n }\n\n /**\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\n * implementation. It is used to validate that the this implementation remains valid after an upgrade.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\n */\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\n return _IMPLEMENTATION_SLOT;\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n */\n function upgradeTo(address newImplementation) external virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n * encoded in `data`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n */\n function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, data, true);\n }\n\n /**\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n * {upgradeTo} and {upgradeToAndCall}.\n *\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\n *\n * ```solidity\n * function _authorizeUpgrade(address) internal override onlyOwner {}\n * ```\n */\n function _authorizeUpgrade(address newImplementation) internal virtual;\n}\n" + }, + "solc_0.8/openzeppelin/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * 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 !Address.isContract(address(this));\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/beacon/UpgradeableBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/UpgradeableBeacon.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IBeacon.sol\";\nimport \"../../access/Ownable.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their\n * implementation contract, which is where they will delegate all function calls.\n *\n * An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon.\n */\ncontract UpgradeableBeacon is IBeacon, Ownable {\n address private _implementation;\n\n /**\n * @dev Emitted when the implementation returned by the beacon is changed.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Sets the address of the initial implementation, and the deployer account as the owner who can upgrade the\n * beacon.\n */\n\n constructor(address implementation_, address initialOwner) Ownable(initialOwner) {\n _setImplementation(implementation_);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function implementation() public view virtual override returns (address) {\n return _implementation;\n }\n\n /**\n * @dev Upgrades the beacon to a new implementation.\n *\n * Emits an {Upgraded} event.\n *\n * Requirements:\n *\n * - msg.sender must be the owner of the contract.\n * - `newImplementation` must be a contract.\n */\n function upgradeTo(address newImplementation) public virtual onlyOwner {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Sets the implementation contract address for this beacon\n *\n * Requirements:\n *\n * - `newImplementation` must be a contract.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableBeacon: implementation is not a contract\");\n _implementation = newImplementation;\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/beacon/BeaconProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/BeaconProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IBeacon.sol\";\nimport \"../Proxy.sol\";\nimport \"../ERC1967/ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements a proxy that gets the implementation address for each call from a {UpgradeableBeacon}.\n *\n * The beacon address is stored in storage slot `uint256(keccak256('eip1967.proxy.beacon')) - 1`, so that it doesn't\n * conflict with the storage layout of the implementation behind the proxy.\n *\n * _Available since v3.4._\n */\ncontract BeaconProxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the proxy with `beacon`.\n *\n * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This\n * will typically be an encoded function call, and allows initializating the storage of the proxy like a Solidity\n * constructor.\n *\n * Requirements:\n *\n * - `beacon` must be a contract with the interface {IBeacon}.\n */\n constructor(address beacon, bytes memory data) payable {\n assert(_BEACON_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.beacon\")) - 1));\n _upgradeBeaconToAndCall(beacon, data, false);\n }\n\n /**\n * @dev Returns the current beacon address.\n */\n function _beacon() internal view virtual returns (address) {\n return _getBeacon();\n }\n\n /**\n * @dev Returns the current implementation address of the associated beacon.\n */\n function _implementation() internal view virtual override returns (address) {\n return IBeacon(_getBeacon()).implementation();\n }\n\n /**\n * @dev Changes the proxy to use a new beacon. Deprecated: see {_upgradeBeaconToAndCall}.\n *\n * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon.\n *\n * Requirements:\n *\n * - `beacon` must be a contract.\n * - The implementation returned by `beacon` must be a contract.\n */\n function _setBeacon(address beacon, bytes memory data) internal virtual {\n _upgradeBeaconToAndCall(beacon, data, false);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "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/deployments/mainnet/solcInputs/39876b9d6995fafd8c4442fb1a03f418.json b/deployments/mainnet/solcInputs/39876b9d6995fafd8c4442fb1a03f418.json new file mode 100644 index 0000000..891dec4 --- /dev/null +++ b/deployments/mainnet/solcInputs/39876b9d6995fafd8c4442fb1a03f418.json @@ -0,0 +1,452 @@ +{ + "language": "Solidity", + "sources": { + "@opengsn/gsn/contracts/BaseRelayRecipient.sol": { + "content": "// SPDX-License-Identifier:MIT\n// solhint-disable no-inline-assembly\npragma solidity ^0.6.2;\n\nimport \"./interfaces/IRelayRecipient.sol\";\n\n/**\n * A base contract to be inherited by any contract that want to receive relayed transactions\n * A subclass must use \"_msgSender()\" instead of \"msg.sender\"\n */\nabstract contract BaseRelayRecipient is IRelayRecipient {\n\n /*\n * Forwarder singleton we accept calls from\n */\n address public trustedForwarder;\n\n function isTrustedForwarder(address forwarder) public override view returns(bool) {\n return forwarder == trustedForwarder;\n }\n\n /**\n * return the sender of this call.\n * if the call came through our trusted forwarder, return the original sender.\n * otherwise, return `msg.sender`.\n * should be used in the contract anywhere instead of msg.sender\n */\n function _msgSender() internal override virtual view returns (address payable ret) {\n if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // so we trust that the last bytes of msg.data are the verified sender address.\n // extract sender address from the end of msg.data\n assembly {\n ret := shr(96,calldataload(sub(calldatasize(),20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n /**\n * return the msg.data of this call.\n * if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes\n * of the msg.data - so this method will strip those 20 bytes off.\n * otherwise, return `msg.data`\n * should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly\n * signing or hashing the\n */\n function _msgData() internal override virtual view returns (bytes memory ret) {\n if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // we copy the msg.data , except the last 20 bytes (and update the total length)\n assembly {\n let ptr := mload(0x40)\n // copy only size-20 bytes\n let size := sub(calldatasize(),20)\n // structure RLP data as \n mstore(ptr, 0x20)\n mstore(add(ptr,32), size)\n calldatacopy(add(ptr,64), 0, size)\n return(ptr, add(size,64))\n }\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "@opengsn/gsn/contracts/interfaces/IRelayRecipient.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.6.2;\n\n/**\n * a contract must implement this interface in order to support relayed transaction.\n * It is better to inherit the BaseRelayRecipient as its implementation.\n */\nabstract contract IRelayRecipient {\n\n /**\n * return if the forwarder is trusted to forward relayed transactions to us.\n * the forwarder is required to verify the sender's signature, and verify\n * the call is not a replay.\n */\n function isTrustedForwarder(address forwarder) public virtual view returns(bool);\n\n /**\n * return the sender of this call.\n * if the call came through our trusted forwarder, then the real sender is appended as the last 20 bytes\n * of the msg.data.\n * otherwise, return `msg.sender`\n * should be used in the contract anywhere instead of msg.sender\n */\n function _msgSender() internal virtual view returns (address payable);\n\n /**\n * return the msg.data of this call.\n * if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes\n * of the msg.data - so this method will strip those 20 bytes off.\n * otherwise, return `msg.data`\n * should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly\n * signing or hashing the\n */\n function _msgData() internal virtual view returns (bytes memory);\n\n function versionRecipient() external virtual view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\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 initializer {\n __Context_init_unchained();\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal initializer {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), 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 emit OwnershipTransferred(_owner, address(0));\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n function __ERC165_init() internal initializer {\n __ERC165_init_unchained();\n }\n\n function __ERC165_init_unchained() internal initializer {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMathUpgradeable {\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 uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\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 if (b > a) return (false, 0);\n return (true, a - b);\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 // 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 * @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 if (b == 0) return (false, 0);\n return (true, a / b);\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 if (b == 0) return (false, 0);\n return (true, a % b);\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 uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n return c;\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 require(b <= a, \"SafeMath: subtraction overflow\");\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 if (a == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n return c;\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. 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(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: division by zero\");\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 require(b > 0, \"SafeMath: modulo by zero\");\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n return a - b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a / b;\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.4.24 <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 {UpgradeableProxy-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 */\nabstract contract Initializable {\n\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 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 /// @dev Returns true if and only if the function is running in the constructor\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\n\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 )\n external\n 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 )\n external\n returns(bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC20Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../proxy/Initializable.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 guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable {\n using SafeMathUpgradeable for uint256;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal initializer {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer {\n _name = name_;\n _symbol = symbol_;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal virtual {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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(address sender, address recipient, uint256 amount) 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/ERC20/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.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 SafeERC20Upgradeable {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) 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(IERC20Upgradeable token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\n require((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(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\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(IERC20Upgradeable 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) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721MetadataUpgradeable.sol\";\nimport \"./IERC721EnumerableUpgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"../../introspection/ERC165Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/EnumerableSetUpgradeable.sol\";\nimport \"../../utils/EnumerableMapUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../proxy/Initializable.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable, IERC721EnumerableUpgradeable {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet;\n using EnumerableMapUpgradeable for EnumerableMapUpgradeable.UintToAddressMap;\n using StringsUpgradeable for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSetUpgradeable.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMapUpgradeable.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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 initializer {\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 initializer {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\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 _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\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 _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\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(_msgSender() == owner || ERC721Upgradeable.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 require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) 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(address from, address to, uint256 tokenId, bytes memory _data) 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 _tokenOwners.contains(tokenId);\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 || ERC721Upgradeable.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\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 _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(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); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(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(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721ReceiverUpgradeable(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); // internal owner\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(address from, address to, uint256 tokenId) internal virtual { }\n uint256[41] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721EnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 /**\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/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 /**\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\npragma solidity >=0.6.0 <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(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) 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 // solhint-disable-next-line avoid-low-level-calls\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(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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 // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/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 GSN 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 initializer {\n __Context_init_unchained();\n }\n\n function __Context_init_unchained() internal initializer {\n }\n function _msgSender() internal view virtual returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/EnumerableMapUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMapUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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 EnumerableSetUpgradeable {\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\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\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] = toDeleteIndex + 1; // All indexes are 1-based\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 require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\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 // 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 // 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" + }, + "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/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 initializer {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal initializer {\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 make 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/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n /**\n * @dev Converts a `uint256` to its ASCII `string` 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 uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = bytes1(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../GSN/Context.sol\";\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 */\ncontract 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 () internal {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), msgSender);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view 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 emit OwnershipTransferred(_owner, address(0));\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n" + }, + "@openzeppelin/contracts/cryptography/MerkleProof.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev These functions deal with verification of Merkle trees (hash trees),\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(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {\n bytes32 computedHash = leaf;\n\n for (uint256 i = 0; i < proof.length; i++) {\n bytes32 proofElement = proof[i];\n\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\n // Check if the computed hash (root) is equal to the provided root\n return computedHash == root;\n }\n}\n" + }, + "@openzeppelin/contracts/GSN/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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 GSN 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 payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\ncontract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () internal {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n" + }, + "@openzeppelin/contracts/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\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 uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\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 sub(a, b, \"SafeMath: subtraction overflow\");\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 * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\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 // 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) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts 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 mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\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 SafeMath for uint256;\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 * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri) public {\n _setURI(uri);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\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) external view 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 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(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\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 require(accounts[i] != address(0), \"ERC1155: batch balance query for the zero address\");\n batchBalances[i] = _balances[ids[i]][accounts[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 require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view 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 )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, 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 )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\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 _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(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 `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` 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(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, 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(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) 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 (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\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 `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, 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(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != 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, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\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 )\n internal virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).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 )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).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/token/ERC1155/ERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() public {\n _registerInterface(\n ERC1155Receiver(0).onERC1155Received.selector ^\n ERC1155Receiver(0).onERC1155BatchReceived.selector\n );\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\nimport \"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\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 )\n external\n 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 )\n external\n returns(bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.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 guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 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 {\n using SafeMath for uint256;\n using Address for address;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name, string memory symbol) public {\n _name = name;\n _symbol = symbol;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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/token/ERC20/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.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 SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\n require((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(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\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) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n\n // If there is no base URI, return the token URI.\n if (bytes(_baseURI).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(_baseURI, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(_baseURI, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_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 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 require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) 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(address from, address to, uint256 tokenId, bytes memory _data) 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 returns (bool) {\n return _tokenOwners.contains(tokenId);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = 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 d*\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\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 _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(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 = ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(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(address from, address to, uint256 tokenId) internal virtual {\n require(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 _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\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(address from, address to, uint256 tokenId) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\nimport \"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 /**\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/token/ERC721/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 /**\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/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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(address operator, address from, uint256 tokenId, bytes calldata data)\n external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 in 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 // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n return _functionCallWithValue(target, data, value, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\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 // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../math/SafeMath.sol\";\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented or decremented by one. 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 * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}\n * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never\n * directly accessed.\n */\nlibrary Counters {\n using SafeMath for uint256;\n\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 // The {SafeMath} overflow check can be skipped here, see the comment at the top\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableMap.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n return _get(map, key, \"EnumerableMap: nonexistent key\");\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(value)));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint256(value)));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint256(_get(map._inner, bytes32(key))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint256(_get(map._inner, bytes32(key), errorMessage)));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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.0.0, only sets of type `address` (`AddressSet`) and `uint256`\n * (`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\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\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] = toDeleteIndex + 1; // All indexes are 1-based\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 require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\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(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(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(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(uint256(_at(set._inner, index)));\n }\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" + }, + "@openzeppelin/contracts/utils/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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 */\ncontract 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 () internal {\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 make 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/utils/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value < 2**128, \"SafeCast: value doesn\\'t fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value < 2**64, \"SafeCast: value doesn\\'t fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value < 2**32, \"SafeCast: value doesn\\'t fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value < 2**16, \"SafeCast: value doesn\\'t fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value < 2**8, \"SafeCast: value doesn\\'t fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= -2**127 && value < 2**127, \"SafeCast: value doesn\\'t fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= -2**63 && value < 2**63, \"SafeCast: value doesn\\'t fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= -2**31 && value < 2**31, \"SafeCast: value doesn\\'t fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= -2**15 && value < 2**15, \"SafeCast: value doesn\\'t fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= -2**7 && value < 2**7, \"SafeCast: value doesn\\'t fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n require(value < 2**255, \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` 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 uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = byte(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n" + }, + "contracts/v1/ChargedManagers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Wallet-Managers Contract\n */\ncontract ChargedManagers is\n IChargedManagers,\n Initializable,\n OwnableUpgradeable,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n\n IChargedSettings internal _chargedSettings;\n IChargedState internal _chargedState;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // Wallet/Basket Managers (by Unique Manager ID)\n mapping (string => IWalletManager) internal _ftWalletManager;\n mapping (string => IBasketManager) internal _nftBasketManager;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n /// @notice Checks if an Account is the Owner of an NFT Contract\n /// When Custom Contracts are registered, only the \"owner\" or operator of the Contract\n /// is allowed to register them and define custom rules for how their tokens are \"Charged\".\n /// Otherwise, any token can be \"Charged\" according to the default rules of Charged Particles.\n /// @param contractAddress The Address to the External NFT Contract to check\n /// @param account The Account to check if it is the Owner of the specified Contract\n /// @return True if the account is the Owner of the _contract\n function isContractOwner(address contractAddress, address account) external view override virtual returns (bool) {\n return contractAddress.isContractOwner(account);\n }\n\n function isWalletManagerEnabled(string calldata walletManagerId) external virtual override view returns (bool) {\n return _isWalletManagerEnabled(walletManagerId);\n }\n\n function getWalletManager(string calldata walletManagerId) external virtual override view returns (IWalletManager) {\n return _ftWalletManager[walletManagerId];\n }\n\n function isNftBasketEnabled(string calldata basketId) external virtual override view returns (bool) {\n return _isNftBasketEnabled(basketId);\n }\n\n function getBasketManager(string calldata basketId) external virtual override view returns (IBasketManager) {\n return _nftBasketManager[basketId];\n }\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param sender The sender address to validate against\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external virtual override {\n _validateDeposit(sender, contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param sender The sender address to validate against\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external virtual override {\n _validateNftDeposit(sender, contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateDischarge(sender, contractAddress, tokenId);\n }\n\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateRelease(sender, contractAddress, tokenId);\n }\n\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateBreakBond(sender, contractAddress, tokenId);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"state\"))) {\n _chargedState = IChargedState(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n /// @dev Register Contracts as wallet managers with a unique liquidity provider ID\n function registerWalletManager(string calldata walletManagerId, address walletManager) external virtual onlyOwner {\n // Validate wallet manager\n IWalletManager newWalletMgr = IWalletManager(walletManager);\n require(newWalletMgr.isPaused() != true, \"CP:E-418\");\n\n // Register LP ID\n _ftWalletManager[walletManagerId] = newWalletMgr;\n emit WalletManagerRegistered(walletManagerId, walletManager);\n }\n\n /// @dev Register Contracts as basket managers with a unique basket ID\n function registerBasketManager(string calldata basketId, address basketManager) external virtual onlyOwner {\n // Validate basket manager\n IBasketManager newBasketMgr = IBasketManager(basketManager);\n require(newBasketMgr.isPaused() != true, \"CP:E-418\");\n\n // Register Basket ID\n _nftBasketManager[basketId] = newBasketMgr;\n emit BasketManagerRegistered(basketId, basketManager);\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev See {ChargedParticles-isWalletManagerEnabled}.\n function _isWalletManagerEnabled(string calldata walletManagerId) internal view virtual returns (bool) {\n return (address(_ftWalletManager[walletManagerId]) != address(0x0) && !_ftWalletManager[walletManagerId].isPaused());\n }\n\n /// @dev See {ChargedParticles-isNftBasketEnabled}.\n function _isNftBasketEnabled(string calldata basketId) internal view virtual returns (bool) {\n return (address(_nftBasketManager[basketId]) != address(0x0) && !_nftBasketManager[basketId].isPaused());\n }\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n internal\n virtual\n {\n if (_chargedState.isEnergizeRestricted(contractAddress, tokenId)) {\n bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender);\n require(isNFTOwnerOrOperator, \"CP:E-105\");\n }\n\n ( string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n ) = _chargedSettings.getAssetRequirements(contractAddress, assetToken);\n\n require(energizeEnabled, \"CP:E-417\");\n\n require(!invalidAsset, \"CP:E-424\");\n\n // Valid Wallet Manager?\n if (bytes(requiredWalletManager).length > 0) {\n require(keccak256(abi.encodePacked(requiredWalletManager)) == keccak256(abi.encodePacked(walletManagerId)), \"CP:E-419\");\n }\n\n // Valid Asset?\n if (restrictedAssets) {\n require(validAsset, \"CP:E-424\");\n }\n\n _validateDepositAmount(\n contractAddress,\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n depositCap,\n depositMin,\n depositMax\n );\n }\n\n /// @dev Validates a Deposit-Amount according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDepositAmount(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax\n )\n internal\n virtual\n {\n uint256 existingBalance = _ftWalletManager[walletManagerId].getPrincipal(contractAddress, tokenId, assetToken);\n uint256 newBalance = assetAmount.add(existingBalance);\n\n // Validate Deposit Cap\n if (depositCap > 0) {\n require(newBalance <= depositCap, \"CP:E-408\");\n }\n\n // Valid Amount for Deposit?\n if (depositMin > 0) {\n require(newBalance >= depositMin, \"CP:E-410\");\n }\n if (depositMax > 0) {\n require(newBalance <= depositMax, \"CP:E-410\");\n }\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n {\n // Prevent Ouroboros NFTs\n require(contractAddress.getTokenUUID(tokenId) != nftTokenAddress.getTokenUUID(nftTokenId), \"CP:E-433\");\n\n if (_chargedState.isCovalentBondRestricted(contractAddress, tokenId)) {\n bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender);\n require(isNFTOwnerOrOperator, \"CP:E-105\");\n }\n\n ( string memory requiredBasketManager,\n bool basketEnabled,\n uint256 maxNfts\n ) = _chargedSettings.getNftAssetRequirements(contractAddress, nftTokenAddress);\n\n require(basketEnabled, \"CP:E-417\");\n\n // Valid Basket Manager?\n if (bytes(requiredBasketManager).length > 0) {\n require(keccak256(abi.encodePacked(requiredBasketManager)) == keccak256(abi.encodePacked(basketManagerId)), \"CP:E-419\");\n }\n\n if (maxNfts > 0) {\n uint256 tokenCount = _nftBasketManager[basketManagerId].getTokenTotalCount(contractAddress, tokenId);\n require(maxNfts >= (tokenCount + nftTokenAmount), \"CP:E-427\");\n }\n }\n\n function _validateDischarge(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getDischargeState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateRelease(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getReleaseState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateBreakBond(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getBreakBondState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateState(\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n internal\n view\n virtual\n {\n if (!allowFromAll) {\n require(isApproved, \"CP:E-105\");\n }\n if (timelock > 0) {\n require(block.number >= timelock, \"CP:E-302\");\n }\n if (tempLockExpiry > 0) {\n require(block.number >= tempLockExpiry, \"CP:E-303\");\n }\n }\n}\n" + }, + "contracts/v1/ChargedParticles.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\n\nimport \"./interfaces/IUniverse.sol\";\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/IWalletManager.sol\";\nimport \"./interfaces/IBasketManager.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/RelayRecipient.sol\";\n\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles V2 Contract\n * @dev Upgradeable Contract\n */\ncontract ChargedParticles is\n IChargedParticles,\n Initializable,\n OwnableUpgradeable,\n ReentrancyGuardUpgradeable,\n RelayRecipient,\n IERC721ReceiverUpgradeable,\n BlackholePrevention,\n IERC1155ReceiverUpgradeable\n{\n using SafeMathUpgradeable for uint256;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using Bitwise for uint32;\n using AddressUpgradeable for address;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n //\n // Particle Terminology\n //\n // Particle - Non-fungible Token (NFT)\n // Mass - Underlying Asset of a Token (ex; DAI)\n // Charge - Accrued Interest on the Underlying Asset of a Token\n // Charged Particle - Any NFT that has a Mass and a Positive Charge\n // Neutral Particle - Any NFT that has a Mass and No Charge\n // Energize / Recharge - Deposit of an Underlying Asset into an NFT\n // Discharge - Withdraw the Accrued Interest of an NFT leaving the Particle with its initial Mass\n // Release - Withdraw the Underlying Asset & Accrued Interest of an NFT leaving the Particle with No Mass or Charge\n //\n // Proton - NFTs minted from the Charged Particle Accelerator\n // - A proton is a subatomic particle, symbol p or p⁺, with a positive electric charge of +1e elementary\n // charge and a mass slightly less than that of a neutron.\n // Ion - Platform Governance Token\n // - A charged subatomic particle. An atom or group of atoms that carries a positive or negative electric charge\n // as a result of having lost or gained one or more electrons.\n //\n\n // Linked Contracts\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n address internal _lepton;\n uint256 internal depositFee;\n ITokenInfoProxy internal _tokenInfoProxy;\n IChargedManagers internal _chargedManagers;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n __ReentrancyGuard_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getStateAddress() external view virtual override returns (address stateAddress) {\n return address(_chargedState);\n }\n\n function getSettingsAddress() external view virtual override returns (address settingsAddress) {\n return address(_chargedSettings);\n }\n\n function getManagersAddress() external view virtual override returns (address managersAddress) {\n return address(_chargedManagers);\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external virtual override returns (bytes4) {\n return IERC721ReceiverUpgradeable(0).onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external virtual override returns (bytes4) {\n return IERC1155ReceiverUpgradeable(0).onERC1155Received.selector;\n }\n\n // Unimplemented\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external virtual override returns (bytes4) {\n return \"\"; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector;\n }\n\n function supportsInterface(bytes4 /* interfaceId */) external view virtual override returns (bool) {\n return false;\n }\n\n /// @notice Calculates the amount of Fees to be paid for a specific deposit amount\n /// @param assetAmount The Amount of Assets to calculate Fees on\n /// @return protocolFee The amount of deposit fees for the protocol\n function getFeesForDeposit(\n uint256 assetAmount\n )\n external\n override\n view\n returns (uint256 protocolFee)\n {\n protocolFee = _getFeesForDeposit(assetAmount);\n }\n\n /// @notice Gets the Amount of Asset Tokens that have been Deposited into the Particle\n /// representing the Mass of the Particle.\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Asset balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The Amount of underlying Assets held within the Token\n function baseParticleMass(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _baseParticleMass(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the amount of Interest that the Particle has generated representing\n /// the Charge of the Particle\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Interest balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The amount of interest the Token has generated (in Asset Token)\n function currentParticleCharge(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _currentParticleCharge(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the amount of LP Tokens that the Particle has generated representing\n /// the Kinetics of the Particle\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Kinetics balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The amount of LP tokens that have been generated\n function currentParticleKinetics(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _currentParticleKinetics(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the total amount of ERC721 Tokens that the Particle holds\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param basketManagerId The ID of the BasketManager to check the token balance of\n /// @return The total amount of ERC721 tokens that are held within the Particle\n function currentParticleCovalentBonds(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId\n )\n external\n view\n virtual\n override\n basketEnabled(basketManagerId)\n returns (uint256)\n {\n return _currentParticleCovalentBonds(contractAddress, tokenId, basketManagerId);\n }\n\n\n /***********************************|\n | Energize Particles |\n |__________________________________*/\n\n /// @notice Fund Particle with Asset Token\n /// Must be called by the account providing the Asset\n /// Account must Approve THIS contract as Operator of Asset\n ///\n /// NOTE: DO NOT Energize an ERC20 Token, as anyone who holds any amount\n /// of the same ERC20 token could discharge or release the funds.\n /// All holders of the ERC20 token would essentially be owners of the Charged Particle.\n ///\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param walletManagerId The Asset-Pair to Energize the Token with\n /// @param assetToken The Address of the Asset Token being used\n /// @param assetAmount The Amount of Asset Token to Energize the Token with\n /// @return yieldTokensAmount The amount of Yield-bearing Tokens added to the escrow for the Token\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 yieldTokensAmount)\n {\n _validateDeposit(contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n\n // Transfer ERC20 Token from Caller to Contract (reverts on fail)\n uint256 feeAmount = _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n yieldTokensAmount = _depositIntoWalletManager(contractAddress, tokenId, walletManagerId, assetToken, assetAmount, feeAmount);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onEnergize(_msgSender(), referrer, contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n }\n\n\n /***********************************|\n | Discharge Particles |\n |__________________________________*/\n\n /// @notice Allows the owner or operator of the Token to collect or transfer the interest generated\n /// from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @return creatorAmount Amount of Asset Token discharged to the Creator\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateDischarge(contractAddress, tokenId);\n\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).discharge(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount);\n }\n }\n\n /// @notice Allows the owner or operator of the Token to collect or transfer a specific amount of the interest\n /// generated from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @param assetAmount The specific amount of Asset Token to Discharge from the Token\n /// @return creatorAmount Amount of Asset Token discharged to the Creator\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateDischarge(contractAddress, tokenId);\n\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).dischargeAmount(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n assetAmount,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount);\n }\n }\n\n /// @notice Allows the Creator of the Token to collect or transfer a their portion of the interest (if any)\n /// generated from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @param assetAmount The specific amount of Asset Token to Discharge from the Particle\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 receiverAmount)\n {\n address sender = _msgSender();\n address tokenCreator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId);\n require(sender == tokenCreator, \"CP:E-104\");\n\n receiverAmount = _chargedManagers.getWalletManager(walletManagerId).dischargeAmountForCreator(\n receiver,\n contractAddress,\n tokenId,\n sender,\n assetToken,\n assetAmount\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischargeForCreator(contractAddress, tokenId, walletManagerId, sender, assetToken, receiverAmount);\n }\n }\n\n\n /***********************************|\n | Release Particles |\n |__________________________________*/\n\n /// @notice Releases the Full amount of Asset + Interest held within the Particle by LP of the Assets\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Release\n /// @param tokenId The ID of the Token to Release\n /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token\n /// @param assetToken The Address of the Asset Token being released\n /// @return creatorAmount Amount of Asset Token released to the Creator\n /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount)\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateRelease(contractAddress, tokenId);\n\n // Release Particle to Receiver\n uint256 principalAmount;\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).release(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n }\n\n\n /// @notice Releases a partial amount of Asset + Interest held within the Particle by LP of the Assets\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Release\n /// @param tokenId The ID of the Token to Release\n /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token\n /// @param assetToken The Address of the Asset Token being released\n /// @param assetAmount The specific amount of Asset Token to Release from the Particle\n /// @return creatorAmount Amount of Asset Token released to the Creator\n /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount)\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateRelease(contractAddress, tokenId);\n\n // Release Particle to Receiver\n uint256 principalAmount;\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).releaseAmount(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n assetAmount,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n }\n\n\n /***********************************|\n | Covalent Bonding |\n |__________________________________*/\n\n /// @notice Deposit other NFT Assets into the Particle\n /// Must be called by the account providing the Asset\n /// Account must Approve THIS contract as Operator of Asset\n ///\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n basketEnabled(basketManagerId)\n nonReentrant\n returns (bool success)\n {\n _validateNftDeposit(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Transfer ERC721 Token from Caller to Contract (reverts on fail)\n _collectNftToken(_msgSender(), nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n success = _depositIntoBasketManager(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onCovalentBond(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n }\n\n /// @notice Release NFT Assets from the Particle\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Withdraw (ERC1155-specific)\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n basketEnabled(basketManagerId)\n nonReentrant\n returns (bool success)\n {\n _validateBreakBond(contractAddress, tokenId);\n\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked(\"generic\"))) {\n basketMgr.prepareTransferAmount(nftTokenAmount);\n }\n\n // Release Particle to Receiver\n success = basketMgr.removeFromBasket(\n receiver,\n contractAddress,\n tokenId,\n nftTokenAddress,\n nftTokenId\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onCovalentBreak(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"universe\"))) {\n _universe = IUniverse(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"state\"))) {\n _chargedState = IChargedState(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"managers\"))) {\n _chargedManagers = IChargedManagers(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"leptons\"))) {\n _lepton = controller;\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"forwarder\"))) {\n trustedForwarder = controller;\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n\n /***********************************|\n | Protocol Fees |\n |__________________________________*/\n\n /// @dev Setup the Base Deposit Fee for the Protocol\n function setDepositFee(uint256 fee) external onlyOwner {\n require(fee < PERCENTAGE_SCALE, \"CP:E-421\");\n depositFee = fee;\n emit DepositFeeSet(fee);\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n internal\n virtual\n {\n _chargedManagers.validateDeposit(_msgSender(), contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _validateNftDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n {\n _chargedManagers.validateNftDeposit(_msgSender(), contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function _validateDischarge(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateDischarge(_msgSender(), contractAddress, tokenId);\n }\n\n function _validateRelease(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateRelease(_msgSender(), contractAddress, tokenId);\n }\n\n function _validateBreakBond(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateBreakBond(_msgSender(), contractAddress, tokenId);\n }\n\n /// @dev Deposit Asset Tokens into an NFT via the Wallet Manager\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n /// @param feeAmount The Amount of Protocol Fees charged\n function _depositIntoWalletManager(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 feeAmount\n )\n internal\n virtual\n returns (uint256)\n {\n // Get Wallet-Manager for LP\n IWalletManager lpWalletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n address wallet = lpWalletMgr.getWalletAddressById(contractAddress, tokenId, creator, annuityPct);\n IERC20Upgradeable(assetToken).transfer(wallet, assetAmount);\n\n emit ProtocolFeesCollected(assetToken, assetAmount, feeAmount);\n\n return lpWalletMgr.energize(contractAddress, tokenId, assetToken, assetAmount);\n }\n\n /// @dev Deposit NFT Tokens into the Basket Manager\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @param basketManagerId The Wallet Manager of the Assets to Deposit\n /// @param nftTokenAddress The Address of the Asset Token to Deposit\n /// @param nftTokenId The specific amount of Asset Token to Deposit\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _depositIntoBasketManager(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n returns (bool)\n {\n // Deposit NFT Token directly into Smart Wallet (reverts on fail) and Update BasketManager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId);\n\n if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked(\"generic\"))) {\n basketMgr.prepareTransferAmount(nftTokenAmount);\n }\n\n if (_isERC1155(nftTokenAddress)) {\n if (nftTokenAmount == 0) { nftTokenAmount = 1; }\n IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(address(this), wallet, nftTokenId, nftTokenAmount, \"\");\n } else {\n IERC721Upgradeable(nftTokenAddress).transferFrom(address(this), wallet, nftTokenId);\n }\n return basketMgr.addToBasket(contractAddress, tokenId, nftTokenAddress, nftTokenId);\n }\n\n /**\n * @dev Calculates the amount of Fees to be paid for a specific deposit amount\n * Fees are calculated in Interest-Token as they are the type collected for Fees\n * @param assetAmount The Amount of Assets to calculate Fees on\n * @return protocolFee The amount of fees reserved for the protocol\n */\n function _getFeesForDeposit(\n uint256 assetAmount\n )\n internal\n view\n returns (uint256 protocolFee)\n {\n if (depositFee > 0) {\n protocolFee = assetAmount.mul(depositFee).div(PERCENTAGE_SCALE);\n }\n }\n\n /// @dev Collects the Required ERC20 Token(s) from the users wallet\n /// Be sure to Approve this Contract to transfer your Token(s)\n /// @param from The owner address to collect the tokens from\n /// @param tokenAddress The addres of the token to transfer\n /// @param tokenAmount The amount of tokens to collect\n function _collectAssetToken(address from, address tokenAddress, uint256 tokenAmount) internal virtual returns (uint256 protocolFee) {\n protocolFee = _getFeesForDeposit(tokenAmount);\n IERC20Upgradeable(tokenAddress).safeTransferFrom(from, address(this), tokenAmount.add(protocolFee));\n }\n\n /// @dev Collects the Required ERC721 Token(s) from the users wallet\n /// Be sure to Approve this Contract to transfer your Token(s)\n /// @param from The owner address to collect the tokens from\n /// @param nftTokenAddress The address of the NFT token to transfer\n /// @param nftTokenId The ID of the NFT token to transfer\n /// @param nftTokenAmount The amount of Tokens to Transfer (ERC1155-specific)\n function _collectNftToken(address from, address nftTokenAddress, uint256 nftTokenId, uint256 nftTokenAmount) internal virtual {\n if (_isERC1155(nftTokenAddress)) {\n IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId, nftTokenAmount, \"\");\n } else {\n IERC721Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId);\n }\n }\n\n /// @dev Checks if an NFT token contract supports the ERC1155 standard interface\n function _isERC1155(address nftTokenAddress) internal view virtual returns (bool) {\n bytes4 _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n return IERC165Upgradeable(nftTokenAddress).supportsInterface(_INTERFACE_ID_ERC1155);\n }\n\n /// @dev See {ChargedParticles-baseParticleMass}.\n function _baseParticleMass(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n return _chargedManagers.getWalletManager(walletManagerId).getPrincipal(contractAddress, tokenId, assetToken);\n }\n\n /// @dev See {ChargedParticles-currentParticleCharge}.\n function _currentParticleCharge(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n (, uint256 ownerInterest) = _chargedManagers.getWalletManager(walletManagerId).getInterest(contractAddress, tokenId, assetToken);\n return ownerInterest;\n }\n\n /// @dev See {ChargedParticles-currentParticleKinetics}.\n function _currentParticleKinetics(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n return _chargedManagers.getWalletManager(walletManagerId).getRewards(contractAddress, tokenId, assetToken);\n }\n\n /// @dev See {ChargedParticles-currentParticleCovalentBonds}.\n function _currentParticleCovalentBonds(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId\n )\n internal\n view\n virtual\n returns (uint256)\n {\n return _chargedManagers.getBasketManager(basketManagerId).getTokenTotalCount(contractAddress, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier managerEnabled(string calldata walletManagerId) {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"CP:E-419\");\n _;\n }\n\n modifier basketEnabled(string calldata basketManagerId) {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"CP:E-419\");\n _;\n }\n}\n" + }, + "contracts/v1/ChargedSettings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/RelayRecipient.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\nimport \"./lib/TokenInfoProxy.sol\";\n\n/**\n * @notice Charged Particles Settings Contract\n */\ncontract ChargedSettings is\n IChargedSettings,\n Initializable,\n OwnableUpgradeable,\n RelayRecipient,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using Bitwise for uint32;\n\n uint256 constant internal MAX_ANNUITIES = 1e4; // 10000 (100%)\n\n // NftSettings - actionPerms\n uint32 constant internal PERM_CHARGE_NFT = 1; // NFT Contracts that can have assets Deposited into them (Charged)\n uint32 constant internal PERM_BASKET_NFT = 2; // NFT Contracts that can have other NFTs Deposited into them\n uint32 constant internal PERM_TIMELOCK_ANY_NFT = 4; // NFT Contracts that can timelock any NFT on behalf of users (primarily used for Front-run Protection)\n uint32 constant internal PERM_TIMELOCK_OWN_NFT = 8; // NFT Contracts that can timelock their own NFTs on behalf of their users\n uint32 constant internal PERM_RESTRICTED_ASSETS = 16; // NFT Contracts that have restricted deposits to specific assets\n\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // Current Settings for External NFT Token Contracts;\n // - Any user can add any ERC721 or ERC1155 token as a Charged Particle without Limits,\n // unless the Owner of the ERC721 or ERC1155 token contract registers the token\n // and sets the Custom Settings for their token(s)\n mapping (address => uint32) internal _nftActionPerms;\n\n mapping (address => string) internal _nftRequiredWalletManager;\n mapping (address => string) internal _nftRequiredBasketManager;\n\n // ERC20\n mapping (address => mapping(address => bool)) internal _nftAllowedAssetTokens;\n mapping (address => mapping (address => uint256)) internal _nftDepositMin;\n mapping (address => mapping (address => uint256)) internal _nftDepositMax;\n\n // ERC721 / ERC1155\n mapping (address => mapping (address => uint256)) internal _nftMaxNfts; // NFT Token Address => Max\n\n // Optional Configs for individual NFTs set by NFT Creator (by Token UUID)\n mapping (uint256 => uint256) internal _creatorAnnuityPercent;\n mapping (uint256 => address) internal _creatorAnnuityRedirect;\n\n mapping (address => uint256) internal _depositCap;\n uint256 internal _tempLockExpiryBlocks;\n\n // Blacklist for non-compliant tokens\n mapping (address => bool) internal _invalidAssets;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n /// @dev Gets the amount of creator annuities reserved for the creator for the specified NFT\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @return creator The address of the creator\n /// @return annuityPct The percentage amount of annuities reserved for the creator\n function getCreatorAnnuities(\n address contractAddress,\n uint256 tokenId\n )\n external\n override\n virtual\n returns (address creator, uint256 annuityPct)\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n creator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId);\n annuityPct = _creatorAnnuityPercent[tokenUuid];\n }\n\n function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId)\n external\n view\n override\n virtual\n returns (address)\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _creatorAnnuityRedirect[tokenUuid];\n }\n\n function getTempLockExpiryBlocks() external view override virtual returns (uint256) {\n return _tempLockExpiryBlocks;\n }\n\n function getTimelockApprovals(address operator)\n external\n view\n override\n virtual\n returns (bool timelockAny, bool timelockOwn)\n {\n timelockAny = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_ANY_NFT);\n timelockOwn = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_OWN_NFT);\n }\n\n function getAssetRequirements(address contractAddress, address assetToken)\n external\n view\n override\n virtual\n returns (\n string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n )\n {\n requiredWalletManager = _nftRequiredWalletManager[contractAddress];\n energizeEnabled = _nftActionPerms[contractAddress].hasBit(PERM_CHARGE_NFT);\n restrictedAssets = _nftActionPerms[contractAddress].hasBit(PERM_RESTRICTED_ASSETS);\n validAsset = _nftAllowedAssetTokens[contractAddress][assetToken];\n depositCap = _depositCap[assetToken];\n depositMin = _nftDepositMin[contractAddress][assetToken];\n depositMax = _nftDepositMax[contractAddress][assetToken];\n invalidAsset = _invalidAssets[assetToken];\n }\n\n function getNftAssetRequirements(address contractAddress, address nftTokenAddress)\n external\n view\n override\n virtual\n returns (string memory requiredBasketManager, bool basketEnabled, uint256 maxNfts)\n {\n requiredBasketManager = _nftRequiredBasketManager[contractAddress];\n basketEnabled = _nftActionPerms[contractAddress].hasBit(PERM_BASKET_NFT);\n maxNfts = _nftMaxNfts[contractAddress][nftTokenAddress];\n }\n\n\n /***********************************|\n | Only NFT Creator |\n |__________________________________*/\n\n /// @notice Sets the Custom Configuration for Creators of Proton-based NFTs\n /// @param contractAddress The Address to the Proton-based NFT to configure\n /// @param tokenId The token ID of the Proton-based NFT to configure\n /// @param creator The creator of the Proton-based NFT\n /// @param annuityPercent The percentage of interest-annuities to reserve for the creator\n function setCreatorAnnuities(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent\n )\n external\n virtual\n override\n {\n require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), \"CP:E-104\");\n _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent);\n }\n\n /// @notice Sets a Custom Receiver Address for the Creator Annuities\n /// @param contractAddress The Address to the Proton-based NFT to configure\n /// @param tokenId The token ID of the Proton-based NFT to configure\n /// @param receiver The receiver of the Creator interest-annuities\n function setCreatorAnnuitiesRedirect(\n address contractAddress,\n uint256 tokenId,\n address receiver\n )\n external\n virtual\n override\n {\n require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), \"CP:E-104\");\n _setCreatorAnnuitiesRedirect(contractAddress, tokenId, receiver);\n }\n\n\n /***********************************|\n | Register Contract Settings |\n |(For External Contract Integration)|\n |__________________________________*/\n\n /// @notice Sets a Required Wallet-Manager for External NFT Contracts (otherwise set to \"none\" to allow any Wallet-Manager)\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param walletManager If set, will only allow deposits from this specific Wallet-Manager\n function setRequiredWalletManager(\n address contractAddress,\n string calldata walletManager\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (keccak256(bytes(walletManager)) == keccak256(bytes(\"none\"))) {\n _nftRequiredWalletManager[contractAddress] = \"\";\n } else {\n _nftRequiredWalletManager[contractAddress] = walletManager;\n }\n\n emit RequiredWalletManagerSet(\n contractAddress,\n walletManager\n );\n }\n\n /// @notice Sets a Required Basket-Manager for External NFT Contracts (otherwise set to \"none\" to allow any Basket-Manager)\n /// @param contractAddress The Address to the External Contract to configure\n /// @param basketManager If set, will only allow deposits from this specific Basket-Manager\n function setRequiredBasketManager(\n address contractAddress,\n string calldata basketManager\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (keccak256(bytes(basketManager)) == keccak256(bytes(\"none\"))) {\n _nftRequiredBasketManager[contractAddress] = \"\";\n } else {\n _nftRequiredBasketManager[contractAddress] = basketManager;\n }\n\n emit RequiredBasketManagerSet(\n contractAddress,\n basketManager\n );\n }\n\n /// @notice Enables or Disables Asset-Token Restrictions for External NFT Contracts\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param restrictionsEnabled If set, will only allow deposits from Allowed Asset Tokens\n function setAssetTokenRestrictions(\n address contractAddress,\n bool restrictionsEnabled\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (restrictionsEnabled) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_RESTRICTED_ASSETS);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_RESTRICTED_ASSETS);\n }\n\n emit AssetTokenRestrictionsSet(\n contractAddress,\n restrictionsEnabled\n );\n }\n\n /// @notice Enables or Disables Allowed Asset Tokens for External NFT Contracts\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param assetToken The Address of the Asset Token to Allow or Disallow\n /// @param isAllowed True if the Asset Token is allowed\n function setAllowedAssetToken(\n address contractAddress,\n address assetToken,\n bool isAllowed\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftAllowedAssetTokens[contractAddress][assetToken] = isAllowed;\n\n emit AllowedAssetTokenSet(\n contractAddress,\n assetToken,\n isAllowed\n );\n }\n\n /// @notice Sets the Custom Configuration for External Contracts\n /// @param contractAddress The Address to the External Contract to configure\n /// @param assetToken The address of the Asset Token to set Limits for\n /// @param depositMin If set, will define the minimum amount of Asset tokens the NFT may hold, otherwise any amount\n /// @param depositMax If set, will define the maximum amount of Asset tokens the NFT may hold, otherwise any amount\n function setAssetTokenLimits(\n address contractAddress,\n address assetToken,\n uint256 depositMin,\n uint256 depositMax\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftDepositMin[contractAddress][assetToken] = depositMin;\n _nftDepositMax[contractAddress][assetToken] = depositMax;\n\n emit AssetTokenLimitsSet(\n contractAddress,\n assetToken,\n depositMin,\n depositMax\n );\n }\n\n /// @notice Sets the Max Number of NFTs that can be held by a Charged Particle NFT\n /// @param contractAddress The Address to the External Contract to configure\n /// @param nftTokenAddress The address of the NFT Token to set a Max for\n /// @param maxNfts The maximum numbers of NFTs that can be held by a given NFT (0 = unlimited)\n function setMaxNfts(\n address contractAddress,\n address nftTokenAddress,\n uint256 maxNfts\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftMaxNfts[contractAddress][nftTokenAddress] = maxNfts;\n\n emit MaxNftsSet(\n contractAddress,\n nftTokenAddress,\n maxNfts\n );\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n function setAssetInvalidity(address assetToken, bool invalidity) external virtual override onlyOwner {\n _invalidAssets[assetToken] = invalidity;\n emit AssetInvaliditySet(assetToken, invalidity);\n }\n\n function setDepositCap(address assetToken, uint256 cap) external virtual onlyOwner {\n _depositCap[assetToken] = cap;\n emit DepositCapSet(assetToken, cap);\n }\n\n function setTempLockExpiryBlocks(uint256 numBlocks) external virtual onlyOwner {\n _tempLockExpiryBlocks = numBlocks;\n emit TempLockExpirySet(numBlocks);\n }\n\n function enableNftContracts(address[] calldata contracts) external override virtual onlyOwner {\n uint count = contracts.length;\n for (uint i = 0; i < count; i++) {\n address tokenContract = contracts[i];\n _setPermsForCharge(tokenContract, true);\n _setPermsForBasket(tokenContract, true);\n _setPermsForTimelockSelf(tokenContract, true);\n }\n }\n\n function migrateToken(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent,\n address annuityReceiver\n )\n external\n onlyOwner\n {\n _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent);\n if (annuityReceiver != address(0)) {\n _setCreatorAnnuitiesRedirect(contractAddress, tokenId, annuityReceiver);\n }\n }\n\n /// @dev Update the list of NFT contracts that can be Charged\n function setPermsForCharge(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForCharge(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can hold other NFTs\n function setPermsForBasket(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForBasket(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection\n function setPermsForTimelockAny(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForTimelockAny(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock their own tokens\n function setPermsForTimelockSelf(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForTimelockSelf(contractAddress, state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Update the list of NFT contracts that can be Charged\n function _setPermsForCharge(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_CHARGE_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_CHARGE_NFT);\n }\n emit PermsSetForCharge(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can hold other NFTs\n function _setPermsForBasket(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_BASKET_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_BASKET_NFT);\n }\n emit PermsSetForBasket(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection\n function _setPermsForTimelockAny(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_ANY_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_ANY_NFT);\n }\n emit PermsSetForTimelockAny(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock their own tokens\n function _setPermsForTimelockSelf(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_OWN_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_OWN_NFT);\n }\n emit PermsSetForTimelockSelf(contractAddress, state);\n }\n\n /// @dev see setCreatorAnnuities()\n function _setCreatorAnnuities(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent\n )\n internal\n virtual\n {\n require(annuityPercent <= MAX_ANNUITIES, \"CP:E-421\");\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Update Configs for External Token Creator\n _creatorAnnuityPercent[tokenUuid] = annuityPercent;\n\n emit TokenCreatorConfigsSet(\n contractAddress,\n tokenId,\n creator,\n annuityPercent\n );\n }\n\n /// @dev see setCreatorAnnuitiesRedirect()\n function _setCreatorAnnuitiesRedirect(\n address contractAddress,\n uint256 tokenId,\n address receiver\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _creatorAnnuityRedirect[tokenUuid] = receiver;\n emit TokenCreatorAnnuitiesRedirected(contractAddress, tokenId, receiver);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyValidExternalContract(address contractAddress) {\n require(contractAddress.isContract(), \"CP:E-420\");\n _;\n }\n\n modifier onlyContractOwnerOrAdmin(address contractAddress, address sender) {\n require(sender == owner() || contractAddress.isContractOwner(sender), \"CP:E-103\");\n _;\n }\n}\n" + }, + "contracts/v1/ChargedState.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedState.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/RelayRecipient.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Settings Contract\n */\ncontract ChargedState is\n IChargedState,\n Initializable,\n OwnableUpgradeable,\n RelayRecipient,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using Bitwise for uint32;\n\n // NftState - actionPerms\n uint32 constant internal PERM_RESTRICT_ENERGIZE_FROM_ALL = 1; // NFTs that have Restrictions on Energize\n uint32 constant internal PERM_ALLOW_DISCHARGE_FROM_ALL = 2; // NFTs that allow Discharge by anyone\n uint32 constant internal PERM_ALLOW_RELEASE_FROM_ALL = 4; // NFTs that allow Release by anyone\n uint32 constant internal PERM_RESTRICT_BOND_FROM_ALL = 8; // NFTs that have Restrictions on Covalent Bonds\n uint32 constant internal PERM_ALLOW_BREAK_BOND_FROM_ALL = 16; // NFTs that allow Breaking Covalent Bonds by anyone\n\n IChargedSettings internal _chargedSettings;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // NftTimelocks\n /// @dev discharge unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftDischargeTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftDischargeTimelockLockedBy;\n\n /// @dev release unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftReleaseTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftReleaseTimelockLockedBy;\n\n /// @dev release unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftBreakBondTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftBreakBondTimelockLockedBy;\n\n // NftState\n /// @dev maps nft by tokenId to actionPermissions uint32 which is a composite of all possible NftState - actionPerms\n mapping (uint256 => uint32) internal _nftActionPerms;\n\n /// @dev maps nft by tokenId to its tempLockExpiry\n mapping (uint256 => uint256) internal _nftTempLockExpiry;\n\n /// @dev maps tokenId to user address to operator address for approving various actions\n mapping (uint256 => mapping(address => address)) internal _nftDischargeApproval;\n mapping (uint256 => mapping(address => address)) internal _nftReleaseApproval;\n mapping (uint256 => mapping(address => address)) internal _nftBreakBondApproval;\n mapping (uint256 => mapping(address => address)) internal _nftTimelockApproval;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftDischargeTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftDischargeTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftReleaseTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftReleaseTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftBreakBondTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftBreakBondTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n\n /// @notice Checks if an operator is allowed to Discharge a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForDischarge(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Release a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForRelease(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Break Covalent Bonds on a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForBreakBond(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Timelock a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForTimelock(contractAddress, tokenId, operator);\n }\n\n\n function isEnergizeRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n }\n\n\n function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_BOND_FROM_ALL);\n }\n\n\n function getDischargeState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n isApproved = _isApprovedForDischarge(contractAddress, tokenId, sender);\n timelock = _nftDischargeTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n function getReleaseState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_RELEASE_FROM_ALL);\n isApproved = _isApprovedForRelease(contractAddress, tokenId, sender);\n timelock = _nftReleaseTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n function getBreakBondState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n isApproved = _isApprovedForBreakBond(contractAddress, tokenId, sender);\n timelock = _nftBreakBondTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n\n /***********************************|\n | Only NFT Owner/Operator |\n |__________________________________*/\n\n /// @notice Sets an Operator as Approved to Discharge a specific Token\n /// This allows an operator to withdraw the interest-portion only\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setDischargeApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Release a specific Token\n /// This allows an operator to withdraw the principal + interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setReleaseApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token\n /// This allows an operator to withdraw Basket NFTs\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setBreakBondApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Timelock a specific Token\n /// This allows an operator to timelock the principal or interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setTimelockApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Discharge/Release/Timelock a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setApprovalForAll(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @dev Updates Restrictions on Energizing an NFT\n function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForRestrictCharge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowDischarge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowRelease(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Restrictions on Covalent Bonds on an NFT\n function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForRestrictBond(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone\n function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowBreakBond(contractAddress, tokenId, state);\n }\n\n /// @notice Sets a Timelock on the ability to Discharge the Interest of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setDischargeTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftDischargeTimelockLockedBy[tokenUuid] == sender) {\n delete _nftDischargeTimelockUnlockBlock[tokenUuid];\n delete _nftDischargeTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftDischargeTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftDischargeTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftDischargeTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenDischargeTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n /// @notice Sets a Timelock on the ability to Release the Assets of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setReleaseTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftReleaseTimelockLockedBy[tokenUuid] == sender) {\n delete _nftReleaseTimelockUnlockBlock[tokenUuid];\n delete _nftReleaseTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftReleaseTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftReleaseTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftReleaseTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenReleaseTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n /// @notice Sets a Timelock on the ability to Break the Covalent Bond of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setBreakBondTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftBreakBondTimelockLockedBy[tokenUuid] == sender) {\n delete _nftBreakBondTimelockUnlockBlock[tokenUuid];\n delete _nftBreakBondTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftBreakBondTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftBreakBondTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftBreakBondTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenBreakBondTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n\n /***********************************|\n | Only NFT Contract |\n |__________________________________*/\n\n /// @notice Sets a Temporary-Lock on the ability to Release/Discharge the Assets of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param isLocked The locked state; contracts are expected to disable this lock before expiry\n function setTemporaryLock(\n address contractAddress,\n uint256 tokenId,\n bool isLocked\n )\n external\n override\n virtual\n {\n require(msg.sender == contractAddress, \"CP:E-112\");\n\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n uint256 unlockBlock;\n if (isLocked && _nftTempLockExpiry[tokenUuid] == 0) {\n unlockBlock = block.number.add(_chargedSettings.getTempLockExpiryBlocks());\n _nftTempLockExpiry[tokenUuid] = unlockBlock;\n }\n if (!isLocked) {\n _nftTempLockExpiry[tokenUuid] = 0;\n }\n\n emit TokenTempLock(contractAddress, tokenId, unlockBlock);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n function migrateToken(\n address contractAddress,\n uint256 tokenId,\n uint256 releaseTimelockExpiry,\n address releaseTimelockLockedBy,\n uint256 tempLockExpiry\n )\n external\n onlyOwner\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (releaseTimelockExpiry > block.number && releaseTimelockLockedBy != address(0)) {\n _nftReleaseTimelockUnlockBlock[tokenUuid] = releaseTimelockExpiry;\n _nftReleaseTimelockLockedBy[tokenUuid] = releaseTimelockLockedBy;\n emit TokenReleaseTimelock(contractAddress, tokenId, releaseTimelockLockedBy, releaseTimelockExpiry);\n }\n\n if (tempLockExpiry > 0) {\n _nftTempLockExpiry[tokenUuid] = tempLockExpiry;\n emit TokenTempLock(contractAddress, tokenId, tempLockExpiry);\n }\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev See {ChargedParticles-isApprovedForDischarge}.\n function _isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftDischargeApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForRelease}.\n function _isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftReleaseApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForBreakBond}.\n function _isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftBreakBondApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForTimelock}.\n function _isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n (bool timelockAny, bool timelockOwn) = _chargedSettings.getTimelockApprovals(operator);\n if (timelockAny || (timelockOwn && contractAddress == operator)) { return true; }\n\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return tokenOwner == operator || _nftTimelockApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @notice Sets an Operator as Approved to Discharge a specific Token\n /// This allows an operator to withdraw the interest-portion only\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setDischargeApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftDischargeApproval[tokenUuid][tokenOwner] = operator;\n emit DischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Release a specific Token\n /// This allows an operator to withdraw the principal + interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setReleaseApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftReleaseApproval[tokenUuid][tokenOwner] = operator;\n emit ReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token\n /// This allows an operator to withdraw Basket NFTs\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setBreakBondApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftBreakBondApproval[tokenUuid][tokenOwner] = operator;\n emit BreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Timelock a specific Token\n /// This allows an operator to timelock the principal or interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setTimelockApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftTimelockApproval[tokenUuid][tokenOwner] = operator;\n emit TimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @dev Updates Restrictions on Energizing an NFT\n function _setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n }\n emit PermsSetForRestrictCharge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function _setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n }\n emit PermsSetForAllowDischarge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function _setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_RELEASE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_RELEASE_FROM_ALL);\n }\n emit PermsSetForAllowRelease(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Restrictions on Covalent Bonds on an NFT\n function _setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_BOND_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_BOND_FROM_ALL);\n }\n emit PermsSetForRestrictBond(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone\n function _setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n }\n emit PermsSetForAllowBreakBond(contractAddress, tokenId, state);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) {\n require(_tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender), \"CP:E-105\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/CommunityVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract CommunityVault is Ownable, BlackholePrevention {\n\n IERC20 private immutable _ionx;\n\n constructor (address ionx) public {\n _ionx = IERC20(ionx);\n }\n\n event SetAllowance(address indexed caller, address indexed spender, uint256 amount);\n\n function setAllowance(address spender, uint amount) public onlyOwner {\n _ionx.approve(spender, amount);\n\n emit SetAllowance(msg.sender, spender, amount);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens other than IONX, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n require(tokenAddress != address(_ionx), \"CommunityVault: cannot withdraw IONX\");\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n}" + }, + "contracts/v1/incentives/MerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_) public {\n token = token_;\n merkleRoot = merkleRoot_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), 'MerkleDistributor: Drop already claimed.');\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), 'MerkleDistributor: Invalid proof.');\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), 'MerkleDistributor: Transfer failed.');\n\n emit Claimed(index, account, amount);\n }\n}\n" + }, + "contracts/v1/incentives/MerkleDistributor2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor2 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"MerkleDistributor2: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"MerkleDistributor2: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor2: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"MerkleDistributor2: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"MerkleDistributor2: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"MerkleDistributor2: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/MerkleDistributor3.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor3 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"MerkleDistributor3: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"MerkleDistributor3: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor3: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"MerkleDistributor3: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"MerkleDistributor3: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"MerkleDistributor3: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/RewardProgram.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// RewardProgram.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/IRewardProgram.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/introspection/IERC165.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"../interfaces/IUniverseRP.sol\";\nimport \"../interfaces/IChargedManagers.sol\";\nimport \"../interfaces/IWalletManager.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IERC20Detailed.sol\";\n\ncontract RewardProgram is\n IRewardProgram,\n BlackholePrevention,\n IERC165,\n ReentrancyGuard,\n IERC721Receiver,\n IERC1155Receiver\n{\n using SafeMath for uint256;\n using TokenInfo for address;\n using SafeERC20 for IERC20;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n\n address private _owner;\n IUniverseRP private _universe;\n IChargedManagers private _chargedManagers;\n ProgramRewardData private _programData;\n mapping(uint256 => AssetStake) private _assetStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public {}\n\n function initialize(\n address stakingToken,\n address rewardToken,\n uint256 baseMultiplier,\n address chargedManagers,\n address universe,\n address owner\n ) external override {\n require(_owner == address(0x0), \"Already initialized\");\n _owner = owner;\n\n // Prepare Reward Program\n _programData.stakingToken = stakingToken;\n _programData.rewardToken = rewardToken;\n _programData.baseMultiplier = baseMultiplier; // Basis Points\n\n // Connect to Charged Particles\n _chargedManagers = IChargedManagers(chargedManagers);\n _universe = IUniverseRP(universe);\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getProgramData() external view override returns (ProgramRewardData memory) {\n return _programData;\n }\n\n function getAssetStake(uint256 parentNftUuid) external view override returns (AssetStake memory) {\n return _assetStake[parentNftUuid];\n }\n\n function getFundBalance() external view override returns (uint256) {\n return _getFundBalance();\n }\n\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) public view override returns (uint256) {\n return _calculateRewardsEarned(parentNftUuid, interestAmount);\n }\n\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n return _assetStake[parentNftUuid].claimableRewards;\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\n return \"\";\n }\n\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(IERC165)\n returns (bool)\n {\n // default interface support\n if (\n interfaceId == type(IERC721Receiver).interfaceId ||\n interfaceId == type(IERC1155Receiver).interfaceId ||\n interfaceId == type(IERC165).interfaceId\n ) {\n return true;\n }\n }\n\n function owner() public view returns (address) {\n return _owner;\n }\n\n\n /***********************************|\n | Only Universe |\n |__________________________________*/\n\n function registerAssetDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n uint256 principalAmount\n )\n external\n override\n onlyUniverse\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n if (assetStake.start == 0) {\n assetStake.start = block.number;\n assetStake.walletManagerId = walletManagerId;\n }\n emit AssetDeposit(contractAddress, tokenId, walletManagerId, principalAmount);\n }\n\n function registerAssetRelease(\n address contractAddress,\n uint256 tokenId,\n uint256 interestAmount\n )\n external\n override\n onlyUniverse\n nonReentrant\n returns (uint256 rewards)\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n // Update Claimable Rewards\n uint256 newRewards = _calculateRewardsEarned(parentNftUuid, interestAmount);\n assetStake.claimableRewards = assetStake.claimableRewards.add(newRewards);\n\n // Reset Stake if Principal Balance falls to Zero\n IWalletManager walletMgr = _chargedManagers.getWalletManager(assetStake.walletManagerId);\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\n if (principal == 0) {\n assetStake.start = 0;\n }\n\n // Issue Rewards to NFT Owner\n rewards = _claimRewards(contractAddress, tokenId);\n\n emit AssetRelease(contractAddress, tokenId, interestAmount);\n }\n\n\n /***********************************|\n | Reward Calculation |\n |__________________________________*/\n\n function _calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) internal view returns (uint256 totalReward) {\n uint256 baseReward = _calculateBaseReward(interestAmount);\n uint256 leptonMultipliedReward = _calculateMultipliedReward(parentNftUuid, baseReward);\n totalReward = _convertDecimals(leptonMultipliedReward);\n }\n\n function _calculateBaseReward(uint256 amount) internal view returns(uint256 baseReward) {\n baseReward = amount.mul(_programData.baseMultiplier).div(PERCENTAGE_SCALE);\n }\n\n function _calculateMultipliedReward(uint256 parentNftUuid, uint256 baseReward) internal view returns(uint256) {\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n if (assetStake.start == 0) { return baseReward; }\n\n IUniverseRP.NftStake memory nftStake = _universe.getNftStake(parentNftUuid);\n uint256 multiplierBP = nftStake.multiplier;\n\n uint256 assetDepositLength = block.number.sub(assetStake.start);\n uint256 nftDepositLength = 0;\n if (nftStake.releaseBlockNumber > 0) {\n nftDepositLength = nftStake.releaseBlockNumber.sub(nftStake.depositBlockNumber);\n } else {\n nftDepositLength = block.number.sub(nftStake.depositBlockNumber);\n }\n\n if (multiplierBP == 0 || nftDepositLength == 0 || assetDepositLength == 0) {\n return baseReward;\n }\n\n if (nftDepositLength > assetDepositLength) {\n nftDepositLength = assetDepositLength;\n }\n\n // Percentage of the total program that the Multiplier Nft was deposited for\n uint256 nftRewardRatioBP = nftDepositLength.mul(PERCENTAGE_SCALE).div(assetDepositLength);\n\n // Amount of reward that the Multiplier Nft is responsible for\n uint256 amountGeneratedDuringNftDeposit = baseReward.mul(nftRewardRatioBP).div(PERCENTAGE_SCALE);\n\n // Amount of Multiplied Reward from NFT\n uint256 multipliedReward = amountGeneratedDuringNftDeposit.mul(multiplierBP.mul(LEPTON_MULTIPLIER_SCALE)).div(PERCENTAGE_SCALE);\n\n // Amount of Base Reward without Multiplied NFT Rewards\n uint256 amountGeneratedWithoutNftDeposit = baseReward.sub(amountGeneratedDuringNftDeposit);\n\n // Amount of Base Rewards + Multiplied NFT Rewards\n return amountGeneratedWithoutNftDeposit.add(multipliedReward);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function fundProgram(uint256 amount) external onlyOwner {\n require(_programData.rewardToken != address(0), \"RP:E-405\");\n IERC20(_programData.rewardToken).safeTransferFrom(msg.sender, address(this), amount);\n emit RewardProgramFunded(amount);\n }\n\n function setStakingToken(address newStakingToken) external onlyOwner {\n _programData.stakingToken = newStakingToken;\n }\n\n function setRewardToken(address newRewardToken) external onlyOwner {\n _programData.rewardToken = newRewardToken;\n }\n\n function setBaseMultiplier(uint256 newMultiplier) external onlyOwner {\n _programData.baseMultiplier = newMultiplier; // Basis Points\n }\n\n function setChargedManagers(address manager) external onlyOwner {\n _chargedManagers = IChargedManagers(manager);\n }\n\n function setUniverse(address universe) external onlyOwner {\n _universe = IUniverseRP(universe);\n }\n\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external override onlyOwner {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n\n // Initiate Asset Stake\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\n if (principal > 0) {\n _assetStake[parentNftUuid] = AssetStake(block.number, 0, walletManagerId);\n emit AssetRegistered(contractAddress, tokenId, walletManagerId, principal);\n }\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _claimRewards(\n address contractAddress,\n uint256 tokenId\n )\n internal\n returns (uint256 totalReward)\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n // Rewards Receiver\n address receiver = IERC721(contractAddress).ownerOf(tokenId);\n\n // Ensure Reward Pool has Sufficient Balance\n totalReward = assetStake.claimableRewards;\n uint256 fundBalance = _getFundBalance();\n uint256 unavailReward = totalReward > fundBalance ? totalReward.sub(fundBalance) : 0;\n\n // Determine amount of Rewards to Transfer\n if (unavailReward > 0) {\n totalReward = totalReward.sub(unavailReward);\n emit RewardProgramOutOfFunds();\n }\n\n // Update Asset Stake\n assetStake.claimableRewards = unavailReward;\n\n if (totalReward > 0) {\n // Transfer Available Rewards to Receiver\n IERC20(_programData.rewardToken).safeTransfer(receiver, totalReward);\n }\n\n emit RewardsClaimed(contractAddress, tokenId, receiver, totalReward, unavailReward);\n }\n\n function _convertDecimals(uint256 reward) internal view returns (uint256) {\n uint8 stakingTokenDecimals = IERC20Detailed(_programData.stakingToken).decimals();\n return reward.mul(10**(18 - uint256(stakingTokenDecimals)));\n }\n\n function _getFundBalance() internal view returns (uint256) {\n return IERC20Detailed(_programData.rewardToken).balanceOf(address(this));\n }\n\n\n modifier onlyOwner() {\n require(_owner == msg.sender, \"Caller is not the owner\");\n _;\n }\n\n modifier onlyUniverse() {\n require(msg.sender == address(_universe), \"RP:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/RewardProgramFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// RewardProgramFactory.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport \"./RewardProgram.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract RewardProgramFactory is BlackholePrevention, Ownable {\n event RewardProgramCreated(address indexed rewardProgram);\n\n address public _template;\n\n constructor () public {\n _template = address(new RewardProgram());\n }\n\n // function _msgSender() internal view override returns (address payable) {\n // return msg.sender;\n // }\n\n function createRewardProgram(\n address stakingToken,\n address rewardToken,\n uint256 baseMultiplier,\n address chargedManagers,\n address universe\n )\n external\n onlyOwner\n returns (address)\n {\n address newRewardProgram = _createClone(_template);\n RewardProgram rewardProgram = RewardProgram(newRewardProgram);\n rewardProgram.initialize(stakingToken, rewardToken, baseMultiplier, chargedManagers, universe, _msgSender());\n emit RewardProgramCreated(newRewardProgram);\n return newRewardProgram;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n}\n" + }, + "contracts/v1/incentives/Staking.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/Staking2.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking2 is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/Staking3.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking3 is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/YieldFarm.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/incentives/YieldFarm2.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm2 is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/incentives/YieldFarm3.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm3 is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/interfaces/IAaveBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IAaveBridge.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n\ninterface IAaveBridge {\n function getReserveInterestToken(address assetToken) external view returns (address aTokenAddress);\n function isReserveActive(address assetToken) external view returns (bool);\n\n function getTotalBalance(address account, address assetToken) external view returns (uint256);\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(address receiver, address assetToken, uint256 assetAmount) external;\n}\n" + }, + "contracts/v1/interfaces/IBaseProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IBaseProton is IERC721 {\n event PausedStateSet(bool isPaused);\n event SalePriceSet(uint256 indexed tokenId, uint256 salePrice);\n event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct);\n event FeesWithdrawn(address indexed receiver, uint256 amount);\n event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties);\n event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view returns (address);\n function getSalePrice(uint256 tokenId) external view returns (uint256);\n function getLastSellPrice(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyalties(address account) external view returns (uint256);\n function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address);\n\n function buyProton(uint256 tokenId, uint256 gasLimit) external payable returns (bool);\n function claimCreatorRoyalties() external returns (uint256);\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n ) external returns (uint256 newTokenId);\n\n function createProtons(\n address creator,\n address receiver,\n string[] calldata tokenMetaUris\n ) external returns (bool);\n\n function createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n ) external returns (bool);\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice) external;\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external;\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external;\n}" + }, + "contracts/v1/interfaces/IBasketManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Particle Basket Manager interface\n * @dev The basket-manager for underlying assets attached to Charged Particles\n * @dev Manages the link between NFTs and their respective Smart-Baskets\n */\ninterface IBasketManager {\n\n event ControllerSet(address indexed controller);\n event ExecutorSet(address indexed executor);\n event PausedStateSet(bool isPaused);\n event NewSmartBasket(address indexed contractAddress, uint256 indexed tokenId, address indexed smartBasket);\n event BasketAdd(address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\n event BasketRemove(address indexed receiver, address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\n event BasketRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\n event RewardProgramSet(address indexed rewardProgram);\n\n function isPaused() external view returns (bool);\n\n function getTokenTotalCount(address contractAddress, uint256 tokenId) external view returns (uint256);\n function getTokenCountByType(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (uint256);\n\n function prepareTransferAmount(uint256 nftTokenAmount) external;\n function addToBasket(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function getBasketAddressById(address contractAddress, uint256 tokenId) external returns (address);\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/IChargedManagers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IWalletManager.sol\";\nimport \"./IBasketManager.sol\";\n\n/**\n * @notice Interface for Charged Wallet-Managers\n */\ninterface IChargedManagers {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function isContractOwner(address contractAddress, address account) external view returns (bool);\n\n // ERC20\n function isWalletManagerEnabled(string calldata walletManagerId) external view returns (bool);\n function getWalletManager(string calldata walletManagerId) external view returns (IWalletManager);\n\n // ERC721\n function isNftBasketEnabled(string calldata basketId) external view returns (bool);\n function getBasketManager(string calldata basketId) external view returns (IBasketManager);\n\n // Validation\n function validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external;\n function validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external;\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external;\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event WalletManagerRegistered(string indexed walletManagerId, address indexed walletManager);\n event BasketManagerRegistered(string indexed basketId, address indexed basketManager);\n}\n" + }, + "contracts/v1/interfaces/IChargedParticles.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Charged Particles\n */\ninterface IChargedParticles {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getStateAddress() external view returns (address stateAddress);\n function getSettingsAddress() external view returns (address settingsAddress);\n function getManagersAddress() external view returns (address managersAddress);\n\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\n\n /***********************************|\n | Particle Mechanics |\n |__________________________________*/\n\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n ) external returns (uint256 yieldTokensAmount);\n\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 receiverAmount);\n\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositFeeSet(uint256 depositFee);\n event ProtocolFeesCollected(address indexed assetToken, uint256 depositAmount, uint256 feesCollected);\n}\n" + }, + "contracts/v1/interfaces/IChargedSettings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IWalletManager.sol\";\nimport \"./IBasketManager.sol\";\n\n/**\n * @notice Interface for Charged Settings\n */\ninterface IChargedSettings {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n // function isContractOwner(address contractAddress, address account) external view returns (bool);\n function getCreatorAnnuities(address contractAddress, uint256 tokenId) external returns (address creator, uint256 annuityPct);\n function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId) external view returns (address);\n function getTempLockExpiryBlocks() external view returns (uint256);\n function getTimelockApprovals(address operator) external view returns (bool timelockAny, bool timelockOwn);\n function getAssetRequirements(\n address contractAddress,\n address assetToken\n ) external view returns (\n string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n );\n function getNftAssetRequirements(\n address contractAddress,\n address nftTokenAddress\n ) external view returns (\n string memory requiredBasketManager,\n bool basketEnabled,\n uint256 maxNfts\n );\n\n /***********************************|\n | Only NFT Creator |\n |__________________________________*/\n\n function setCreatorAnnuities(address contractAddress, uint256 tokenId, address creator, uint256 annuityPercent) external;\n function setCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId, address receiver) external;\n\n\n /***********************************|\n | Only NFT Contract Owner |\n |__________________________________*/\n\n function setRequiredWalletManager(address contractAddress, string calldata walletManager) external;\n function setRequiredBasketManager(address contractAddress, string calldata basketManager) external;\n function setAssetTokenRestrictions(address contractAddress, bool restrictionsEnabled) external;\n function setAllowedAssetToken(address contractAddress, address assetToken, bool isAllowed) external;\n function setAssetTokenLimits(address contractAddress, address assetToken, uint256 depositMin, uint256 depositMax) external;\n function setMaxNfts(address contractAddress, address nftTokenAddress, uint256 maxNfts) external;\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAssetInvalidity(address assetToken, bool invalidity) external;\n function enableNftContracts(address[] calldata contracts) external;\n function setPermsForCharge(address contractAddress, bool state) external;\n function setPermsForBasket(address contractAddress, bool state) external;\n function setPermsForTimelockAny(address contractAddress, bool state) external;\n function setPermsForTimelockSelf(address contractAddress, bool state) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositCapSet(address assetToken, uint256 depositCap);\n event TempLockExpirySet(uint256 expiryBlocks);\n\n event RequiredWalletManagerSet(address indexed contractAddress, string walletManager);\n event RequiredBasketManagerSet(address indexed contractAddress, string basketManager);\n event AssetTokenRestrictionsSet(address indexed contractAddress, bool restrictionsEnabled);\n event AllowedAssetTokenSet(address indexed contractAddress, address assetToken, bool isAllowed);\n event AssetTokenLimitsSet(address indexed contractAddress, address assetToken, uint256 assetDepositMin, uint256 assetDepositMax);\n event MaxNftsSet(address indexed contractAddress, address indexed nftTokenAddress, uint256 maxNfts);\n event AssetInvaliditySet(address indexed assetToken, bool invalidity);\n\n event TokenCreatorConfigsSet(address indexed contractAddress, uint256 indexed tokenId, address indexed creatorAddress, uint256 annuityPercent);\n event TokenCreatorAnnuitiesRedirected(address indexed contractAddress, uint256 indexed tokenId, address indexed redirectAddress);\n\n event PermsSetForCharge(address indexed contractAddress, bool state);\n event PermsSetForBasket(address indexed contractAddress, bool state);\n event PermsSetForTimelockAny(address indexed contractAddress, bool state);\n event PermsSetForTimelockSelf(address indexed contractAddress, bool state);\n}\n" + }, + "contracts/v1/interfaces/IChargedState.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IChargedSettings.sol\";\n\n/**\n * @notice Interface for Charged State\n */\ninterface IChargedState {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n\n function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n\n function isEnergizeRestricted(address contractAddress, uint256 tokenId) external view returns (bool);\n function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external view returns (bool);\n\n function getDischargeState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n function getReleaseState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n function getBreakBondState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n\n /***********************************|\n | Only NFT Owner/Operator |\n |__________________________________*/\n\n function setDischargeApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setReleaseApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setBreakBondApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setTimelockApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setApprovalForAll(address contractAddress, uint256 tokenId, address operator) external;\n\n function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) external;\n\n function setDischargeTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n function setReleaseTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n function setBreakBondTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n /***********************************|\n | Only NFT Contract |\n |__________________________________*/\n\n function setTemporaryLock(\n address contractAddress,\n uint256 tokenId,\n bool isLocked\n ) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n\n event DischargeApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event ReleaseApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event BreakBondApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event TimelockApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n\n event TokenDischargeTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenReleaseTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenBreakBondTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenTempLock(address indexed contractAddress, uint256 indexed tokenId, uint256 unlockBlock);\n\n event PermsSetForRestrictCharge(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowDischarge(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowRelease(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForRestrictBond(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowBreakBond(address indexed contractAddress, uint256 indexed tokenId, bool state);\n}\n" + }, + "contracts/v1/interfaces/IDai.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\ninterface IDai is IERC20Upgradeable {\n // --- Approve by signature ---\n function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external;\n function transferFrom(address src, address dst, uint wad) external override returns (bool);\n}" + }, + "contracts/v1/interfaces/IERC20Detailed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Detailed {\n function decimals() external view returns (uint8);\n function symbol() external view returns (string memory);\n function name() external view returns (string memory);\n\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(address sender, address recipient, uint256 amount) 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" + }, + "contracts/v1/interfaces/IERC721Chargeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IERC721Chargeable.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\n\ninterface IERC721Chargeable is IERC165Upgradeable {\n function owner() external view returns (address);\n function creatorOf(uint256 tokenId) external view returns (address);\n function balanceOf(address tokenOwner) external view returns (uint256 balance);\n function ownerOf(uint256 tokenId) external view returns (address tokenOwner);\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n function transferFrom(address from, address to, uint256 tokenId) external;\n function approve(address to, uint256 tokenId) external;\n function getApproved(uint256 tokenId) external view returns (address operator);\n function setApprovalForAll(address operator, bool _approved) external;\n function isApprovedForAll(address tokenOwner, address operator) external view returns (bool);\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "contracts/v1/interfaces/ILepton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ILepton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Lepton Interface\n * @dev ...\n */\ninterface ILepton {\n\n struct Classification {\n string tokenUri;\n uint256 price;\n uint128 _upperBounds;\n uint32 supply;\n uint32 multiplier;\n uint32 bonus;\n }\n\n function mintLepton() external payable returns (uint256 newTokenId);\n function batchMintLepton(uint256 count) external payable;\n function getNextType() external view returns (uint256);\n function getNextPrice() external view returns (uint256);\n function getMultiplier(uint256 tokenId) external view returns (uint256);\n function getBonus(uint256 tokenId) external view returns (uint256);\n\n\n event MaxMintPerTxSet(uint256 maxAmount);\n event LeptonTypeAdded(string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\n event LeptonTypeUpdated(uint256 leptonIndex, string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\n event LeptonMinted(address indexed receiver, uint256 indexed tokenId, uint256 price, uint32 multiplier);\n event LeptonBatchMinted(address indexed receiver, uint256 indexed tokenId, uint256 count, uint256 price, uint32 multiplier);\n event PausedStateSet(bool isPaused);\n}\n" + }, + "contracts/v1/interfaces/IMerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.6.0;\n\n// Allows anyone to claim a token if they exist in a merkle root.\ninterface IMerkleDistributor {\n // Returns the address of the token distributed by this contract.\n function token() external view returns (address);\n // Returns the merkle root of the merkle tree containing account balances available to claim.\n function merkleRoot() external view returns (bytes32);\n // Returns true if the index has been marked claimed.\n function isClaimed(uint256 index) external view returns (bool);\n // Claim the given amount of the token to the given address. Reverts if the inputs are invalid.\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external;\n\n // This event is triggered whenever a call to #claim succeeds.\n event Claimed(uint256 index, address account, uint256 amount);\n}" + }, + "contracts/v1/interfaces/IParticleSplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IParticleSplitter.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Particle Splitter\n */\ninterface IParticleSplitter {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function executeForWallet(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address externalAddress,\n bytes memory encodedParams\n ) external payable returns (bytes memory);\n\n function executeForBasket(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address externalAddress,\n bytes memory encodedParams\n ) external payable returns (bytes memory);\n\n function withdrawWalletRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n ) external returns (uint256 amountWithdrawn);\n\n function withdrawBasketRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n ) external returns (uint256 amountWithdrawn);\n\n function refreshWalletPrincipal(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external;\n\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event ChargedManagersSet(address indexed chargedManagers);\n event TokenInfoProxySet(address indexed tokenInfoProxy);\n\n event ExecuteForWallet(\n address indexed contractAddress,\n uint256 tokenId,\n string walletManagerId,\n address indexed externalAddress,\n bytes encodedParams,\n uint256 ethValue\n );\n event ExecuteForBasket(\n address indexed contractAddress,\n uint256 tokenId,\n string basketManagerId,\n address indexed externalAddress,\n bytes encodedParams,\n uint256 ethValue\n );\n event PrincipalRefreshed(\n address contractAddress,\n uint256 tokenId,\n string walletManagerId,\n address assetToken\n );\n event PermsSetForExternal(\n address indexed contractAddress,\n bool state\n );\n}\n" + }, + "contracts/v1/interfaces/IProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IProton is IERC721 {\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n event PausedStateSet(bool isPaused);\n event SalePriceSet(uint256 indexed tokenId, uint256 salePrice);\n event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct);\n event FeesWithdrawn(address indexed receiver, uint256 amount);\n event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties);\n event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view returns (address);\n function getSalePrice(uint256 tokenId) external view returns (uint256);\n function getLastSellPrice(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyalties(address account) external view returns (uint256);\n function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address);\n\n function buyProton(uint256 tokenId) external payable returns (bool);\n function claimCreatorRoyalties() external returns (uint256);\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n ) external returns (uint256 newTokenId);\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n ) external returns (uint256 newTokenId);\n\n function batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n ) external;\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice) external;\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external;\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external;\n}" + }, + "contracts/v1/interfaces/IProtonB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IProtonB is IERC721 {\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n ) external returns (uint256 newTokenId);\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n}" + }, + "contracts/v1/interfaces/IRewardNft.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IRewardNft.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Reward-NFT Interface\n * @dev ...\n */\ninterface IRewardNft {\n function getMultiplier(uint256 tokenId) external view returns (uint256);\n function getBonus(uint256 tokenId) external view returns (uint256);\n}\n" + }, + "contracts/v1/interfaces/IRewardProgram.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IRewardProgram.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\ninterface IRewardProgram {\n /* admin events */\n event RewardProgramFunded(uint256 amount);\n event RewardProgramOutOfFunds();\n\n /* user events */\n event RewardsClaimed(address indexed contractAddress, uint256 tokenId, address indexed receiver, uint256 rewarded, uint256 remaining);\n\n event AssetRegistered(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\n event AssetDeposit(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\n event AssetRelease(address indexed contractAddress, uint256 tokenId, uint256 interestAmount);\n\n /* data types */\n struct ProgramRewardData {\n address stakingToken;\n address rewardToken;\n uint256 baseMultiplier; // Basis Points\n }\n\n struct AssetStake {\n uint256 start;\n uint256 claimableRewards;\n string walletManagerId;\n }\n\n function initialize(address stakingToken, address rewardToken, uint256 baseMultiplier, address chargedManagers, address universe, address owner) external;\n\n /* user functions */\n function getProgramData() external view returns (ProgramRewardData memory programData);\n function getAssetStake(uint256 uuid) external view returns (AssetStake memory);\n function getFundBalance() external view returns (uint256);\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) external view returns (uint256);\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external;\n function registerAssetDeposit(address contractAddress, uint256 tokenId, string calldata walletManagerId, uint256 principalAmount) external;\n function registerAssetRelease(address contractAddress, uint256 tokenId, uint256 interestAmount) external returns (uint256 rewards);\n}" + }, + "contracts/v1/interfaces/ISmartBasket.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartBasket.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Basket\n * @dev Manages holding and transferring NFTs within an NFT (if any),\n */\ninterface ISmartBasket {\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function addToBasket(address contractAddress, uint256 tokenId) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId) external returns (bool);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartBasketB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartBasketB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Basket \"B\"\n * @dev Manages holding and transferring NFTs within an NFT (if any),\n */\ninterface ISmartBasketB {\n function getNestedNftCount() external view returns (uint256);\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool);\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Wallet\n * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any),\n */\ninterface ISmartWallet {\n function getAssetTokenCount() external view returns (uint256);\n function getAssetTokenByIndex(uint256 index) external view returns (address);\n\n function setNftCreator(address creator, uint256 annuityPct) external;\n\n function isReserveActive(address assetToken) external view returns (bool);\n function getReserveInterestToken(address assetToken) external view returns (address);\n\n function getPrincipal(address assetToken) external returns (uint256);\n function getInterest(address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getTotal(address assetToken) external returns (uint256);\n function getRewards(address assetToken) external returns (uint256);\n\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(address receiver, address creatorRedirect, address assetToken) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function withdrawAmount(address receiver, address creatorRedirect, address assetToken, uint256 assetAmount) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function withdrawAmountForCreator(address receiver, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address assetToken) external;\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Wallet\n * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any),\n */\ninterface ISmartWalletB {\n function getAssetTokenCount() external view returns (uint256);\n function getAssetTokenByIndex(uint256 index) external view returns (address);\n\n function isReserveActive(address assetToken) external view returns (bool);\n function getReserveInterestToken(address assetToken) external view returns (address);\n\n function getPrincipal(address assetToken) external returns (uint256);\n function getInterest(address assetToken, uint256 creatorPct) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getTotal(address assetToken) external returns (uint256);\n function getRewards(address assetToken) external returns (uint256);\n\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken\n ) external returns (\n uint256 creatorAmount,\n uint256 receiverAmount\n );\n function withdrawAmount(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n ) external returns (\n uint256 creatorAmount,\n uint256 receiverAmount\n );\n function withdrawAmountForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n ) external returns (\n uint256 receiverAmount\n );\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address assetToken) external;\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/IStaking.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\ninterface IStaking {\n function manualEpochInit(address[] memory tokens, uint128 epochId) external;\n function getCurrentEpoch() external view returns (uint128);\n function getEpochId(uint timestamp) external view returns (uint); // get epoch id\n function getEpochUserBalance(address user, address token, uint128 epoch) external view returns(uint);\n function getEpochPoolSize(address token, uint128 epoch) external view returns (uint);\n function epoch1Start() external view returns (uint);\n function epochDuration() external view returns (uint);\n}" + }, + "contracts/v1/interfaces/ITokenInfoProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfoProxy.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\n\ninterface ITokenInfoProxy {\n\n event ContractFunctionSignatureSet(address indexed contractAddress, string fnName, bytes4 fnSig);\n\n struct FnSignatures {\n bytes4 ownerOf;\n bytes4 creatorOf;\n }\n\n function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external;\n function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external;\n\n function getTokenUUID(address contractAddress, uint256 tokenId) external pure returns (uint256);\n function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external returns (bool);\n function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external returns (bool);\n function getTokenOwner(address contractAddress, uint256 tokenId) external returns (address);\n function getTokenCreator(address contractAddress, uint256 tokenId) external returns (address);\n}\n" + }, + "contracts/v1/interfaces/IUniverse.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IUniverse.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Universal Controller interface\n * @dev ...\n */\ninterface IUniverse {\n\n event ChargedParticlesSet(address indexed chargedParticles);\n event PhotonSet(address indexed photonToken, uint256 maxSupply);\n event ProtonTokenSet(address indexed protonToken);\n event LeptonTokenSet(address indexed leptonToken);\n event QuarkTokenSet(address indexed quarkToken);\n event BosonTokenSet(address indexed bosonToken);\n event EsaMultiplierSet(address indexed assetToken, uint256 multiplier);\n event ElectrostaticAttraction(address indexed account, address photonSource, uint256 energy, uint256 multiplier);\n event ElectrostaticDischarge(address indexed account, address photonSource, uint256 energy);\n\n function onEnergize(\n address sender,\n address referrer,\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 assetEnergy\n ) external;\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n ) external;\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address creator,\n address assetToken,\n uint256 receiverEnergy\n ) external;\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 principalEnergy,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n ) external;\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n ) external;\n}\n" + }, + "contracts/v1/interfaces/IUniverseRP.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IUniverseRP.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport \"./IUniverse.sol\";\n\n/**\n * @title Universal Controller interface for Rewards Program\n * @dev ...\n */\ninterface IUniverseRP is IUniverse {\n event RewardProgramSet(address indexed assetToken, address indexed rewardProgram);\n event RewardProgramRemoved(address indexed assetToken);\n event NftDeposit(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\n event NftRelease(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\n\n struct NftStake {\n uint256 multiplier; // in Basis Points\n uint256 depositBlockNumber;\n uint256 releaseBlockNumber;\n }\n\n function getRewardProgram(address asset) external view returns (address);\n function getNftStake(uint256 uuid) external view returns (NftStake memory);\n}\n" + }, + "contracts/v1/interfaces/IWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Particle Wallet Manager interface\n * @dev The wallet-manager for underlying assets attached to Charged Particles\n * @dev Manages the link between NFTs and their respective Smart-Wallets\n */\ninterface IWalletManager {\n\n event ControllerSet(address indexed controller);\n event ExecutorSet(address indexed executor);\n event PausedStateSet(bool isPaused);\n event NewSmartWallet(address indexed contractAddress, uint256 indexed tokenId, address indexed smartWallet, address creator, uint256 annuityPct);\n event WalletEnergized(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 assetAmount, uint256 yieldTokensAmount);\n event WalletDischarged(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 creatorAmount, uint256 receiverAmount);\n event WalletDischargedForCreator(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, address creator, uint256 receiverAmount);\n event WalletReleased(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address assetToken, uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n event WalletRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\n\n function isPaused() external view returns (bool);\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view returns (bool);\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view returns (address);\n\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\n function getInterest(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken) external returns (uint256);\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount) external returns (uint256 yieldTokensAmount);\n function discharge(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function dischargeAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function dischargeAmountForCreator(address receiver, address contractAddress, uint256 tokenId, address creator, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\n function release(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n function releaseAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken) external;\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct) external returns (address);\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\n}\n" + }, + "contracts/v1/lib/BaseProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IBaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n/// @title Base Proton Contract for Charged Particles compatible ERC721 NFTs\n/// @dev MUST NOT be Upgradeable, as Upgradeable NFTs are incompatible with Charged Particles.\ncontract BaseProton is \n IBaseProton, \n ERC721, \n Ownable, \n RelayRecipient, \n ReentrancyGuard, \n BlackholePrevention \n{\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n event Received(address, uint);\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n /// @dev Sequential Token IDs storage\n Counters.Counter internal _tokenIds;\n\n /// @dev NFT Token Creator settings\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct;\n mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect;\n mapping (address => uint256) internal _tokenCreatorClaimableRoyalties;\n\n /// @dev NFT Token Sale settings\n mapping (uint256 => uint256) internal _tokenSalePrice;\n mapping (uint256 => uint256) internal _tokenLastSellPrice;\n\n /// @dev Whether of not the Contract is Paused\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n /// @dev Inherit from ERC721 standard\n constructor(string memory _name, string memory _symbol) public ERC721(_name, _symbol) {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n receive() external payable virtual {\n emit Received(msg.sender, msg.value);\n }\n\n /// Returns the Creator address of an NFT by Token ID\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The address of the Creator account\n function creatorOf(uint256 tokenId) external view virtual override returns (address) {\n return _tokenCreator[tokenId];\n }\n\n /// Returns the Sale Price of an NFT by Token ID\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The sale price of the NFT\n function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenSalePrice[tokenId];\n }\n\n /// Returns the Last Sale Price of an NFT by Token ID\n /// @notice This is used to determine any increase in sale price used in royalties calculations\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The last sale price of the NFT\n function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenLastSellPrice[tokenId];\n }\n\n /// Returns the Claimable Royalties for the NFT Creator\n /// @param account The address of the Creator account to lookup\n /// @return The amount of earned royalties for the creator account\n function getCreatorRoyalties(address account) external view virtual override returns (uint256) {\n return _tokenCreatorClaimableRoyalties[account];\n }\n\n /// Returns the Percentage of Royalties reserved for the NFT Creator\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The percentage of royalties reserved for the creator\n function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenCreatorRoyaltiesPct[tokenId];\n }\n\n /// Returns the Receiving address of the Creator Royalties (or Creator if not set)\n /// @dev Returns the creator address if a receiving address has not been configured\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The Receiving address of the Creator Royalties\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) {\n return _creatorRoyaltiesReceiver(tokenId);\n }\n\n /// Allows an NFT Creator to Claim any Royalties that have been earned from NFT sales\n /// @dev Must be called by the royalties receiver account (not neccessarily the creator)\n /// @return The amout of creator royalties claimed\n function claimCreatorRoyalties()\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256)\n {\n return _claimCreatorRoyalties(_msgSender());\n }\n\n\n /***********************************|\n | Create Single Protons |\n |__________________________________*/\n\n /// Creates a Basic NFT with no Royalties and no initial Sale Price\n /// @dev Royalties and Sale Price can be configured later\n /// @param creator The address of the NFT Creator (can be different from the caller)\n /// @param receiver The receiving address of the NFT (can be different from the caller)\n /// @param tokenMetaUri The unique metadata URI for the NFT\n /// @return newTokenId The newly minted NFT Token ID\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n\n /***********************************|\n | Create Multiple Protons |\n |__________________________________*/\n\n function createProtons(\n address creator,\n address receiver,\n string[] calldata tokenMetaUris\n )\n external\n virtual\n override\n whenNotPaused\n returns (bool)\n {\n _createProtons(\n creator,\n receiver,\n 0, // royaltiesPercent\n tokenMetaUris\n );\n return true;\n }\n\n function createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n external\n virtual\n override\n whenNotPaused\n returns (bool)\n {\n _createProtonsForSale(\n creator,\n receiver,\n royaltiesPercent,\n tokenMetaUris,\n salePrices\n );\n return true;\n }\n\n\n /***********************************|\n | Buy Protons |\n |__________________________________*/\n\n function buyProton(uint256 tokenId, uint256 gasLimit)\n external\n payable\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (bool)\n {\n _buyProton(tokenId, gasLimit);\n return true;\n }\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice)\n external\n virtual\n override\n whenNotPaused\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setSalePrice(tokenId, salePrice);\n }\n\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setRoyaltiesPct(tokenId, royaltiesPct);\n }\n\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n {\n _tokenCreatorRoyaltiesRedirect[tokenId] = receiver;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual {\n _tokenSalePrice[tokenId] = salePrice;\n emit SalePriceSet(tokenId, salePrice);\n }\n\n function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual {\n require(royaltiesPct <= PERCENTAGE_SCALE, \"PRT:E-421\");\n _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct;\n emit CreatorRoyaltiesSet(tokenId, royaltiesPct);\n }\n\n function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) {\n address receiver = _tokenCreatorRoyaltiesRedirect[tokenId];\n if (receiver == address(0x0)) {\n receiver = _tokenCreator[tokenId];\n }\n return receiver;\n }\n\n function _createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n _tokenIds.increment();\n\n newTokenId = _tokenIds.current();\n _safeMint(receiver, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUri);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n }\n\n function _createProtons(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris\n )\n internal\n virtual\n {\n uint256 count = tokenMetaUris.length;\n for (uint256 i; i < count; i++) {\n _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, 0);\n }\n }\n\n function _createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n internal\n virtual\n {\n require(tokenMetaUris.length == salePrices.length, \"PRT:E-202\");\n\n uint256 count = tokenMetaUris.length;\n for (uint256 i; i < count; i++) {\n _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, salePrices[i]);\n }\n }\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n contractAddress = address(this);\n tokenId = _tokenId;\n salePrice = _tokenSalePrice[_tokenId];\n require(salePrice > 0, \"PRT:E-416\");\n require(msg.value >= salePrice, \"PRT:E-414\");\n\n uint256 ownerAmount = salePrice;\n creatorAmount;\n oldOwner = ownerOf(_tokenId);\n newOwner = _msgSender();\n\n // Creator Royalties\n royaltiesReceiver = _creatorRoyaltiesReceiver(_tokenId);\n uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[_tokenId];\n uint256 lastSellPrice = _tokenLastSellPrice[_tokenId];\n if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) {\n creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE);\n ownerAmount = ownerAmount.sub(creatorAmount);\n }\n _tokenLastSellPrice[_tokenId] = salePrice;\n\n // Reserve Royalties for Creator\n if (creatorAmount > 0) {\n _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount);\n }\n\n // Transfer Token\n _transfer(oldOwner, newOwner, _tokenId);\n\n // Transfer Payment\n if (ownerAmount > 0) {\n payable(oldOwner).sendValue(ownerAmount, _gasLimit);\n }\n\n emit ProtonSold(_tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n\n _refundOverpayment(salePrice, _gasLimit);\n }\n\n /**\n * @dev Pays out the Creator Royalties of the calling account\n * @param receiver The receiver of the claimable royalties\n * @return The amount of Creator Royalties claimed\n */\n function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) {\n uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver];\n require(claimableAmount > 0, \"PRT:E-411\");\n\n delete _tokenCreatorClaimableRoyalties[receiver];\n payable(receiver).sendValue(claimableAmount, 0);\n\n emit RoyaltiesClaimed(receiver, claimableAmount);\n }\n\n /**\n * @dev Collects the Required Asset Token from the users wallet\n * @param from The owner address to collect the Assets from\n * @param assetAmount The Amount of Asset Tokens to Collect\n */\n function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual {\n uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from);\n require(assetAmount <= _userAssetBalance, \"PRT:E-411\");\n // Be sure to Approve this Contract to transfer your Asset Token\n require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), \"PRT:E-401\");\n }\n\n function _refundOverpayment(uint256 threshold, uint256 gasLimit) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage, gasLimit);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n _tokenSalePrice[tokenId] = 0;\n super._transfer(from, to, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"PRT:E-101\");\n _;\n }\n\n modifier onlyTokenOwnerOrApproved(uint256 tokenId) {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"PRT:E-105\");\n _;\n }\n\n modifier onlyTokenCreator(uint256 tokenId) {\n require(_tokenCreator[tokenId] == _msgSender(), \"PRT:E-104\");\n _;\n }\n}" + }, + "contracts/v1/lib/Bitwise.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Bitwise.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nlibrary Bitwise {\n function negate(uint32 a) internal pure returns (uint32) {\n return a ^ maxInt();\n }\n\n function shiftLeft(uint32 a, uint32 n) internal pure returns (uint32) {\n return a * uint32(2) ** n;\n }\n\n function shiftRight(uint32 a, uint32 n) internal pure returns (uint32) {\n return a / uint32(2) ** n;\n }\n\n function maxInt() internal pure returns (uint32) {\n return uint32(-1);\n }\n\n // Get bit value at position\n function hasBit(uint32 a, uint32 n) internal pure returns (bool) {\n return a & shiftLeft(0x01, n) != 0;\n }\n\n // Set bit value at position\n function setBit(uint32 a, uint32 n) internal pure returns (uint32) {\n return a | shiftLeft(0x01, n);\n }\n\n // Set the bit into state \"false\"\n function clearBit(uint32 a, uint32 n) internal pure returns (uint32) {\n uint32 mask = negate(shiftLeft(0x01, n));\n return a & mask;\n }\n}\n" + }, + "contracts/v1/lib/BlackholePrevention.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\n\n/**\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\n * the Owner/DAO to pull them out on behalf of a user\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\n */\ncontract BlackholePrevention {\n using Address for address payable;\n using SafeERC20 for IERC20;\n\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\n\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (address(this).balance >= amount) {\n receiver.sendValue(amount);\n emit WithdrawStuckEther(receiver, amount);\n }\n }\n\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\n IERC20(tokenAddress).safeTransfer(receiver, amount);\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\n }\n }\n\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\n }\n }\n\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \"\");\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\n }\n }\n}\n" + }, + "contracts/v1/lib/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/GSN/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableMap.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n /**\n * @dev Emitted when `tokenId` token is transfered from `from` to `to`.\n */\n event TransferBatch(address indexed from, address indexed to, uint256 startTokenId, uint256 count);\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721:E-403\");\n\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721:E-405\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"ERC721:E-405\");\n return _tokenURIs[tokenId];\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721:E-111\");\n\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \"ERC721:E-105\");\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view override returns (address) {\n require(_exists(tokenId), \"ERC721:E-405\");\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 require(operator != _msgSender(), \"ERC721:E-111\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721:E-402\");\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 returns (bool) {\n return _tokenOwners.contains(tokenId);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721:E-405\");\n address owner = ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721:E-402\");\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 _safeMintBatch(address to, uint256 startTokenId, uint256 count, bytes memory _data) internal virtual {\n _mintBatch(to, startTokenId, count);\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \"ERC721:E-402\");\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:E-403\");\n require(!_exists(tokenId), \"ERC721:E-407\");\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\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 _mintBatch(address to, uint256 startTokenId, uint256 count) internal virtual {\n require(to != address(0), \"ERC721:E-403\");\n require(!_exists(startTokenId), \"ERC721:E-407\");\n\n for (uint i = 0; i < count; i++) {\n uint256 tokenId = startTokenId.add(i);\n _holderTokens[to].add(tokenId);\n _tokenOwners.set(tokenId, to);\n }\n\n emit TransferBatch(address(0), to, startTokenId, count);\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(address from, address to, uint256 tokenId) internal virtual {\n require(ownerOf(tokenId) == from, \"ERC721:E-102\");\n require(to != address(0), \"ERC721:E-403\");\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721:E-405\");\n _tokenURIs[tokenId] = _tokenURI;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721:E-402\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\n }\n}\n" + }, + "contracts/v1/lib/ERC721Basic.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/GSN/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Basic is Context, ERC165, IERC721, IERC721Metadata {\n using SafeMath for uint256;\n using Address for address;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 internal constant _ERC721_RECEIVED = 0x150b7a02;\n\n // mapping from token ids to their owners\n mapping (uint256 => address) internal _tokenOwners;\n\n // mapping from owner to token balance\n mapping (address => uint256) internal _ownerBalance;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) internal _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) internal _operatorApprovals;\n\n // Token name\n string internal _name;\n\n // Token symbol\n string internal _symbol;\n\n // Token Count\n uint256 internal _tokenCount;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 internal constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 internal constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721:E-403\");\n return _ownerBalance[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners[tokenId];\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view 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 return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721:E-111\");\n\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \"ERC721:E-105\");\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view override returns (address) {\n require(_exists(tokenId), \"ERC721:E-405\");\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721:E-111\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721:E-402\");\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 returns (bool) {\n return _tokenOwners[tokenId] != address(0x0);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721:E-405\");\n address owner = ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\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(address to, bytes memory _data) internal virtual returns (uint256) {\n uint256 tokenId = _mint(to);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721:E-402\");\n return 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 _safeMintBatch(address to, uint256 count, bytes memory _data) internal virtual {\n uint256 startTokenId = _mintBatch(to, count);\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \"ERC721:E-402\");\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) internal virtual returns (uint256) {\n require(to != address(0), \"ERC721:E-403\");\n\n _tokenCount = _tokenCount.add(1);\n uint256 tokenId = _tokenCount;\n require(!_exists(tokenId), \"ERC721:E-407\");\n\n _tokenOwners[tokenId] = to;\n _ownerBalance[to] = _ownerBalance[to].add(1);\n\n emit Transfer(address(0), to, tokenId);\n return tokenId;\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 _mintBatch(address to, uint256 count) internal virtual returns (uint256) {\n require(to != address(0), \"ERC721:E-403\");\n\n uint256 startTokenId = _tokenCount.add(1);\n for (uint i = 1; i <= count; i++) {\n uint256 tokenId = _tokenCount.add(i);\n _tokenOwners[tokenId] = to;\n emit Transfer(address(0), to, tokenId);\n }\n\n _tokenCount = _tokenCount.add(count);\n _ownerBalance[to] = _ownerBalance[to].add(count);\n return startTokenId;\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(address from, address to, uint256 tokenId) internal virtual {\n require(ownerOf(tokenId) == from, \"ERC721:E-102\");\n require(to != address(0), \"ERC721:E-403\");\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _tokenOwners[tokenId] = to;\n _ownerBalance[from] = _ownerBalance[from].sub(1);\n _ownerBalance[to] = _ownerBalance[to].add(1);\n\n emit Transfer(from, to, tokenId);\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(address from, address to, uint256 tokenId, bytes memory _data)\n internal returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721:E-402\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) internal {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\n }\n}\n" + }, + "contracts/v1/lib/IERC5192.sol": { + "content": "// SPDX-License-Identifier: CC0-1.0\npragma solidity ^0.6.0;\n\ninterface IERC5192 {\n /// @notice Emitted when the locking status is changed to locked.\n /// @dev If a token is minted and the status is locked, this event should be emitted.\n /// @param tokenId The identifier for a token.\n event Locked(uint256 tokenId);\n\n /// @notice Emitted when the locking status is changed to unlocked.\n /// @dev If a token is minted and the status is unlocked, this event should be emitted.\n /// @param tokenId The identifier for a token.\n event Unlocked(uint256 tokenId);\n\n /// @notice Returns the locking status of an Soulbound Token\n /// @dev SBTs assigned to zero address are considered invalid, and queries\n /// about them do throw.\n /// @param tokenId The identifier for an SBT.\n function locked(uint256 tokenId) external view returns (bool);\n}\n" + }, + "contracts/v1/lib/NftTokenType.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// NftTokenType.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/introspection/IERC165.sol\";\n\nlibrary NftTokenType {\n bytes4 constant internal INTERFACE_SIGNATURE_ERC721 = 0x80ac58cd;\n bytes4 constant internal INTERFACE_SIGNATURE_ERC1155 = 0xd9b67a26;\n\n uint256 constant internal TYPE_MASK = uint256(uint128(~0)) << 128;\n uint256 constant internal TYPE_NFT_BIT = 1 << 255;\n\n function isERC721(address contractAddress) internal view returns (bool) {\n return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC721);\n }\n\n function isERC1155(address contractAddress) internal view returns (bool) {\n return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC1155);\n }\n\n function getTokenType(address contractAddress, uint256 tokenId) internal view returns (uint256) {\n IERC165 tokenInterface = IERC165(contractAddress);\n bool is1155 = tokenInterface.supportsInterface(INTERFACE_SIGNATURE_ERC1155);\n\n if (!is1155 || (tokenId & TYPE_NFT_BIT != TYPE_NFT_BIT)) { return 0; }\n\n return tokenId & TYPE_MASK;\n }\n}\n" + }, + "contracts/v1/lib/ReentrancyGuard.sol": { + "content": "pragma solidity 0.6.12;\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 () public {\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 _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\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 /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}" + }, + "contracts/v1/lib/RelayRecipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0;\n\nimport \"@opengsn/gsn/contracts/BaseRelayRecipient.sol\";\n\ncontract RelayRecipient is BaseRelayRecipient {\n function versionRecipient() external override view returns (string memory) {\n return \"1.0.0-beta.1/charged-particles.relay.recipient\";\n }\n}\n" + }, + "contracts/v1/lib/SmartWalletBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// SmartWalletBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../interfaces/ISmartWallet.sol\";\nimport \"./BlackholePrevention.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract SmartWalletBase is ISmartWallet, BlackholePrevention {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n address internal _walletManager;\n\n address internal nftCreator;\n uint256 internal nftCreatorAnnuityPct;\n uint256 internal nftCreatorAmountDischarged;\n\n EnumerableSet.AddressSet internal _assetTokens;\n\n // Asset Token => Principal Balance\n mapping (address => uint256) internal _assetPrincipalBalance;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initializeBase() public {\n require(_walletManager == address(0x0), \"SWB:E-002\");\n _walletManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getAssetTokenCount() external view virtual override returns (uint256) {\n return _assetTokens.length();\n }\n\n function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) {\n if (index >= _assetTokens.length()) {\n return address(0);\n }\n return _assetTokens.at(index);\n }\n\n function setNftCreator(address creator, uint256 annuityPct) external virtual override onlyWalletManager {\n nftCreator = creator;\n nftCreatorAnnuityPct = annuityPct;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyWalletManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n function refreshPrincipal(address assetToken)\n external\n virtual\n override\n onlyWalletManager\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getPrincipal(address assetToken) internal view virtual returns (uint256) {\n return _assetPrincipalBalance[assetToken];\n }\n\n function _trackAssetToken(address assetToken) internal virtual {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n }\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the wallet manager\n modifier onlyWalletManager() {\n require(_walletManager == msg.sender, \"SWB:E-109\");\n _;\n }\n}" + }, + "contracts/v1/lib/SmartWalletBaseB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// SmartWalletBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../interfaces/ISmartWalletB.sol\";\nimport \"./BlackholePrevention.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract SmartWalletBaseB is ISmartWalletB, BlackholePrevention {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n address internal _walletManager;\n\n EnumerableSet.AddressSet internal _assetTokens;\n\n // Asset Token => Principal Balance\n mapping (address => uint256) internal _assetPrincipalBalance;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initializeBase() public {\n require(_walletManager == address(0x0), \"SWB:E-002\");\n _walletManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getAssetTokenCount() external view virtual override returns (uint256) {\n return _assetTokens.length();\n }\n\n function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) {\n if (index >= _assetTokens.length()) {\n return address(0);\n }\n return _assetTokens.at(index);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyWalletManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getPrincipal(address assetToken) internal view virtual returns (uint256) {\n return _assetPrincipalBalance[assetToken];\n }\n\n function _trackAssetToken(address assetToken) internal virtual {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n }\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the wallet manager\n modifier onlyWalletManager() {\n require(_walletManager == msg.sender, \"SWB:E-109\");\n _;\n }\n}" + }, + "contracts/v1/lib/Soul.sol": { + "content": "// SPDX-License-Identifier: CC0-1.0\npragma solidity ^0.6.12;\n\nimport \"./IERC5192.sol\";\n\ncontract Soul is IERC5192 {\n \n mapping (uint256 => bool) public lockedTokens;\n\n function _lockToken(uint256 tokenId) internal {\n lockedTokens[tokenId] = true;\n emit Locked(tokenId);\n }\n\n function _unlockToken(uint256 tokenId) internal {\n lockedTokens[tokenId] = false;\n emit Unlocked(tokenId);\n }\n\n function locked(uint256 tokenId)\n external\n view\n override(IERC5192)\n returns (bool)\n {\n return lockedTokens[tokenId];\n }\n}\n" + }, + "contracts/v1/lib/TokenInfo.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfo.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"../interfaces/IERC721Chargeable.sol\";\n\nlibrary TokenInfo {\n function getTokenUUID(address contractAddress, uint256 tokenId) internal pure virtual returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n function getTokenOwner(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n return tokenInterface.ownerOf(tokenId);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n function getTokenCreator(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n return tokenInterface.creatorOf(tokenId);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Owner of an External NFT contract\n /// @param contractAddress The Address to the Contract of the NFT to check\n /// @param account The Address of the Account to check\n /// @return True if the account owns the contract\n function isContractOwner(address contractAddress, address account) internal view virtual returns (bool) {\n address contractOwner = IERC721Chargeable(contractAddress).owner();\n return contractOwner != address(0x0) && contractOwner == account;\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Creator of a Proton-based NFT\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the Proton-based NFT\n function isTokenCreator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenCreator = tokenInterface.creatorOf(tokenId);\n return (sender == tokenCreator);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the Proton-based NFT or the Contract itself\n function isTokenContractOrCreator(address contractAddress, uint256 tokenId, address creator, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenCreator = tokenInterface.creatorOf(tokenId);\n if (sender == contractAddress && creator == tokenCreator) { return true; }\n return (sender == tokenCreator);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Owner or Operator of an External NFT\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the Owner or Operator of the External NFT\n function isErc721OwnerOrOperator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenOwner = tokenInterface.ownerOf(tokenId);\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\n }\n\n /**\n * @dev Returns true if `account` is a contract.\n * @dev Taken from OpenZeppelin library\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\n // for accounts without code, i.e. `keccak256('')`\n bytes32 codehash;\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n // solhint-disable-next-line no-inline-assembly\n assembly { codehash := extcodehash(account) }\n return (codehash != accountHash && codehash != 0x0);\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 * @dev Taken from OpenZeppelin library\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, uint256 gasLimit) internal {\n require(address(this).balance >= amount, \"TokenInfo: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = (gasLimit > 0)\n ? recipient.call{ value: amount, gas: gasLimit }(\"\")\n : recipient.call{ value: amount }(\"\");\n require(success, \"TokenInfo: unable to send value, recipient may have reverted\");\n }\n}\n" + }, + "contracts/v1/lib/TokenInfoProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfoProxy.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../interfaces/ITokenInfoProxy.sol\";\nimport \"../interfaces/IERC721Chargeable.sol\";\n\n\ncontract TokenInfoProxy is ITokenInfoProxy, Ownable {\n using Address for address;\n\n mapping (address => FnSignatures) internal _remappedFnSigs;\n\n function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner {\n _remappedFnSigs[contractAddress].ownerOf = fnSig;\n emit ContractFunctionSignatureSet(contractAddress, \"ownerOf\", fnSig);\n }\n\n function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner {\n _remappedFnSigs[contractAddress].creatorOf = fnSig;\n emit ContractFunctionSignatureSet(contractAddress, \"creatorOf\", fnSig);\n }\n\n\n function getTokenUUID(address contractAddress, uint256 tokenId) external pure virtual override returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n function getTokenOwner(address contractAddress, uint256 tokenId) external virtual override returns (address) {\n return _getTokenOwner(contractAddress, tokenId);\n }\n\n function getTokenCreator(address contractAddress, uint256 tokenId) external virtual override returns (address) {\n return _getTokenCreator(contractAddress, tokenId);\n }\n\n function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenOwner = _getTokenOwner(contractAddress, tokenId);\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\n }\n\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the NFT or the Contract itself\n function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) {\n address tokenCreator = _getTokenCreator(contractAddress, tokenId);\n return (sender == tokenCreator || sender == contractAddress);\n }\n\n\n\n function _getTokenCreator(address contractAddress, uint256 tokenId) internal returns (address) {\n bytes4 fnSig = IERC721Chargeable.creatorOf.selector;\n if (_remappedFnSigs[contractAddress].creatorOf != bytes4(0)) {\n fnSig = _remappedFnSigs[contractAddress].creatorOf;\n }\n\n // solhint-disable-next-line\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n if (success) {\n return abi.decode(returnData, (address));\n } else {\n return address(0x0);\n }\n }\n\n function _getTokenOwner(address contractAddress, uint256 tokenId) internal returns (address) {\n bytes4 fnSig = IERC721Chargeable.ownerOf.selector;\n if (_remappedFnSigs[contractAddress].ownerOf != bytes4(0)) {\n fnSig = _remappedFnSigs[contractAddress].ownerOf;\n }\n\n // solhint-disable-next-line\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n if (success) {\n return abi.decode(returnData, (address));\n } else {\n return address(0x0);\n }\n }\n}\n" + }, + "contracts/v1/lib/WalletManagerBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// WalletManagerBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IWalletManager.sol\";\nimport \"../interfaces/ISmartWallet.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"./BlackholePrevention.sol\";\n\n\n/**\n * @notice Wallet-Manager Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract WalletManagerBase is Ownable, BlackholePrevention, IWalletManager {\n using TokenInfo for address;\n\n // The Controller Contract Address\n address internal _controller;\n\n // The Executor Contract Address\n address internal _executor;\n\n // Template Contract for creating Token Smart-Wallet Bridges\n address internal _walletTemplate;\n\n // TokenID => Token Smart-Wallet Address\n mapping (uint256 => address) internal _wallets;\n\n // State of Wallet Manager\n bool internal _paused;\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Wallet Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n /**\n * @dev Connects to the ExecForAccount Controller\n */\n function setExecutor(address executor) external onlyOwner {\n _executor = executor;\n emit ExecutorSet(executor);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartWallet(wallet).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartWallet(wallet).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartWallet(wallet).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Executor contract\n modifier onlyExecutor() {\n require(_executor == msg.sender, \"WMB:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Controller or Executor contract\n modifier onlyControllerOrExecutor() {\n require(_executor == msg.sender || _controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"WMB:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/ParticleSplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ParticleSplitter.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"./interfaces/IParticleSplitter.sol\";\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IWalletManager.sol\";\nimport \"./interfaces/IBasketManager.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Contract\n * @dev Upgradeable Contract\n */\ncontract ParticleSplitter is IParticleSplitter, Ownable, ReentrancyGuard, BlackholePrevention\n{\n IChargedManagers internal _chargedManagers;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n mapping (address => bool) internal _externalAddressesAllowed;\n\n\n /***********************************|\n | Execute for Account |\n |__________________________________*/\n\n /// @notice Executes an arbitrary command on an NFT Wallet\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Wallet Manager controlling the NFT Wallet to execute on\n /// @param externalAddress The Address of the External Contract to execute on\n /// @param encodedParams The encoded function call to execute\n function executeForWallet(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address externalAddress,\n bytes memory encodedParams\n )\n external\n payable\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (bytes memory)\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n require(_externalAddressesAllowed[externalAddress], \"PS:E-117\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Wallet Manager\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n // Get Address of Wallet to send any ETH into\n if (msg.value > 0) {\n address wallet = walletMgr.getWalletAddressById(contractAddress, tokenId, address(0), 0);\n payable(wallet).sendValue(msg.value);\n }\n\n emit ExecuteForWallet(contractAddress, tokenId, walletManagerId, externalAddress, encodedParams, msg.value);\n\n // Execute command for NFT Wallet\n return walletMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams);\n }\n\n /// @notice Executes an arbitrary command on an NFT Basket\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param basketManagerId The Basket Manager controlling the NFT Wallet to execute on\n /// @param externalAddress The Address of the External Contract to execute on\n /// @param encodedParams The encoded function call to execute\n function executeForBasket(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address externalAddress,\n bytes memory encodedParams\n )\n external\n payable\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (bytes memory)\n {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"PS:E-419\");\n require(_externalAddressesAllowed[externalAddress], \"PS:E-117\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Basket Manager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n\n // Get Address of Wallet to send any ETH into\n if (msg.value > 0) {\n address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId);\n payable(wallet).sendValue(msg.value);\n }\n\n emit ExecuteForBasket(contractAddress, tokenId, basketManagerId, externalAddress, encodedParams, msg.value);\n\n // Execute command for NFT Wallet\n return basketMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams);\n }\n\n function withdrawWalletRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (uint256 amountWithdrawn)\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Wallet Manager\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n // Withdraw Rewards for NFT Wallet\n return walletMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount);\n }\n\n function withdrawBasketRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (uint256 amountWithdrawn)\n {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"PS:E-419\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Basket Manager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n\n // Withdraw Rewards for NFT Basket\n return basketMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount);\n }\n\n function refreshWalletPrincipal(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n walletMgr.refreshPrincipal(contractAddress, tokenId, assetToken);\n\n emit PrincipalRefreshed(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedManagers Interface\n */\n function setChargedManagers(address chargedManagers) external virtual onlyOwner {\n _chargedManagers = IChargedManagers(chargedManagers);\n emit ChargedManagersSet(chargedManagers);\n }\n\n /**\n * @dev Setup the ChargedManagers Interface\n */\n function setTokenInfoProxy(address tokenInfoProxy) external virtual onlyOwner {\n _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy);\n emit TokenInfoProxySet(tokenInfoProxy);\n }\n\n /**\n * @dev Allows/Disallows execute from on specific contracts\n */\n function setExternalContracts(address[] calldata contracts, bool state) external onlyOwner {\n uint count = contracts.length;\n for (uint i; i < count; i++) {\n address externalContract = contracts[i];\n _externalAddressesAllowed[externalContract] = state;\n emit PermsSetForExternal(externalContract, state);\n }\n }\n\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyTokenOwner(address contractAddress, uint256 tokenId) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(msg.sender == tokenOwner, \"PS:E-102\");\n _;\n }\n}\n" + }, + "contracts/v1/test/Dai.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"../interfaces/IDai.sol\";\n\ncontract Dai is IDai {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (uint256 chainId_) public {\n string memory version = \"1\";\n\n _name = \"Dai Stablecoin\";\n _symbol = \"DAI\";\n _decimals = 18;\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(_name)),\n keccak256(bytes(version)),\n chainId_,\n address(this)\n )\n );\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view 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(msg.sender, 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(msg.sender, 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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(msg.sender, spender, _allowances[msg.sender][spender].add(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 _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20:E-403\");\n require(recipient != address(0), \"ERC20:E-403\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20:E-403\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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:E-403\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20:E-403\");\n require(spender != address(0), \"ERC20:E-403\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n\n mapping (address => uint) public nonces;\n\n // --- EIP712 niceties ---\n bytes32 public DOMAIN_SEPARATOR;\n // bytes32 public constant PERMIT_TYPEHASH = keccak256(\"Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)\");\n bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;\n\n // --- Approve by signature ---\n function permit(\n address holder, address spender, uint256 nonce, uint256 expiry,\n bool allowed, uint8 v, bytes32 r, bytes32 s) external override\n {\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n holder,\n spender,\n nonce,\n expiry,\n allowed\n )\n )\n )\n );\n\n require(holder != address(0), \"Dai/invalid-address-0\");\n require(holder == ecrecover(digest, v, r, s), \"Dai/invalid-permit\");\n require(expiry == 0 || now <= expiry, \"Dai/permit-expired\");\n require(nonce == nonces[holder]++, \"Dai/invalid-nonce\");\n uint wad = allowed ? uint(-1) : 0;\n _allowances[holder][spender] = wad;\n emit Approval(holder, spender, wad);\n }\n\n function mint(address to, uint256 amount) external {\n _mint(to, amount);\n }\n}" + }, + "contracts/v1/test/ERC20Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.7.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/**\n * @dev Extension of {ERC20} that adds a set of accounts with the {MinterRole},\n * which have permission to mint (create) new tokens as they see fit.\n *\n * At construction, the deployer of the contract is the only minter.\n */\ncontract ERC20Mintable is ERC20Upgradeable {\n\n constructor(string memory _name, string memory _symbol) public {\n __ERC20_init(_name, _symbol);\n }\n\n /**\n * @dev See {ERC20-_mint}.\n *\n * Requirements:\n *\n * - the caller must have the {MinterRole}.\n */\n function mint(address account, uint256 amount) public returns (bool) {\n _mint(account, amount);\n return true;\n }\n\n function burn(address account, uint256 amount) public returns (bool) {\n _burn(account, amount);\n return true;\n }\n}" + }, + "contracts/v1/test/ERC721Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.7.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\n\n/**\n * @dev Extension of {ERC721} for Minting/Burning\n */\ncontract ERC721Mintable is ERC721Upgradeable {\n\n constructor () public {\n __ERC721_init(\"ERC 721\", \"NFT\");\n }\n\n /**\n * @dev See {ERC721-_mint}.\n */\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n\n /**\n * @dev See {ERC721-_burn}.\n */\n function burn(uint256 tokenId) public {\n _burn(tokenId);\n }\n}\n" + }, + "contracts/v1/tokens/ExternalERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ExternalERC721.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\n\ncontract ExternalERC721 is ERC721 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n\n constructor() public ERC721(\"Charged Particles - ExternalERC721\", \"ExNFT\") {}\n\n function mintNft(address receiver, string memory tokenUri) external returns (uint256 newTokenId) {\n return _mintNft(receiver, tokenUri);\n }\n\n function _mintNft(address receiver, string memory tokenUri) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n\n _safeMint(receiver, newTokenId, \"\");\n\n _setTokenURI(newTokenId, tokenUri);\n }\n}\n" + }, + "contracts/v1/tokens/FungibleERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// FungibleERC1155.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract FungibleERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n\n constructor() public ERC1155(\"https://staging.app.charged.fi/erc1155/metadata.json\") {}\n\n function mintNft(address receiver, uint256 amount) external returns (uint256 newTokenId) {\n return _mintNft(receiver, amount);\n }\n\n function _mintNft(address receiver, uint256 amount) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n _mint(receiver, newTokenId, amount, \"\");\n }\n}\n" + }, + "contracts/v1/tokens/Ionx.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Ionx.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"erc20permit/contracts/ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\n\ncontract Ionx is ERC20Permit, Ownable, BlackholePrevention {\n using SafeMath for uint256;\n\n /// @notice An event thats emitted when the minter address is changed\n event MinterChanged(address minter, address newMinter);\n\n /// @notice Total number of tokens in circulation\n uint256 constant public INITIAL_SUPPLY = 1e8 ether;\n\n /// @notice Minimum time between mints\n uint32 public constant INFLATION_EPOCH = 1 days * 365;\n\n /// @notice Cap on the percentage of totalSupply that can be minted at each mint\n uint8 public constant INFLATION_CAP = 2;\n\n /// @notice Address which may mint new tokens\n address public minter;\n\n /// @notice The timestamp after which minting may occur\n uint256 public mintingAllowedAfter;\n\n\n constructor() public ERC20Permit(\"Charged Particles - IONX\", \"IONX\") {}\n\n\n /**\n * @notice Change the minter address\n * @param newMinter The address of the new minter\n */\n function setMinter(address newMinter) external onlyOwner {\n emit MinterChanged(minter, newMinter);\n minter = newMinter;\n }\n\n /**\n * @notice Mint new tokens\n * @param receiver The address of the destination account\n * @param amount The number of tokens to be minted\n */\n function mint(address receiver, uint256 amount) external onlyMinter {\n require(block.timestamp >= mintingAllowedAfter, \"Ionx:E-114\");\n require(receiver != address(0), \"Ionx:E-403\");\n\n uint256 amountToMint = amount;\n uint256 _totalSupply = totalSupply();\n\n // From Inflationary Supply\n if (_totalSupply >= INITIAL_SUPPLY) {\n mintingAllowedAfter = mintingAllowedAfter.add(INFLATION_EPOCH);\n amountToMint = _totalSupply.mul(INFLATION_CAP).div(100);\n }\n\n // From Initial Supply\n else {\n if (_totalSupply.add(amountToMint) > INITIAL_SUPPLY) {\n amountToMint = INITIAL_SUPPLY.sub(_totalSupply);\n }\n if (_totalSupply.add(amountToMint) == INITIAL_SUPPLY) {\n mintingAllowedAfter = block.timestamp.add(INFLATION_EPOCH);\n }\n }\n\n // transfer the amount to the recipient\n _mint(receiver, amountToMint);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n modifier onlyMinter() {\n require(msg.sender == minter, \"Ionx:E-113\");\n _;\n }\n}\n" + }, + "contracts/v1/tokens/Lepton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Lepton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/ILepton.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\n\ncontract Lepton is ILepton, ERC721, Ownable, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenIds;\n Classification[] internal _leptonTypes;\n mapping (uint256 => Classification) internal _leptonData;\n\n uint256 internal _typeIndex;\n uint256 internal _maxSupply;\n uint256 internal _maxMintPerTx;\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721(\"Charged Particles - Lepton\", \"LEPTON\") {\n _paused = true;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function mintLepton() external payable virtual override nonReentrant whenNotPaused returns (uint256 newTokenId) {\n newTokenId = _mintLepton(msg.sender);\n }\n\n function batchMintLepton(uint256 count) external payable virtual override nonReentrant whenNotPaused {\n _batchMintLepton(msg.sender, count);\n }\n\n function getNextType() external view virtual override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _typeIndex;\n }\n\n function getNextPrice() external view virtual override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _leptonTypes[_typeIndex].price;\n }\n\n function getMultiplier(uint256 tokenId) external view virtual override returns (uint256) {\n return _leptonData[tokenId].multiplier;\n }\n\n function getBonus(uint256 tokenId) external view virtual override returns (uint256) {\n return _leptonData[tokenId].bonus;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function addLeptonType(\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n virtual\n onlyOwner\n {\n _maxSupply = _maxSupply.add(uint256(supply));\n\n Classification memory lepton = Classification({\n tokenUri: tokenUri,\n price: price,\n supply: supply,\n multiplier: multiplier,\n bonus: bonus,\n _upperBounds: uint128(_maxSupply)\n });\n _leptonTypes.push(lepton);\n\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function updateLeptonType(\n uint256 leptonIndex,\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n virtual\n onlyOwner\n {\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\n _leptonTypes[leptonIndex].price = price;\n _leptonTypes[leptonIndex].supply = supply;\n _leptonTypes[leptonIndex].multiplier = multiplier;\n _leptonTypes[leptonIndex].bonus = bonus;\n\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function setMaxMintPerTx(uint256 maxAmount) external virtual onlyOwner {\n _maxMintPerTx = maxAmount;\n emit MaxMintPerTxSet(maxAmount);\n }\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _mintLepton(address receiver) internal virtual returns (uint256 newTokenId) {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n require(msg.value >= lepton.price, \"LPT:E-414\");\n\n _tokenIds.increment();\n newTokenId = _tokenIds.current();\n\n _leptonData[newTokenId] = lepton;\n _safeMint(receiver, newTokenId, \"\");\n _setTokenURI(newTokenId, lepton.tokenUri);\n\n // Distribute Next Type\n if (newTokenId == lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n emit LeptonMinted(receiver, newTokenId, lepton.price, lepton.multiplier);\n\n _refundOverpayment(lepton.price);\n }\n\n\n function _batchMintLepton(address receiver, uint256 count) internal virtual {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \"LPT:E-429\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n\n uint256 startTokenId = _tokenIds.current();\n uint256 endTokenId = startTokenId.add(count);\n if (endTokenId > lepton._upperBounds) {\n count = count.sub(endTokenId.sub(lepton._upperBounds));\n }\n\n uint256 salePrice = lepton.price.mul(count);\n require(msg.value >= salePrice, \"LPT:E-414\");\n\n _safeMintBatch(receiver, startTokenId.add(1), count, \"\");\n\n for (uint i = 0; i < count; i++) {\n _tokenIds.increment();\n startTokenId = _tokenIds.current();\n\n _leptonData[startTokenId] = lepton;\n _setTokenURI(startTokenId, lepton.tokenUri);\n }\n\n // Distribute Next Type\n if (startTokenId >= lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n emit LeptonBatchMinted(receiver, startTokenId, count, lepton.price, lepton.multiplier);\n\n _refundOverpayment(salePrice);\n }\n\n function _refundOverpayment(uint256 threshold) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"LPT:E-101\");\n _;\n }\n}" + }, + "contracts/v1/tokens/Lepton2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Lepton2.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"../lib/ERC721Basic.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\n\nimport \"../interfaces/ILepton.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Lepton2 is ILepton, ERC721Basic, Ownable, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n\n Classification[] internal _leptonTypes;\n\n uint256 internal _typeIndex;\n uint256 internal _maxSupply;\n uint256 internal _maxMintPerTx;\n uint256 internal _migratedCount;\n\n bool internal _paused;\n bool internal _migrationComplete;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721Basic(\"Charged Particles - Lepton2\", \"LEPTON2\") {\n _paused = true;\n _migrationComplete = false;\n _migratedCount = 0;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function mintLepton() external payable override nonReentrant whenNotPaused returns (uint256 newTokenId) {\n newTokenId = _mintLepton(msg.sender);\n }\n\n function batchMintLepton(uint256 count) external payable override nonReentrant whenNotPaused {\n _batchMintLepton(msg.sender, count);\n }\n\n function totalSupply() public view returns (uint256) {\n return _tokenCount;\n }\n\n function maxSupply() external view returns (uint256) {\n return _maxSupply;\n }\n\n function getNextType() external view override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _typeIndex;\n }\n\n function getNextPrice() external view override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _leptonTypes[_typeIndex].price;\n }\n\n function getMultiplier(uint256 tokenId) external view override returns (uint256) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).multiplier;\n }\n\n function getBonus(uint256 tokenId) external view override returns (uint256) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).bonus;\n }\n\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).tokenUri;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function addLeptonType(\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n onlyOwner\n {\n _maxSupply = _maxSupply.add(uint256(supply));\n\n Classification memory lepton = Classification({\n tokenUri: tokenUri,\n price: price,\n supply: supply,\n multiplier: multiplier,\n bonus: bonus,\n _upperBounds: uint128(_maxSupply)\n });\n _leptonTypes.push(lepton);\n\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function updateLeptonType(\n uint256 leptonIndex,\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n onlyOwner\n {\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\n _leptonTypes[leptonIndex].price = price;\n _leptonTypes[leptonIndex].supply = supply;\n _leptonTypes[leptonIndex].multiplier = multiplier;\n _leptonTypes[leptonIndex].bonus = bonus;\n\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function setMaxMintPerTx(uint256 maxAmount) external onlyOwner {\n _maxMintPerTx = maxAmount;\n emit MaxMintPerTxSet(maxAmount);\n }\n\n function setPausedState(bool state) external onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function migrateAccounts(address oldLeptonContract, uint256 count) external onlyOwner whenNotMigrated {\n uint256 oldSupply = IERC721Enumerable(oldLeptonContract).totalSupply();\n require(oldSupply == 0 || oldSupply > _migratedCount, \"LPT:E-004\");\n\n if (oldSupply > 0) {\n uint256 endTokenId = _migratedCount.add(count);\n if (endTokenId > oldSupply) {\n count = count.sub(endTokenId.sub(oldSupply));\n }\n\n for (uint256 i = 1; i <= count; i++) {\n uint256 tokenId = _migratedCount.add(i);\n address tokenOwner = IERC721(oldLeptonContract).ownerOf(tokenId);\n _mint(tokenOwner);\n }\n _migratedCount = _migratedCount.add(count);\n }\n\n if (oldSupply == _migratedCount) {\n _finalizeMigration();\n }\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getLepton(uint256 tokenId) internal view returns (Classification memory) {\n uint256 types = _leptonTypes.length;\n for (uint256 i = 0; i < types; i++) {\n Classification memory lepton = _leptonTypes[i];\n if (tokenId <= lepton._upperBounds) {\n return lepton;\n }\n }\n }\n\n function _mintLepton(address receiver) internal returns (uint256 newTokenId) {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n require(msg.value >= lepton.price, \"LPT:E-414\");\n\n newTokenId = _safeMint(receiver, \"\");\n\n // Determine Next Type\n if (newTokenId == lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n _refundOverpayment(lepton.price);\n }\n\n function _batchMintLepton(address receiver, uint256 count) internal {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \"LPT:E-429\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n\n uint256 endTokenId = _tokenCount.add(count);\n if (endTokenId > lepton._upperBounds) {\n count = count.sub(endTokenId.sub(lepton._upperBounds));\n }\n\n uint256 salePrice = lepton.price.mul(count);\n require(msg.value >= salePrice, \"LPT:E-414\");\n\n _safeMintBatch(receiver, count, \"\");\n\n // Determine Next Type\n if (endTokenId >= lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n _refundOverpayment(salePrice);\n }\n\n function _refundOverpayment(uint256 threshold) internal {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n function _finalizeMigration() internal {\n // Determine Next Type\n _typeIndex = 0;\n for (uint256 i = 0; i < _leptonTypes.length; i++) {\n Classification memory lepton = _leptonTypes[i];\n if (_migratedCount >= lepton._upperBounds) {\n _typeIndex = i + 1;\n }\n }\n _migrationComplete = true;\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotMigrated() {\n require(!_migrationComplete, \"LPT:E-004\");\n _;\n }\n\n modifier whenNotPaused() {\n require(!_paused, \"LPT:E-101\");\n _;\n }\n}" + }, + "contracts/v1/tokens/NonFungibleERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// NonFungibleERC1155.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract NonFungibleERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => address) internal _tokenOwner;\n\n constructor() public ERC1155(\"https://staging.app.charged.fi/erc1155/metadata.json\") {}\n\n function creatorOf(uint256 tokenId) external view returns (address) {\n return _tokenCreator[tokenId];\n }\n\n function ownerOf(uint256 tokenId) external view returns (address) {\n return _tokenOwner[tokenId];\n }\n\n function mintNft(address receiver) external returns (uint256 newTokenId) {\n return _mintNft(msg.sender, receiver);\n }\n\n function _mintNft(address creator, address receiver) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n\n _mint(receiver, newTokenId, 1, \"\");\n _tokenCreator[newTokenId] = creator;\n _tokenOwner[newTokenId] = receiver;\n }\n}\n" + }, + "contracts/v1/tokens/Proton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IProton.sol\";\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ncontract Proton is IProton, ERC721, Ownable, RelayRecipient, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n using Counters for Counters.Counter;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n uint256 constant internal MAX_ROYALTIES = 8e3; // 8000 (80%)\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n Counters.Counter internal _tokenIds;\n\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct;\n mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect;\n mapping (address => uint256) internal _tokenCreatorClaimableRoyalties;\n\n mapping (uint256 => uint256) internal _tokenSalePrice;\n mapping (uint256 => uint256) internal _tokenLastSellPrice;\n\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721(\"Charged Particles - Proton\", \"PROTON\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view virtual override returns (address) {\n return _tokenCreator[tokenId];\n }\n\n function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenSalePrice[tokenId];\n }\n\n function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenLastSellPrice[tokenId];\n }\n\n function getCreatorRoyalties(address account) external view virtual override returns (uint256) {\n return _tokenCreatorClaimableRoyalties[account];\n }\n\n function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenCreatorRoyaltiesPct[tokenId];\n }\n\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) {\n return _creatorRoyaltiesReceiver(tokenId);\n }\n\n function claimCreatorRoyalties()\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256)\n {\n return _claimCreatorRoyalties(_msgSender());\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // annuityPercent,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n royaltiesPercent,\n salePrice\n );\n }\n\n function batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n external\n virtual\n override\n whenNotPaused\n {\n _batchProtonsForSale(\n creator,\n annuityPercent,\n royaltiesPercent,\n tokenMetaUris,\n salePrices\n );\n }\n\n function buyProton(uint256 tokenId)\n external\n payable\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (bool)\n {\n return _buyProton(tokenId);\n }\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice)\n external\n virtual\n override\n whenNotPaused\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setSalePrice(tokenId, salePrice);\n }\n\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setRoyaltiesPct(tokenId, royaltiesPct);\n }\n\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n {\n _tokenCreatorRoyaltiesRedirect[tokenId] = receiver;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual {\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n\n _tokenSalePrice[tokenId] = salePrice;\n emit SalePriceSet(tokenId, salePrice);\n }\n\n function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual {\n require(royaltiesPct <= MAX_ROYALTIES, \"PRT:E-421\");\n _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct;\n emit CreatorRoyaltiesSet(tokenId, royaltiesPct);\n }\n\n function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) {\n address receiver = _tokenCreatorRoyaltiesRedirect[tokenId];\n if (receiver == address(0x0)) {\n receiver = _tokenCreator[tokenId];\n }\n return receiver;\n }\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, annuityPercent, 0, 0);\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n _tokenIds.increment();\n\n newTokenId = _tokenIds.current();\n _safeMint(receiver, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUri);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function _batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n internal\n virtual\n {\n require(tokenMetaUris.length == salePrices.length, \"PRT:E-202\");\n address self = address(this);\n\n uint256 count = tokenMetaUris.length;\n for (uint256 i = 0; i < count; i++) {\n _tokenIds.increment();\n uint256 newTokenId = _tokenIds.current();\n\n _safeMint(creator, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUris[i]);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n uint256 salePrice = salePrices[i];\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n self,\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n function _buyProton(uint256 tokenId)\n internal\n virtual\n returns (bool)\n {\n uint256 salePrice = _tokenSalePrice[tokenId];\n require(salePrice > 0, \"PRT:E-416\");\n require(msg.value >= salePrice, \"PRT:E-414\");\n\n uint256 ownerAmount = salePrice;\n uint256 creatorAmount;\n address oldOwner = ownerOf(tokenId);\n address newOwner = _msgSender();\n\n // Creator Royalties\n address royaltiesReceiver = _creatorRoyaltiesReceiver(tokenId);\n uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[tokenId];\n uint256 lastSellPrice = _tokenLastSellPrice[tokenId];\n if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) {\n creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE);\n ownerAmount = ownerAmount.sub(creatorAmount);\n }\n _tokenLastSellPrice[tokenId] = salePrice;\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(address(this), tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n\n // Reserve Royalties for Creator\n if (creatorAmount > 0) {\n _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount);\n }\n\n // Transfer Token\n _transfer(oldOwner, newOwner, tokenId);\n\n // Transfer Payment\n payable(oldOwner).sendValue(ownerAmount);\n\n emit ProtonSold(tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n\n _refundOverpayment(salePrice);\n return true;\n }\n\n /**\n * @dev Pays out the Creator Royalties of the calling account\n * @param receiver The receiver of the claimable royalties\n * @return The amount of Creator Royalties claimed\n */\n function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) {\n uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver];\n require(claimableAmount > 0, \"PRT:E-411\");\n\n delete _tokenCreatorClaimableRoyalties[receiver];\n payable(receiver).sendValue(claimableAmount);\n\n emit RoyaltiesClaimed(receiver, claimableAmount);\n }\n\n /**\n * @dev Collects the Required Asset Token from the users wallet\n * @param from The owner address to collect the Assets from\n * @param assetAmount The Amount of Asset Tokens to Collect\n */\n function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual {\n uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from);\n require(assetAmount <= _userAssetBalance, \"PRT:E-411\");\n // Be sure to Approve this Contract to transfer your Asset Token\n require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), \"PRT:E-401\");\n }\n\n function _refundOverpayment(uint256 threshold) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n _tokenSalePrice[tokenId] = 0;\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n super._transfer(from, to, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"PRT:E-101\");\n _;\n }\n\n modifier onlyTokenOwnerOrApproved(uint256 tokenId) {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"PRT:E-105\");\n _;\n }\n\n modifier onlyTokenCreator(uint256 tokenId) {\n require(_tokenCreator[tokenId] == _msgSender(), \"PRT:E-104\");\n _;\n }\n}" + }, + "contracts/v1/tokens/ProtonB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\nimport \"../interfaces/IProtonB.sol\";\n\nimport \"../lib/BaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ncontract ProtonB is BaseProton, IProtonB {\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public BaseProton(\"Charged Particles - ProtonB\", \"PROTON.B\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n external\n virtual\n override\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n royaltiesPercent,\n salePrice\n );\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n /// @dev for backwards compatibility with v1\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0);\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n\n /***********************************|\n | Function Overrides |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override {\n super._setSalePrice(tokenId, salePrice);\n\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n }\n\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n override\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n }\n\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n // Unlock NFT\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n\n super._transfer(from, to, tokenId);\n }\n}" + }, + "contracts/v1/tokens/ProtonC.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\nimport \"../lib/Soul.sol\";\n\n\ncontract ProtonC is BaseProton, Soul {\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public BaseProton(\"Charged Particles - ProtonC\", \"PROTON.C\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createBondedToken(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent\n )\n external\n virtual\n payable\n returns (uint256 newTokenId)\n {\n uint256 tokenId = createProtonForSale(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n royaltiesPercent,\n 0\n );\n lockToken(tokenId);\n\n return tokenId;\n }\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n public \n virtual\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n royaltiesPercent,\n salePrice\n );\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n nonReentrant\n whenNotPaused\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n /// @dev for backwards compatibility with v1\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n whenNotPaused\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function burn(uint256 tokenId) public {\n requireTokenOwner(tokenId); \n _burn(tokenId);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n function requireTokenOwner(uint256 tokenId) public view {\n require(ownerOf(tokenId) == msg.sender, \"Only token owner\");\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0);\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n function _burn(uint256 tokenId) internal {\n _unlockToken(tokenId);\n _transfer(ownerOf(tokenId), address(0x000000000000000000000000000000000000dEaD), tokenId);\n }\n\n /***********************************|\n | Soul bounded |\n |__________________________________*/\n\n function lockToken(uint256 tokenId) public {\n requireTokenOwner(tokenId);\n _lockToken(tokenId);\n }\n\n /***********************************|\n | Function Overrides |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override {\n super._setSalePrice(tokenId, salePrice);\n\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n }\n\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n override\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n require(lockedTokens[tokenId] == false, \"BondedToken: Token is locked\");\n\n // Unlock NFT\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n\n super._transfer(from, to, tokenId);\n }\n}" + }, + "contracts/v1/Universe.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\n\nimport \"./interfaces/IUniverse.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n\n/**\n * @notice Charged Particles Universe Contract\n * @dev Upgradeable Contract\n */\ncontract Universe is IUniverse, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n // The ChargedParticles Contract Address\n address public chargedParticles;\n address public proton;\n address public lepton;\n address public quark;\n address public boson;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // Positive Charge\n uint256 internal photonMaxSupply;\n uint256 internal totalPhotonDischarged;\n\n // Source of Positive Charge\n IERC20Upgradeable public photonSource;\n\n // Asset Token => Electrostatic Attraction Multiplier\n mapping (address => uint256) internal esaMultiplier;\n\n // Account => Electrostatic Attraction Levels\n mapping (address => uint256) internal esaLevel;\n\n // Energizing Account => Referral Source\n mapping (address => address) internal referralSource;\n\n // NFT Token UUID => Bonded Lepton Mass\n mapping (uint256 => uint256) internal bondedLeptonMass;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getStaticCharge(address /* account */) external pure virtual returns (uint256 positiveEnergy) {\n return 0;\n }\n\n function conductElectrostaticDischarge(address /* account */, uint256 /* amount */) external pure virtual returns (uint256 positiveEnergy) {\n return 0;\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n onlyProton\n {\n // no-op\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(controller)\n {\n chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setPhoton(\n address token,\n uint256 maxSupply\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n photonSource = IERC20Upgradeable(token);\n photonMaxSupply = maxSupply;\n emit PhotonSet(token, maxSupply);\n }\n\n function setProtonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n proton = token;\n emit ProtonTokenSet(token);\n }\n\n function setLeptonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n lepton = token;\n emit LeptonTokenSet(token);\n }\n\n function setQuarkToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n quark = token;\n emit QuarkTokenSet(token);\n }\n\n function setBosonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n boson = token;\n emit BosonTokenSet(token);\n }\n\n function setEsaMultiplier(\n address assetToken,\n uint256 multiplier\n )\n external\n virtual\n onlyOwner\n {\n esaMultiplier[assetToken] = multiplier;\n emit EsaMultiplierSet(assetToken, multiplier);\n }\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _electrostaticAttraction(uint256 tokenUuid, address receiver, address assetToken, uint256 baseAmount) internal virtual {\n }\n\n function _conductElectrostaticDischarge(address /* account */, uint256 /* energy */) internal virtual pure returns (uint256) {\n return 0;\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Proton NFT contract\n modifier onlyProton() {\n require(proton == msg.sender, \"UNI:E-110\");\n _;\n }\n}\n" + }, + "contracts/v1/UniverseRP.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"./interfaces/IUniverseRP.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./interfaces/IRewardNft.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\nimport \"./interfaces/IRewardProgram.sol\";\n\n/**\n * @notice Charged Particles Universe Contract with Rewards Program\n * @dev Upgradeable Contract\n */\ncontract UniverseRP is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // The ChargedParticles Contract Address\n address public _chargedParticles;\n\n // The Lepton NFT Contract Address\n address public _multiplierNft;\n\n // Asset Token => Reward Program\n mapping (address => address) internal _assetRewardPrograms;\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\n\n // Token UUID => NFT Staking Data\n mapping (uint256 => NftStake) private _nftStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n function getRewardProgram(address asset) external view override returns (address) {\n return _getRewardProgram(asset);\n }\n\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\n return _nftStake[uuid];\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetDeposit(\n contractAddress,\n tokenId,\n walletManagerId,\n assetAmount\n );\n }\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\n }\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n // \"receiverEnergy\" includes the \"principalAmount\"\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n onlyOwner\n onlyValidContractAddress(controller)\n {\n _chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setMultiplierNft(address nftTokenAddress)\n external\n onlyOwner\n onlyValidContractAddress(nftTokenAddress)\n {\n _multiplierNft = nftTokenAddress;\n }\n\n function setRewardProgram(\n address rewardProgam,\n address assetToken\n )\n external\n onlyOwner\n onlyValidContractAddress(rewardProgam)\n {\n require(assetToken != address(0x0), \"UNI:E-403\");\n _assetRewardPrograms[assetToken] = rewardProgam;\n emit RewardProgramSet(assetToken, rewardProgam);\n }\n\n function removeRewardProgram(address assetToken) external onlyOwner {\n delete _assetRewardPrograms[assetToken];\n emit RewardProgramRemoved(assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getRewardProgram(address assetToken) internal view returns (address) {\n return _assetRewardPrograms[assetToken];\n }\n\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != depositNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n uint256 multiplier = _getNftMultiplier(depositNftAddress, depositNftTokenId);\n\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\n // Add to Multipliers Set\n _multiplierNftsSet[parentNftUuid].add(multiplier);\n\n // Update NFT Stake\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\n } else {\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\n }\n }\n\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\n }\n\n function _registerNftRelease(\n address contractAddress,\n uint256 tokenId,\n address releaseNftAddress,\n uint256 releaseNftTokenId,\n uint256 /* nftTokenAmount */\n )\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != releaseNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n NftStake storage nftStake = _nftStake[parentNftUuid];\n\n // Remove from Multipliers Set\n uint256 multiplier = _getNftMultiplier(releaseNftAddress, releaseNftTokenId);\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\n\n // Determine New Multiplier or Mark as Released\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\n } else {\n nftStake.releaseBlockNumber = block.number;\n }\n\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\n }\n\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\n uint256 multiplier = 0;\n uint256 loss = 50;\n uint256 i = 0;\n\n for (; i < len; i++) {\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\n }\n if (len > 1) {\n multiplier = multiplier.sub(loss.mul(len));\n }\n return multiplier;\n }\n\n function _getNftMultiplier(address contractAddress, uint256 tokenId) internal returns (uint256) {\n bytes4 fnSig = IRewardNft.getMultiplier.selector;\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n\n if (success) {\n return abi.decode(returnData, (uint256));\n } else {\n return 0;\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(_chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/vesting/VestingClaim7.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract VestingClaim7 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"VestingClaim7: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"VestingClaim7: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"VestingClaim7: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"VestingClaim7: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"VestingClaim7: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"VestingClaim7: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveSmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\nimport \"../../interfaces/IAaveBridge.sol\";\nimport \"../../lib/SmartWalletBase.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet for Aave Assets\n * @dev Non-upgradeable Contract\n */\ncontract AaveSmartWallet is SmartWalletBase {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 constant internal RAY = 1e27;\n\n IAaveBridge internal _bridge;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(\n address aaveBridge\n )\n public\n {\n SmartWalletBase.initializeBase();\n _bridge = IAaveBridge(aaveBridge);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _bridge.isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address) {\n return _bridge.getReserveInterestToken(assetToken);\n }\n\n function getPrincipal(address assetToken) external override returns (uint256) {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address assetToken) external override returns (uint256 creatorInterest, uint256 ownerInterest) {\n return _getInterest(assetToken);\n }\n\n function getTotal(address assetToken) external override returns (uint256) {\n return _getTotal(assetToken);\n }\n\n function getRewards(address rewardToken) external override returns (uint256) {\n return IERC20(rewardToken).balanceOf(address(this));\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _deposit(assetToken, assetAmount, referralCode);\n }\n\n\n function withdraw(\n address receiver,\n address creatorRedirect,\n address assetToken\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (, uint256 ownerInterest) = _getInterest(assetToken);\n return _withdraw(receiver, creatorRedirect, assetToken, walletPrincipal.add(ownerInterest));\n }\n\n function withdrawAmount(\n address receiver,\n address creatorRedirect,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return _withdraw(receiver, creatorRedirect, assetToken, assetAmount);\n }\n\n function withdrawAmountForCreator(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return _withdrawForCreator(receiver, assetToken, assetAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _withdrawRewards(receiver, rewardsToken, rewardsAmount);\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n internal\n returns (uint256)\n {\n _trackAssetToken(assetToken);\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n\n // Deposit Assets into Aave (reverts on fail)\n _sendToken(address(_bridge), assetToken, assetAmount);\n uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function _withdraw(\n address receiver,\n address creatorRedirect,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken);\n\n // Withdraw from Interest only\n if (assetAmount < ownerInterest) {\n if (creatorInterest > 0) {\n uint256 ratio = assetAmount.mul(RAY).div(ownerInterest);\n creatorAmount = creatorInterest.add(nftCreatorAmountDischarged).mul(ratio).div(RAY);\n\n if (creatorAmount <= nftCreatorAmountDischarged) {\n nftCreatorAmountDischarged = nftCreatorAmountDischarged.sub(creatorAmount);\n creatorAmount = 0;\n }\n\n else {\n creatorAmount = creatorAmount.sub(nftCreatorAmountDischarged);\n nftCreatorAmountDischarged = 0;\n }\n }\n receiverAmount = assetAmount;\n }\n\n // Withdraw from Interest + Principal\n else {\n uint256 fromPrincipal = assetAmount.sub(ownerInterest);\n if (fromPrincipal > walletPrincipal) {\n fromPrincipal = walletPrincipal.sub(ownerInterest);\n }\n\n creatorAmount = creatorInterest;\n receiverAmount = ownerInterest.add(fromPrincipal);\n nftCreatorAmountDischarged = 0;\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal);\n }\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount));\n\n // Withdraw Assets for Creator\n if (creatorAmount > 0) {\n address receivesForCreator = (creatorRedirect != address(0x0)) ? creatorRedirect : nftCreator;\n _bridge.withdraw(receivesForCreator, assetToken, creatorAmount);\n }\n\n // Withdraw Assets for Receiver\n _bridge.withdraw(receiver, assetToken, receiverAmount);\n }\n\n function _withdrawForCreator(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 receiverAmount)\n {\n (uint256 creatorInterest,) = _getInterest(assetToken);\n if (creatorInterest == 0) { return 0; }\n if (assetAmount > creatorInterest) {\n assetAmount = creatorInterest;\n }\n\n nftCreatorAmountDischarged = nftCreatorAmountDischarged.add(assetAmount);\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, assetAmount);\n\n // Withdraw Assets for Receiver on behalf of Creator\n _bridge.withdraw(receiver, assetToken, assetAmount);\n }\n\n function _withdrawRewards(\n address receiver,\n address rewardsTokenAddress,\n uint256 rewardsAmount\n )\n internal\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"ASW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function _getTotal(address assetToken) internal view returns (uint256) {\n return _bridge.getTotalBalance(address(this), assetToken);\n }\n\n function _getInterest(address assetToken) internal view returns (uint256 creatorInterest, uint256 ownerInterest) {\n uint256 total = _getTotal(assetToken);\n uint256 principal = _getPrincipal(assetToken);\n uint256 interest = total.sub(principal);\n\n // Creator Royalties\n if (nftCreatorAnnuityPct > 0) {\n\n // Interest too small to calculate percentage;\n if (interest <= PERCENTAGE_SCALE) {\n // creatorInterest = interest.div(2); // split evenly?\n creatorInterest = 0; // All to owner\n }\n\n // Calculate percentage for Creator\n else {\n creatorInterest = interest\n .add(nftCreatorAmountDischarged)\n .mul(nftCreatorAnnuityPct)\n .div(PERCENTAGE_SCALE)\n .sub(nftCreatorAmountDischarged);\n }\n }\n\n // Owner Portion\n ownerInterest = interest.sub(creatorInterest);\n }\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveSmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\nimport \"../../interfaces/IAaveBridge.sol\";\nimport \"../../lib/SmartWalletBaseB.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet for Aave Assets\n * @dev Non-upgradeable Contract\n */\ncontract AaveSmartWalletB is SmartWalletBaseB {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 constant internal RAY = 1e27;\n\n IAaveBridge internal _bridge;\n\n uint256 internal _nftCreatorAmountDischarged;\n\n mapping (address => address) internal _assetATokens;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(\n address aaveBridge\n )\n public\n {\n SmartWalletBaseB.initializeBase();\n _bridge = IAaveBridge(aaveBridge);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _bridge.isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address) {\n return _bridge.getReserveInterestToken(assetToken);\n }\n\n function getPrincipal(address assetToken) external override returns (uint256) {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address assetToken, uint256 creatorPct) external override returns (uint256 creatorInterest, uint256 ownerInterest) {\n return _getInterest(assetToken, creatorPct);\n }\n\n function getTotal(address assetToken) external override returns (uint256) {\n return _getTotal(assetToken);\n }\n\n function getRewards(address rewardToken) external override returns (uint256) {\n return IERC20(rewardToken).balanceOf(address(this));\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _deposit(assetToken, assetAmount, referralCode);\n }\n\n\n function withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (, uint256 ownerInterest) = _getInterest(assetToken, creatorPct);\n return _withdraw(receiver, creator, creatorPct, assetToken, walletPrincipal.add(ownerInterest));\n }\n\n function withdrawAmount(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return _withdraw(receiver, creator, creatorPct, assetToken, assetAmount);\n }\n\n function withdrawAmountForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return _withdrawForCreator(receiver, creatorPct, assetToken, assetAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _withdrawRewards(receiver, rewardsToken, rewardsAmount);\n }\n\n function refreshPrincipal(address assetToken) external virtual override onlyWalletManager {\n uint256 aTokenBalance = IERC20(_assetATokens[assetToken]).balanceOf(address(this));\n if (_assetPrincipalBalance[assetToken] > aTokenBalance) {\n _assetPrincipalBalance[assetToken] = aTokenBalance;\n }\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n internal\n returns (uint256)\n {\n _trackAssetToken(assetToken);\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n\n // Deposit Assets into Aave (reverts on fail)\n _sendToken(address(_bridge), assetToken, assetAmount);\n uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function _withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken, creatorPct);\n\n // Withdraw from Interest only\n if (assetAmount < ownerInterest) {\n if (creatorInterest > 0) {\n uint256 ratio = assetAmount.mul(RAY).div(ownerInterest);\n creatorAmount = creatorInterest.add(_nftCreatorAmountDischarged).mul(ratio).div(RAY);\n\n if (creatorAmount <= _nftCreatorAmountDischarged) {\n _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.sub(creatorAmount);\n creatorAmount = 0;\n }\n else {\n creatorAmount = creatorAmount.sub(_nftCreatorAmountDischarged);\n _nftCreatorAmountDischarged = 0;\n }\n }\n receiverAmount = assetAmount;\n }\n\n // Withdraw from Interest + Principal\n else {\n uint256 fromPrincipal = assetAmount.sub(ownerInterest);\n if (fromPrincipal > walletPrincipal) {\n fromPrincipal = walletPrincipal.sub(ownerInterest);\n }\n\n creatorAmount = creatorInterest;\n receiverAmount = ownerInterest.add(fromPrincipal);\n _nftCreatorAmountDischarged = 0;\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal);\n }\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount));\n\n // Withdraw Assets for Creator\n if (creatorAmount > 0) {\n if (creator != address(0)) {\n _bridge.withdraw(creator, assetToken, creatorAmount);\n } else {\n receiverAmount = receiverAmount.add(creatorAmount);\n creatorAmount = 0;\n }\n }\n\n // Withdraw Assets for Receiver\n _bridge.withdraw(receiver, assetToken, receiverAmount);\n }\n\n function _withdrawForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 receiverAmount)\n {\n (uint256 creatorInterest,) = _getInterest(assetToken, creatorPct);\n if (creatorInterest == 0) { return 0; }\n if (assetAmount > creatorInterest) {\n assetAmount = creatorInterest;\n }\n\n _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.add(assetAmount);\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, assetAmount);\n\n // Withdraw Assets for Receiver on behalf of Creator\n _bridge.withdraw(receiver, assetToken, assetAmount);\n }\n\n function _withdrawRewards(\n address receiver,\n address rewardsTokenAddress,\n uint256 rewardsAmount\n )\n internal\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"ASW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function _getTotal(address assetToken) internal view returns (uint256) {\n return _bridge.getTotalBalance(address(this), assetToken);\n }\n\n function _getInterest(address assetToken, uint256 creatorPct) internal view returns (uint256 creatorInterest, uint256 ownerInterest) {\n uint256 total = _getTotal(assetToken);\n uint256 principal = _getPrincipal(assetToken);\n uint256 interest = total.sub(principal);\n\n // Creator Royalties\n if (creatorPct > 0) {\n\n // Interest too small to calculate percentage;\n if (interest <= PERCENTAGE_SCALE) {\n // creatorInterest = interest.div(2); // split evenly?\n creatorInterest = 0; // All to owner\n }\n\n // Calculate percentage for Creator\n else {\n creatorInterest = interest\n .add(_nftCreatorAmountDischarged)\n .mul(creatorPct)\n .div(PERCENTAGE_SCALE)\n .sub(_nftCreatorAmountDischarged);\n }\n }\n\n // Owner Portion\n ownerInterest = interest.sub(creatorInterest);\n }\n\n function _trackAssetToken(address assetToken) internal override {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _assetATokens[assetToken] = aTokenAddress;\n }\n }\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../lib/WalletManagerBase.sol\";\n\nimport \"./AaveSmartWallet.sol\";\n\n/**\n * @notice Wallet Manager for Aave\n * @dev Non-upgradeable Contract\n */\ncontract AaveWalletManager is WalletManagerBase {\n using SafeMath for uint256;\n\n event AaveBridgeSet(address indexed aaveBridge);\n event ValidRewardsTokenSet(address indexed rewardsToken, bool state);\n\n address internal _aaveBridge;\n uint256 internal _referralCode;\n\n mapping (address => bool) public rewardsTokenWhitelist;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new AaveSmartWallet());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return AaveSmartWallet(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return AaveSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return AaveSmartWallet(_wallets[uuid]).getInterest(assetToken);\n }\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getTotal(assetToken);\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getRewards(_rewardToken);\n }\n\n\n /***********************************|\n | Only Controller |\n |__________________________________*/\n\n function energize(\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = AaveSmartWallet(wallet).deposit(assetToken, assetAmount, _referralCode);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(ownerInterest > 0, \"AWM:E-412\");\n\n // Discharge the full amount of interest\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, ownerInterest);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(assetAmount > 0 && ownerInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmountForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address creator,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (uint256 creatorInterest,) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(assetAmount > 0 && creatorInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n receiverAmount = AaveSmartWallet(wallet).withdrawAmountForCreator(receiver, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount);\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = AaveSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0;\n\n // Release from interest first + principal if needed\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n require(rewardsTokenWhitelist[rewardsToken], \"AWM:E-423\");\n\n // Withdraw Rewards to Receiver\n amount = AaveSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 tokenId,\n address externalAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return AaveSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n // no-op\n }\n\n function getWalletAddressById(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPct\n )\n external\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n\n if (creator != address(0x0)) {\n AaveSmartWallet(wallet).setNftCreator(creator, annuityPct);\n }\n\n emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAaveBridge(address aaveBridge) external onlyOwner {\n require(aaveBridge != address(0x0), \"AWM:E-403\");\n _aaveBridge = aaveBridge;\n emit AaveBridgeSet(aaveBridge);\n }\n\n // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool\n function setReferralCode(uint256 referralCode) external onlyOwner {\n _referralCode = referralCode;\n }\n\n function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner {\n rewardsTokenWhitelist[rewardsToken] = state;\n emit ValidRewardsTokenSet(rewardsToken, state);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n AaveSmartWallet(newWallet).initialize(_aaveBridge);\n return newWallet;\n }\n}" + }, + "contracts/v1/yield/aave/AaveWalletManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../lib/WalletManagerBase.sol\";\nimport \"../../interfaces/IChargedSettings.sol\";\nimport \"./AaveSmartWalletB.sol\";\n\n/**\n * @notice Wallet Manager for Aave\n * @dev Non-upgradeable Contract\n */\ncontract AaveWalletManagerB is WalletManagerBase {\n using SafeMath for uint256;\n\n event AaveBridgeSet(address indexed aaveBridge);\n event ChargedSettingsSet(address indexed settings);\n event ValidRewardsTokenSet(address indexed rewardsToken, bool state);\n\n IChargedSettings internal _chargedSettings;\n\n address internal _aaveBridge;\n uint256 internal _referralCode;\n\n mapping (address => bool) public _rewardsTokenWhitelist;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new AaveSmartWalletB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return AaveSmartWalletB(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return AaveSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n return AaveSmartWalletB(_wallets[uuid]).getInterest(assetToken, annuityPct);\n }\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getTotal(assetToken);\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getRewards(_rewardToken);\n }\n\n\n /***********************************|\n | Only Controller |\n |__________________________________*/\n\n function energize(\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = AaveSmartWalletB(wallet).deposit(assetToken, assetAmount, _referralCode);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(ownerInterest > 0, \"AWM:E-412\");\n\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Discharge the full amount of interest\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, ownerInterest);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(assetAmount > 0 && ownerInterest >= assetAmount, \"AWM:E-412\");\n\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Discharge a portion of the interest\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmountForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address creator,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (uint256 creatorInterest,) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(assetAmount > 0 && creatorInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n receiverAmount = AaveSmartWalletB(wallet).withdrawAmountForCreator(receiver, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount);\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Release Principal + Interest\n principalAmount = AaveSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdraw(receiver, creator, annuityPct, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0;\n\n // Release from interest first + principal if needed\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n require(_rewardsTokenWhitelist[rewardsToken], \"AWM:E-423\");\n\n // Withdraw Rewards to Receiver\n amount = AaveSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 tokenId,\n address externalAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return AaveSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n AaveSmartWalletB(wallet).refreshPrincipal(assetToken);\n }\n\n function getWalletAddressById(\n address contractAddress,\n uint256 tokenId,\n address /* creator */,\n uint256 /* annuityPct */\n )\n external\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAaveBridge(address aaveBridge) external onlyOwner {\n require(aaveBridge != address(0x0), \"AWM:E-403\");\n _aaveBridge = aaveBridge;\n emit AaveBridgeSet(aaveBridge);\n }\n\n function setChargedSettings(address settings) external onlyOwner {\n require(settings != address(0x0), \"AWM:E-403\");\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool\n function setReferralCode(uint256 referralCode) external onlyOwner {\n _referralCode = referralCode;\n }\n\n function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner {\n _rewardsTokenWhitelist[rewardsToken] = state;\n emit ValidRewardsTokenSet(rewardsToken, state);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n AaveSmartWalletB(newWallet).initialize(_aaveBridge);\n return newWallet;\n }\n}" + }, + "contracts/v1/yield/aave/v2/AaveBridgeV2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveBridgeV2.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/SafeCast.sol\";\n\nimport \"./IATokenV2.sol\";\nimport \"./ILendingPoolV2.sol\";\nimport \"./ILendingPoolAddressesProviderV2.sol\";\n\nimport \"../../../interfaces/IAaveBridge.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\n\ncontract AaveBridgeV2 is Ownable, IAaveBridge, BlackholePrevention {\n using SafeMath for uint256;\n using SafeCast for uint256;\n using SafeERC20 for IERC20;\n using ReserveLogic for ReserveLogic.ReserveData;\n\n ILendingPoolAddressesProviderV2 public provider;\n ILendingPoolV2 public lendingPool;\n\n constructor (address lendingPoolProvider) public {\n provider = ILendingPoolAddressesProviderV2(lendingPoolProvider);\n lendingPool = ILendingPoolV2(provider.getLendingPool());\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address aTokenAddress) {\n return _getReserveInterestToken(assetToken);\n }\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _isReserveActive(assetToken);\n }\n\n function getTotalBalance(address account, address assetToken) external view override returns (uint256) {\n address aTokenAddress = _getReserveInterestToken(assetToken);\n if (aTokenAddress == address(0x0)) { return 0; }\n return IATokenV2(aTokenAddress).balanceOf(account);\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n returns (uint256)\n {\n address self = address(this);\n address aTokenAddress = _getReserveInterestToken(assetToken);\n require(_isReserveActive(assetToken), \"ABV2:E-424\");\n\n IERC20 token = IERC20(assetToken);\n IATokenV2 aToken = IATokenV2(aTokenAddress);\n\n if (token.allowance(address(this), address(lendingPool)) < assetAmount) {\n token.approve(address(lendingPool), uint256(-1));\n }\n\n // Deposit Assets into Aave\n uint256 preBalance = aToken.balanceOf(self);\n lendingPool.deposit(assetToken, assetAmount, self, referralCode.toUint16());\n uint256 postBalance = aToken.balanceOf(self);\n uint256 aTokensAmount = postBalance.sub(preBalance);\n\n // Transfer back the Interest Tokens\n _sendToken(msg.sender, aTokenAddress, aTokensAmount);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function withdraw(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n {\n address self = address(this);\n require(_isReserveActive(assetToken), \"ABV2:E-424\");\n\n // Redeem aTokens for Asset Tokens\n lendingPool.withdraw(assetToken, assetAmount, self);\n\n // Transfer back the Asset Tokens\n _sendToken(receiver, assetToken, assetAmount);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n\n function _getReserveInterestToken(address assetToken) internal view returns (address aTokenAddress) {\n ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken);\n return config.aTokenAddress;\n }\n\n function _isReserveActive(address assetToken) internal view returns (bool) {\n ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken);\n uint256 isActiveFlag = 2 ** 56; // bit 56: reserve is active\n return (config.configuration.data & isActiveFlag) == isActiveFlag;\n }\n}\n" + }, + "contracts/v1/yield/aave/v2/IATokenV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\n\ninterface IATokenV2 {\n function balanceOf(address account) external view returns (uint256);\n}\n" + }, + "contracts/v1/yield/aave/v2/ILendingPoolAddressesProviderV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\n\ninterface ILendingPoolAddressesProviderV2 {\n function getLendingPool() external view returns (address);\n}" + }, + "contracts/v1/yield/aave/v2/ILendingPoolV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport \"./ILendingPoolAddressesProviderV2.sol\";\n\nlibrary ReserveConfiguration {\n struct Map {\n uint256 data;\n }\n}\n\nlibrary ReserveLogic {\n struct ReserveData {\n ReserveConfiguration.Map configuration;\n uint128 liquidityIndex;\n uint128 variableBorrowIndex;\n uint128 currentLiquidityRate;\n uint128 currentVariableBorrowRate;\n uint128 currentStableBorrowRate;\n uint40 lastUpdateTimestamp;\n address aTokenAddress;\n address stableDebtTokenAddress;\n address variableDebtTokenAddress;\n address interestRateStrategyAddress;\n uint8 id;\n }\n}\n\ninterface ILendingPoolV2 {\n function deposit(address reserve, uint256 amount, address onBehalfOf, uint16 referralCode) external;\n function withdraw(address reserve, uint256 amount, address to) external;\n function getReserveData(address asset) external view returns (ReserveLogic.ReserveData memory);\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericSmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"../../../lib/SmartWalletBase.sol\";\n\n\n/**\n * @notice Generic ERC20-Token Smart-Wallet Bridge\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartWallet is SmartWalletBase {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize()\n public\n {\n SmartWalletBase.initializeBase();\n }\n\n function isReserveActive(address assetToken)\n external\n override\n view\n returns (bool)\n {\n return _getPrincipal(assetToken) == 0;\n }\n\n function getReserveInterestToken(address assetToken)\n external\n override\n view\n returns (address)\n {\n return assetToken;\n }\n\n function getPrincipal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address /* assetToken */)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n return (0, 0);\n }\n\n function getTotal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getRewards(address assetToken)\n external\n override\n returns (uint256)\n {\n return IERC20(assetToken).balanceOf(address(this));\n }\n\n function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n // Track Principal\n _trackAssetToken(assetToken);\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n }\n\n function withdraw(address receiver, address /* creatorRedirect */, address assetToken)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmount(address receiver, address /* creatorRedirect */, address assetToken, uint256 assetAmount)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n if (receiverAmount >= assetAmount) {\n receiverAmount = assetAmount;\n }\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmountForCreator(\n address /* receiver */,\n address /* assetToken */,\n uint256 /* assetID */\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericSmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWalletB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"../../../lib/SmartWalletBaseB.sol\";\n\n\n/**\n * @notice Generic ERC20-Token Smart-Wallet Bridge\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartWalletB is SmartWalletBaseB {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize()\n public\n {\n SmartWalletBaseB.initializeBase();\n }\n\n function isReserveActive(address assetToken)\n external\n override\n view\n returns (bool)\n {\n return _getPrincipal(assetToken) == 0;\n }\n\n function getReserveInterestToken(address assetToken)\n external\n override\n view\n returns (address)\n {\n return assetToken;\n }\n\n function getPrincipal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address /* assetToken */, uint256 /* creatorPct */)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n return (0, 0);\n }\n\n function getTotal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getRewards(address assetToken)\n external\n override\n returns (uint256)\n {\n return IERC20(assetToken).balanceOf(address(this));\n }\n\n function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n // Track Principal\n _trackAssetToken(assetToken);\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n }\n\n function withdraw(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmount(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken, uint256 assetAmount)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n if (receiverAmount >= assetAmount) {\n receiverAmount = assetAmount;\n }\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmountForCreator(\n address /* receiver */,\n uint256 /* creatorPct */,\n address /* assetToken */,\n uint256 /* assetID */\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function refreshPrincipal(address assetToken) external virtual override onlyWalletManager {\n _assetPrincipalBalance[assetToken] = IERC20(assetToken).balanceOf(address(this));\n }\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../../lib/WalletManagerBase.sol\";\nimport \"./GenericSmartWallet.sol\";\n\n/**\n * @notice Generic ERC20 Wallet Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericWalletManager is WalletManagerBase {\n using SafeMath for uint256;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new GenericSmartWallet());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return GenericSmartWallet(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return GenericSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getTotal(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return GenericSmartWallet(_wallets[uuid]).getInterest(assetToken);\n }\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getRewards(rewardToken);\n }\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount)\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = GenericSmartWallet(wallet).deposit(assetToken, assetAmount, 0);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmountForCreator(\n address /* receiver */,\n address /* contractAddress */,\n uint256 /* tokenId */,\n address /* creator */,\n address /* assetToken */,\n uint256 /* assetAmount */\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release from interest first + principal if needed\n principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n external\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return GenericSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n // no-op\n }\n\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct)\n external\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n\n if (creator != address(0x0)) {\n GenericSmartWallet(wallet).setNftCreator(creator, annuityPct);\n }\n\n emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n GenericSmartWallet(newWallet).initialize();\n return newWallet;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericWalletManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericWalletManagerB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../../lib/WalletManagerBase.sol\";\nimport \"./GenericSmartWalletB.sol\";\n\n/**\n * @notice Generic ERC20 Wallet Manager B\n * @dev Non-upgradeable Contract\n */\ncontract GenericWalletManagerB is WalletManagerBase {\n using SafeMath for uint256;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new GenericSmartWalletB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return GenericSmartWalletB(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return GenericSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getTotal(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return GenericSmartWalletB(_wallets[uuid]).getInterest(assetToken, 0);\n }\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getRewards(rewardToken);\n }\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount)\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = GenericSmartWalletB(wallet).deposit(assetToken, assetAmount, 0);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmountForCreator(\n address /* receiver */,\n address /* contractAddress */,\n uint256 /* tokenId */,\n address /* creator */,\n address /* assetToken */,\n uint256 /* assetAmount */\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdraw(receiver, creatorRedirect, 0, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release from interest first + principal if needed\n principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdrawAmount(receiver, creatorRedirect, 0, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyControllerOrExecutor\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n external\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return GenericSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n GenericSmartWalletB(wallet).refreshPrincipal(assetToken);\n }\n\n function getWalletAddressById(address contractAddress, uint256 tokenId, address /* creator */, uint256 /* annuityPct */)\n external\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n GenericSmartWalletB(newWallet).initialize();\n return newWallet;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericBasketManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"../../../interfaces/IBasketManager.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"./GenericSmartBasket.sol\";\n\n/**\n * @notice Generic ERC721 Basket Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericBasketManager is Ownable, BlackholePrevention, IBasketManager {\n using Counters for Counters.Counter;\n using TokenInfo for address;\n\n // The Controller Contract Address\n address internal _controller;\n\n // Template Contract for creating Token Smart-Baskets\n address internal _basketTemplate;\n\n // TokenID => Token Smart-Basket Address\n mapping (uint256 => address) internal _baskets;\n\n mapping (uint256 => Counters.Counter) internal _totalTokens;\n\n // State of Basket Manager\n bool internal _paused;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _basketTemplate = address(new GenericSmartBasket());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n function getTokenTotalCount(\n address contractAddress,\n uint256 tokenId\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n return _totalTokens[uuid].current();\n }\n\n function getTokenCountByType(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n external\n override\n returns (uint256)\n {\n address basket = getBasketAddressById(contractAddress, tokenId);\n return GenericSmartBasket(basket).getTokenCountByType(basketTokenAddress, basketTokenId);\n }\n\n function prepareTransferAmount(uint256 /* nftTokenAmount */) external override onlyController {\n // no-op\n }\n\n function addToBasket(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n whenNotPaused\n returns (bool added)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n added = GenericSmartBasket(basket).addToBasket(basketTokenAddress, basketTokenId);\n\n // Log Event\n if (added) {\n _totalTokens[uuid].increment();\n emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, 1);\n }\n }\n\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n returns (bool removed)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n removed = GenericSmartBasket(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId);\n\n // Log Event\n if (removed) {\n _totalTokens[uuid].decrement();\n emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, 1);\n }\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyController\n returns (uint256 amount)\n {\n // no-op\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n public\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n return GenericSmartBasket(basket).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function getBasketAddressById(address contractAddress, uint256 tokenId)\n public\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n // Create Smart-Basket if none exists\n if (basket == address(0x0)) {\n basket = _createBasket();\n _baskets[uuid] = basket;\n\n emit NewSmartBasket(contractAddress, tokenId, basket);\n }\n\n return basket;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Basket Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartBasket(basket).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n function _createBasket()\n internal\n returns (address)\n {\n address newBasket = _createClone(_basketTemplate);\n GenericSmartBasket(newBasket).initialize();\n return newBasket;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"GBM:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"GBM:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericBasketManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport \"../../../interfaces/IBasketManager.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../interfaces/ITokenInfoProxy.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"../../../lib/NftTokenType.sol\";\nimport \"./GenericSmartBasketB.sol\";\n\n/**\n * @notice Generic ERC721 Basket Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericBasketManagerB is Ownable, BlackholePrevention, IBasketManager {\n using Counters for Counters.Counter;\n using TokenInfo for address;\n using NftTokenType for address;\n\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // The Controller Contract Address\n address internal _controller;\n\n // The Executor Contract Address\n address internal _executor;\n\n // Template Contract for creating Token Smart-Baskets\n address internal _basketTemplate;\n\n // TokenID => Token Smart-Basket Address\n mapping (uint256 => address) internal _baskets;\n\n // Prepared Amount\n uint256 internal _preparedAmount;\n\n // State of Basket Manager\n bool internal _paused;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _basketTemplate = address(new GenericSmartBasketB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n function getTokenTotalCount(\n address contractAddress,\n uint256 tokenId\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n if (basket == address(0)) { return 0; }\n return GenericSmartBasketB(basket).getNestedNftCount();\n }\n\n function getTokenCountByType(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n if (basket == address(0)) { return 0; }\n return GenericSmartBasketB(basket).getTokenCountByType(basketTokenAddress, basketTokenId);\n }\n\n function prepareTransferAmount(uint256 nftTokenAmount) external override onlyController {\n _preparedAmount = nftTokenAmount;\n }\n\n function addToBasket(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n whenNotPaused\n returns (bool added)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n uint256 nftTokenAmount = 1;\n if (_preparedAmount > 0) {\n nftTokenAmount = _preparedAmount;\n _preparedAmount = 0;\n }\n\n added = GenericSmartBasketB(basket).addToBasket(basketTokenAddress, basketTokenId, nftTokenAmount);\n if (added) {\n emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount);\n }\n }\n\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n returns (bool removed)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n uint256 nftTokenAmount = 1;\n if (_preparedAmount > 0) {\n nftTokenAmount = _preparedAmount;\n _preparedAmount = 0;\n }\n\n removed = GenericSmartBasketB(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId, nftTokenAmount);\n if (removed) {\n emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount);\n }\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyControllerOrExecutor\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartBasketB(basket).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit BasketRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n public\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n return GenericSmartBasketB(basket).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function getBasketAddressById(address contractAddress, uint256 tokenId)\n public\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n // Create Smart-Basket if none exists\n if (basket == address(0x0)) {\n basket = _createBasket();\n _baskets[uuid] = basket;\n\n emit NewSmartBasket(contractAddress, tokenId, basket);\n }\n\n return basket;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Basket Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n /**\n * @dev Connects to the ExecForAccount Controller\n */\n function setExecutor(address executor) external onlyOwner {\n _executor = executor;\n emit ExecutorSet(executor);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setTokenInfoProxy(address tokenInfoProxy) external onlyOwner {\n _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartBasket(basket).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createBasket()\n internal\n returns (address)\n {\n address newBasket = _createClone(_basketTemplate);\n GenericSmartBasketB(newBasket).initialize(_tokenInfoProxy);\n return newBasket;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"GBM:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Controller or Executor contract\n modifier onlyControllerOrExecutor() {\n require(_executor == msg.sender || _controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"GBM:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericSmartBasket.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/NftTokenType.sol\";\n\n\n/**\n * @notice Generic ERC721-Token Smart-Basket\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartBasket is ISmartBasket, BlackholePrevention, IERC721Receiver {\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableSet for EnumerableSet.AddressSet;\n using NftTokenType for address;\n\n address internal _basketManager;\n\n // NFT contract address => Token Ids in Basket\n mapping (address => mapping(uint256 => EnumerableSet.UintSet)) internal _nftContractTokens;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public {\n require(_basketManager == address(0x0), \"GSB:E-002\");\n _basketManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n return _nftContractTokens[contractAddress][nftType].length();\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver(0).onERC721Received.selector;\n }\n\n function addToBasket(address contractAddress, uint256 tokenId)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n require(!_nftContractTokens[contractAddress][nftType].contains(tokenId), \"GSB:E-425\");\n\n bool added = _nftContractTokens[contractAddress][nftType].add(tokenId);\n if (added) {\n // NFT should have been Transferred into here via Charged-Particles\n added = (IERC721(contractAddress).ownerOf(tokenId) == address(this));\n }\n return added;\n }\n\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n require(_nftContractTokens[contractAddress][nftType].contains(tokenId), \"GSB:E-426\");\n\n bool removed = _nftContractTokens[contractAddress][nftType].remove(tokenId);\n if (removed) {\n IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId);\n }\n return removed;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyBasketManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the basket manager\n modifier onlyBasketManager() {\n require(_basketManager == msg.sender, \"GSB:E-109\");\n _;\n }\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericSmartBasketB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155Receiver.sol\";\nimport \"../../../interfaces/ISmartBasketB.sol\";\nimport \"../../../interfaces/ITokenInfoProxy.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"../../../lib/NftTokenType.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\n\n/**\n * @notice Generic ERC721-Token Smart-Basket\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartBasketB is ISmartBasketB, BlackholePrevention, IERC721Receiver, ERC1155Receiver {\n using TokenInfo for address;\n using NftTokenType for address;\n\n address internal _basketManager;\n\n // NFT TokenUUID => ERC1155 Balance\n mapping (uint256 => uint256) internal _nftContractTokenBalance;\n uint256 internal _nestedNftCount;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(ITokenInfoProxy /* tokenInfoProxy */) public {\n require(_basketManager == address(0x0), \"GSB:E-002\");\n _basketManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getNestedNftCount() external view override returns (uint256) {\n return _nestedNftCount;\n }\n\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n return _nftContractTokenBalance[contractAddress.getTokenUUID(tokenId)];\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver(0).onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\n return IERC1155Receiver(0).onERC1155Received.selector;\n }\n\n // Unimplemented\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\n return \"\"; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector;\n }\n\n function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n _nftContractTokenBalance[uuid] += nftTokenAmount;\n _nestedNftCount += nftTokenAmount;\n return true;\n }\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n uint256 nftTokenAmount\n )\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n _nftContractTokenBalance[uuid] -= nftTokenAmount;\n _nestedNftCount -= nftTokenAmount;\n\n if (contractAddress.isERC1155()) {\n IERC1155(contractAddress).safeTransferFrom(address(this), receiver, tokenId, nftTokenAmount, \"\");\n } else {\n IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId);\n }\n return true;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyBasketManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSB:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyBasketManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the basket manager\n modifier onlyBasketManager() {\n require(_basketManager == msg.sender, \"GSB:E-109\");\n _;\n }\n}\n" + }, + "erc20permit/contracts/ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"./IERC2612.sol\";\n\n/**\n * @author Georgios Konstantopoulos\n * @dev Extension of {ERC20} that allows token holders to use their tokens\n * without sending any transactions by setting {IERC20-allowance} with a\n * signature using the {permit} method, and then spend them via\n * {IERC20-transferFrom}.\n *\n * The {permit} signature mechanism conforms to the {IERC2612} interface.\n */\nabstract contract ERC20Permit is ERC20, IERC2612 {\n mapping (address => uint256) public override nonces;\n\n bytes32 public immutable PERMIT_TYPEHASH = keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public immutable DOMAIN_SEPARATOR;\n\n constructor(string memory name_, string memory symbol_) internal ERC20(name_, symbol_) {\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name_)),\n keccak256(bytes(\"1\")),\n chainId,\n address(this)\n )\n );\n }\n\n /**\n * @dev See {IERC2612-permit}.\n *\n * In cases where the free option is not a concern, deadline can simply be\n * set to uint(-1), so it should be seen as an optional parameter\n */\n function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {\n require(deadline >= block.timestamp, \"ERC20Permit: expired deadline\");\n\n bytes32 hashStruct = keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n amount,\n nonces[owner]++,\n deadline\n )\n );\n\n bytes32 hash = keccak256(\n abi.encodePacked(\n '\\x19\\x01',\n DOMAIN_SEPARATOR,\n hashStruct\n )\n );\n\n address signer = ecrecover(hash, v, r, s);\n require(\n signer != address(0) && signer == owner,\n \"ERC20Permit: invalid signature\"\n );\n\n _approve(owner, spender, amount);\n }\n}\n" + }, + "erc20permit/contracts/IERC2612.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC2612 standard as defined in the EIP.\n *\n * Adds the {permit} method, which can be used to change one's\n * {IERC20-allowance} without having to send a transaction, by signing a\n * message. This allows users to spend tokens without having to hold Ether.\n *\n * See https://eips.ethereum.org/EIPS/eip-2612.\n */\ninterface IERC2612 {\n /**\n * @dev Sets `amount` 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 * - `owner` cannot be the zero address.\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(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n /**\n * @dev Returns the current ERC2612 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" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "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/deployments/mainnet/solcInputs/6c591955ea21cfe459186084b0851c19.json b/deployments/mainnet/solcInputs/6c591955ea21cfe459186084b0851c19.json new file mode 100644 index 0000000..bf677b9 --- /dev/null +++ b/deployments/mainnet/solcInputs/6c591955ea21cfe459186084b0851c19.json @@ -0,0 +1,458 @@ +{ + "language": "Solidity", + "sources": { + "@opengsn/gsn/contracts/BaseRelayRecipient.sol": { + "content": "// SPDX-License-Identifier:MIT\n// solhint-disable no-inline-assembly\npragma solidity ^0.6.2;\n\nimport \"./interfaces/IRelayRecipient.sol\";\n\n/**\n * A base contract to be inherited by any contract that want to receive relayed transactions\n * A subclass must use \"_msgSender()\" instead of \"msg.sender\"\n */\nabstract contract BaseRelayRecipient is IRelayRecipient {\n\n /*\n * Forwarder singleton we accept calls from\n */\n address public trustedForwarder;\n\n function isTrustedForwarder(address forwarder) public override view returns(bool) {\n return forwarder == trustedForwarder;\n }\n\n /**\n * return the sender of this call.\n * if the call came through our trusted forwarder, return the original sender.\n * otherwise, return `msg.sender`.\n * should be used in the contract anywhere instead of msg.sender\n */\n function _msgSender() internal override virtual view returns (address payable ret) {\n if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // so we trust that the last bytes of msg.data are the verified sender address.\n // extract sender address from the end of msg.data\n assembly {\n ret := shr(96,calldataload(sub(calldatasize(),20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n /**\n * return the msg.data of this call.\n * if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes\n * of the msg.data - so this method will strip those 20 bytes off.\n * otherwise, return `msg.data`\n * should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly\n * signing or hashing the\n */\n function _msgData() internal override virtual view returns (bytes memory ret) {\n if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // we copy the msg.data , except the last 20 bytes (and update the total length)\n assembly {\n let ptr := mload(0x40)\n // copy only size-20 bytes\n let size := sub(calldatasize(),20)\n // structure RLP data as \n mstore(ptr, 0x20)\n mstore(add(ptr,32), size)\n calldatacopy(add(ptr,64), 0, size)\n return(ptr, add(size,64))\n }\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "@opengsn/gsn/contracts/interfaces/IRelayRecipient.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.6.2;\n\n/**\n * a contract must implement this interface in order to support relayed transaction.\n * It is better to inherit the BaseRelayRecipient as its implementation.\n */\nabstract contract IRelayRecipient {\n\n /**\n * return if the forwarder is trusted to forward relayed transactions to us.\n * the forwarder is required to verify the sender's signature, and verify\n * the call is not a replay.\n */\n function isTrustedForwarder(address forwarder) public virtual view returns(bool);\n\n /**\n * return the sender of this call.\n * if the call came through our trusted forwarder, then the real sender is appended as the last 20 bytes\n * of the msg.data.\n * otherwise, return `msg.sender`\n * should be used in the contract anywhere instead of msg.sender\n */\n function _msgSender() internal virtual view returns (address payable);\n\n /**\n * return the msg.data of this call.\n * if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes\n * of the msg.data - so this method will strip those 20 bytes off.\n * otherwise, return `msg.data`\n * should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly\n * signing or hashing the\n */\n function _msgData() internal virtual view returns (bytes memory);\n\n function versionRecipient() external virtual view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\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 initializer {\n __Context_init_unchained();\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal initializer {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), 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 emit OwnershipTransferred(_owner, address(0));\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n function __ERC165_init() internal initializer {\n __ERC165_init_unchained();\n }\n\n function __ERC165_init_unchained() internal initializer {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMathUpgradeable {\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 uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\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 if (b > a) return (false, 0);\n return (true, a - b);\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 // 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 * @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 if (b == 0) return (false, 0);\n return (true, a / b);\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 if (b == 0) return (false, 0);\n return (true, a % b);\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 uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n return c;\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 require(b <= a, \"SafeMath: subtraction overflow\");\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 if (a == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n return c;\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. 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(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: division by zero\");\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 require(b > 0, \"SafeMath: modulo by zero\");\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n return a - b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a / b;\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.4.24 <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 {UpgradeableProxy-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 */\nabstract contract Initializable {\n\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 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 /// @dev Returns true if and only if the function is running in the constructor\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\n\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 )\n external\n 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 )\n external\n returns(bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC20Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../proxy/Initializable.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 guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable {\n using SafeMathUpgradeable for uint256;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal initializer {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer {\n _name = name_;\n _symbol = symbol_;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal virtual {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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(address sender, address recipient, uint256 amount) 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/ERC20/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.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 SafeERC20Upgradeable {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) 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(IERC20Upgradeable token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\n require((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(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\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(IERC20Upgradeable 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) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721MetadataUpgradeable.sol\";\nimport \"./IERC721EnumerableUpgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"../../introspection/ERC165Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/EnumerableSetUpgradeable.sol\";\nimport \"../../utils/EnumerableMapUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../proxy/Initializable.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable, IERC721EnumerableUpgradeable {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet;\n using EnumerableMapUpgradeable for EnumerableMapUpgradeable.UintToAddressMap;\n using StringsUpgradeable for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSetUpgradeable.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMapUpgradeable.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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 initializer {\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 initializer {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\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 _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\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 _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\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(_msgSender() == owner || ERC721Upgradeable.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 require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) 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(address from, address to, uint256 tokenId, bytes memory _data) 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 _tokenOwners.contains(tokenId);\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 || ERC721Upgradeable.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\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 _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(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); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(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(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721ReceiverUpgradeable(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); // internal owner\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(address from, address to, uint256 tokenId) internal virtual { }\n uint256[41] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721EnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 /**\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/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 /**\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\npragma solidity >=0.6.0 <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(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) 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 // solhint-disable-next-line avoid-low-level-calls\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(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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 // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/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 GSN 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 initializer {\n __Context_init_unchained();\n }\n\n function __Context_init_unchained() internal initializer {\n }\n function _msgSender() internal view virtual returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/EnumerableMapUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMapUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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 EnumerableSetUpgradeable {\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\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\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] = toDeleteIndex + 1; // All indexes are 1-based\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 require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\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 // 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 // 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" + }, + "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/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 initializer {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal initializer {\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 make 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/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n /**\n * @dev Converts a `uint256` to its ASCII `string` 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 uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = bytes1(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../GSN/Context.sol\";\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 */\ncontract 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 () internal {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), msgSender);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view 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 emit OwnershipTransferred(_owner, address(0));\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n" + }, + "@openzeppelin/contracts/cryptography/MerkleProof.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev These functions deal with verification of Merkle trees (hash trees),\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(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {\n bytes32 computedHash = leaf;\n\n for (uint256 i = 0; i < proof.length; i++) {\n bytes32 proofElement = proof[i];\n\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\n // Check if the computed hash (root) is equal to the provided root\n return computedHash == root;\n }\n}\n" + }, + "@openzeppelin/contracts/GSN/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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 GSN 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 payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\ncontract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () internal {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n" + }, + "@openzeppelin/contracts/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\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 uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\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 sub(a, b, \"SafeMath: subtraction overflow\");\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 * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\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 // 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) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts 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 mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\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 SafeMath for uint256;\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 * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri) public {\n _setURI(uri);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\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) external view 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 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(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\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 require(accounts[i] != address(0), \"ERC1155: batch balance query for the zero address\");\n batchBalances[i] = _balances[ids[i]][accounts[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 require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view 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 )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, 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 )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\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 _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(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 `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` 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(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, 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(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) 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 (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\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 `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, 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(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != 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, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\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 )\n internal virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).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 )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).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/token/ERC1155/ERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() public {\n _registerInterface(\n ERC1155Receiver(0).onERC1155Received.selector ^\n ERC1155Receiver(0).onERC1155BatchReceived.selector\n );\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\nimport \"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\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 )\n external\n 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 )\n external\n returns(bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.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 guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 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 {\n using SafeMath for uint256;\n using Address for address;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name, string memory symbol) public {\n _name = name;\n _symbol = symbol;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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/token/ERC20/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.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 SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\n require((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(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\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) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n\n // If there is no base URI, return the token URI.\n if (bytes(_baseURI).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(_baseURI, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(_baseURI, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_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 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 require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) 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(address from, address to, uint256 tokenId, bytes memory _data) 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 returns (bool) {\n return _tokenOwners.contains(tokenId);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = 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 d*\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\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 _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(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 = ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(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(address from, address to, uint256 tokenId) internal virtual {\n require(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 _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\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(address from, address to, uint256 tokenId) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\nimport \"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 /**\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/token/ERC721/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 /**\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/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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(address operator, address from, uint256 tokenId, bytes calldata data)\n external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 in 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 // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n return _functionCallWithValue(target, data, value, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\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 // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../math/SafeMath.sol\";\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented or decremented by one. 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 * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}\n * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never\n * directly accessed.\n */\nlibrary Counters {\n using SafeMath for uint256;\n\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 // The {SafeMath} overflow check can be skipped here, see the comment at the top\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableMap.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n return _get(map, key, \"EnumerableMap: nonexistent key\");\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(value)));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint256(value)));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint256(_get(map._inner, bytes32(key))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint256(_get(map._inner, bytes32(key), errorMessage)));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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.0.0, only sets of type `address` (`AddressSet`) and `uint256`\n * (`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\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\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] = toDeleteIndex + 1; // All indexes are 1-based\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 require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\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(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(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(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(uint256(_at(set._inner, index)));\n }\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" + }, + "@openzeppelin/contracts/utils/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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 */\ncontract 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 () internal {\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 make 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/utils/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value < 2**128, \"SafeCast: value doesn\\'t fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value < 2**64, \"SafeCast: value doesn\\'t fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value < 2**32, \"SafeCast: value doesn\\'t fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value < 2**16, \"SafeCast: value doesn\\'t fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value < 2**8, \"SafeCast: value doesn\\'t fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= -2**127 && value < 2**127, \"SafeCast: value doesn\\'t fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= -2**63 && value < 2**63, \"SafeCast: value doesn\\'t fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= -2**31 && value < 2**31, \"SafeCast: value doesn\\'t fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= -2**15 && value < 2**15, \"SafeCast: value doesn\\'t fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= -2**7 && value < 2**7, \"SafeCast: value doesn\\'t fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n require(value < 2**255, \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` 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 uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = byte(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n" + }, + "contracts/v1/ChargedManagers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Wallet-Managers Contract\n */\ncontract ChargedManagers is\n IChargedManagers,\n Initializable,\n OwnableUpgradeable,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n\n IChargedSettings internal _chargedSettings;\n IChargedState internal _chargedState;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // Wallet/Basket Managers (by Unique Manager ID)\n mapping (string => IWalletManager) internal _ftWalletManager;\n mapping (string => IBasketManager) internal _nftBasketManager;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n /// @notice Checks if an Account is the Owner of an NFT Contract\n /// When Custom Contracts are registered, only the \"owner\" or operator of the Contract\n /// is allowed to register them and define custom rules for how their tokens are \"Charged\".\n /// Otherwise, any token can be \"Charged\" according to the default rules of Charged Particles.\n /// @param contractAddress The Address to the External NFT Contract to check\n /// @param account The Account to check if it is the Owner of the specified Contract\n /// @return True if the account is the Owner of the _contract\n function isContractOwner(address contractAddress, address account) external view override virtual returns (bool) {\n return contractAddress.isContractOwner(account);\n }\n\n function isWalletManagerEnabled(string calldata walletManagerId) external virtual override view returns (bool) {\n return _isWalletManagerEnabled(walletManagerId);\n }\n\n function getWalletManager(string calldata walletManagerId) external virtual override view returns (IWalletManager) {\n return _ftWalletManager[walletManagerId];\n }\n\n function isNftBasketEnabled(string calldata basketId) external virtual override view returns (bool) {\n return _isNftBasketEnabled(basketId);\n }\n\n function getBasketManager(string calldata basketId) external virtual override view returns (IBasketManager) {\n return _nftBasketManager[basketId];\n }\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param sender The sender address to validate against\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external virtual override {\n _validateDeposit(sender, contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param sender The sender address to validate against\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external virtual override {\n _validateNftDeposit(sender, contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateDischarge(sender, contractAddress, tokenId);\n }\n\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateRelease(sender, contractAddress, tokenId);\n }\n\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateBreakBond(sender, contractAddress, tokenId);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"state\"))) {\n _chargedState = IChargedState(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n /// @dev Register Contracts as wallet managers with a unique liquidity provider ID\n function registerWalletManager(string calldata walletManagerId, address walletManager) external virtual onlyOwner {\n // Validate wallet manager\n IWalletManager newWalletMgr = IWalletManager(walletManager);\n require(newWalletMgr.isPaused() != true, \"CP:E-418\");\n\n // Register LP ID\n _ftWalletManager[walletManagerId] = newWalletMgr;\n emit WalletManagerRegistered(walletManagerId, walletManager);\n }\n\n /// @dev Register Contracts as basket managers with a unique basket ID\n function registerBasketManager(string calldata basketId, address basketManager) external virtual onlyOwner {\n // Validate basket manager\n IBasketManager newBasketMgr = IBasketManager(basketManager);\n require(newBasketMgr.isPaused() != true, \"CP:E-418\");\n\n // Register Basket ID\n _nftBasketManager[basketId] = newBasketMgr;\n emit BasketManagerRegistered(basketId, basketManager);\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev See {ChargedParticles-isWalletManagerEnabled}.\n function _isWalletManagerEnabled(string calldata walletManagerId) internal view virtual returns (bool) {\n return (address(_ftWalletManager[walletManagerId]) != address(0x0) && !_ftWalletManager[walletManagerId].isPaused());\n }\n\n /// @dev See {ChargedParticles-isNftBasketEnabled}.\n function _isNftBasketEnabled(string calldata basketId) internal view virtual returns (bool) {\n return (address(_nftBasketManager[basketId]) != address(0x0) && !_nftBasketManager[basketId].isPaused());\n }\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n internal\n virtual\n {\n if (_chargedState.isEnergizeRestricted(contractAddress, tokenId)) {\n bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender);\n require(isNFTOwnerOrOperator, \"CP:E-105\");\n }\n\n ( string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n ) = _chargedSettings.getAssetRequirements(contractAddress, assetToken);\n\n require(energizeEnabled, \"CP:E-417\");\n\n require(!invalidAsset, \"CP:E-424\");\n\n // Valid Wallet Manager?\n if (bytes(requiredWalletManager).length > 0) {\n require(keccak256(abi.encodePacked(requiredWalletManager)) == keccak256(abi.encodePacked(walletManagerId)), \"CP:E-419\");\n }\n\n // Valid Asset?\n if (restrictedAssets) {\n require(validAsset, \"CP:E-424\");\n }\n\n _validateDepositAmount(\n contractAddress,\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n depositCap,\n depositMin,\n depositMax\n );\n }\n\n /// @dev Validates a Deposit-Amount according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDepositAmount(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax\n )\n internal\n virtual\n {\n uint256 existingBalance = _ftWalletManager[walletManagerId].getPrincipal(contractAddress, tokenId, assetToken);\n uint256 newBalance = assetAmount.add(existingBalance);\n\n // Validate Deposit Cap\n if (depositCap > 0) {\n require(newBalance <= depositCap, \"CP:E-408\");\n }\n\n // Valid Amount for Deposit?\n if (depositMin > 0) {\n require(newBalance >= depositMin, \"CP:E-410\");\n }\n if (depositMax > 0) {\n require(newBalance <= depositMax, \"CP:E-410\");\n }\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n {\n // Prevent Ouroboros NFTs\n require(contractAddress.getTokenUUID(tokenId) != nftTokenAddress.getTokenUUID(nftTokenId), \"CP:E-433\");\n\n if (_chargedState.isCovalentBondRestricted(contractAddress, tokenId)) {\n bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender);\n require(isNFTOwnerOrOperator, \"CP:E-105\");\n }\n\n ( string memory requiredBasketManager,\n bool basketEnabled,\n uint256 maxNfts\n ) = _chargedSettings.getNftAssetRequirements(contractAddress, nftTokenAddress);\n\n require(basketEnabled, \"CP:E-417\");\n\n // Valid Basket Manager?\n if (bytes(requiredBasketManager).length > 0) {\n require(keccak256(abi.encodePacked(requiredBasketManager)) == keccak256(abi.encodePacked(basketManagerId)), \"CP:E-419\");\n }\n\n if (maxNfts > 0) {\n uint256 tokenCount = _nftBasketManager[basketManagerId].getTokenTotalCount(contractAddress, tokenId);\n require(maxNfts >= (tokenCount + nftTokenAmount), \"CP:E-427\");\n }\n }\n\n function _validateDischarge(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getDischargeState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateRelease(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getReleaseState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateBreakBond(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getBreakBondState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateState(\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n internal\n view\n virtual\n {\n if (!allowFromAll) {\n require(isApproved, \"CP:E-105\");\n }\n if (timelock > 0) {\n require(block.number >= timelock, \"CP:E-302\");\n }\n if (tempLockExpiry > 0) {\n require(block.number >= tempLockExpiry, \"CP:E-303\");\n }\n }\n}\n" + }, + "contracts/v1/ChargedParticles.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\n\nimport \"./interfaces/IUniverse.sol\";\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/IWalletManager.sol\";\nimport \"./interfaces/IBasketManager.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/RelayRecipient.sol\";\n\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles V2 Contract\n * @dev Upgradeable Contract\n */\ncontract ChargedParticles is\n IChargedParticles,\n Initializable,\n OwnableUpgradeable,\n ReentrancyGuardUpgradeable,\n RelayRecipient,\n IERC721ReceiverUpgradeable,\n BlackholePrevention,\n IERC1155ReceiverUpgradeable\n{\n using SafeMathUpgradeable for uint256;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using Bitwise for uint32;\n using AddressUpgradeable for address;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n //\n // Particle Terminology\n //\n // Particle - Non-fungible Token (NFT)\n // Mass - Underlying Asset of a Token (ex; DAI)\n // Charge - Accrued Interest on the Underlying Asset of a Token\n // Charged Particle - Any NFT that has a Mass and a Positive Charge\n // Neutral Particle - Any NFT that has a Mass and No Charge\n // Energize / Recharge - Deposit of an Underlying Asset into an NFT\n // Discharge - Withdraw the Accrued Interest of an NFT leaving the Particle with its initial Mass\n // Release - Withdraw the Underlying Asset & Accrued Interest of an NFT leaving the Particle with No Mass or Charge\n //\n // Proton - NFTs minted from the Charged Particle Accelerator\n // - A proton is a subatomic particle, symbol p or p⁺, with a positive electric charge of +1e elementary\n // charge and a mass slightly less than that of a neutron.\n // Ion - Platform Governance Token\n // - A charged subatomic particle. An atom or group of atoms that carries a positive or negative electric charge\n // as a result of having lost or gained one or more electrons.\n //\n\n // Linked Contracts\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n address internal _lepton;\n uint256 internal depositFee;\n ITokenInfoProxy internal _tokenInfoProxy;\n IChargedManagers internal _chargedManagers;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n __ReentrancyGuard_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getStateAddress() external view virtual override returns (address stateAddress) {\n return address(_chargedState);\n }\n\n function getSettingsAddress() external view virtual override returns (address settingsAddress) {\n return address(_chargedSettings);\n }\n\n function getManagersAddress() external view virtual override returns (address managersAddress) {\n return address(_chargedManagers);\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external virtual override returns (bytes4) {\n return IERC721ReceiverUpgradeable(0).onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external virtual override returns (bytes4) {\n return IERC1155ReceiverUpgradeable(0).onERC1155Received.selector;\n }\n\n // Unimplemented\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external virtual override returns (bytes4) {\n return \"\"; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector;\n }\n\n function supportsInterface(bytes4 /* interfaceId */) external view virtual override returns (bool) {\n return false;\n }\n\n /// @notice Calculates the amount of Fees to be paid for a specific deposit amount\n /// @param assetAmount The Amount of Assets to calculate Fees on\n /// @return protocolFee The amount of deposit fees for the protocol\n function getFeesForDeposit(\n uint256 assetAmount\n )\n external\n override\n view\n returns (uint256 protocolFee)\n {\n protocolFee = _getFeesForDeposit(assetAmount);\n }\n\n /// @notice Gets the Amount of Asset Tokens that have been Deposited into the Particle\n /// representing the Mass of the Particle.\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Asset balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The Amount of underlying Assets held within the Token\n function baseParticleMass(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _baseParticleMass(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the amount of Interest that the Particle has generated representing\n /// the Charge of the Particle\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Interest balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The amount of interest the Token has generated (in Asset Token)\n function currentParticleCharge(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _currentParticleCharge(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the amount of LP Tokens that the Particle has generated representing\n /// the Kinetics of the Particle\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Kinetics balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The amount of LP tokens that have been generated\n function currentParticleKinetics(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _currentParticleKinetics(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the total amount of ERC721 Tokens that the Particle holds\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param basketManagerId The ID of the BasketManager to check the token balance of\n /// @return The total amount of ERC721 tokens that are held within the Particle\n function currentParticleCovalentBonds(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId\n )\n external\n view\n virtual\n override\n basketEnabled(basketManagerId)\n returns (uint256)\n {\n return _currentParticleCovalentBonds(contractAddress, tokenId, basketManagerId);\n }\n\n\n /***********************************|\n | Energize Particles |\n |__________________________________*/\n\n /// @notice Fund Particle with Asset Token\n /// Must be called by the account providing the Asset\n /// Account must Approve THIS contract as Operator of Asset\n ///\n /// NOTE: DO NOT Energize an ERC20 Token, as anyone who holds any amount\n /// of the same ERC20 token could discharge or release the funds.\n /// All holders of the ERC20 token would essentially be owners of the Charged Particle.\n ///\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param walletManagerId The Asset-Pair to Energize the Token with\n /// @param assetToken The Address of the Asset Token being used\n /// @param assetAmount The Amount of Asset Token to Energize the Token with\n /// @return yieldTokensAmount The amount of Yield-bearing Tokens added to the escrow for the Token\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 yieldTokensAmount)\n {\n _validateDeposit(contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n\n // Transfer ERC20 Token from Caller to Contract (reverts on fail)\n uint256 feeAmount = _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n yieldTokensAmount = _depositIntoWalletManager(contractAddress, tokenId, walletManagerId, assetToken, assetAmount, feeAmount);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onEnergize(_msgSender(), referrer, contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n }\n\n\n /***********************************|\n | Discharge Particles |\n |__________________________________*/\n\n /// @notice Allows the owner or operator of the Token to collect or transfer the interest generated\n /// from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @return creatorAmount Amount of Asset Token discharged to the Creator\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateDischarge(contractAddress, tokenId);\n\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).discharge(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount);\n }\n }\n\n /// @notice Allows the owner or operator of the Token to collect or transfer a specific amount of the interest\n /// generated from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @param assetAmount The specific amount of Asset Token to Discharge from the Token\n /// @return creatorAmount Amount of Asset Token discharged to the Creator\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateDischarge(contractAddress, tokenId);\n\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).dischargeAmount(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n assetAmount,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount);\n }\n }\n\n /// @notice Allows the Creator of the Token to collect or transfer a their portion of the interest (if any)\n /// generated from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @param assetAmount The specific amount of Asset Token to Discharge from the Particle\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 receiverAmount)\n {\n address sender = _msgSender();\n address tokenCreator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId);\n require(sender == tokenCreator, \"CP:E-104\");\n\n receiverAmount = _chargedManagers.getWalletManager(walletManagerId).dischargeAmountForCreator(\n receiver,\n contractAddress,\n tokenId,\n sender,\n assetToken,\n assetAmount\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischargeForCreator(contractAddress, tokenId, walletManagerId, sender, assetToken, receiverAmount);\n }\n }\n\n\n /***********************************|\n | Release Particles |\n |__________________________________*/\n\n /// @notice Releases the Full amount of Asset + Interest held within the Particle by LP of the Assets\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Release\n /// @param tokenId The ID of the Token to Release\n /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token\n /// @param assetToken The Address of the Asset Token being released\n /// @return creatorAmount Amount of Asset Token released to the Creator\n /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount)\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateRelease(contractAddress, tokenId);\n\n // Release Particle to Receiver\n uint256 principalAmount;\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).release(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n }\n\n\n /// @notice Releases a partial amount of Asset + Interest held within the Particle by LP of the Assets\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Release\n /// @param tokenId The ID of the Token to Release\n /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token\n /// @param assetToken The Address of the Asset Token being released\n /// @param assetAmount The specific amount of Asset Token to Release from the Particle\n /// @return creatorAmount Amount of Asset Token released to the Creator\n /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount)\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateRelease(contractAddress, tokenId);\n\n // Release Particle to Receiver\n uint256 principalAmount;\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).releaseAmount(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n assetAmount,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n }\n\n\n /***********************************|\n | Covalent Bonding |\n |__________________________________*/\n\n /// @notice Deposit other NFT Assets into the Particle\n /// Must be called by the account providing the Asset\n /// Account must Approve THIS contract as Operator of Asset\n ///\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n basketEnabled(basketManagerId)\n nonReentrant\n returns (bool success)\n {\n _validateNftDeposit(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Transfer ERC721 Token from Caller to Contract (reverts on fail)\n _collectNftToken(_msgSender(), nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n success = _depositIntoBasketManager(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onCovalentBond(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n }\n\n /// @notice Release NFT Assets from the Particle\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Withdraw (ERC1155-specific)\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n basketEnabled(basketManagerId)\n nonReentrant\n returns (bool success)\n {\n _validateBreakBond(contractAddress, tokenId);\n\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked(\"generic\"))) {\n basketMgr.prepareTransferAmount(nftTokenAmount);\n }\n\n // Release Particle to Receiver\n success = basketMgr.removeFromBasket(\n receiver,\n contractAddress,\n tokenId,\n nftTokenAddress,\n nftTokenId\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onCovalentBreak(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"universe\"))) {\n _universe = IUniverse(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"state\"))) {\n _chargedState = IChargedState(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"managers\"))) {\n _chargedManagers = IChargedManagers(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"leptons\"))) {\n _lepton = controller;\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"forwarder\"))) {\n trustedForwarder = controller;\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n\n /***********************************|\n | Protocol Fees |\n |__________________________________*/\n\n /// @dev Setup the Base Deposit Fee for the Protocol\n function setDepositFee(uint256 fee) external onlyOwner {\n require(fee < PERCENTAGE_SCALE, \"CP:E-421\");\n depositFee = fee;\n emit DepositFeeSet(fee);\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n internal\n virtual\n {\n _chargedManagers.validateDeposit(_msgSender(), contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _validateNftDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n {\n _chargedManagers.validateNftDeposit(_msgSender(), contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function _validateDischarge(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateDischarge(_msgSender(), contractAddress, tokenId);\n }\n\n function _validateRelease(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateRelease(_msgSender(), contractAddress, tokenId);\n }\n\n function _validateBreakBond(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateBreakBond(_msgSender(), contractAddress, tokenId);\n }\n\n /// @dev Deposit Asset Tokens into an NFT via the Wallet Manager\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n /// @param feeAmount The Amount of Protocol Fees charged\n function _depositIntoWalletManager(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 feeAmount\n )\n internal\n virtual\n returns (uint256)\n {\n // Get Wallet-Manager for LP\n IWalletManager lpWalletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n address wallet = lpWalletMgr.getWalletAddressById(contractAddress, tokenId, creator, annuityPct);\n IERC20Upgradeable(assetToken).transfer(wallet, assetAmount);\n\n emit ProtocolFeesCollected(assetToken, assetAmount, feeAmount);\n\n return lpWalletMgr.energize(contractAddress, tokenId, assetToken, assetAmount);\n }\n\n /// @dev Deposit NFT Tokens into the Basket Manager\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @param basketManagerId The Wallet Manager of the Assets to Deposit\n /// @param nftTokenAddress The Address of the Asset Token to Deposit\n /// @param nftTokenId The specific amount of Asset Token to Deposit\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _depositIntoBasketManager(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n returns (bool)\n {\n // Deposit NFT Token directly into Smart Wallet (reverts on fail) and Update BasketManager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId);\n\n if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked(\"generic\"))) {\n basketMgr.prepareTransferAmount(nftTokenAmount);\n }\n\n if (_isERC1155(nftTokenAddress)) {\n if (nftTokenAmount == 0) { nftTokenAmount = 1; }\n IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(address(this), wallet, nftTokenId, nftTokenAmount, \"\");\n } else {\n IERC721Upgradeable(nftTokenAddress).transferFrom(address(this), wallet, nftTokenId);\n }\n return basketMgr.addToBasket(contractAddress, tokenId, nftTokenAddress, nftTokenId);\n }\n\n /**\n * @dev Calculates the amount of Fees to be paid for a specific deposit amount\n * Fees are calculated in Interest-Token as they are the type collected for Fees\n * @param assetAmount The Amount of Assets to calculate Fees on\n * @return protocolFee The amount of fees reserved for the protocol\n */\n function _getFeesForDeposit(\n uint256 assetAmount\n )\n internal\n view\n returns (uint256 protocolFee)\n {\n if (depositFee > 0) {\n protocolFee = assetAmount.mul(depositFee).div(PERCENTAGE_SCALE);\n }\n }\n\n /// @dev Collects the Required ERC20 Token(s) from the users wallet\n /// Be sure to Approve this Contract to transfer your Token(s)\n /// @param from The owner address to collect the tokens from\n /// @param tokenAddress The addres of the token to transfer\n /// @param tokenAmount The amount of tokens to collect\n function _collectAssetToken(address from, address tokenAddress, uint256 tokenAmount) internal virtual returns (uint256 protocolFee) {\n protocolFee = _getFeesForDeposit(tokenAmount);\n IERC20Upgradeable(tokenAddress).safeTransferFrom(from, address(this), tokenAmount.add(protocolFee));\n }\n\n /// @dev Collects the Required ERC721 Token(s) from the users wallet\n /// Be sure to Approve this Contract to transfer your Token(s)\n /// @param from The owner address to collect the tokens from\n /// @param nftTokenAddress The address of the NFT token to transfer\n /// @param nftTokenId The ID of the NFT token to transfer\n /// @param nftTokenAmount The amount of Tokens to Transfer (ERC1155-specific)\n function _collectNftToken(address from, address nftTokenAddress, uint256 nftTokenId, uint256 nftTokenAmount) internal virtual {\n if (_isERC1155(nftTokenAddress)) {\n IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId, nftTokenAmount, \"\");\n } else {\n IERC721Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId);\n }\n }\n\n /// @dev Checks if an NFT token contract supports the ERC1155 standard interface\n function _isERC1155(address nftTokenAddress) internal view virtual returns (bool) {\n bytes4 _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n return IERC165Upgradeable(nftTokenAddress).supportsInterface(_INTERFACE_ID_ERC1155);\n }\n\n /// @dev See {ChargedParticles-baseParticleMass}.\n function _baseParticleMass(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n return _chargedManagers.getWalletManager(walletManagerId).getPrincipal(contractAddress, tokenId, assetToken);\n }\n\n /// @dev See {ChargedParticles-currentParticleCharge}.\n function _currentParticleCharge(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n (, uint256 ownerInterest) = _chargedManagers.getWalletManager(walletManagerId).getInterest(contractAddress, tokenId, assetToken);\n return ownerInterest;\n }\n\n /// @dev See {ChargedParticles-currentParticleKinetics}.\n function _currentParticleKinetics(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n return _chargedManagers.getWalletManager(walletManagerId).getRewards(contractAddress, tokenId, assetToken);\n }\n\n /// @dev See {ChargedParticles-currentParticleCovalentBonds}.\n function _currentParticleCovalentBonds(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId\n )\n internal\n view\n virtual\n returns (uint256)\n {\n return _chargedManagers.getBasketManager(basketManagerId).getTokenTotalCount(contractAddress, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier managerEnabled(string calldata walletManagerId) {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"CP:E-419\");\n _;\n }\n\n modifier basketEnabled(string calldata basketManagerId) {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"CP:E-419\");\n _;\n }\n}\n" + }, + "contracts/v1/ChargedSettings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/RelayRecipient.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\nimport \"./lib/TokenInfoProxy.sol\";\n\n/**\n * @notice Charged Particles Settings Contract\n */\ncontract ChargedSettings is\n IChargedSettings,\n Initializable,\n OwnableUpgradeable,\n RelayRecipient,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using Bitwise for uint32;\n\n uint256 constant internal MAX_ANNUITIES = 1e4; // 10000 (100%)\n\n // NftSettings - actionPerms\n uint32 constant internal PERM_CHARGE_NFT = 1; // NFT Contracts that can have assets Deposited into them (Charged)\n uint32 constant internal PERM_BASKET_NFT = 2; // NFT Contracts that can have other NFTs Deposited into them\n uint32 constant internal PERM_TIMELOCK_ANY_NFT = 4; // NFT Contracts that can timelock any NFT on behalf of users (primarily used for Front-run Protection)\n uint32 constant internal PERM_TIMELOCK_OWN_NFT = 8; // NFT Contracts that can timelock their own NFTs on behalf of their users\n uint32 constant internal PERM_RESTRICTED_ASSETS = 16; // NFT Contracts that have restricted deposits to specific assets\n\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // Current Settings for External NFT Token Contracts;\n // - Any user can add any ERC721 or ERC1155 token as a Charged Particle without Limits,\n // unless the Owner of the ERC721 or ERC1155 token contract registers the token\n // and sets the Custom Settings for their token(s)\n mapping (address => uint32) internal _nftActionPerms;\n\n mapping (address => string) internal _nftRequiredWalletManager;\n mapping (address => string) internal _nftRequiredBasketManager;\n\n // ERC20\n mapping (address => mapping(address => bool)) internal _nftAllowedAssetTokens;\n mapping (address => mapping (address => uint256)) internal _nftDepositMin;\n mapping (address => mapping (address => uint256)) internal _nftDepositMax;\n\n // ERC721 / ERC1155\n mapping (address => mapping (address => uint256)) internal _nftMaxNfts; // NFT Token Address => Max\n\n // Optional Configs for individual NFTs set by NFT Creator (by Token UUID)\n mapping (uint256 => uint256) internal _creatorAnnuityPercent;\n mapping (uint256 => address) internal _creatorAnnuityRedirect;\n\n mapping (address => uint256) internal _depositCap;\n uint256 internal _tempLockExpiryBlocks;\n\n // Blacklist for non-compliant tokens\n mapping (address => bool) internal _invalidAssets;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n /// @dev Gets the amount of creator annuities reserved for the creator for the specified NFT\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @return creator The address of the creator\n /// @return annuityPct The percentage amount of annuities reserved for the creator\n function getCreatorAnnuities(\n address contractAddress,\n uint256 tokenId\n )\n external\n override\n virtual\n returns (address creator, uint256 annuityPct)\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n creator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId);\n annuityPct = _creatorAnnuityPercent[tokenUuid];\n }\n\n function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId)\n external\n view\n override\n virtual\n returns (address)\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _creatorAnnuityRedirect[tokenUuid];\n }\n\n function getTempLockExpiryBlocks() external view override virtual returns (uint256) {\n return _tempLockExpiryBlocks;\n }\n\n function getTimelockApprovals(address operator)\n external\n view\n override\n virtual\n returns (bool timelockAny, bool timelockOwn)\n {\n timelockAny = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_ANY_NFT);\n timelockOwn = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_OWN_NFT);\n }\n\n function getAssetRequirements(address contractAddress, address assetToken)\n external\n view\n override\n virtual\n returns (\n string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n )\n {\n requiredWalletManager = _nftRequiredWalletManager[contractAddress];\n energizeEnabled = _nftActionPerms[contractAddress].hasBit(PERM_CHARGE_NFT);\n restrictedAssets = _nftActionPerms[contractAddress].hasBit(PERM_RESTRICTED_ASSETS);\n validAsset = _nftAllowedAssetTokens[contractAddress][assetToken];\n depositCap = _depositCap[assetToken];\n depositMin = _nftDepositMin[contractAddress][assetToken];\n depositMax = _nftDepositMax[contractAddress][assetToken];\n invalidAsset = _invalidAssets[assetToken];\n }\n\n function getNftAssetRequirements(address contractAddress, address nftTokenAddress)\n external\n view\n override\n virtual\n returns (string memory requiredBasketManager, bool basketEnabled, uint256 maxNfts)\n {\n requiredBasketManager = _nftRequiredBasketManager[contractAddress];\n basketEnabled = _nftActionPerms[contractAddress].hasBit(PERM_BASKET_NFT);\n maxNfts = _nftMaxNfts[contractAddress][nftTokenAddress];\n }\n\n\n /***********************************|\n | Only NFT Creator |\n |__________________________________*/\n\n /// @notice Sets the Custom Configuration for Creators of Proton-based NFTs\n /// @param contractAddress The Address to the Proton-based NFT to configure\n /// @param tokenId The token ID of the Proton-based NFT to configure\n /// @param creator The creator of the Proton-based NFT\n /// @param annuityPercent The percentage of interest-annuities to reserve for the creator\n function setCreatorAnnuities(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent\n )\n external\n virtual\n override\n {\n require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), \"CP:E-104\");\n _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent);\n }\n\n /// @notice Sets a Custom Receiver Address for the Creator Annuities\n /// @param contractAddress The Address to the Proton-based NFT to configure\n /// @param tokenId The token ID of the Proton-based NFT to configure\n /// @param receiver The receiver of the Creator interest-annuities\n function setCreatorAnnuitiesRedirect(\n address contractAddress,\n uint256 tokenId,\n address receiver\n )\n external\n virtual\n override\n {\n require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), \"CP:E-104\");\n _setCreatorAnnuitiesRedirect(contractAddress, tokenId, receiver);\n }\n\n\n /***********************************|\n | Register Contract Settings |\n |(For External Contract Integration)|\n |__________________________________*/\n\n /// @notice Sets a Required Wallet-Manager for External NFT Contracts (otherwise set to \"none\" to allow any Wallet-Manager)\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param walletManager If set, will only allow deposits from this specific Wallet-Manager\n function setRequiredWalletManager(\n address contractAddress,\n string calldata walletManager\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (keccak256(bytes(walletManager)) == keccak256(bytes(\"none\"))) {\n _nftRequiredWalletManager[contractAddress] = \"\";\n } else {\n _nftRequiredWalletManager[contractAddress] = walletManager;\n }\n\n emit RequiredWalletManagerSet(\n contractAddress,\n walletManager\n );\n }\n\n /// @notice Sets a Required Basket-Manager for External NFT Contracts (otherwise set to \"none\" to allow any Basket-Manager)\n /// @param contractAddress The Address to the External Contract to configure\n /// @param basketManager If set, will only allow deposits from this specific Basket-Manager\n function setRequiredBasketManager(\n address contractAddress,\n string calldata basketManager\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (keccak256(bytes(basketManager)) == keccak256(bytes(\"none\"))) {\n _nftRequiredBasketManager[contractAddress] = \"\";\n } else {\n _nftRequiredBasketManager[contractAddress] = basketManager;\n }\n\n emit RequiredBasketManagerSet(\n contractAddress,\n basketManager\n );\n }\n\n /// @notice Enables or Disables Asset-Token Restrictions for External NFT Contracts\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param restrictionsEnabled If set, will only allow deposits from Allowed Asset Tokens\n function setAssetTokenRestrictions(\n address contractAddress,\n bool restrictionsEnabled\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (restrictionsEnabled) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_RESTRICTED_ASSETS);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_RESTRICTED_ASSETS);\n }\n\n emit AssetTokenRestrictionsSet(\n contractAddress,\n restrictionsEnabled\n );\n }\n\n /// @notice Enables or Disables Allowed Asset Tokens for External NFT Contracts\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param assetToken The Address of the Asset Token to Allow or Disallow\n /// @param isAllowed True if the Asset Token is allowed\n function setAllowedAssetToken(\n address contractAddress,\n address assetToken,\n bool isAllowed\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftAllowedAssetTokens[contractAddress][assetToken] = isAllowed;\n\n emit AllowedAssetTokenSet(\n contractAddress,\n assetToken,\n isAllowed\n );\n }\n\n /// @notice Sets the Custom Configuration for External Contracts\n /// @param contractAddress The Address to the External Contract to configure\n /// @param assetToken The address of the Asset Token to set Limits for\n /// @param depositMin If set, will define the minimum amount of Asset tokens the NFT may hold, otherwise any amount\n /// @param depositMax If set, will define the maximum amount of Asset tokens the NFT may hold, otherwise any amount\n function setAssetTokenLimits(\n address contractAddress,\n address assetToken,\n uint256 depositMin,\n uint256 depositMax\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftDepositMin[contractAddress][assetToken] = depositMin;\n _nftDepositMax[contractAddress][assetToken] = depositMax;\n\n emit AssetTokenLimitsSet(\n contractAddress,\n assetToken,\n depositMin,\n depositMax\n );\n }\n\n /// @notice Sets the Max Number of NFTs that can be held by a Charged Particle NFT\n /// @param contractAddress The Address to the External Contract to configure\n /// @param nftTokenAddress The address of the NFT Token to set a Max for\n /// @param maxNfts The maximum numbers of NFTs that can be held by a given NFT (0 = unlimited)\n function setMaxNfts(\n address contractAddress,\n address nftTokenAddress,\n uint256 maxNfts\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftMaxNfts[contractAddress][nftTokenAddress] = maxNfts;\n\n emit MaxNftsSet(\n contractAddress,\n nftTokenAddress,\n maxNfts\n );\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n function setAssetInvalidity(address assetToken, bool invalidity) external virtual override onlyOwner {\n _invalidAssets[assetToken] = invalidity;\n emit AssetInvaliditySet(assetToken, invalidity);\n }\n\n function setDepositCap(address assetToken, uint256 cap) external virtual onlyOwner {\n _depositCap[assetToken] = cap;\n emit DepositCapSet(assetToken, cap);\n }\n\n function setTempLockExpiryBlocks(uint256 numBlocks) external virtual onlyOwner {\n _tempLockExpiryBlocks = numBlocks;\n emit TempLockExpirySet(numBlocks);\n }\n\n function enableNftContracts(address[] calldata contracts) external override virtual onlyOwner {\n uint count = contracts.length;\n for (uint i = 0; i < count; i++) {\n address tokenContract = contracts[i];\n _setPermsForCharge(tokenContract, true);\n _setPermsForBasket(tokenContract, true);\n _setPermsForTimelockSelf(tokenContract, true);\n }\n }\n\n function migrateToken(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent,\n address annuityReceiver\n )\n external\n onlyOwner\n {\n _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent);\n if (annuityReceiver != address(0)) {\n _setCreatorAnnuitiesRedirect(contractAddress, tokenId, annuityReceiver);\n }\n }\n\n /// @dev Update the list of NFT contracts that can be Charged\n function setPermsForCharge(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForCharge(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can hold other NFTs\n function setPermsForBasket(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForBasket(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection\n function setPermsForTimelockAny(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForTimelockAny(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock their own tokens\n function setPermsForTimelockSelf(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForTimelockSelf(contractAddress, state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Update the list of NFT contracts that can be Charged\n function _setPermsForCharge(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_CHARGE_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_CHARGE_NFT);\n }\n emit PermsSetForCharge(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can hold other NFTs\n function _setPermsForBasket(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_BASKET_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_BASKET_NFT);\n }\n emit PermsSetForBasket(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection\n function _setPermsForTimelockAny(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_ANY_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_ANY_NFT);\n }\n emit PermsSetForTimelockAny(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock their own tokens\n function _setPermsForTimelockSelf(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_OWN_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_OWN_NFT);\n }\n emit PermsSetForTimelockSelf(contractAddress, state);\n }\n\n /// @dev see setCreatorAnnuities()\n function _setCreatorAnnuities(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent\n )\n internal\n virtual\n {\n require(annuityPercent <= MAX_ANNUITIES, \"CP:E-421\");\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Update Configs for External Token Creator\n _creatorAnnuityPercent[tokenUuid] = annuityPercent;\n\n emit TokenCreatorConfigsSet(\n contractAddress,\n tokenId,\n creator,\n annuityPercent\n );\n }\n\n /// @dev see setCreatorAnnuitiesRedirect()\n function _setCreatorAnnuitiesRedirect(\n address contractAddress,\n uint256 tokenId,\n address receiver\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _creatorAnnuityRedirect[tokenUuid] = receiver;\n emit TokenCreatorAnnuitiesRedirected(contractAddress, tokenId, receiver);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyValidExternalContract(address contractAddress) {\n require(contractAddress.isContract(), \"CP:E-420\");\n _;\n }\n\n modifier onlyContractOwnerOrAdmin(address contractAddress, address sender) {\n require(sender == owner() || contractAddress.isContractOwner(sender), \"CP:E-103\");\n _;\n }\n}\n" + }, + "contracts/v1/ChargedState.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedState.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/RelayRecipient.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Settings Contract\n */\ncontract ChargedState is\n IChargedState,\n Initializable,\n OwnableUpgradeable,\n RelayRecipient,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using Bitwise for uint32;\n\n // NftState - actionPerms\n uint32 constant internal PERM_RESTRICT_ENERGIZE_FROM_ALL = 1; // NFTs that have Restrictions on Energize\n uint32 constant internal PERM_ALLOW_DISCHARGE_FROM_ALL = 2; // NFTs that allow Discharge by anyone\n uint32 constant internal PERM_ALLOW_RELEASE_FROM_ALL = 4; // NFTs that allow Release by anyone\n uint32 constant internal PERM_RESTRICT_BOND_FROM_ALL = 8; // NFTs that have Restrictions on Covalent Bonds\n uint32 constant internal PERM_ALLOW_BREAK_BOND_FROM_ALL = 16; // NFTs that allow Breaking Covalent Bonds by anyone\n\n IChargedSettings internal _chargedSettings;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // NftTimelocks\n /// @dev discharge unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftDischargeTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftDischargeTimelockLockedBy;\n\n /// @dev release unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftReleaseTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftReleaseTimelockLockedBy;\n\n /// @dev release unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftBreakBondTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftBreakBondTimelockLockedBy;\n\n // NftState\n /// @dev maps nft by tokenId to actionPermissions uint32 which is a composite of all possible NftState - actionPerms\n mapping (uint256 => uint32) internal _nftActionPerms;\n\n /// @dev maps nft by tokenId to its tempLockExpiry\n mapping (uint256 => uint256) internal _nftTempLockExpiry;\n\n /// @dev maps tokenId to user address to operator address for approving various actions\n mapping (uint256 => mapping(address => address)) internal _nftDischargeApproval;\n mapping (uint256 => mapping(address => address)) internal _nftReleaseApproval;\n mapping (uint256 => mapping(address => address)) internal _nftBreakBondApproval;\n mapping (uint256 => mapping(address => address)) internal _nftTimelockApproval;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftDischargeTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftDischargeTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftReleaseTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftReleaseTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftBreakBondTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftBreakBondTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n\n /// @notice Checks if an operator is allowed to Discharge a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForDischarge(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Release a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForRelease(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Break Covalent Bonds on a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForBreakBond(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Timelock a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForTimelock(contractAddress, tokenId, operator);\n }\n\n\n function isEnergizeRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n }\n\n\n function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_BOND_FROM_ALL);\n }\n\n\n function getDischargeState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n isApproved = _isApprovedForDischarge(contractAddress, tokenId, sender);\n timelock = _nftDischargeTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n function getReleaseState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_RELEASE_FROM_ALL);\n isApproved = _isApprovedForRelease(contractAddress, tokenId, sender);\n timelock = _nftReleaseTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n function getBreakBondState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n isApproved = _isApprovedForBreakBond(contractAddress, tokenId, sender);\n timelock = _nftBreakBondTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n\n /***********************************|\n | Only NFT Owner/Operator |\n |__________________________________*/\n\n /// @notice Sets an Operator as Approved to Discharge a specific Token\n /// This allows an operator to withdraw the interest-portion only\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setDischargeApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Release a specific Token\n /// This allows an operator to withdraw the principal + interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setReleaseApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token\n /// This allows an operator to withdraw Basket NFTs\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setBreakBondApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Timelock a specific Token\n /// This allows an operator to timelock the principal or interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setTimelockApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Discharge/Release/Timelock a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setApprovalForAll(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @dev Updates Restrictions on Energizing an NFT\n function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForRestrictCharge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowDischarge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowRelease(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Restrictions on Covalent Bonds on an NFT\n function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForRestrictBond(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone\n function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowBreakBond(contractAddress, tokenId, state);\n }\n\n /// @notice Sets a Timelock on the ability to Discharge the Interest of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setDischargeTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftDischargeTimelockLockedBy[tokenUuid] == sender) {\n delete _nftDischargeTimelockUnlockBlock[tokenUuid];\n delete _nftDischargeTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftDischargeTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftDischargeTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftDischargeTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenDischargeTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n /// @notice Sets a Timelock on the ability to Release the Assets of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setReleaseTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftReleaseTimelockLockedBy[tokenUuid] == sender) {\n delete _nftReleaseTimelockUnlockBlock[tokenUuid];\n delete _nftReleaseTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftReleaseTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftReleaseTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftReleaseTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenReleaseTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n /// @notice Sets a Timelock on the ability to Break the Covalent Bond of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setBreakBondTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftBreakBondTimelockLockedBy[tokenUuid] == sender) {\n delete _nftBreakBondTimelockUnlockBlock[tokenUuid];\n delete _nftBreakBondTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftBreakBondTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftBreakBondTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftBreakBondTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenBreakBondTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n\n /***********************************|\n | Only NFT Contract |\n |__________________________________*/\n\n /// @notice Sets a Temporary-Lock on the ability to Release/Discharge the Assets of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param isLocked The locked state; contracts are expected to disable this lock before expiry\n function setTemporaryLock(\n address contractAddress,\n uint256 tokenId,\n bool isLocked\n )\n external\n override\n virtual\n {\n require(msg.sender == contractAddress, \"CP:E-112\");\n\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n uint256 unlockBlock;\n if (isLocked && _nftTempLockExpiry[tokenUuid] == 0) {\n unlockBlock = block.number.add(_chargedSettings.getTempLockExpiryBlocks());\n _nftTempLockExpiry[tokenUuid] = unlockBlock;\n }\n if (!isLocked) {\n _nftTempLockExpiry[tokenUuid] = 0;\n }\n\n emit TokenTempLock(contractAddress, tokenId, unlockBlock);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n function migrateToken(\n address contractAddress,\n uint256 tokenId,\n uint256 releaseTimelockExpiry,\n address releaseTimelockLockedBy,\n uint256 tempLockExpiry\n )\n external\n onlyOwner\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (releaseTimelockExpiry > block.number && releaseTimelockLockedBy != address(0)) {\n _nftReleaseTimelockUnlockBlock[tokenUuid] = releaseTimelockExpiry;\n _nftReleaseTimelockLockedBy[tokenUuid] = releaseTimelockLockedBy;\n emit TokenReleaseTimelock(contractAddress, tokenId, releaseTimelockLockedBy, releaseTimelockExpiry);\n }\n\n if (tempLockExpiry > 0) {\n _nftTempLockExpiry[tokenUuid] = tempLockExpiry;\n emit TokenTempLock(contractAddress, tokenId, tempLockExpiry);\n }\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev See {ChargedParticles-isApprovedForDischarge}.\n function _isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftDischargeApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForRelease}.\n function _isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftReleaseApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForBreakBond}.\n function _isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftBreakBondApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForTimelock}.\n function _isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n (bool timelockAny, bool timelockOwn) = _chargedSettings.getTimelockApprovals(operator);\n if (timelockAny || (timelockOwn && contractAddress == operator)) { return true; }\n\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return tokenOwner == operator || _nftTimelockApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @notice Sets an Operator as Approved to Discharge a specific Token\n /// This allows an operator to withdraw the interest-portion only\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setDischargeApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftDischargeApproval[tokenUuid][tokenOwner] = operator;\n emit DischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Release a specific Token\n /// This allows an operator to withdraw the principal + interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setReleaseApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftReleaseApproval[tokenUuid][tokenOwner] = operator;\n emit ReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token\n /// This allows an operator to withdraw Basket NFTs\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setBreakBondApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftBreakBondApproval[tokenUuid][tokenOwner] = operator;\n emit BreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Timelock a specific Token\n /// This allows an operator to timelock the principal or interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setTimelockApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftTimelockApproval[tokenUuid][tokenOwner] = operator;\n emit TimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @dev Updates Restrictions on Energizing an NFT\n function _setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n }\n emit PermsSetForRestrictCharge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function _setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n }\n emit PermsSetForAllowDischarge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function _setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_RELEASE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_RELEASE_FROM_ALL);\n }\n emit PermsSetForAllowRelease(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Restrictions on Covalent Bonds on an NFT\n function _setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_BOND_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_BOND_FROM_ALL);\n }\n emit PermsSetForRestrictBond(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone\n function _setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n }\n emit PermsSetForAllowBreakBond(contractAddress, tokenId, state);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) {\n require(_tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender), \"CP:E-105\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/CommunityVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract CommunityVault is Ownable, BlackholePrevention {\n\n IERC20 private immutable _ionx;\n\n constructor (address ionx) public {\n _ionx = IERC20(ionx);\n }\n\n event SetAllowance(address indexed caller, address indexed spender, uint256 amount);\n\n function setAllowance(address spender, uint amount) public onlyOwner {\n _ionx.approve(spender, amount);\n\n emit SetAllowance(msg.sender, spender, amount);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens other than IONX, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n require(tokenAddress != address(_ionx), \"CommunityVault: cannot withdraw IONX\");\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n}" + }, + "contracts/v1/incentives/MerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_) public {\n token = token_;\n merkleRoot = merkleRoot_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), 'MerkleDistributor: Drop already claimed.');\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), 'MerkleDistributor: Invalid proof.');\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), 'MerkleDistributor: Transfer failed.');\n\n emit Claimed(index, account, amount);\n }\n}\n" + }, + "contracts/v1/incentives/MerkleDistributor2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor2 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"MerkleDistributor2: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"MerkleDistributor2: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor2: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"MerkleDistributor2: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"MerkleDistributor2: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"MerkleDistributor2: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/MerkleDistributor3.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor3 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"MerkleDistributor3: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"MerkleDistributor3: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor3: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"MerkleDistributor3: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"MerkleDistributor3: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"MerkleDistributor3: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/RewardProgram.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// RewardProgram.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/IRewardProgram.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/introspection/IERC165.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"../interfaces/IUniverseRP.sol\";\nimport \"../interfaces/IChargedManagers.sol\";\nimport \"../interfaces/IWalletManager.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IERC20Detailed.sol\";\n\ncontract RewardProgram is\n IRewardProgram,\n BlackholePrevention,\n IERC165,\n ReentrancyGuard,\n IERC721Receiver,\n IERC1155Receiver\n{\n using SafeMath for uint256;\n using TokenInfo for address;\n using SafeERC20 for IERC20;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n\n address private _owner;\n IUniverseRP private _universe;\n IChargedManagers private _chargedManagers;\n ProgramRewardData private _programData;\n mapping(uint256 => AssetStake) private _assetStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public {}\n\n function initialize(\n address stakingToken,\n address rewardToken,\n uint256 baseMultiplier,\n address chargedManagers,\n address universe,\n address owner\n ) external override {\n require(_owner == address(0x0), \"Already initialized\");\n _owner = owner;\n\n // Prepare Reward Program\n _programData.stakingToken = stakingToken;\n _programData.rewardToken = rewardToken;\n _programData.baseMultiplier = baseMultiplier; // Basis Points\n\n // Connect to Charged Particles\n _chargedManagers = IChargedManagers(chargedManagers);\n _universe = IUniverseRP(universe);\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getProgramData() external view override returns (ProgramRewardData memory) {\n return _programData;\n }\n\n function getAssetStake(uint256 parentNftUuid) external view override returns (AssetStake memory) {\n return _assetStake[parentNftUuid];\n }\n\n function getFundBalance() external view override returns (uint256) {\n return _getFundBalance();\n }\n\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) public view override returns (uint256) {\n return _calculateRewardsEarned(parentNftUuid, interestAmount);\n }\n\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n return _assetStake[parentNftUuid].claimableRewards;\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\n return \"\";\n }\n\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(IERC165)\n returns (bool)\n {\n // default interface support\n if (\n interfaceId == type(IERC721Receiver).interfaceId ||\n interfaceId == type(IERC1155Receiver).interfaceId ||\n interfaceId == type(IERC165).interfaceId\n ) {\n return true;\n }\n }\n\n function owner() public view returns (address) {\n return _owner;\n }\n\n\n /***********************************|\n | Only Universe |\n |__________________________________*/\n\n function registerAssetDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n uint256 principalAmount\n )\n external\n override\n onlyUniverse\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n if (assetStake.start == 0) {\n assetStake.start = block.number;\n assetStake.walletManagerId = walletManagerId;\n }\n emit AssetDeposit(contractAddress, tokenId, walletManagerId, principalAmount);\n }\n\n function registerAssetRelease(\n address contractAddress,\n uint256 tokenId,\n uint256 interestAmount\n )\n external\n override\n onlyUniverse\n nonReentrant\n returns (uint256 rewards)\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n if (assetStake.start > 0) {\n // Update Claimable Rewards\n uint256 newRewards = _calculateRewardsEarned(parentNftUuid, interestAmount);\n assetStake.claimableRewards = assetStake.claimableRewards.add(newRewards);\n\n // Reset Stake if Principal Balance falls to Zero\n IWalletManager walletMgr = _chargedManagers.getWalletManager(assetStake.walletManagerId);\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\n if (principal == 0) {\n assetStake.start = 0;\n }\n\n // Issue Rewards to NFT Owner\n rewards = _claimRewards(contractAddress, tokenId);\n\n emit AssetRelease(contractAddress, tokenId, interestAmount);\n }\n }\n\n\n /***********************************|\n | Reward Calculation |\n |__________________________________*/\n\n function _calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) internal view returns (uint256 totalReward) {\n uint256 baseReward = _calculateBaseReward(interestAmount);\n uint256 leptonMultipliedReward = _calculateMultipliedReward(parentNftUuid, baseReward);\n totalReward = _convertDecimals(leptonMultipliedReward);\n }\n\n function _calculateBaseReward(uint256 amount) internal view returns(uint256 baseReward) {\n baseReward = amount.mul(_programData.baseMultiplier).div(PERCENTAGE_SCALE);\n }\n\n function _calculateMultipliedReward(uint256 parentNftUuid, uint256 baseReward) internal view returns(uint256) {\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n if (assetStake.start == 0) { return baseReward; }\n\n IUniverseRP.NftStake memory nftStake = _universe.getNftStake(parentNftUuid);\n uint256 multiplierBP = nftStake.multiplier;\n\n uint256 assetDepositLength = block.number.sub(assetStake.start);\n uint256 nftDepositLength = 0;\n if (nftStake.releaseBlockNumber > 0) {\n nftDepositLength = nftStake.releaseBlockNumber.sub(nftStake.depositBlockNumber);\n } else {\n nftDepositLength = block.number.sub(nftStake.depositBlockNumber);\n }\n\n if (multiplierBP == 0 || nftDepositLength == 0 || assetDepositLength == 0) {\n return baseReward;\n }\n\n if (nftDepositLength > assetDepositLength) {\n nftDepositLength = assetDepositLength;\n }\n\n // Percentage of the total program that the Multiplier Nft was deposited for\n uint256 nftRewardRatioBP = nftDepositLength.mul(PERCENTAGE_SCALE).div(assetDepositLength);\n\n // Amount of reward that the Multiplier Nft is responsible for\n uint256 amountGeneratedDuringNftDeposit = baseReward.mul(nftRewardRatioBP).div(PERCENTAGE_SCALE);\n\n // Amount of Multiplied Reward from NFT\n uint256 multipliedReward = amountGeneratedDuringNftDeposit.mul(multiplierBP.mul(LEPTON_MULTIPLIER_SCALE)).div(PERCENTAGE_SCALE);\n\n // Amount of Base Reward without Multiplied NFT Rewards\n uint256 amountGeneratedWithoutNftDeposit = baseReward.sub(amountGeneratedDuringNftDeposit);\n\n // Amount of Base Rewards + Multiplied NFT Rewards\n return amountGeneratedWithoutNftDeposit.add(multipliedReward);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function fundProgram(uint256 amount) external onlyOwner {\n require(_programData.rewardToken != address(0), \"RP:E-405\");\n IERC20(_programData.rewardToken).safeTransferFrom(msg.sender, address(this), amount);\n emit RewardProgramFunded(amount);\n }\n\n function setStakingToken(address newStakingToken) external onlyOwner {\n _programData.stakingToken = newStakingToken;\n }\n\n function setRewardToken(address newRewardToken) external onlyOwner {\n _programData.rewardToken = newRewardToken;\n }\n\n function setBaseMultiplier(uint256 newMultiplier) external onlyOwner {\n _programData.baseMultiplier = newMultiplier; // Basis Points\n }\n\n function setChargedManagers(address manager) external onlyOwner {\n _chargedManagers = IChargedManagers(manager);\n }\n\n function setUniverse(address universe) external onlyOwner {\n _universe = IUniverseRP(universe);\n }\n\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external override onlyOwner {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n\n // Initiate Asset Stake\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\n if (principal > 0) {\n _assetStake[parentNftUuid] = AssetStake(block.number, 0, walletManagerId);\n emit AssetRegistered(contractAddress, tokenId, walletManagerId, principal);\n }\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _claimRewards(\n address contractAddress,\n uint256 tokenId\n )\n internal\n returns (uint256 totalReward)\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n // Rewards Receiver\n address receiver = IERC721(contractAddress).ownerOf(tokenId);\n\n // Ensure Reward Pool has Sufficient Balance\n totalReward = assetStake.claimableRewards;\n uint256 fundBalance = _getFundBalance();\n uint256 unavailReward = totalReward > fundBalance ? totalReward.sub(fundBalance) : 0;\n\n // Determine amount of Rewards to Transfer\n if (unavailReward > 0) {\n totalReward = totalReward.sub(unavailReward);\n emit RewardProgramOutOfFunds();\n }\n\n // Update Asset Stake\n assetStake.claimableRewards = unavailReward;\n\n if (totalReward > 0) {\n // Transfer Available Rewards to Receiver\n IERC20(_programData.rewardToken).safeTransfer(receiver, totalReward);\n }\n\n emit RewardsClaimed(contractAddress, tokenId, receiver, totalReward, unavailReward);\n }\n\n function _convertDecimals(uint256 reward) internal view returns (uint256) {\n uint8 stakingTokenDecimals = IERC20Detailed(_programData.stakingToken).decimals();\n return reward.mul(10**(18 - uint256(stakingTokenDecimals)));\n }\n\n function _getFundBalance() internal view returns (uint256) {\n return IERC20Detailed(_programData.rewardToken).balanceOf(address(this));\n }\n\n\n modifier onlyOwner() {\n require(_owner == msg.sender, \"Caller is not the owner\");\n _;\n }\n\n modifier onlyUniverse() {\n require(msg.sender == address(_universe), \"RP:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/RewardProgramFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// RewardProgramFactory.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport \"./RewardProgram.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract RewardProgramFactory is BlackholePrevention, Ownable {\n event RewardProgramCreated(address indexed rewardProgram);\n\n address public _template;\n\n constructor () public {\n _template = address(new RewardProgram());\n }\n\n // function _msgSender() internal view override returns (address payable) {\n // return msg.sender;\n // }\n\n function createRewardProgram(\n address stakingToken,\n address rewardToken,\n uint256 baseMultiplier,\n address chargedManagers,\n address universe\n )\n external\n onlyOwner\n returns (address)\n {\n address newRewardProgram = _createClone(_template);\n RewardProgram rewardProgram = RewardProgram(newRewardProgram);\n rewardProgram.initialize(stakingToken, rewardToken, baseMultiplier, chargedManagers, universe, _msgSender());\n emit RewardProgramCreated(newRewardProgram);\n return newRewardProgram;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n}\n" + }, + "contracts/v1/incentives/Staking.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/Staking2.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking2 is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/Staking3.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking3 is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/YieldFarm.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/incentives/YieldFarm2.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm2 is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/incentives/YieldFarm3.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm3 is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/interfaces/IAaveBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IAaveBridge.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n\ninterface IAaveBridge {\n function getReserveInterestToken(address assetToken) external view returns (address aTokenAddress);\n function isReserveActive(address assetToken) external view returns (bool);\n\n function getTotalBalance(address account, address assetToken) external view returns (uint256);\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(address receiver, address assetToken, uint256 assetAmount) external;\n}\n" + }, + "contracts/v1/interfaces/IBaseProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IBaseProton is IERC721 {\n event PausedStateSet(bool isPaused);\n event SalePriceSet(uint256 indexed tokenId, uint256 salePrice);\n event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct);\n event FeesWithdrawn(address indexed receiver, uint256 amount);\n event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties);\n event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view returns (address);\n function getSalePrice(uint256 tokenId) external view returns (uint256);\n function getLastSellPrice(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyalties(address account) external view returns (uint256);\n function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address);\n\n function buyProton(uint256 tokenId, uint256 gasLimit) external payable returns (bool);\n function claimCreatorRoyalties() external returns (uint256);\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n ) external returns (uint256 newTokenId);\n\n function createProtons(\n address creator,\n address receiver,\n string[] calldata tokenMetaUris\n ) external returns (bool);\n\n function createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n ) external returns (bool);\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice) external;\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external;\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external;\n}" + }, + "contracts/v1/interfaces/IBasketManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Particle Basket Manager interface\n * @dev The basket-manager for underlying assets attached to Charged Particles\n * @dev Manages the link between NFTs and their respective Smart-Baskets\n */\ninterface IBasketManager {\n\n event ControllerSet(address indexed controller);\n event ExecutorSet(address indexed executor);\n event PausedStateSet(bool isPaused);\n event NewSmartBasket(address indexed contractAddress, uint256 indexed tokenId, address indexed smartBasket);\n event BasketAdd(address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\n event BasketRemove(address indexed receiver, address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\n event BasketRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\n event RewardProgramSet(address indexed rewardProgram);\n\n function isPaused() external view returns (bool);\n\n function getTokenTotalCount(address contractAddress, uint256 tokenId) external view returns (uint256);\n function getTokenCountByType(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (uint256);\n\n function prepareTransferAmount(uint256 nftTokenAmount) external;\n function addToBasket(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function getBasketAddressById(address contractAddress, uint256 tokenId) external returns (address);\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/IChargedManagers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IWalletManager.sol\";\nimport \"./IBasketManager.sol\";\n\n/**\n * @notice Interface for Charged Wallet-Managers\n */\ninterface IChargedManagers {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function isContractOwner(address contractAddress, address account) external view returns (bool);\n\n // ERC20\n function isWalletManagerEnabled(string calldata walletManagerId) external view returns (bool);\n function getWalletManager(string calldata walletManagerId) external view returns (IWalletManager);\n\n // ERC721\n function isNftBasketEnabled(string calldata basketId) external view returns (bool);\n function getBasketManager(string calldata basketId) external view returns (IBasketManager);\n\n // Validation\n function validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external;\n function validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external;\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external;\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event WalletManagerRegistered(string indexed walletManagerId, address indexed walletManager);\n event BasketManagerRegistered(string indexed basketId, address indexed basketManager);\n}\n" + }, + "contracts/v1/interfaces/IChargedParticles.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Charged Particles\n */\ninterface IChargedParticles {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getStateAddress() external view returns (address stateAddress);\n function getSettingsAddress() external view returns (address settingsAddress);\n function getManagersAddress() external view returns (address managersAddress);\n\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\n\n /***********************************|\n | Particle Mechanics |\n |__________________________________*/\n\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n ) external returns (uint256 yieldTokensAmount);\n\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 receiverAmount);\n\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositFeeSet(uint256 depositFee);\n event ProtocolFeesCollected(address indexed assetToken, uint256 depositAmount, uint256 feesCollected);\n}\n" + }, + "contracts/v1/interfaces/IChargedSettings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IWalletManager.sol\";\nimport \"./IBasketManager.sol\";\n\n/**\n * @notice Interface for Charged Settings\n */\ninterface IChargedSettings {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n // function isContractOwner(address contractAddress, address account) external view returns (bool);\n function getCreatorAnnuities(address contractAddress, uint256 tokenId) external returns (address creator, uint256 annuityPct);\n function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId) external view returns (address);\n function getTempLockExpiryBlocks() external view returns (uint256);\n function getTimelockApprovals(address operator) external view returns (bool timelockAny, bool timelockOwn);\n function getAssetRequirements(\n address contractAddress,\n address assetToken\n ) external view returns (\n string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n );\n function getNftAssetRequirements(\n address contractAddress,\n address nftTokenAddress\n ) external view returns (\n string memory requiredBasketManager,\n bool basketEnabled,\n uint256 maxNfts\n );\n\n /***********************************|\n | Only NFT Creator |\n |__________________________________*/\n\n function setCreatorAnnuities(address contractAddress, uint256 tokenId, address creator, uint256 annuityPercent) external;\n function setCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId, address receiver) external;\n\n\n /***********************************|\n | Only NFT Contract Owner |\n |__________________________________*/\n\n function setRequiredWalletManager(address contractAddress, string calldata walletManager) external;\n function setRequiredBasketManager(address contractAddress, string calldata basketManager) external;\n function setAssetTokenRestrictions(address contractAddress, bool restrictionsEnabled) external;\n function setAllowedAssetToken(address contractAddress, address assetToken, bool isAllowed) external;\n function setAssetTokenLimits(address contractAddress, address assetToken, uint256 depositMin, uint256 depositMax) external;\n function setMaxNfts(address contractAddress, address nftTokenAddress, uint256 maxNfts) external;\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAssetInvalidity(address assetToken, bool invalidity) external;\n function enableNftContracts(address[] calldata contracts) external;\n function setPermsForCharge(address contractAddress, bool state) external;\n function setPermsForBasket(address contractAddress, bool state) external;\n function setPermsForTimelockAny(address contractAddress, bool state) external;\n function setPermsForTimelockSelf(address contractAddress, bool state) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositCapSet(address assetToken, uint256 depositCap);\n event TempLockExpirySet(uint256 expiryBlocks);\n\n event RequiredWalletManagerSet(address indexed contractAddress, string walletManager);\n event RequiredBasketManagerSet(address indexed contractAddress, string basketManager);\n event AssetTokenRestrictionsSet(address indexed contractAddress, bool restrictionsEnabled);\n event AllowedAssetTokenSet(address indexed contractAddress, address assetToken, bool isAllowed);\n event AssetTokenLimitsSet(address indexed contractAddress, address assetToken, uint256 assetDepositMin, uint256 assetDepositMax);\n event MaxNftsSet(address indexed contractAddress, address indexed nftTokenAddress, uint256 maxNfts);\n event AssetInvaliditySet(address indexed assetToken, bool invalidity);\n\n event TokenCreatorConfigsSet(address indexed contractAddress, uint256 indexed tokenId, address indexed creatorAddress, uint256 annuityPercent);\n event TokenCreatorAnnuitiesRedirected(address indexed contractAddress, uint256 indexed tokenId, address indexed redirectAddress);\n\n event PermsSetForCharge(address indexed contractAddress, bool state);\n event PermsSetForBasket(address indexed contractAddress, bool state);\n event PermsSetForTimelockAny(address indexed contractAddress, bool state);\n event PermsSetForTimelockSelf(address indexed contractAddress, bool state);\n}\n" + }, + "contracts/v1/interfaces/IChargedState.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IChargedSettings.sol\";\n\n/**\n * @notice Interface for Charged State\n */\ninterface IChargedState {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n\n function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n\n function isEnergizeRestricted(address contractAddress, uint256 tokenId) external view returns (bool);\n function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external view returns (bool);\n\n function getDischargeState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n function getReleaseState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n function getBreakBondState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n\n /***********************************|\n | Only NFT Owner/Operator |\n |__________________________________*/\n\n function setDischargeApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setReleaseApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setBreakBondApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setTimelockApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setApprovalForAll(address contractAddress, uint256 tokenId, address operator) external;\n\n function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) external;\n\n function setDischargeTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n function setReleaseTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n function setBreakBondTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n /***********************************|\n | Only NFT Contract |\n |__________________________________*/\n\n function setTemporaryLock(\n address contractAddress,\n uint256 tokenId,\n bool isLocked\n ) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n\n event DischargeApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event ReleaseApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event BreakBondApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event TimelockApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n\n event TokenDischargeTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenReleaseTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenBreakBondTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenTempLock(address indexed contractAddress, uint256 indexed tokenId, uint256 unlockBlock);\n\n event PermsSetForRestrictCharge(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowDischarge(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowRelease(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForRestrictBond(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowBreakBond(address indexed contractAddress, uint256 indexed tokenId, bool state);\n}\n" + }, + "contracts/v1/interfaces/IDai.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\ninterface IDai is IERC20Upgradeable {\n // --- Approve by signature ---\n function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external;\n function transferFrom(address src, address dst, uint wad) external override returns (bool);\n}" + }, + "contracts/v1/interfaces/IERC20Detailed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Detailed {\n function decimals() external view returns (uint8);\n function symbol() external view returns (string memory);\n function name() external view returns (string memory);\n\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(address sender, address recipient, uint256 amount) 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" + }, + "contracts/v1/interfaces/IERC721Chargeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IERC721Chargeable.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\n\ninterface IERC721Chargeable is IERC165Upgradeable {\n function owner() external view returns (address);\n function creatorOf(uint256 tokenId) external view returns (address);\n function balanceOf(address tokenOwner) external view returns (uint256 balance);\n function ownerOf(uint256 tokenId) external view returns (address tokenOwner);\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n function transferFrom(address from, address to, uint256 tokenId) external;\n function approve(address to, uint256 tokenId) external;\n function getApproved(uint256 tokenId) external view returns (address operator);\n function setApprovalForAll(address operator, bool _approved) external;\n function isApprovedForAll(address tokenOwner, address operator) external view returns (bool);\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "contracts/v1/interfaces/ILepton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ILepton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Lepton Interface\n * @dev ...\n */\ninterface ILepton {\n\n struct Classification {\n string tokenUri;\n uint256 price;\n uint128 _upperBounds;\n uint32 supply;\n uint32 multiplier;\n uint32 bonus;\n }\n\n function mintLepton() external payable returns (uint256 newTokenId);\n function batchMintLepton(uint256 count) external payable;\n function getNextType() external view returns (uint256);\n function getNextPrice() external view returns (uint256);\n function getMultiplier(uint256 tokenId) external view returns (uint256);\n function getBonus(uint256 tokenId) external view returns (uint256);\n\n\n event MaxMintPerTxSet(uint256 maxAmount);\n event LeptonTypeAdded(string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\n event LeptonTypeUpdated(uint256 leptonIndex, string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\n event LeptonMinted(address indexed receiver, uint256 indexed tokenId, uint256 price, uint32 multiplier);\n event LeptonBatchMinted(address indexed receiver, uint256 indexed tokenId, uint256 count, uint256 price, uint32 multiplier);\n event PausedStateSet(bool isPaused);\n}\n" + }, + "contracts/v1/interfaces/IMerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.6.0;\n\n// Allows anyone to claim a token if they exist in a merkle root.\ninterface IMerkleDistributor {\n // Returns the address of the token distributed by this contract.\n function token() external view returns (address);\n // Returns the merkle root of the merkle tree containing account balances available to claim.\n function merkleRoot() external view returns (bytes32);\n // Returns true if the index has been marked claimed.\n function isClaimed(uint256 index) external view returns (bool);\n // Claim the given amount of the token to the given address. Reverts if the inputs are invalid.\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external;\n\n // This event is triggered whenever a call to #claim succeeds.\n event Claimed(uint256 index, address account, uint256 amount);\n}" + }, + "contracts/v1/interfaces/IParticleSplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IParticleSplitter.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Particle Splitter\n */\ninterface IParticleSplitter {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function executeForWallet(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address externalAddress,\n bytes memory encodedParams\n ) external payable returns (bytes memory);\n\n function executeForBasket(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address externalAddress,\n bytes memory encodedParams\n ) external payable returns (bytes memory);\n\n function withdrawWalletRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n ) external returns (uint256 amountWithdrawn);\n\n function withdrawBasketRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n ) external returns (uint256 amountWithdrawn);\n\n function refreshWalletPrincipal(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external;\n\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event ChargedManagersSet(address indexed chargedManagers);\n event TokenInfoProxySet(address indexed tokenInfoProxy);\n\n event ExecuteForWallet(\n address indexed contractAddress,\n uint256 tokenId,\n string walletManagerId,\n address indexed externalAddress,\n bytes encodedParams,\n uint256 ethValue\n );\n event ExecuteForBasket(\n address indexed contractAddress,\n uint256 tokenId,\n string basketManagerId,\n address indexed externalAddress,\n bytes encodedParams,\n uint256 ethValue\n );\n event PrincipalRefreshed(\n address contractAddress,\n uint256 tokenId,\n string walletManagerId,\n address assetToken\n );\n event PermsSetForExternal(\n address indexed contractAddress,\n bool state\n );\n}\n" + }, + "contracts/v1/interfaces/IProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IProton is IERC721 {\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n event PausedStateSet(bool isPaused);\n event SalePriceSet(uint256 indexed tokenId, uint256 salePrice);\n event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct);\n event FeesWithdrawn(address indexed receiver, uint256 amount);\n event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties);\n event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view returns (address);\n function getSalePrice(uint256 tokenId) external view returns (uint256);\n function getLastSellPrice(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyalties(address account) external view returns (uint256);\n function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address);\n\n function buyProton(uint256 tokenId) external payable returns (bool);\n function claimCreatorRoyalties() external returns (uint256);\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n ) external returns (uint256 newTokenId);\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n ) external returns (uint256 newTokenId);\n\n function batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n ) external;\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice) external;\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external;\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external;\n}" + }, + "contracts/v1/interfaces/IProtonB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IProtonB is IERC721 {\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n ) external returns (uint256 newTokenId);\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n}" + }, + "contracts/v1/interfaces/IRewardNft.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IRewardNft.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Reward-NFT Interface\n * @dev ...\n */\ninterface IRewardNft {\n function getMultiplier(uint256 tokenId) external view returns (uint256);\n function getBonus(uint256 tokenId) external view returns (uint256);\n}\n" + }, + "contracts/v1/interfaces/IRewardProgram.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IRewardProgram.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\ninterface IRewardProgram {\n /* admin events */\n event RewardProgramFunded(uint256 amount);\n event RewardProgramOutOfFunds();\n\n /* user events */\n event RewardsClaimed(address indexed contractAddress, uint256 tokenId, address indexed receiver, uint256 rewarded, uint256 remaining);\n\n event AssetRegistered(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\n event AssetDeposit(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\n event AssetRelease(address indexed contractAddress, uint256 tokenId, uint256 interestAmount);\n\n /* data types */\n struct ProgramRewardData {\n address stakingToken;\n address rewardToken;\n uint256 baseMultiplier; // Basis Points\n }\n\n struct AssetStake {\n uint256 start;\n uint256 claimableRewards;\n string walletManagerId;\n }\n\n function initialize(address stakingToken, address rewardToken, uint256 baseMultiplier, address chargedManagers, address universe, address owner) external;\n\n /* user functions */\n function getProgramData() external view returns (ProgramRewardData memory programData);\n function getAssetStake(uint256 uuid) external view returns (AssetStake memory);\n function getFundBalance() external view returns (uint256);\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) external view returns (uint256);\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external;\n function registerAssetDeposit(address contractAddress, uint256 tokenId, string calldata walletManagerId, uint256 principalAmount) external;\n function registerAssetRelease(address contractAddress, uint256 tokenId, uint256 interestAmount) external returns (uint256 rewards);\n}" + }, + "contracts/v1/interfaces/ISmartBasket.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartBasket.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Basket\n * @dev Manages holding and transferring NFTs within an NFT (if any),\n */\ninterface ISmartBasket {\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function addToBasket(address contractAddress, uint256 tokenId) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId) external returns (bool);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartBasketB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartBasketB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Basket \"B\"\n * @dev Manages holding and transferring NFTs within an NFT (if any),\n */\ninterface ISmartBasketB {\n function getNestedNftCount() external view returns (uint256);\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool);\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Wallet\n * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any),\n */\ninterface ISmartWallet {\n function getAssetTokenCount() external view returns (uint256);\n function getAssetTokenByIndex(uint256 index) external view returns (address);\n\n function setNftCreator(address creator, uint256 annuityPct) external;\n\n function isReserveActive(address assetToken) external view returns (bool);\n function getReserveInterestToken(address assetToken) external view returns (address);\n\n function getPrincipal(address assetToken) external returns (uint256);\n function getInterest(address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getTotal(address assetToken) external returns (uint256);\n function getRewards(address assetToken) external returns (uint256);\n\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(address receiver, address creatorRedirect, address assetToken) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function withdrawAmount(address receiver, address creatorRedirect, address assetToken, uint256 assetAmount) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function withdrawAmountForCreator(address receiver, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address assetToken) external;\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Wallet\n * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any),\n */\ninterface ISmartWalletB {\n function getAssetTokenCount() external view returns (uint256);\n function getAssetTokenByIndex(uint256 index) external view returns (address);\n\n function isReserveActive(address assetToken) external view returns (bool);\n function getReserveInterestToken(address assetToken) external view returns (address);\n\n function getPrincipal(address assetToken) external returns (uint256);\n function getInterest(address assetToken, uint256 creatorPct) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getTotal(address assetToken) external returns (uint256);\n function getRewards(address assetToken) external returns (uint256);\n\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken\n ) external returns (\n uint256 creatorAmount,\n uint256 receiverAmount\n );\n function withdrawAmount(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n ) external returns (\n uint256 creatorAmount,\n uint256 receiverAmount\n );\n function withdrawAmountForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n ) external returns (\n uint256 receiverAmount\n );\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address assetToken) external;\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/IStaking.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\ninterface IStaking {\n function manualEpochInit(address[] memory tokens, uint128 epochId) external;\n function getCurrentEpoch() external view returns (uint128);\n function getEpochId(uint timestamp) external view returns (uint); // get epoch id\n function getEpochUserBalance(address user, address token, uint128 epoch) external view returns(uint);\n function getEpochPoolSize(address token, uint128 epoch) external view returns (uint);\n function epoch1Start() external view returns (uint);\n function epochDuration() external view returns (uint);\n}" + }, + "contracts/v1/interfaces/ITokenInfoProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfoProxy.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\n\ninterface ITokenInfoProxy {\n\n event ContractFunctionSignatureSet(address indexed contractAddress, string fnName, bytes4 fnSig);\n\n struct FnSignatures {\n bytes4 ownerOf;\n bytes4 creatorOf;\n }\n\n function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external;\n function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external;\n\n function getTokenUUID(address contractAddress, uint256 tokenId) external pure returns (uint256);\n function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external returns (bool);\n function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external returns (bool);\n function getTokenOwner(address contractAddress, uint256 tokenId) external returns (address);\n function getTokenCreator(address contractAddress, uint256 tokenId) external returns (address);\n}\n" + }, + "contracts/v1/interfaces/IUniverse.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IUniverse.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Universal Controller interface\n * @dev ...\n */\ninterface IUniverse {\n\n event ChargedParticlesSet(address indexed chargedParticles);\n event PhotonSet(address indexed photonToken, uint256 maxSupply);\n event ProtonTokenSet(address indexed protonToken);\n event LeptonTokenSet(address indexed leptonToken);\n event QuarkTokenSet(address indexed quarkToken);\n event BosonTokenSet(address indexed bosonToken);\n event EsaMultiplierSet(address indexed assetToken, uint256 multiplier);\n event ElectrostaticAttraction(address indexed account, address photonSource, uint256 energy, uint256 multiplier);\n event ElectrostaticDischarge(address indexed account, address photonSource, uint256 energy);\n\n function onEnergize(\n address sender,\n address referrer,\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 assetEnergy\n ) external;\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n ) external;\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address creator,\n address assetToken,\n uint256 receiverEnergy\n ) external;\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 principalEnergy,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n ) external;\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n ) external;\n}\n" + }, + "contracts/v1/interfaces/IUniverseRP.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IUniverseRP.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport \"./IUniverse.sol\";\n\n/**\n * @title Universal Controller interface for Rewards Program\n * @dev ...\n */\ninterface IUniverseRP is IUniverse {\n event RewardProgramSet(address indexed assetToken, address indexed rewardProgram);\n event RewardProgramRemoved(address indexed assetToken);\n event NftDeposit(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\n event NftRelease(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\n\n struct NftStake {\n uint256 multiplier; // in Basis Points\n uint256 depositBlockNumber;\n uint256 releaseBlockNumber;\n }\n\n function getRewardProgram(address asset) external view returns (address);\n function getNftStake(uint256 uuid) external view returns (NftStake memory);\n}\n" + }, + "contracts/v1/interfaces/IWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Particle Wallet Manager interface\n * @dev The wallet-manager for underlying assets attached to Charged Particles\n * @dev Manages the link between NFTs and their respective Smart-Wallets\n */\ninterface IWalletManager {\n\n event ControllerSet(address indexed controller);\n event ExecutorSet(address indexed executor);\n event PausedStateSet(bool isPaused);\n event NewSmartWallet(address indexed contractAddress, uint256 indexed tokenId, address indexed smartWallet, address creator, uint256 annuityPct);\n event WalletEnergized(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 assetAmount, uint256 yieldTokensAmount);\n event WalletDischarged(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 creatorAmount, uint256 receiverAmount);\n event WalletDischargedForCreator(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, address creator, uint256 receiverAmount);\n event WalletReleased(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address assetToken, uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n event WalletRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\n\n function isPaused() external view returns (bool);\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view returns (bool);\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view returns (address);\n\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\n function getInterest(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken) external returns (uint256);\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount) external returns (uint256 yieldTokensAmount);\n function discharge(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function dischargeAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function dischargeAmountForCreator(address receiver, address contractAddress, uint256 tokenId, address creator, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\n function release(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n function releaseAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken) external;\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct) external returns (address);\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\n}\n" + }, + "contracts/v1/leptons/store.sol": { + "content": "pragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../tokens/Ionx.sol\";\nimport \"../tokens/Lepton2.sol\";\n\ninterface ILepsonsStore {\n function load(uint256 amount) external payable;\n function setLepton(address _lepton) external;\n}\n\ncontract LeptonsStore is ILepsonsStore, IERC721Receiver, Ownable, BlackholePrevention {\n using SafeMath for uint256;\n\n event SoldLepton(address indexed buyer, uint256 amount, uint256 price);\n\n Lepton2 public lepton;\n Ionx public ionx;\n\n uint256 public nextTokenId;\n uint256 public ionxPerLepton;\n\n constructor(address _lepton, address _ionx, uint256 _ionxPerLepton) public {\n lepton = Lepton2(_lepton);\n ionx = Ionx(_ionx);\n ionxPerLepton = _ionxPerLepton;\n }\n\n function buyWithIonx(\n uint256 leptonAmount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n uint256 ionxAmount = leptonAmount * ionxPerLepton;\n require(ionx.balanceOf(msg.sender) >= ionxAmount, \"Insufficient IONX balance\");\n\n ionx.permit(msg.sender, address(this), ionxAmount, deadline, v, r, s);\n ionx.transferFrom(msg.sender, address(this), ionxAmount);\n\n for (uint256 i = 0; i < leptonAmount; ++i) {\n uint256 tokenId = nextTokenId;\n nextTokenId = nextTokenId.add(1);\n\n lepton.safeTransferFrom(address(this), msg.sender, tokenId);\n }\n\n emit SoldLepton(msg.sender, leptonAmount, ionxAmount);\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function load(uint256 amount) external payable override onlyOwner {\n nextTokenId = lepton.totalSupply().add(1);\n lepton.batchMintLepton{ value: msg.value }(amount);\n }\n\n function setLepton(address _lepton) external override onlyOwner {\n require(_lepton != address(0), \"Invalid address\");\n lepton = Lepton2(_lepton);\n }\n\n function setIonx(address _ionx) external onlyOwner {\n require(_ionx != address(0), \"Invalid address\");\n ionx = Ionx(_ionx);\n }\n\n function setIonxPerLepton(uint256 ionxAmount) external onlyOwner {\n ionxPerLepton = ionxAmount;\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n}" + }, + "contracts/v1/lib/BaseProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IBaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n/// @title Base Proton Contract for Charged Particles compatible ERC721 NFTs\n/// @dev MUST NOT be Upgradeable, as Upgradeable NFTs are incompatible with Charged Particles.\ncontract BaseProton is \n IBaseProton, \n ERC721, \n Ownable, \n RelayRecipient, \n ReentrancyGuard, \n BlackholePrevention \n{\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n event Received(address, uint);\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n /// @dev Sequential Token IDs storage\n Counters.Counter internal _tokenIds;\n\n /// @dev NFT Token Creator settings\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct;\n mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect;\n mapping (address => uint256) internal _tokenCreatorClaimableRoyalties;\n\n /// @dev NFT Token Sale settings\n mapping (uint256 => uint256) internal _tokenSalePrice;\n mapping (uint256 => uint256) internal _tokenLastSellPrice;\n\n /// @dev Whether of not the Contract is Paused\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n /// @dev Inherit from ERC721 standard\n constructor(string memory _name, string memory _symbol) public ERC721(_name, _symbol) {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n receive() external payable virtual {\n emit Received(msg.sender, msg.value);\n }\n\n /// Returns the Creator address of an NFT by Token ID\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The address of the Creator account\n function creatorOf(uint256 tokenId) external view virtual override returns (address) {\n return _tokenCreator[tokenId];\n }\n\n /// Returns the Sale Price of an NFT by Token ID\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The sale price of the NFT\n function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenSalePrice[tokenId];\n }\n\n /// Returns the Last Sale Price of an NFT by Token ID\n /// @notice This is used to determine any increase in sale price used in royalties calculations\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The last sale price of the NFT\n function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenLastSellPrice[tokenId];\n }\n\n /// Returns the Claimable Royalties for the NFT Creator\n /// @param account The address of the Creator account to lookup\n /// @return The amount of earned royalties for the creator account\n function getCreatorRoyalties(address account) external view virtual override returns (uint256) {\n return _tokenCreatorClaimableRoyalties[account];\n }\n\n /// Returns the Percentage of Royalties reserved for the NFT Creator\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The percentage of royalties reserved for the creator\n function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenCreatorRoyaltiesPct[tokenId];\n }\n\n /// Returns the Receiving address of the Creator Royalties (or Creator if not set)\n /// @dev Returns the creator address if a receiving address has not been configured\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The Receiving address of the Creator Royalties\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) {\n return _creatorRoyaltiesReceiver(tokenId);\n }\n\n /// Allows an NFT Creator to Claim any Royalties that have been earned from NFT sales\n /// @dev Must be called by the royalties receiver account (not neccessarily the creator)\n /// @return The amout of creator royalties claimed\n function claimCreatorRoyalties()\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256)\n {\n return _claimCreatorRoyalties(_msgSender());\n }\n\n\n /***********************************|\n | Create Single Protons |\n |__________________________________*/\n\n /// Creates a Basic NFT with no Royalties and no initial Sale Price\n /// @dev Royalties and Sale Price can be configured later\n /// @param creator The address of the NFT Creator (can be different from the caller)\n /// @param receiver The receiving address of the NFT (can be different from the caller)\n /// @param tokenMetaUri The unique metadata URI for the NFT\n /// @return newTokenId The newly minted NFT Token ID\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n\n /***********************************|\n | Create Multiple Protons |\n |__________________________________*/\n\n function createProtons(\n address creator,\n address receiver,\n string[] calldata tokenMetaUris\n )\n external\n virtual\n override\n whenNotPaused\n returns (bool)\n {\n _createProtons(\n creator,\n receiver,\n 0, // royaltiesPercent\n tokenMetaUris\n );\n return true;\n }\n\n function createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n external\n virtual\n override\n whenNotPaused\n returns (bool)\n {\n _createProtonsForSale(\n creator,\n receiver,\n royaltiesPercent,\n tokenMetaUris,\n salePrices\n );\n return true;\n }\n\n\n /***********************************|\n | Buy Protons |\n |__________________________________*/\n\n function buyProton(uint256 tokenId, uint256 gasLimit)\n external\n payable\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (bool)\n {\n _buyProton(tokenId, gasLimit);\n return true;\n }\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice)\n external\n virtual\n override\n whenNotPaused\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setSalePrice(tokenId, salePrice);\n }\n\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setRoyaltiesPct(tokenId, royaltiesPct);\n }\n\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n {\n _tokenCreatorRoyaltiesRedirect[tokenId] = receiver;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual {\n _tokenSalePrice[tokenId] = salePrice;\n emit SalePriceSet(tokenId, salePrice);\n }\n\n function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual {\n require(royaltiesPct <= PERCENTAGE_SCALE, \"PRT:E-421\");\n _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct;\n emit CreatorRoyaltiesSet(tokenId, royaltiesPct);\n }\n\n function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) {\n address receiver = _tokenCreatorRoyaltiesRedirect[tokenId];\n if (receiver == address(0x0)) {\n receiver = _tokenCreator[tokenId];\n }\n return receiver;\n }\n\n function _createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n _tokenIds.increment();\n\n newTokenId = _tokenIds.current();\n _safeMint(receiver, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUri);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n }\n\n function _createProtons(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris\n )\n internal\n virtual\n {\n uint256 count = tokenMetaUris.length;\n for (uint256 i; i < count; i++) {\n _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, 0);\n }\n }\n\n function _createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n internal\n virtual\n {\n require(tokenMetaUris.length == salePrices.length, \"PRT:E-202\");\n\n uint256 count = tokenMetaUris.length;\n for (uint256 i; i < count; i++) {\n _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, salePrices[i]);\n }\n }\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n contractAddress = address(this);\n tokenId = _tokenId;\n salePrice = _tokenSalePrice[_tokenId];\n require(salePrice > 0, \"PRT:E-416\");\n require(msg.value >= salePrice, \"PRT:E-414\");\n\n uint256 ownerAmount = salePrice;\n creatorAmount;\n oldOwner = ownerOf(_tokenId);\n newOwner = _msgSender();\n\n // Creator Royalties\n royaltiesReceiver = _creatorRoyaltiesReceiver(_tokenId);\n uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[_tokenId];\n uint256 lastSellPrice = _tokenLastSellPrice[_tokenId];\n if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) {\n creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE);\n ownerAmount = ownerAmount.sub(creatorAmount);\n }\n _tokenLastSellPrice[_tokenId] = salePrice;\n\n // Reserve Royalties for Creator\n if (creatorAmount > 0) {\n _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount);\n }\n\n // Transfer Token\n _transfer(oldOwner, newOwner, _tokenId);\n\n // Transfer Payment\n if (ownerAmount > 0) {\n payable(oldOwner).sendValue(ownerAmount, _gasLimit);\n }\n\n emit ProtonSold(_tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n\n _refundOverpayment(salePrice, _gasLimit);\n }\n\n /**\n * @dev Pays out the Creator Royalties of the calling account\n * @param receiver The receiver of the claimable royalties\n * @return The amount of Creator Royalties claimed\n */\n function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) {\n uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver];\n require(claimableAmount > 0, \"PRT:E-411\");\n\n delete _tokenCreatorClaimableRoyalties[receiver];\n payable(receiver).sendValue(claimableAmount, 0);\n\n emit RoyaltiesClaimed(receiver, claimableAmount);\n }\n\n /**\n * @dev Collects the Required Asset Token from the users wallet\n * @param from The owner address to collect the Assets from\n * @param assetAmount The Amount of Asset Tokens to Collect\n */\n function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual {\n uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from);\n require(assetAmount <= _userAssetBalance, \"PRT:E-411\");\n // Be sure to Approve this Contract to transfer your Asset Token\n require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), \"PRT:E-401\");\n }\n\n function _refundOverpayment(uint256 threshold, uint256 gasLimit) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage, gasLimit);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n _tokenSalePrice[tokenId] = 0;\n super._transfer(from, to, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"PRT:E-101\");\n _;\n }\n\n modifier onlyTokenOwnerOrApproved(uint256 tokenId) {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"PRT:E-105\");\n _;\n }\n\n modifier onlyTokenCreator(uint256 tokenId) {\n require(_tokenCreator[tokenId] == _msgSender(), \"PRT:E-104\");\n _;\n }\n}" + }, + "contracts/v1/lib/Bitwise.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Bitwise.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nlibrary Bitwise {\n function negate(uint32 a) internal pure returns (uint32) {\n return a ^ maxInt();\n }\n\n function shiftLeft(uint32 a, uint32 n) internal pure returns (uint32) {\n return a * uint32(2) ** n;\n }\n\n function shiftRight(uint32 a, uint32 n) internal pure returns (uint32) {\n return a / uint32(2) ** n;\n }\n\n function maxInt() internal pure returns (uint32) {\n return uint32(-1);\n }\n\n // Get bit value at position\n function hasBit(uint32 a, uint32 n) internal pure returns (bool) {\n return a & shiftLeft(0x01, n) != 0;\n }\n\n // Set bit value at position\n function setBit(uint32 a, uint32 n) internal pure returns (uint32) {\n return a | shiftLeft(0x01, n);\n }\n\n // Set the bit into state \"false\"\n function clearBit(uint32 a, uint32 n) internal pure returns (uint32) {\n uint32 mask = negate(shiftLeft(0x01, n));\n return a & mask;\n }\n}\n" + }, + "contracts/v1/lib/BlackholePrevention.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\n\n/**\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\n * the Owner/DAO to pull them out on behalf of a user\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\n */\ncontract BlackholePrevention {\n using Address for address payable;\n using SafeERC20 for IERC20;\n\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\n\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (address(this).balance >= amount) {\n receiver.sendValue(amount);\n emit WithdrawStuckEther(receiver, amount);\n }\n }\n\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\n IERC20(tokenAddress).safeTransfer(receiver, amount);\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\n }\n }\n\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\n }\n }\n\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \"\");\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\n }\n }\n}\n" + }, + "contracts/v1/lib/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/GSN/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableMap.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n /**\n * @dev Emitted when `tokenId` token is transfered from `from` to `to`.\n */\n event TransferBatch(address indexed from, address indexed to, uint256 startTokenId, uint256 count);\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721:E-403\");\n\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721:E-405\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"ERC721:E-405\");\n return _tokenURIs[tokenId];\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721:E-111\");\n\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \"ERC721:E-105\");\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view override returns (address) {\n require(_exists(tokenId), \"ERC721:E-405\");\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 require(operator != _msgSender(), \"ERC721:E-111\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721:E-402\");\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 returns (bool) {\n return _tokenOwners.contains(tokenId);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721:E-405\");\n address owner = ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721:E-402\");\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 _safeMintBatch(address to, uint256 startTokenId, uint256 count, bytes memory _data) internal virtual {\n _mintBatch(to, startTokenId, count);\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \"ERC721:E-402\");\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:E-403\");\n require(!_exists(tokenId), \"ERC721:E-407\");\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\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 _mintBatch(address to, uint256 startTokenId, uint256 count) internal virtual {\n require(to != address(0), \"ERC721:E-403\");\n require(!_exists(startTokenId), \"ERC721:E-407\");\n\n for (uint i = 0; i < count; i++) {\n uint256 tokenId = startTokenId.add(i);\n _holderTokens[to].add(tokenId);\n _tokenOwners.set(tokenId, to);\n }\n\n emit TransferBatch(address(0), to, startTokenId, count);\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(address from, address to, uint256 tokenId) internal virtual {\n require(ownerOf(tokenId) == from, \"ERC721:E-102\");\n require(to != address(0), \"ERC721:E-403\");\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721:E-405\");\n _tokenURIs[tokenId] = _tokenURI;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721:E-402\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\n }\n}\n" + }, + "contracts/v1/lib/ERC721Basic.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/GSN/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Basic is Context, ERC165, IERC721, IERC721Metadata {\n using SafeMath for uint256;\n using Address for address;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 internal constant _ERC721_RECEIVED = 0x150b7a02;\n\n // mapping from token ids to their owners\n mapping (uint256 => address) internal _tokenOwners;\n\n // mapping from owner to token balance\n mapping (address => uint256) internal _ownerBalance;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) internal _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) internal _operatorApprovals;\n\n // Token name\n string internal _name;\n\n // Token symbol\n string internal _symbol;\n\n // Token Count\n uint256 internal _tokenCount;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 internal constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 internal constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721:E-403\");\n return _ownerBalance[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners[tokenId];\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view 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 return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721:E-111\");\n\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \"ERC721:E-105\");\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view override returns (address) {\n require(_exists(tokenId), \"ERC721:E-405\");\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721:E-111\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721:E-402\");\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 returns (bool) {\n return _tokenOwners[tokenId] != address(0x0);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721:E-405\");\n address owner = ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\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(address to, bytes memory _data) internal virtual returns (uint256) {\n uint256 tokenId = _mint(to);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721:E-402\");\n return 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 _safeMintBatch(address to, uint256 count, bytes memory _data) internal virtual {\n uint256 startTokenId = _mintBatch(to, count);\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \"ERC721:E-402\");\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) internal virtual returns (uint256) {\n require(to != address(0), \"ERC721:E-403\");\n\n _tokenCount = _tokenCount.add(1);\n uint256 tokenId = _tokenCount;\n require(!_exists(tokenId), \"ERC721:E-407\");\n\n _tokenOwners[tokenId] = to;\n _ownerBalance[to] = _ownerBalance[to].add(1);\n\n emit Transfer(address(0), to, tokenId);\n return tokenId;\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 _mintBatch(address to, uint256 count) internal virtual returns (uint256) {\n require(to != address(0), \"ERC721:E-403\");\n\n uint256 startTokenId = _tokenCount.add(1);\n for (uint i = 1; i <= count; i++) {\n uint256 tokenId = _tokenCount.add(i);\n _tokenOwners[tokenId] = to;\n emit Transfer(address(0), to, tokenId);\n }\n\n _tokenCount = _tokenCount.add(count);\n _ownerBalance[to] = _ownerBalance[to].add(count);\n return startTokenId;\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(address from, address to, uint256 tokenId) internal virtual {\n require(ownerOf(tokenId) == from, \"ERC721:E-102\");\n require(to != address(0), \"ERC721:E-403\");\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _tokenOwners[tokenId] = to;\n _ownerBalance[from] = _ownerBalance[from].sub(1);\n _ownerBalance[to] = _ownerBalance[to].add(1);\n\n emit Transfer(from, to, tokenId);\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(address from, address to, uint256 tokenId, bytes memory _data)\n internal returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721:E-402\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) internal {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\n }\n}\n" + }, + "contracts/v1/lib/IERC5192.sol": { + "content": "// SPDX-License-Identifier: CC0-1.0\npragma solidity ^0.6.0;\n\ninterface IERC5192 {\n /// @notice Emitted when the locking status is changed to locked.\n /// @dev If a token is minted and the status is locked, this event should be emitted.\n /// @param tokenId The identifier for a token.\n event Locked(uint256 tokenId);\n\n /// @notice Emitted when the locking status is changed to unlocked.\n /// @dev If a token is minted and the status is unlocked, this event should be emitted.\n /// @param tokenId The identifier for a token.\n event Unlocked(uint256 tokenId);\n\n /// @notice Returns the locking status of an Soulbound Token\n /// @dev SBTs assigned to zero address are considered invalid, and queries\n /// about them do throw.\n /// @param tokenId The identifier for an SBT.\n function locked(uint256 tokenId) external view returns (bool);\n}\n" + }, + "contracts/v1/lib/NftTokenType.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// NftTokenType.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/introspection/IERC165.sol\";\n\nlibrary NftTokenType {\n bytes4 constant internal INTERFACE_SIGNATURE_ERC721 = 0x80ac58cd;\n bytes4 constant internal INTERFACE_SIGNATURE_ERC1155 = 0xd9b67a26;\n\n uint256 constant internal TYPE_MASK = uint256(uint128(~0)) << 128;\n uint256 constant internal TYPE_NFT_BIT = 1 << 255;\n\n function isERC721(address contractAddress) internal view returns (bool) {\n return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC721);\n }\n\n function isERC1155(address contractAddress) internal view returns (bool) {\n return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC1155);\n }\n\n function getTokenType(address contractAddress, uint256 tokenId) internal view returns (uint256) {\n IERC165 tokenInterface = IERC165(contractAddress);\n bool is1155 = tokenInterface.supportsInterface(INTERFACE_SIGNATURE_ERC1155);\n\n if (!is1155 || (tokenId & TYPE_NFT_BIT != TYPE_NFT_BIT)) { return 0; }\n\n return tokenId & TYPE_MASK;\n }\n}\n" + }, + "contracts/v1/lib/ReentrancyGuard.sol": { + "content": "pragma solidity 0.6.12;\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 () public {\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 _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\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 /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}" + }, + "contracts/v1/lib/RelayRecipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0;\n\nimport \"@opengsn/gsn/contracts/BaseRelayRecipient.sol\";\n\ncontract RelayRecipient is BaseRelayRecipient {\n function versionRecipient() external override view returns (string memory) {\n return \"1.0.0-beta.1/charged-particles.relay.recipient\";\n }\n}\n" + }, + "contracts/v1/lib/SmartWalletBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// SmartWalletBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../interfaces/ISmartWallet.sol\";\nimport \"./BlackholePrevention.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract SmartWalletBase is ISmartWallet, BlackholePrevention {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n address internal _walletManager;\n\n address internal nftCreator;\n uint256 internal nftCreatorAnnuityPct;\n uint256 internal nftCreatorAmountDischarged;\n\n EnumerableSet.AddressSet internal _assetTokens;\n\n // Asset Token => Principal Balance\n mapping (address => uint256) internal _assetPrincipalBalance;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initializeBase() public {\n require(_walletManager == address(0x0), \"SWB:E-002\");\n _walletManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getAssetTokenCount() external view virtual override returns (uint256) {\n return _assetTokens.length();\n }\n\n function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) {\n if (index >= _assetTokens.length()) {\n return address(0);\n }\n return _assetTokens.at(index);\n }\n\n function setNftCreator(address creator, uint256 annuityPct) external virtual override onlyWalletManager {\n nftCreator = creator;\n nftCreatorAnnuityPct = annuityPct;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyWalletManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n function refreshPrincipal(address assetToken)\n external\n virtual\n override\n onlyWalletManager\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getPrincipal(address assetToken) internal view virtual returns (uint256) {\n return _assetPrincipalBalance[assetToken];\n }\n\n function _trackAssetToken(address assetToken) internal virtual {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n }\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the wallet manager\n modifier onlyWalletManager() {\n require(_walletManager == msg.sender, \"SWB:E-109\");\n _;\n }\n}" + }, + "contracts/v1/lib/SmartWalletBaseB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// SmartWalletBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../interfaces/ISmartWalletB.sol\";\nimport \"./BlackholePrevention.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract SmartWalletBaseB is ISmartWalletB, BlackholePrevention {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n address internal _walletManager;\n\n EnumerableSet.AddressSet internal _assetTokens;\n\n // Asset Token => Principal Balance\n mapping (address => uint256) internal _assetPrincipalBalance;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initializeBase() public {\n require(_walletManager == address(0x0), \"SWB:E-002\");\n _walletManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getAssetTokenCount() external view virtual override returns (uint256) {\n return _assetTokens.length();\n }\n\n function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) {\n if (index >= _assetTokens.length()) {\n return address(0);\n }\n return _assetTokens.at(index);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyWalletManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getPrincipal(address assetToken) internal view virtual returns (uint256) {\n return _assetPrincipalBalance[assetToken];\n }\n\n function _trackAssetToken(address assetToken) internal virtual {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n }\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the wallet manager\n modifier onlyWalletManager() {\n require(_walletManager == msg.sender, \"SWB:E-109\");\n _;\n }\n}" + }, + "contracts/v1/lib/Soul.sol": { + "content": "// SPDX-License-Identifier: CC0-1.0\npragma solidity ^0.6.12;\n\nimport \"./IERC5192.sol\";\n\ncontract Soul is IERC5192 {\n \n mapping (uint256 => bool) public lockedTokens;\n\n function _lockToken(uint256 tokenId) internal {\n lockedTokens[tokenId] = true;\n emit Locked(tokenId);\n }\n\n function _unlockToken(uint256 tokenId) internal {\n lockedTokens[tokenId] = false;\n emit Unlocked(tokenId);\n }\n\n function locked(uint256 tokenId)\n external\n view\n override(IERC5192)\n returns (bool)\n {\n return lockedTokens[tokenId];\n }\n}\n" + }, + "contracts/v1/lib/TokenInfo.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfo.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"../interfaces/IERC721Chargeable.sol\";\n\nlibrary TokenInfo {\n function getTokenUUID(address contractAddress, uint256 tokenId) internal pure virtual returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n function getTokenOwner(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n return tokenInterface.ownerOf(tokenId);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n function getTokenCreator(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n return tokenInterface.creatorOf(tokenId);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Owner of an External NFT contract\n /// @param contractAddress The Address to the Contract of the NFT to check\n /// @param account The Address of the Account to check\n /// @return True if the account owns the contract\n function isContractOwner(address contractAddress, address account) internal view virtual returns (bool) {\n address contractOwner = IERC721Chargeable(contractAddress).owner();\n return contractOwner != address(0x0) && contractOwner == account;\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Creator of a Proton-based NFT\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the Proton-based NFT\n function isTokenCreator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenCreator = tokenInterface.creatorOf(tokenId);\n return (sender == tokenCreator);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the Proton-based NFT or the Contract itself\n function isTokenContractOrCreator(address contractAddress, uint256 tokenId, address creator, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenCreator = tokenInterface.creatorOf(tokenId);\n if (sender == contractAddress && creator == tokenCreator) { return true; }\n return (sender == tokenCreator);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Owner or Operator of an External NFT\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the Owner or Operator of the External NFT\n function isErc721OwnerOrOperator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenOwner = tokenInterface.ownerOf(tokenId);\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\n }\n\n /**\n * @dev Returns true if `account` is a contract.\n * @dev Taken from OpenZeppelin library\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\n // for accounts without code, i.e. `keccak256('')`\n bytes32 codehash;\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n // solhint-disable-next-line no-inline-assembly\n assembly { codehash := extcodehash(account) }\n return (codehash != accountHash && codehash != 0x0);\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 * @dev Taken from OpenZeppelin library\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, uint256 gasLimit) internal {\n require(address(this).balance >= amount, \"TokenInfo: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = (gasLimit > 0)\n ? recipient.call{ value: amount, gas: gasLimit }(\"\")\n : recipient.call{ value: amount }(\"\");\n require(success, \"TokenInfo: unable to send value, recipient may have reverted\");\n }\n}\n" + }, + "contracts/v1/lib/TokenInfoProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfoProxy.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../interfaces/ITokenInfoProxy.sol\";\nimport \"../interfaces/IERC721Chargeable.sol\";\n\n\ncontract TokenInfoProxy is ITokenInfoProxy, Ownable {\n using Address for address;\n\n mapping (address => FnSignatures) internal _remappedFnSigs;\n\n function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner {\n _remappedFnSigs[contractAddress].ownerOf = fnSig;\n emit ContractFunctionSignatureSet(contractAddress, \"ownerOf\", fnSig);\n }\n\n function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner {\n _remappedFnSigs[contractAddress].creatorOf = fnSig;\n emit ContractFunctionSignatureSet(contractAddress, \"creatorOf\", fnSig);\n }\n\n\n function getTokenUUID(address contractAddress, uint256 tokenId) external pure virtual override returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n function getTokenOwner(address contractAddress, uint256 tokenId) external virtual override returns (address) {\n return _getTokenOwner(contractAddress, tokenId);\n }\n\n function getTokenCreator(address contractAddress, uint256 tokenId) external virtual override returns (address) {\n return _getTokenCreator(contractAddress, tokenId);\n }\n\n function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenOwner = _getTokenOwner(contractAddress, tokenId);\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\n }\n\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the NFT or the Contract itself\n function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) {\n address tokenCreator = _getTokenCreator(contractAddress, tokenId);\n return (sender == tokenCreator || sender == contractAddress);\n }\n\n\n\n function _getTokenCreator(address contractAddress, uint256 tokenId) internal returns (address) {\n bytes4 fnSig = IERC721Chargeable.creatorOf.selector;\n if (_remappedFnSigs[contractAddress].creatorOf != bytes4(0)) {\n fnSig = _remappedFnSigs[contractAddress].creatorOf;\n }\n\n // solhint-disable-next-line\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n if (success) {\n return abi.decode(returnData, (address));\n } else {\n return address(0x0);\n }\n }\n\n function _getTokenOwner(address contractAddress, uint256 tokenId) internal returns (address) {\n bytes4 fnSig = IERC721Chargeable.ownerOf.selector;\n if (_remappedFnSigs[contractAddress].ownerOf != bytes4(0)) {\n fnSig = _remappedFnSigs[contractAddress].ownerOf;\n }\n\n // solhint-disable-next-line\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n if (success) {\n return abi.decode(returnData, (address));\n } else {\n return address(0x0);\n }\n }\n}\n" + }, + "contracts/v1/lib/WalletManagerBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// WalletManagerBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IWalletManager.sol\";\nimport \"../interfaces/ISmartWallet.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"./BlackholePrevention.sol\";\n\n\n/**\n * @notice Wallet-Manager Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract WalletManagerBase is Ownable, BlackholePrevention, IWalletManager {\n using TokenInfo for address;\n\n // The Controller Contract Address\n address internal _controller;\n\n // The Executor Contract Address\n address internal _executor;\n\n // Template Contract for creating Token Smart-Wallet Bridges\n address internal _walletTemplate;\n\n // TokenID => Token Smart-Wallet Address\n mapping (uint256 => address) internal _wallets;\n\n // State of Wallet Manager\n bool internal _paused;\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Wallet Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n /**\n * @dev Connects to the ExecForAccount Controller\n */\n function setExecutor(address executor) external onlyOwner {\n _executor = executor;\n emit ExecutorSet(executor);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartWallet(wallet).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartWallet(wallet).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartWallet(wallet).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Executor contract\n modifier onlyExecutor() {\n require(_executor == msg.sender, \"WMB:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Controller or Executor contract\n modifier onlyControllerOrExecutor() {\n require(_executor == msg.sender || _controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"WMB:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/ParticleSplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ParticleSplitter.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"./interfaces/IParticleSplitter.sol\";\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IWalletManager.sol\";\nimport \"./interfaces/IBasketManager.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Contract\n * @dev Upgradeable Contract\n */\ncontract ParticleSplitter is IParticleSplitter, Ownable, ReentrancyGuard, BlackholePrevention\n{\n IChargedManagers internal _chargedManagers;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n mapping (address => bool) internal _externalAddressesAllowed;\n\n\n /***********************************|\n | Execute for Account |\n |__________________________________*/\n\n /// @notice Executes an arbitrary command on an NFT Wallet\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Wallet Manager controlling the NFT Wallet to execute on\n /// @param externalAddress The Address of the External Contract to execute on\n /// @param encodedParams The encoded function call to execute\n function executeForWallet(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address externalAddress,\n bytes memory encodedParams\n )\n external\n payable\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (bytes memory)\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n require(_externalAddressesAllowed[externalAddress], \"PS:E-117\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Wallet Manager\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n // Get Address of Wallet to send any ETH into\n if (msg.value > 0) {\n address wallet = walletMgr.getWalletAddressById(contractAddress, tokenId, address(0), 0);\n payable(wallet).sendValue(msg.value);\n }\n\n emit ExecuteForWallet(contractAddress, tokenId, walletManagerId, externalAddress, encodedParams, msg.value);\n\n // Execute command for NFT Wallet\n return walletMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams);\n }\n\n /// @notice Executes an arbitrary command on an NFT Basket\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param basketManagerId The Basket Manager controlling the NFT Wallet to execute on\n /// @param externalAddress The Address of the External Contract to execute on\n /// @param encodedParams The encoded function call to execute\n function executeForBasket(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address externalAddress,\n bytes memory encodedParams\n )\n external\n payable\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (bytes memory)\n {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"PS:E-419\");\n require(_externalAddressesAllowed[externalAddress], \"PS:E-117\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Basket Manager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n\n // Get Address of Wallet to send any ETH into\n if (msg.value > 0) {\n address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId);\n payable(wallet).sendValue(msg.value);\n }\n\n emit ExecuteForBasket(contractAddress, tokenId, basketManagerId, externalAddress, encodedParams, msg.value);\n\n // Execute command for NFT Wallet\n return basketMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams);\n }\n\n function withdrawWalletRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (uint256 amountWithdrawn)\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Wallet Manager\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n // Withdraw Rewards for NFT Wallet\n return walletMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount);\n }\n\n function withdrawBasketRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (uint256 amountWithdrawn)\n {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"PS:E-419\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Basket Manager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n\n // Withdraw Rewards for NFT Basket\n return basketMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount);\n }\n\n function refreshWalletPrincipal(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n walletMgr.refreshPrincipal(contractAddress, tokenId, assetToken);\n\n emit PrincipalRefreshed(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedManagers Interface\n */\n function setChargedManagers(address chargedManagers) external virtual onlyOwner {\n _chargedManagers = IChargedManagers(chargedManagers);\n emit ChargedManagersSet(chargedManagers);\n }\n\n /**\n * @dev Setup the ChargedManagers Interface\n */\n function setTokenInfoProxy(address tokenInfoProxy) external virtual onlyOwner {\n _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy);\n emit TokenInfoProxySet(tokenInfoProxy);\n }\n\n /**\n * @dev Allows/Disallows execute from on specific contracts\n */\n function setExternalContracts(address[] calldata contracts, bool state) external onlyOwner {\n uint count = contracts.length;\n for (uint i; i < count; i++) {\n address externalContract = contracts[i];\n _externalAddressesAllowed[externalContract] = state;\n emit PermsSetForExternal(externalContract, state);\n }\n }\n\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyTokenOwner(address contractAddress, uint256 tokenId) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(msg.sender == tokenOwner, \"PS:E-102\");\n _;\n }\n}\n" + }, + "contracts/v1/test/Dai.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"../interfaces/IDai.sol\";\n\ncontract Dai is IDai {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (uint256 chainId_) public {\n string memory version = \"1\";\n\n _name = \"Dai Stablecoin\";\n _symbol = \"DAI\";\n _decimals = 18;\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(_name)),\n keccak256(bytes(version)),\n chainId_,\n address(this)\n )\n );\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view 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(msg.sender, 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(msg.sender, 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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(msg.sender, spender, _allowances[msg.sender][spender].add(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 _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20:E-403\");\n require(recipient != address(0), \"ERC20:E-403\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20:E-403\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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:E-403\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20:E-403\");\n require(spender != address(0), \"ERC20:E-403\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n\n mapping (address => uint) public nonces;\n\n // --- EIP712 niceties ---\n bytes32 public DOMAIN_SEPARATOR;\n // bytes32 public constant PERMIT_TYPEHASH = keccak256(\"Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)\");\n bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;\n\n // --- Approve by signature ---\n function permit(\n address holder, address spender, uint256 nonce, uint256 expiry,\n bool allowed, uint8 v, bytes32 r, bytes32 s) external override\n {\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n holder,\n spender,\n nonce,\n expiry,\n allowed\n )\n )\n )\n );\n\n require(holder != address(0), \"Dai/invalid-address-0\");\n require(holder == ecrecover(digest, v, r, s), \"Dai/invalid-permit\");\n require(expiry == 0 || now <= expiry, \"Dai/permit-expired\");\n require(nonce == nonces[holder]++, \"Dai/invalid-nonce\");\n uint wad = allowed ? uint(-1) : 0;\n _allowances[holder][spender] = wad;\n emit Approval(holder, spender, wad);\n }\n\n function mint(address to, uint256 amount) external {\n _mint(to, amount);\n }\n}" + }, + "contracts/v1/test/ERC20Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.7.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/**\n * @dev Extension of {ERC20} that adds a set of accounts with the {MinterRole},\n * which have permission to mint (create) new tokens as they see fit.\n *\n * At construction, the deployer of the contract is the only minter.\n */\ncontract ERC20Mintable is ERC20Upgradeable {\n\n constructor(string memory _name, string memory _symbol) public {\n __ERC20_init(_name, _symbol);\n }\n\n /**\n * @dev See {ERC20-_mint}.\n *\n * Requirements:\n *\n * - the caller must have the {MinterRole}.\n */\n function mint(address account, uint256 amount) public returns (bool) {\n _mint(account, amount);\n return true;\n }\n\n function burn(address account, uint256 amount) public returns (bool) {\n _burn(account, amount);\n return true;\n }\n}" + }, + "contracts/v1/test/ERC721Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.7.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\n\n/**\n * @dev Extension of {ERC721} for Minting/Burning\n */\ncontract ERC721Mintable is ERC721Upgradeable {\n\n constructor () public {\n __ERC721_init(\"ERC 721\", \"NFT\");\n }\n\n /**\n * @dev See {ERC721-_mint}.\n */\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n\n /**\n * @dev See {ERC721-_burn}.\n */\n function burn(uint256 tokenId) public {\n _burn(tokenId);\n }\n}\n" + }, + "contracts/v1/tokens/ExternalERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ExternalERC721.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\n\ncontract ExternalERC721 is ERC721 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n\n constructor() public ERC721(\"Charged Particles - ExternalERC721\", \"ExNFT\") {}\n\n function mintNft(address receiver, string memory tokenUri) external returns (uint256 newTokenId) {\n return _mintNft(receiver, tokenUri);\n }\n\n function _mintNft(address receiver, string memory tokenUri) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n\n _safeMint(receiver, newTokenId, \"\");\n\n _setTokenURI(newTokenId, tokenUri);\n }\n}\n" + }, + "contracts/v1/tokens/FungibleERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// FungibleERC1155.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract FungibleERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n\n constructor() public ERC1155(\"https://staging.app.charged.fi/erc1155/metadata.json\") {}\n\n function mintNft(address receiver, uint256 amount) external returns (uint256 newTokenId) {\n return _mintNft(receiver, amount);\n }\n\n function _mintNft(address receiver, uint256 amount) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n _mint(receiver, newTokenId, amount, \"\");\n }\n}\n" + }, + "contracts/v1/tokens/Ionx.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Ionx.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"erc20permit/contracts/ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\n\ncontract Ionx is ERC20Permit, Ownable, BlackholePrevention {\n using SafeMath for uint256;\n\n /// @notice An event thats emitted when the minter address is changed\n event MinterChanged(address minter, address newMinter);\n\n /// @notice Total number of tokens in circulation\n uint256 constant public INITIAL_SUPPLY = 1e8 ether;\n\n /// @notice Minimum time between mints\n uint32 public constant INFLATION_EPOCH = 1 days * 365;\n\n /// @notice Cap on the percentage of totalSupply that can be minted at each mint\n uint8 public constant INFLATION_CAP = 2;\n\n /// @notice Address which may mint new tokens\n address public minter;\n\n /// @notice The timestamp after which minting may occur\n uint256 public mintingAllowedAfter;\n\n\n constructor() public ERC20Permit(\"Charged Particles - IONX\", \"IONX\") {}\n\n\n /**\n * @notice Change the minter address\n * @param newMinter The address of the new minter\n */\n function setMinter(address newMinter) external onlyOwner {\n emit MinterChanged(minter, newMinter);\n minter = newMinter;\n }\n\n /**\n * @notice Mint new tokens\n * @param receiver The address of the destination account\n * @param amount The number of tokens to be minted\n */\n function mint(address receiver, uint256 amount) external onlyMinter {\n require(block.timestamp >= mintingAllowedAfter, \"Ionx:E-114\");\n require(receiver != address(0), \"Ionx:E-403\");\n\n uint256 amountToMint = amount;\n uint256 _totalSupply = totalSupply();\n\n // From Inflationary Supply\n if (_totalSupply >= INITIAL_SUPPLY) {\n mintingAllowedAfter = mintingAllowedAfter.add(INFLATION_EPOCH);\n amountToMint = _totalSupply.mul(INFLATION_CAP).div(100);\n }\n\n // From Initial Supply\n else {\n if (_totalSupply.add(amountToMint) > INITIAL_SUPPLY) {\n amountToMint = INITIAL_SUPPLY.sub(_totalSupply);\n }\n if (_totalSupply.add(amountToMint) == INITIAL_SUPPLY) {\n mintingAllowedAfter = block.timestamp.add(INFLATION_EPOCH);\n }\n }\n\n // transfer the amount to the recipient\n _mint(receiver, amountToMint);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n modifier onlyMinter() {\n require(msg.sender == minter, \"Ionx:E-113\");\n _;\n }\n}\n" + }, + "contracts/v1/tokens/Lepton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Lepton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/ILepton.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\n\ncontract Lepton is ILepton, ERC721, Ownable, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenIds;\n Classification[] internal _leptonTypes;\n mapping (uint256 => Classification) internal _leptonData;\n\n uint256 internal _typeIndex;\n uint256 internal _maxSupply;\n uint256 internal _maxMintPerTx;\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721(\"Charged Particles - Lepton\", \"LEPTON\") {\n _paused = true;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function mintLepton() external payable virtual override nonReentrant whenNotPaused returns (uint256 newTokenId) {\n newTokenId = _mintLepton(msg.sender);\n }\n\n function batchMintLepton(uint256 count) external payable virtual override nonReentrant whenNotPaused {\n _batchMintLepton(msg.sender, count);\n }\n\n function getNextType() external view virtual override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _typeIndex;\n }\n\n function getNextPrice() external view virtual override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _leptonTypes[_typeIndex].price;\n }\n\n function getMultiplier(uint256 tokenId) external view virtual override returns (uint256) {\n return _leptonData[tokenId].multiplier;\n }\n\n function getBonus(uint256 tokenId) external view virtual override returns (uint256) {\n return _leptonData[tokenId].bonus;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function addLeptonType(\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n virtual\n onlyOwner\n {\n _maxSupply = _maxSupply.add(uint256(supply));\n\n Classification memory lepton = Classification({\n tokenUri: tokenUri,\n price: price,\n supply: supply,\n multiplier: multiplier,\n bonus: bonus,\n _upperBounds: uint128(_maxSupply)\n });\n _leptonTypes.push(lepton);\n\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function updateLeptonType(\n uint256 leptonIndex,\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n virtual\n onlyOwner\n {\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\n _leptonTypes[leptonIndex].price = price;\n _leptonTypes[leptonIndex].supply = supply;\n _leptonTypes[leptonIndex].multiplier = multiplier;\n _leptonTypes[leptonIndex].bonus = bonus;\n\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function setMaxMintPerTx(uint256 maxAmount) external virtual onlyOwner {\n _maxMintPerTx = maxAmount;\n emit MaxMintPerTxSet(maxAmount);\n }\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _mintLepton(address receiver) internal virtual returns (uint256 newTokenId) {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n require(msg.value >= lepton.price, \"LPT:E-414\");\n\n _tokenIds.increment();\n newTokenId = _tokenIds.current();\n\n _leptonData[newTokenId] = lepton;\n _safeMint(receiver, newTokenId, \"\");\n _setTokenURI(newTokenId, lepton.tokenUri);\n\n // Distribute Next Type\n if (newTokenId == lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n emit LeptonMinted(receiver, newTokenId, lepton.price, lepton.multiplier);\n\n _refundOverpayment(lepton.price);\n }\n\n\n function _batchMintLepton(address receiver, uint256 count) internal virtual {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \"LPT:E-429\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n\n uint256 startTokenId = _tokenIds.current();\n uint256 endTokenId = startTokenId.add(count);\n if (endTokenId > lepton._upperBounds) {\n count = count.sub(endTokenId.sub(lepton._upperBounds));\n }\n\n uint256 salePrice = lepton.price.mul(count);\n require(msg.value >= salePrice, \"LPT:E-414\");\n\n _safeMintBatch(receiver, startTokenId.add(1), count, \"\");\n\n for (uint i = 0; i < count; i++) {\n _tokenIds.increment();\n startTokenId = _tokenIds.current();\n\n _leptonData[startTokenId] = lepton;\n _setTokenURI(startTokenId, lepton.tokenUri);\n }\n\n // Distribute Next Type\n if (startTokenId >= lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n emit LeptonBatchMinted(receiver, startTokenId, count, lepton.price, lepton.multiplier);\n\n _refundOverpayment(salePrice);\n }\n\n function _refundOverpayment(uint256 threshold) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"LPT:E-101\");\n _;\n }\n}" + }, + "contracts/v1/tokens/Lepton2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Lepton2.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"../lib/ERC721Basic.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\n\nimport \"../interfaces/ILepton.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Lepton2 is ILepton, ERC721Basic, Ownable, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n\n Classification[] internal _leptonTypes;\n\n uint256 internal _typeIndex;\n uint256 internal _maxSupply;\n uint256 internal _maxMintPerTx;\n uint256 internal _migratedCount;\n\n bool internal _paused;\n bool internal _migrationComplete;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721Basic(\"Charged Particles - Lepton2\", \"LEPTON2\") {\n _paused = true;\n _migrationComplete = false;\n _migratedCount = 0;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function mintLepton() external payable override nonReentrant whenNotPaused returns (uint256 newTokenId) {\n newTokenId = _mintLepton(msg.sender);\n }\n\n function batchMintLepton(uint256 count) external payable override nonReentrant whenNotPaused {\n _batchMintLepton(msg.sender, count);\n }\n\n function totalSupply() public view returns (uint256) {\n return _tokenCount;\n }\n\n function maxSupply() external view returns (uint256) {\n return _maxSupply;\n }\n\n function getNextType() external view override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _typeIndex;\n }\n\n function getNextPrice() external view override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _leptonTypes[_typeIndex].price;\n }\n\n function getMultiplier(uint256 tokenId) external view override returns (uint256) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).multiplier;\n }\n\n function getBonus(uint256 tokenId) external view override returns (uint256) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).bonus;\n }\n\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).tokenUri;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function addLeptonType(\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n onlyOwner\n {\n _maxSupply = _maxSupply.add(uint256(supply));\n\n Classification memory lepton = Classification({\n tokenUri: tokenUri,\n price: price,\n supply: supply,\n multiplier: multiplier,\n bonus: bonus,\n _upperBounds: uint128(_maxSupply)\n });\n _leptonTypes.push(lepton);\n\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function updateLeptonType(\n uint256 leptonIndex,\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n onlyOwner\n {\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\n _leptonTypes[leptonIndex].price = price;\n _leptonTypes[leptonIndex].supply = supply;\n _leptonTypes[leptonIndex].multiplier = multiplier;\n _leptonTypes[leptonIndex].bonus = bonus;\n\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function setMaxMintPerTx(uint256 maxAmount) external onlyOwner {\n _maxMintPerTx = maxAmount;\n emit MaxMintPerTxSet(maxAmount);\n }\n\n function setPausedState(bool state) external onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function migrateAccounts(address oldLeptonContract, uint256 count) external onlyOwner whenNotMigrated {\n uint256 oldSupply = IERC721Enumerable(oldLeptonContract).totalSupply();\n require(oldSupply == 0 || oldSupply > _migratedCount, \"LPT:E-004\");\n\n if (oldSupply > 0) {\n uint256 endTokenId = _migratedCount.add(count);\n if (endTokenId > oldSupply) {\n count = count.sub(endTokenId.sub(oldSupply));\n }\n\n for (uint256 i = 1; i <= count; i++) {\n uint256 tokenId = _migratedCount.add(i);\n address tokenOwner = IERC721(oldLeptonContract).ownerOf(tokenId);\n _mint(tokenOwner);\n }\n _migratedCount = _migratedCount.add(count);\n }\n\n if (oldSupply == _migratedCount) {\n _finalizeMigration();\n }\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getLepton(uint256 tokenId) internal view returns (Classification memory) {\n uint256 types = _leptonTypes.length;\n for (uint256 i = 0; i < types; i++) {\n Classification memory lepton = _leptonTypes[i];\n if (tokenId <= lepton._upperBounds) {\n return lepton;\n }\n }\n }\n\n function _mintLepton(address receiver) internal returns (uint256 newTokenId) {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n require(msg.value >= lepton.price, \"LPT:E-414\");\n\n newTokenId = _safeMint(receiver, \"\");\n\n // Determine Next Type\n if (newTokenId == lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n _refundOverpayment(lepton.price);\n }\n\n function _batchMintLepton(address receiver, uint256 count) internal {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \"LPT:E-429\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n\n uint256 endTokenId = _tokenCount.add(count);\n if (endTokenId > lepton._upperBounds) {\n count = count.sub(endTokenId.sub(lepton._upperBounds));\n }\n\n uint256 salePrice = lepton.price.mul(count);\n require(msg.value >= salePrice, \"LPT:E-414\");\n\n _safeMintBatch(receiver, count, \"\");\n\n // Determine Next Type\n if (endTokenId >= lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n _refundOverpayment(salePrice);\n }\n\n function _refundOverpayment(uint256 threshold) internal {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n function _finalizeMigration() internal {\n // Determine Next Type\n _typeIndex = 0;\n for (uint256 i = 0; i < _leptonTypes.length; i++) {\n Classification memory lepton = _leptonTypes[i];\n if (_migratedCount >= lepton._upperBounds) {\n _typeIndex = i + 1;\n }\n }\n _migrationComplete = true;\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotMigrated() {\n require(!_migrationComplete, \"LPT:E-004\");\n _;\n }\n\n modifier whenNotPaused() {\n require(!_paused, \"LPT:E-101\");\n _;\n }\n}" + }, + "contracts/v1/tokens/NonFungibleERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// NonFungibleERC1155.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract NonFungibleERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => address) internal _tokenOwner;\n\n constructor() public ERC1155(\"https://staging.app.charged.fi/erc1155/metadata.json\") {}\n\n function creatorOf(uint256 tokenId) external view returns (address) {\n return _tokenCreator[tokenId];\n }\n\n function ownerOf(uint256 tokenId) external view returns (address) {\n return _tokenOwner[tokenId];\n }\n\n function mintNft(address receiver) external returns (uint256 newTokenId) {\n return _mintNft(msg.sender, receiver);\n }\n\n function _mintNft(address creator, address receiver) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n\n _mint(receiver, newTokenId, 1, \"\");\n _tokenCreator[newTokenId] = creator;\n _tokenOwner[newTokenId] = receiver;\n }\n}\n" + }, + "contracts/v1/tokens/Proton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IProton.sol\";\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ncontract Proton is IProton, ERC721, Ownable, RelayRecipient, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n using Counters for Counters.Counter;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n uint256 constant internal MAX_ROYALTIES = 8e3; // 8000 (80%)\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n Counters.Counter internal _tokenIds;\n\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct;\n mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect;\n mapping (address => uint256) internal _tokenCreatorClaimableRoyalties;\n\n mapping (uint256 => uint256) internal _tokenSalePrice;\n mapping (uint256 => uint256) internal _tokenLastSellPrice;\n\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721(\"Charged Particles - Proton\", \"PROTON\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view virtual override returns (address) {\n return _tokenCreator[tokenId];\n }\n\n function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenSalePrice[tokenId];\n }\n\n function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenLastSellPrice[tokenId];\n }\n\n function getCreatorRoyalties(address account) external view virtual override returns (uint256) {\n return _tokenCreatorClaimableRoyalties[account];\n }\n\n function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenCreatorRoyaltiesPct[tokenId];\n }\n\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) {\n return _creatorRoyaltiesReceiver(tokenId);\n }\n\n function claimCreatorRoyalties()\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256)\n {\n return _claimCreatorRoyalties(_msgSender());\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // annuityPercent,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n royaltiesPercent,\n salePrice\n );\n }\n\n function batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n external\n virtual\n override\n whenNotPaused\n {\n _batchProtonsForSale(\n creator,\n annuityPercent,\n royaltiesPercent,\n tokenMetaUris,\n salePrices\n );\n }\n\n function buyProton(uint256 tokenId)\n external\n payable\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (bool)\n {\n return _buyProton(tokenId);\n }\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice)\n external\n virtual\n override\n whenNotPaused\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setSalePrice(tokenId, salePrice);\n }\n\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setRoyaltiesPct(tokenId, royaltiesPct);\n }\n\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n {\n _tokenCreatorRoyaltiesRedirect[tokenId] = receiver;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual {\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n\n _tokenSalePrice[tokenId] = salePrice;\n emit SalePriceSet(tokenId, salePrice);\n }\n\n function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual {\n require(royaltiesPct <= MAX_ROYALTIES, \"PRT:E-421\");\n _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct;\n emit CreatorRoyaltiesSet(tokenId, royaltiesPct);\n }\n\n function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) {\n address receiver = _tokenCreatorRoyaltiesRedirect[tokenId];\n if (receiver == address(0x0)) {\n receiver = _tokenCreator[tokenId];\n }\n return receiver;\n }\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, annuityPercent, 0, 0);\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n _tokenIds.increment();\n\n newTokenId = _tokenIds.current();\n _safeMint(receiver, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUri);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function _batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n internal\n virtual\n {\n require(tokenMetaUris.length == salePrices.length, \"PRT:E-202\");\n address self = address(this);\n\n uint256 count = tokenMetaUris.length;\n for (uint256 i = 0; i < count; i++) {\n _tokenIds.increment();\n uint256 newTokenId = _tokenIds.current();\n\n _safeMint(creator, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUris[i]);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n uint256 salePrice = salePrices[i];\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n self,\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n function _buyProton(uint256 tokenId)\n internal\n virtual\n returns (bool)\n {\n uint256 salePrice = _tokenSalePrice[tokenId];\n require(salePrice > 0, \"PRT:E-416\");\n require(msg.value >= salePrice, \"PRT:E-414\");\n\n uint256 ownerAmount = salePrice;\n uint256 creatorAmount;\n address oldOwner = ownerOf(tokenId);\n address newOwner = _msgSender();\n\n // Creator Royalties\n address royaltiesReceiver = _creatorRoyaltiesReceiver(tokenId);\n uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[tokenId];\n uint256 lastSellPrice = _tokenLastSellPrice[tokenId];\n if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) {\n creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE);\n ownerAmount = ownerAmount.sub(creatorAmount);\n }\n _tokenLastSellPrice[tokenId] = salePrice;\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(address(this), tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n\n // Reserve Royalties for Creator\n if (creatorAmount > 0) {\n _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount);\n }\n\n // Transfer Token\n _transfer(oldOwner, newOwner, tokenId);\n\n // Transfer Payment\n payable(oldOwner).sendValue(ownerAmount);\n\n emit ProtonSold(tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n\n _refundOverpayment(salePrice);\n return true;\n }\n\n /**\n * @dev Pays out the Creator Royalties of the calling account\n * @param receiver The receiver of the claimable royalties\n * @return The amount of Creator Royalties claimed\n */\n function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) {\n uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver];\n require(claimableAmount > 0, \"PRT:E-411\");\n\n delete _tokenCreatorClaimableRoyalties[receiver];\n payable(receiver).sendValue(claimableAmount);\n\n emit RoyaltiesClaimed(receiver, claimableAmount);\n }\n\n /**\n * @dev Collects the Required Asset Token from the users wallet\n * @param from The owner address to collect the Assets from\n * @param assetAmount The Amount of Asset Tokens to Collect\n */\n function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual {\n uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from);\n require(assetAmount <= _userAssetBalance, \"PRT:E-411\");\n // Be sure to Approve this Contract to transfer your Asset Token\n require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), \"PRT:E-401\");\n }\n\n function _refundOverpayment(uint256 threshold) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n _tokenSalePrice[tokenId] = 0;\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n super._transfer(from, to, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"PRT:E-101\");\n _;\n }\n\n modifier onlyTokenOwnerOrApproved(uint256 tokenId) {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"PRT:E-105\");\n _;\n }\n\n modifier onlyTokenCreator(uint256 tokenId) {\n require(_tokenCreator[tokenId] == _msgSender(), \"PRT:E-104\");\n _;\n }\n}" + }, + "contracts/v1/tokens/ProtonB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\nimport \"../interfaces/IProtonB.sol\";\n\nimport \"../lib/BaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ncontract ProtonB is BaseProton, IProtonB {\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public BaseProton(\"Charged Particles - ProtonB\", \"PROTON.B\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n external\n virtual\n override\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n royaltiesPercent,\n salePrice\n );\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n /// @dev for backwards compatibility with v1\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0);\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n\n /***********************************|\n | Function Overrides |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override {\n super._setSalePrice(tokenId, salePrice);\n\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n }\n\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n override\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n }\n\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n // Unlock NFT\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n\n super._transfer(from, to, tokenId);\n }\n}" + }, + "contracts/v1/tokens/ProtonC.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\nimport \"../lib/Soul.sol\";\n\n\ncontract ProtonC is BaseProton, Soul {\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public BaseProton(\"Charged Particles - ProtonC\", \"PROTON.C\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createBondedToken(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent\n )\n external\n virtual\n payable\n returns (uint256 newTokenId)\n {\n uint256 tokenId = createProtonForSale(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n royaltiesPercent,\n 0\n );\n lockToken(tokenId);\n\n return tokenId;\n }\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n public \n virtual\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n royaltiesPercent,\n salePrice\n );\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n nonReentrant\n whenNotPaused\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n /// @dev for backwards compatibility with v1\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n whenNotPaused\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function burn(uint256 tokenId) public {\n requireTokenOwner(tokenId); \n _burn(tokenId);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n function requireTokenOwner(uint256 tokenId) public view {\n require(ownerOf(tokenId) == msg.sender, \"Only token owner\");\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0);\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n function _burn(uint256 tokenId) internal {\n _unlockToken(tokenId);\n _transfer(ownerOf(tokenId), address(0x000000000000000000000000000000000000dEaD), tokenId);\n }\n\n /***********************************|\n | Soul bounded |\n |__________________________________*/\n\n function lockToken(uint256 tokenId) public {\n requireTokenOwner(tokenId);\n _lockToken(tokenId);\n }\n\n /***********************************|\n | Function Overrides |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override {\n super._setSalePrice(tokenId, salePrice);\n\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n }\n\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n override\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n require(lockedTokens[tokenId] == false, \"BondedToken: Token is locked\");\n\n // Unlock NFT\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n\n super._transfer(from, to, tokenId);\n }\n}" + }, + "contracts/v1/Universe.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\n\nimport \"./interfaces/IUniverse.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n\n/**\n * @notice Charged Particles Universe Contract\n * @dev Upgradeable Contract\n */\ncontract Universe is IUniverse, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n // The ChargedParticles Contract Address\n address public chargedParticles;\n address public proton;\n address public lepton;\n address public quark;\n address public boson;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // Positive Charge\n uint256 internal photonMaxSupply;\n uint256 internal totalPhotonDischarged;\n\n // Source of Positive Charge\n IERC20Upgradeable public photonSource;\n\n // Asset Token => Electrostatic Attraction Multiplier\n mapping (address => uint256) internal esaMultiplier;\n\n // Account => Electrostatic Attraction Levels\n mapping (address => uint256) internal esaLevel;\n\n // Energizing Account => Referral Source\n mapping (address => address) internal referralSource;\n\n // NFT Token UUID => Bonded Lepton Mass\n mapping (uint256 => uint256) internal bondedLeptonMass;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getStaticCharge(address /* account */) external pure virtual returns (uint256 positiveEnergy) {\n return 0;\n }\n\n function conductElectrostaticDischarge(address /* account */, uint256 /* amount */) external pure virtual returns (uint256 positiveEnergy) {\n return 0;\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n onlyProton\n {\n // no-op\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(controller)\n {\n chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setPhoton(\n address token,\n uint256 maxSupply\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n photonSource = IERC20Upgradeable(token);\n photonMaxSupply = maxSupply;\n emit PhotonSet(token, maxSupply);\n }\n\n function setProtonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n proton = token;\n emit ProtonTokenSet(token);\n }\n\n function setLeptonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n lepton = token;\n emit LeptonTokenSet(token);\n }\n\n function setQuarkToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n quark = token;\n emit QuarkTokenSet(token);\n }\n\n function setBosonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n boson = token;\n emit BosonTokenSet(token);\n }\n\n function setEsaMultiplier(\n address assetToken,\n uint256 multiplier\n )\n external\n virtual\n onlyOwner\n {\n esaMultiplier[assetToken] = multiplier;\n emit EsaMultiplierSet(assetToken, multiplier);\n }\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _electrostaticAttraction(uint256 tokenUuid, address receiver, address assetToken, uint256 baseAmount) internal virtual {\n }\n\n function _conductElectrostaticDischarge(address /* account */, uint256 /* energy */) internal virtual pure returns (uint256) {\n return 0;\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Proton NFT contract\n modifier onlyProton() {\n require(proton == msg.sender, \"UNI:E-110\");\n _;\n }\n}\n" + }, + "contracts/v1/UniverseRP.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"./interfaces/IUniverseRP.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./interfaces/IRewardNft.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\nimport \"./interfaces/IRewardProgram.sol\";\n\n/**\n * @notice Charged Particles Universe Contract with Rewards Program\n * @dev Upgradeable Contract\n */\ncontract UniverseRP is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // The ChargedParticles Contract Address\n address public _chargedParticles;\n\n // The Lepton NFT Contract Address\n address public _multiplierNft;\n\n // Asset Token => Reward Program\n mapping (address => address) internal _assetRewardPrograms;\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\n\n // Token UUID => NFT Staking Data\n mapping (uint256 => NftStake) private _nftStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n function getRewardProgram(address asset) external view override returns (address) {\n return _getRewardProgram(asset);\n }\n\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\n return _nftStake[uuid];\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetDeposit(\n contractAddress,\n tokenId,\n walletManagerId,\n assetAmount\n );\n }\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\n }\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n // \"receiverEnergy\" includes the \"principalAmount\"\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n onlyOwner\n onlyValidContractAddress(controller)\n {\n _chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setMultiplierNft(address nftTokenAddress)\n external\n onlyOwner\n onlyValidContractAddress(nftTokenAddress)\n {\n _multiplierNft = nftTokenAddress;\n }\n\n function setRewardProgram(\n address rewardProgam,\n address assetToken\n )\n external\n onlyOwner\n onlyValidContractAddress(rewardProgam)\n {\n require(assetToken != address(0x0), \"UNI:E-403\");\n _assetRewardPrograms[assetToken] = rewardProgam;\n emit RewardProgramSet(assetToken, rewardProgam);\n }\n\n function removeRewardProgram(address assetToken) external onlyOwner {\n delete _assetRewardPrograms[assetToken];\n emit RewardProgramRemoved(assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getRewardProgram(address assetToken) internal view returns (address) {\n return _assetRewardPrograms[assetToken];\n }\n\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != depositNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n uint256 multiplier = _getNftMultiplier(depositNftAddress, depositNftTokenId);\n\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\n // Add to Multipliers Set\n _multiplierNftsSet[parentNftUuid].add(multiplier);\n\n // Update NFT Stake\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\n } else {\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\n }\n }\n\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\n }\n\n function _registerNftRelease(\n address contractAddress,\n uint256 tokenId,\n address releaseNftAddress,\n uint256 releaseNftTokenId,\n uint256 /* nftTokenAmount */\n )\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != releaseNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n NftStake storage nftStake = _nftStake[parentNftUuid];\n\n // Remove from Multipliers Set\n uint256 multiplier = _getNftMultiplier(releaseNftAddress, releaseNftTokenId);\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\n\n // Determine New Multiplier or Mark as Released\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\n } else {\n nftStake.releaseBlockNumber = block.number;\n }\n\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\n }\n\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\n uint256 multiplier = 0;\n uint256 loss = 50;\n uint256 i = 0;\n\n for (; i < len; i++) {\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\n }\n if (len > 1) {\n multiplier = multiplier.sub(loss.mul(len));\n }\n return multiplier;\n }\n\n function _getNftMultiplier(address contractAddress, uint256 tokenId) internal returns (uint256) {\n bytes4 fnSig = IRewardNft.getMultiplier.selector;\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n\n if (success) {\n return abi.decode(returnData, (uint256));\n } else {\n return 0;\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(_chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/UniveserRPPolygon.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"./interfaces/IUniverseRP.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./interfaces/IRewardNft.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\nimport \"./interfaces/IRewardProgram.sol\";\n\n/**\n * @notice Charged Particles Universe Contract with Rewards Program\n * @dev Upgradeable Contract\n */\ncontract UniverseRPPolygon is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // The ChargedParticles Contract Address\n address public _chargedParticles;\n\n // The Lepton NFT Contract Address\n address public _multiplierNft;\n\n // Asset Token => Reward Program\n mapping (address => address) internal _assetRewardPrograms;\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\n\n // Token UUID => NFT Staking Data\n mapping (uint256 => NftStake) private _nftStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n function getRewardProgram(address asset) external view override returns (address) {\n return _getRewardProgram(asset);\n }\n\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\n return _nftStake[uuid];\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetDeposit(\n contractAddress,\n tokenId,\n walletManagerId,\n assetAmount\n );\n }\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\n }\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n // \"receiverEnergy\" includes the \"principalAmount\"\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n onlyOwner\n onlyValidContractAddress(controller)\n {\n _chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setMultiplierNft(address nftTokenAddress)\n external\n onlyOwner\n onlyValidContractAddress(nftTokenAddress)\n {\n _multiplierNft = nftTokenAddress;\n }\n\n function setRewardProgram(\n address rewardProgam,\n address assetToken\n )\n external\n onlyOwner\n onlyValidContractAddress(rewardProgam)\n {\n require(assetToken != address(0x0), \"UNI:E-403\");\n _assetRewardPrograms[assetToken] = rewardProgam;\n emit RewardProgramSet(assetToken, rewardProgam);\n }\n\n function removeRewardProgram(address assetToken) external onlyOwner {\n delete _assetRewardPrograms[assetToken];\n emit RewardProgramRemoved(assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getRewardProgram(address assetToken) internal view returns (address) {\n return _assetRewardPrograms[assetToken];\n }\n\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != depositNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n uint256 multiplier = _getNftMultiplier(depositNftTokenId);\n\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\n // Add to Multipliers Set\n _multiplierNftsSet[parentNftUuid].add(multiplier);\n\n // Update NFT Stake\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\n } else {\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\n }\n }\n\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\n }\n\n function _registerNftRelease(\n address contractAddress,\n uint256 tokenId,\n address releaseNftAddress,\n uint256 releaseNftTokenId,\n uint256 /* nftTokenAmount */\n )\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != releaseNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n NftStake storage nftStake = _nftStake[parentNftUuid];\n\n // Remove from Multipliers Set\n uint256 multiplier = _getNftMultiplier(releaseNftTokenId);\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\n\n // Determine New Multiplier or Mark as Released\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\n } else {\n nftStake.releaseBlockNumber = block.number;\n }\n\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\n }\n\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\n uint256 multiplier = 0;\n uint256 loss = 50;\n uint256 i = 0;\n\n for (; i < len; i++) {\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\n }\n if (len > 1) {\n multiplier = multiplier.sub(loss.mul(len));\n }\n return multiplier;\n }\n\n function _getNftMultiplier(uint256 tokenId) internal pure returns (uint256) {\n if (tokenId >= 1 && tokenId <= 721) {\n return 110;\n } else if (tokenId > 721 && tokenId <= 1122) {\n return 130;\n } else if (tokenId > 1122 && tokenId <= 1423) {\n return 150;\n } else if (tokenId > 1423 && tokenId <= 1624) {\n return 180;\n } else if (tokenId > 1624 && tokenId <= 1712) {\n return 230;\n } else if (tokenId > 1712 && tokenId <= 1733) {\n return 510;\n } else {\n return 1;\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(_chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/vesting/VestingClaim7.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract VestingClaim7 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"VestingClaim7: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"VestingClaim7: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"VestingClaim7: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"VestingClaim7: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"VestingClaim7: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"VestingClaim7: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveSmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\nimport \"../../interfaces/IAaveBridge.sol\";\nimport \"../../lib/SmartWalletBase.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet for Aave Assets\n * @dev Non-upgradeable Contract\n */\ncontract AaveSmartWallet is SmartWalletBase {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 constant internal RAY = 1e27;\n\n IAaveBridge internal _bridge;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(\n address aaveBridge\n )\n public\n {\n SmartWalletBase.initializeBase();\n _bridge = IAaveBridge(aaveBridge);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _bridge.isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address) {\n return _bridge.getReserveInterestToken(assetToken);\n }\n\n function getPrincipal(address assetToken) external override returns (uint256) {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address assetToken) external override returns (uint256 creatorInterest, uint256 ownerInterest) {\n return _getInterest(assetToken);\n }\n\n function getTotal(address assetToken) external override returns (uint256) {\n return _getTotal(assetToken);\n }\n\n function getRewards(address rewardToken) external override returns (uint256) {\n return IERC20(rewardToken).balanceOf(address(this));\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _deposit(assetToken, assetAmount, referralCode);\n }\n\n\n function withdraw(\n address receiver,\n address creatorRedirect,\n address assetToken\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (, uint256 ownerInterest) = _getInterest(assetToken);\n return _withdraw(receiver, creatorRedirect, assetToken, walletPrincipal.add(ownerInterest));\n }\n\n function withdrawAmount(\n address receiver,\n address creatorRedirect,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return _withdraw(receiver, creatorRedirect, assetToken, assetAmount);\n }\n\n function withdrawAmountForCreator(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return _withdrawForCreator(receiver, assetToken, assetAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _withdrawRewards(receiver, rewardsToken, rewardsAmount);\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n internal\n returns (uint256)\n {\n _trackAssetToken(assetToken);\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n\n // Deposit Assets into Aave (reverts on fail)\n _sendToken(address(_bridge), assetToken, assetAmount);\n uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function _withdraw(\n address receiver,\n address creatorRedirect,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken);\n\n // Withdraw from Interest only\n if (assetAmount < ownerInterest) {\n if (creatorInterest > 0) {\n uint256 ratio = assetAmount.mul(RAY).div(ownerInterest);\n creatorAmount = creatorInterest.add(nftCreatorAmountDischarged).mul(ratio).div(RAY);\n\n if (creatorAmount <= nftCreatorAmountDischarged) {\n nftCreatorAmountDischarged = nftCreatorAmountDischarged.sub(creatorAmount);\n creatorAmount = 0;\n }\n\n else {\n creatorAmount = creatorAmount.sub(nftCreatorAmountDischarged);\n nftCreatorAmountDischarged = 0;\n }\n }\n receiverAmount = assetAmount;\n }\n\n // Withdraw from Interest + Principal\n else {\n uint256 fromPrincipal = assetAmount.sub(ownerInterest);\n if (fromPrincipal > walletPrincipal) {\n fromPrincipal = walletPrincipal.sub(ownerInterest);\n }\n\n creatorAmount = creatorInterest;\n receiverAmount = ownerInterest.add(fromPrincipal);\n nftCreatorAmountDischarged = 0;\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal);\n }\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount));\n\n // Withdraw Assets for Creator\n if (creatorAmount > 0) {\n address receivesForCreator = (creatorRedirect != address(0x0)) ? creatorRedirect : nftCreator;\n _bridge.withdraw(receivesForCreator, assetToken, creatorAmount);\n }\n\n // Withdraw Assets for Receiver\n _bridge.withdraw(receiver, assetToken, receiverAmount);\n }\n\n function _withdrawForCreator(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 receiverAmount)\n {\n (uint256 creatorInterest,) = _getInterest(assetToken);\n if (creatorInterest == 0) { return 0; }\n if (assetAmount > creatorInterest) {\n assetAmount = creatorInterest;\n }\n\n nftCreatorAmountDischarged = nftCreatorAmountDischarged.add(assetAmount);\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, assetAmount);\n\n // Withdraw Assets for Receiver on behalf of Creator\n _bridge.withdraw(receiver, assetToken, assetAmount);\n }\n\n function _withdrawRewards(\n address receiver,\n address rewardsTokenAddress,\n uint256 rewardsAmount\n )\n internal\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"ASW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function _getTotal(address assetToken) internal view returns (uint256) {\n return _bridge.getTotalBalance(address(this), assetToken);\n }\n\n function _getInterest(address assetToken) internal view returns (uint256 creatorInterest, uint256 ownerInterest) {\n uint256 total = _getTotal(assetToken);\n uint256 principal = _getPrincipal(assetToken);\n uint256 interest = total.sub(principal);\n\n // Creator Royalties\n if (nftCreatorAnnuityPct > 0) {\n\n // Interest too small to calculate percentage;\n if (interest <= PERCENTAGE_SCALE) {\n // creatorInterest = interest.div(2); // split evenly?\n creatorInterest = 0; // All to owner\n }\n\n // Calculate percentage for Creator\n else {\n creatorInterest = interest\n .add(nftCreatorAmountDischarged)\n .mul(nftCreatorAnnuityPct)\n .div(PERCENTAGE_SCALE)\n .sub(nftCreatorAmountDischarged);\n }\n }\n\n // Owner Portion\n ownerInterest = interest.sub(creatorInterest);\n }\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveSmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\nimport \"../../interfaces/IAaveBridge.sol\";\nimport \"../../lib/SmartWalletBaseB.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet for Aave Assets\n * @dev Non-upgradeable Contract\n */\ncontract AaveSmartWalletB is SmartWalletBaseB {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 constant internal RAY = 1e27;\n\n IAaveBridge internal _bridge;\n\n uint256 internal _nftCreatorAmountDischarged;\n\n mapping (address => address) internal _assetATokens;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(\n address aaveBridge\n )\n public\n {\n SmartWalletBaseB.initializeBase();\n _bridge = IAaveBridge(aaveBridge);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _bridge.isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address) {\n return _bridge.getReserveInterestToken(assetToken);\n }\n\n function getPrincipal(address assetToken) external override returns (uint256) {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address assetToken, uint256 creatorPct) external override returns (uint256 creatorInterest, uint256 ownerInterest) {\n return _getInterest(assetToken, creatorPct);\n }\n\n function getTotal(address assetToken) external override returns (uint256) {\n return _getTotal(assetToken);\n }\n\n function getRewards(address rewardToken) external override returns (uint256) {\n return IERC20(rewardToken).balanceOf(address(this));\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _deposit(assetToken, assetAmount, referralCode);\n }\n\n\n function withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (, uint256 ownerInterest) = _getInterest(assetToken, creatorPct);\n return _withdraw(receiver, creator, creatorPct, assetToken, walletPrincipal.add(ownerInterest));\n }\n\n function withdrawAmount(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return _withdraw(receiver, creator, creatorPct, assetToken, assetAmount);\n }\n\n function withdrawAmountForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return _withdrawForCreator(receiver, creatorPct, assetToken, assetAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _withdrawRewards(receiver, rewardsToken, rewardsAmount);\n }\n\n function refreshPrincipal(address assetToken) external virtual override onlyWalletManager {\n uint256 aTokenBalance = IERC20(_assetATokens[assetToken]).balanceOf(address(this));\n if (_assetPrincipalBalance[assetToken] > aTokenBalance) {\n _assetPrincipalBalance[assetToken] = aTokenBalance;\n }\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n internal\n returns (uint256)\n {\n _trackAssetToken(assetToken);\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n\n // Deposit Assets into Aave (reverts on fail)\n _sendToken(address(_bridge), assetToken, assetAmount);\n uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function _withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken, creatorPct);\n\n // Withdraw from Interest only\n if (assetAmount < ownerInterest) {\n if (creatorInterest > 0) {\n uint256 ratio = assetAmount.mul(RAY).div(ownerInterest);\n creatorAmount = creatorInterest.add(_nftCreatorAmountDischarged).mul(ratio).div(RAY);\n\n if (creatorAmount <= _nftCreatorAmountDischarged) {\n _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.sub(creatorAmount);\n creatorAmount = 0;\n }\n else {\n creatorAmount = creatorAmount.sub(_nftCreatorAmountDischarged);\n _nftCreatorAmountDischarged = 0;\n }\n }\n receiverAmount = assetAmount;\n }\n\n // Withdraw from Interest + Principal\n else {\n uint256 fromPrincipal = assetAmount.sub(ownerInterest);\n if (fromPrincipal > walletPrincipal) {\n fromPrincipal = walletPrincipal.sub(ownerInterest);\n }\n\n creatorAmount = creatorInterest;\n receiverAmount = ownerInterest.add(fromPrincipal);\n _nftCreatorAmountDischarged = 0;\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal);\n }\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount));\n\n // Withdraw Assets for Creator\n if (creatorAmount > 0) {\n if (creator != address(0)) {\n _bridge.withdraw(creator, assetToken, creatorAmount);\n } else {\n receiverAmount = receiverAmount.add(creatorAmount);\n creatorAmount = 0;\n }\n }\n\n // Withdraw Assets for Receiver\n _bridge.withdraw(receiver, assetToken, receiverAmount);\n }\n\n function _withdrawForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 receiverAmount)\n {\n (uint256 creatorInterest,) = _getInterest(assetToken, creatorPct);\n if (creatorInterest == 0) { return 0; }\n if (assetAmount > creatorInterest) {\n assetAmount = creatorInterest;\n }\n\n _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.add(assetAmount);\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, assetAmount);\n\n // Withdraw Assets for Receiver on behalf of Creator\n _bridge.withdraw(receiver, assetToken, assetAmount);\n }\n\n function _withdrawRewards(\n address receiver,\n address rewardsTokenAddress,\n uint256 rewardsAmount\n )\n internal\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"ASW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function _getTotal(address assetToken) internal view returns (uint256) {\n return _bridge.getTotalBalance(address(this), assetToken);\n }\n\n function _getInterest(address assetToken, uint256 creatorPct) internal view returns (uint256 creatorInterest, uint256 ownerInterest) {\n uint256 total = _getTotal(assetToken);\n uint256 principal = _getPrincipal(assetToken);\n uint256 interest = total.sub(principal);\n\n // Creator Royalties\n if (creatorPct > 0) {\n\n // Interest too small to calculate percentage;\n if (interest <= PERCENTAGE_SCALE) {\n // creatorInterest = interest.div(2); // split evenly?\n creatorInterest = 0; // All to owner\n }\n\n // Calculate percentage for Creator\n else {\n creatorInterest = interest\n .add(_nftCreatorAmountDischarged)\n .mul(creatorPct)\n .div(PERCENTAGE_SCALE)\n .sub(_nftCreatorAmountDischarged);\n }\n }\n\n // Owner Portion\n ownerInterest = interest.sub(creatorInterest);\n }\n\n function _trackAssetToken(address assetToken) internal override {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _assetATokens[assetToken] = aTokenAddress;\n }\n }\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../lib/WalletManagerBase.sol\";\n\nimport \"./AaveSmartWallet.sol\";\n\n/**\n * @notice Wallet Manager for Aave\n * @dev Non-upgradeable Contract\n */\ncontract AaveWalletManager is WalletManagerBase {\n using SafeMath for uint256;\n\n event AaveBridgeSet(address indexed aaveBridge);\n event ValidRewardsTokenSet(address indexed rewardsToken, bool state);\n\n address internal _aaveBridge;\n uint256 internal _referralCode;\n\n mapping (address => bool) public rewardsTokenWhitelist;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new AaveSmartWallet());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return AaveSmartWallet(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return AaveSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return AaveSmartWallet(_wallets[uuid]).getInterest(assetToken);\n }\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getTotal(assetToken);\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getRewards(_rewardToken);\n }\n\n\n /***********************************|\n | Only Controller |\n |__________________________________*/\n\n function energize(\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = AaveSmartWallet(wallet).deposit(assetToken, assetAmount, _referralCode);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(ownerInterest > 0, \"AWM:E-412\");\n\n // Discharge the full amount of interest\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, ownerInterest);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(assetAmount > 0 && ownerInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmountForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address creator,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (uint256 creatorInterest,) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(assetAmount > 0 && creatorInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n receiverAmount = AaveSmartWallet(wallet).withdrawAmountForCreator(receiver, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount);\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = AaveSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0;\n\n // Release from interest first + principal if needed\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n require(rewardsTokenWhitelist[rewardsToken], \"AWM:E-423\");\n\n // Withdraw Rewards to Receiver\n amount = AaveSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 tokenId,\n address externalAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return AaveSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n // no-op\n }\n\n function getWalletAddressById(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPct\n )\n external\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n\n if (creator != address(0x0)) {\n AaveSmartWallet(wallet).setNftCreator(creator, annuityPct);\n }\n\n emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAaveBridge(address aaveBridge) external onlyOwner {\n require(aaveBridge != address(0x0), \"AWM:E-403\");\n _aaveBridge = aaveBridge;\n emit AaveBridgeSet(aaveBridge);\n }\n\n // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool\n function setReferralCode(uint256 referralCode) external onlyOwner {\n _referralCode = referralCode;\n }\n\n function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner {\n rewardsTokenWhitelist[rewardsToken] = state;\n emit ValidRewardsTokenSet(rewardsToken, state);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n AaveSmartWallet(newWallet).initialize(_aaveBridge);\n return newWallet;\n }\n}" + }, + "contracts/v1/yield/aave/AaveWalletManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../lib/WalletManagerBase.sol\";\nimport \"../../interfaces/IChargedSettings.sol\";\nimport \"./AaveSmartWalletB.sol\";\n\n/**\n * @notice Wallet Manager for Aave\n * @dev Non-upgradeable Contract\n */\ncontract AaveWalletManagerB is WalletManagerBase {\n using SafeMath for uint256;\n\n event AaveBridgeSet(address indexed aaveBridge);\n event ChargedSettingsSet(address indexed settings);\n event ValidRewardsTokenSet(address indexed rewardsToken, bool state);\n\n IChargedSettings internal _chargedSettings;\n\n address internal _aaveBridge;\n uint256 internal _referralCode;\n\n mapping (address => bool) public _rewardsTokenWhitelist;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new AaveSmartWalletB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return AaveSmartWalletB(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return AaveSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n return AaveSmartWalletB(_wallets[uuid]).getInterest(assetToken, annuityPct);\n }\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getTotal(assetToken);\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getRewards(_rewardToken);\n }\n\n\n /***********************************|\n | Only Controller |\n |__________________________________*/\n\n function energize(\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = AaveSmartWalletB(wallet).deposit(assetToken, assetAmount, _referralCode);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(ownerInterest > 0, \"AWM:E-412\");\n\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Discharge the full amount of interest\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, ownerInterest);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(assetAmount > 0 && ownerInterest >= assetAmount, \"AWM:E-412\");\n\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Discharge a portion of the interest\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmountForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address creator,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (uint256 creatorInterest,) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(assetAmount > 0 && creatorInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n receiverAmount = AaveSmartWalletB(wallet).withdrawAmountForCreator(receiver, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount);\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Release Principal + Interest\n principalAmount = AaveSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdraw(receiver, creator, annuityPct, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0;\n\n // Release from interest first + principal if needed\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n require(_rewardsTokenWhitelist[rewardsToken], \"AWM:E-423\");\n\n // Withdraw Rewards to Receiver\n amount = AaveSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 tokenId,\n address externalAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return AaveSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n AaveSmartWalletB(wallet).refreshPrincipal(assetToken);\n }\n\n function getWalletAddressById(\n address contractAddress,\n uint256 tokenId,\n address /* creator */,\n uint256 /* annuityPct */\n )\n external\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAaveBridge(address aaveBridge) external onlyOwner {\n require(aaveBridge != address(0x0), \"AWM:E-403\");\n _aaveBridge = aaveBridge;\n emit AaveBridgeSet(aaveBridge);\n }\n\n function setChargedSettings(address settings) external onlyOwner {\n require(settings != address(0x0), \"AWM:E-403\");\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool\n function setReferralCode(uint256 referralCode) external onlyOwner {\n _referralCode = referralCode;\n }\n\n function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner {\n _rewardsTokenWhitelist[rewardsToken] = state;\n emit ValidRewardsTokenSet(rewardsToken, state);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n AaveSmartWalletB(newWallet).initialize(_aaveBridge);\n return newWallet;\n }\n}" + }, + "contracts/v1/yield/aave/v2/AaveBridgeV2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveBridgeV2.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/SafeCast.sol\";\n\nimport \"./IATokenV2.sol\";\nimport \"./ILendingPoolV2.sol\";\nimport \"./ILendingPoolAddressesProviderV2.sol\";\n\nimport \"../../../interfaces/IAaveBridge.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\n\ncontract AaveBridgeV2 is Ownable, IAaveBridge, BlackholePrevention {\n using SafeMath for uint256;\n using SafeCast for uint256;\n using SafeERC20 for IERC20;\n using ReserveLogic for ReserveLogic.ReserveData;\n\n ILendingPoolAddressesProviderV2 public provider;\n ILendingPoolV2 public lendingPool;\n\n constructor (address lendingPoolProvider) public {\n provider = ILendingPoolAddressesProviderV2(lendingPoolProvider);\n lendingPool = ILendingPoolV2(provider.getLendingPool());\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address aTokenAddress) {\n return _getReserveInterestToken(assetToken);\n }\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _isReserveActive(assetToken);\n }\n\n function getTotalBalance(address account, address assetToken) external view override returns (uint256) {\n address aTokenAddress = _getReserveInterestToken(assetToken);\n if (aTokenAddress == address(0x0)) { return 0; }\n return IATokenV2(aTokenAddress).balanceOf(account);\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n returns (uint256)\n {\n address self = address(this);\n address aTokenAddress = _getReserveInterestToken(assetToken);\n require(_isReserveActive(assetToken), \"ABV2:E-424\");\n\n IERC20 token = IERC20(assetToken);\n IATokenV2 aToken = IATokenV2(aTokenAddress);\n\n if (token.allowance(address(this), address(lendingPool)) < assetAmount) {\n token.approve(address(lendingPool), uint256(-1));\n }\n\n // Deposit Assets into Aave\n uint256 preBalance = aToken.balanceOf(self);\n lendingPool.deposit(assetToken, assetAmount, self, referralCode.toUint16());\n uint256 postBalance = aToken.balanceOf(self);\n uint256 aTokensAmount = postBalance.sub(preBalance);\n\n // Transfer back the Interest Tokens\n _sendToken(msg.sender, aTokenAddress, aTokensAmount);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function withdraw(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n {\n address self = address(this);\n require(_isReserveActive(assetToken), \"ABV2:E-424\");\n\n // Redeem aTokens for Asset Tokens\n lendingPool.withdraw(assetToken, assetAmount, self);\n\n // Transfer back the Asset Tokens\n _sendToken(receiver, assetToken, assetAmount);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n\n function _getReserveInterestToken(address assetToken) internal view returns (address aTokenAddress) {\n ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken);\n return config.aTokenAddress;\n }\n\n function _isReserveActive(address assetToken) internal view returns (bool) {\n ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken);\n uint256 isActiveFlag = 2 ** 56; // bit 56: reserve is active\n return (config.configuration.data & isActiveFlag) == isActiveFlag;\n }\n}\n" + }, + "contracts/v1/yield/aave/v2/IATokenV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\n\ninterface IATokenV2 {\n function balanceOf(address account) external view returns (uint256);\n}\n" + }, + "contracts/v1/yield/aave/v2/ILendingPoolAddressesProviderV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\n\ninterface ILendingPoolAddressesProviderV2 {\n function getLendingPool() external view returns (address);\n}" + }, + "contracts/v1/yield/aave/v2/ILendingPoolV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport \"./ILendingPoolAddressesProviderV2.sol\";\n\nlibrary ReserveConfiguration {\n struct Map {\n uint256 data;\n }\n}\n\nlibrary ReserveLogic {\n struct ReserveData {\n ReserveConfiguration.Map configuration;\n uint128 liquidityIndex;\n uint128 variableBorrowIndex;\n uint128 currentLiquidityRate;\n uint128 currentVariableBorrowRate;\n uint128 currentStableBorrowRate;\n uint40 lastUpdateTimestamp;\n address aTokenAddress;\n address stableDebtTokenAddress;\n address variableDebtTokenAddress;\n address interestRateStrategyAddress;\n uint8 id;\n }\n}\n\ninterface ILendingPoolV2 {\n function deposit(address reserve, uint256 amount, address onBehalfOf, uint16 referralCode) external;\n function withdraw(address reserve, uint256 amount, address to) external;\n function getReserveData(address asset) external view returns (ReserveLogic.ReserveData memory);\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericSmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"../../../lib/SmartWalletBase.sol\";\n\n\n/**\n * @notice Generic ERC20-Token Smart-Wallet Bridge\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartWallet is SmartWalletBase {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize()\n public\n {\n SmartWalletBase.initializeBase();\n }\n\n function isReserveActive(address assetToken)\n external\n override\n view\n returns (bool)\n {\n return _getPrincipal(assetToken) == 0;\n }\n\n function getReserveInterestToken(address assetToken)\n external\n override\n view\n returns (address)\n {\n return assetToken;\n }\n\n function getPrincipal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address /* assetToken */)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n return (0, 0);\n }\n\n function getTotal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getRewards(address assetToken)\n external\n override\n returns (uint256)\n {\n return IERC20(assetToken).balanceOf(address(this));\n }\n\n function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n // Track Principal\n _trackAssetToken(assetToken);\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n }\n\n function withdraw(address receiver, address /* creatorRedirect */, address assetToken)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmount(address receiver, address /* creatorRedirect */, address assetToken, uint256 assetAmount)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n if (receiverAmount >= assetAmount) {\n receiverAmount = assetAmount;\n }\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmountForCreator(\n address /* receiver */,\n address /* assetToken */,\n uint256 /* assetID */\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericSmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWalletB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"../../../lib/SmartWalletBaseB.sol\";\n\n\n/**\n * @notice Generic ERC20-Token Smart-Wallet Bridge\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartWalletB is SmartWalletBaseB {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize()\n public\n {\n SmartWalletBaseB.initializeBase();\n }\n\n function isReserveActive(address assetToken)\n external\n override\n view\n returns (bool)\n {\n return _getPrincipal(assetToken) == 0;\n }\n\n function getReserveInterestToken(address assetToken)\n external\n override\n view\n returns (address)\n {\n return assetToken;\n }\n\n function getPrincipal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address /* assetToken */, uint256 /* creatorPct */)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n return (0, 0);\n }\n\n function getTotal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getRewards(address assetToken)\n external\n override\n returns (uint256)\n {\n return IERC20(assetToken).balanceOf(address(this));\n }\n\n function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n // Track Principal\n _trackAssetToken(assetToken);\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n }\n\n function withdraw(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmount(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken, uint256 assetAmount)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n if (receiverAmount >= assetAmount) {\n receiverAmount = assetAmount;\n }\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmountForCreator(\n address /* receiver */,\n uint256 /* creatorPct */,\n address /* assetToken */,\n uint256 /* assetID */\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function refreshPrincipal(address assetToken) external virtual override onlyWalletManager {\n _assetPrincipalBalance[assetToken] = IERC20(assetToken).balanceOf(address(this));\n }\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../../lib/WalletManagerBase.sol\";\nimport \"./GenericSmartWallet.sol\";\n\n/**\n * @notice Generic ERC20 Wallet Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericWalletManager is WalletManagerBase {\n using SafeMath for uint256;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new GenericSmartWallet());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return GenericSmartWallet(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return GenericSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getTotal(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return GenericSmartWallet(_wallets[uuid]).getInterest(assetToken);\n }\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getRewards(rewardToken);\n }\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount)\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = GenericSmartWallet(wallet).deposit(assetToken, assetAmount, 0);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmountForCreator(\n address /* receiver */,\n address /* contractAddress */,\n uint256 /* tokenId */,\n address /* creator */,\n address /* assetToken */,\n uint256 /* assetAmount */\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release from interest first + principal if needed\n principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n external\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return GenericSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n // no-op\n }\n\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct)\n external\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n\n if (creator != address(0x0)) {\n GenericSmartWallet(wallet).setNftCreator(creator, annuityPct);\n }\n\n emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n GenericSmartWallet(newWallet).initialize();\n return newWallet;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericWalletManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericWalletManagerB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../../lib/WalletManagerBase.sol\";\nimport \"./GenericSmartWalletB.sol\";\n\n/**\n * @notice Generic ERC20 Wallet Manager B\n * @dev Non-upgradeable Contract\n */\ncontract GenericWalletManagerB is WalletManagerBase {\n using SafeMath for uint256;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new GenericSmartWalletB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return GenericSmartWalletB(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return GenericSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getTotal(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return GenericSmartWalletB(_wallets[uuid]).getInterest(assetToken, 0);\n }\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getRewards(rewardToken);\n }\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount)\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = GenericSmartWalletB(wallet).deposit(assetToken, assetAmount, 0);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmountForCreator(\n address /* receiver */,\n address /* contractAddress */,\n uint256 /* tokenId */,\n address /* creator */,\n address /* assetToken */,\n uint256 /* assetAmount */\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdraw(receiver, creatorRedirect, 0, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release from interest first + principal if needed\n principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdrawAmount(receiver, creatorRedirect, 0, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyControllerOrExecutor\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n external\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return GenericSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n GenericSmartWalletB(wallet).refreshPrincipal(assetToken);\n }\n\n function getWalletAddressById(address contractAddress, uint256 tokenId, address /* creator */, uint256 /* annuityPct */)\n external\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n GenericSmartWalletB(newWallet).initialize();\n return newWallet;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericBasketManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"../../../interfaces/IBasketManager.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"./GenericSmartBasket.sol\";\n\n/**\n * @notice Generic ERC721 Basket Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericBasketManager is Ownable, BlackholePrevention, IBasketManager {\n using Counters for Counters.Counter;\n using TokenInfo for address;\n\n // The Controller Contract Address\n address internal _controller;\n\n // Template Contract for creating Token Smart-Baskets\n address internal _basketTemplate;\n\n // TokenID => Token Smart-Basket Address\n mapping (uint256 => address) internal _baskets;\n\n mapping (uint256 => Counters.Counter) internal _totalTokens;\n\n // State of Basket Manager\n bool internal _paused;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _basketTemplate = address(new GenericSmartBasket());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n function getTokenTotalCount(\n address contractAddress,\n uint256 tokenId\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n return _totalTokens[uuid].current();\n }\n\n function getTokenCountByType(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n external\n override\n returns (uint256)\n {\n address basket = getBasketAddressById(contractAddress, tokenId);\n return GenericSmartBasket(basket).getTokenCountByType(basketTokenAddress, basketTokenId);\n }\n\n function prepareTransferAmount(uint256 /* nftTokenAmount */) external override onlyController {\n // no-op\n }\n\n function addToBasket(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n whenNotPaused\n returns (bool added)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n added = GenericSmartBasket(basket).addToBasket(basketTokenAddress, basketTokenId);\n\n // Log Event\n if (added) {\n _totalTokens[uuid].increment();\n emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, 1);\n }\n }\n\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n returns (bool removed)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n removed = GenericSmartBasket(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId);\n\n // Log Event\n if (removed) {\n _totalTokens[uuid].decrement();\n emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, 1);\n }\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyController\n returns (uint256 amount)\n {\n // no-op\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n public\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n return GenericSmartBasket(basket).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function getBasketAddressById(address contractAddress, uint256 tokenId)\n public\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n // Create Smart-Basket if none exists\n if (basket == address(0x0)) {\n basket = _createBasket();\n _baskets[uuid] = basket;\n\n emit NewSmartBasket(contractAddress, tokenId, basket);\n }\n\n return basket;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Basket Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartBasket(basket).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n function _createBasket()\n internal\n returns (address)\n {\n address newBasket = _createClone(_basketTemplate);\n GenericSmartBasket(newBasket).initialize();\n return newBasket;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"GBM:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"GBM:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericBasketManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport \"../../../interfaces/IBasketManager.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../interfaces/ITokenInfoProxy.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"../../../lib/NftTokenType.sol\";\nimport \"./GenericSmartBasketB.sol\";\n\n/**\n * @notice Generic ERC721 Basket Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericBasketManagerB is Ownable, BlackholePrevention, IBasketManager {\n using Counters for Counters.Counter;\n using TokenInfo for address;\n using NftTokenType for address;\n\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // The Controller Contract Address\n address internal _controller;\n\n // The Executor Contract Address\n address internal _executor;\n\n // Template Contract for creating Token Smart-Baskets\n address internal _basketTemplate;\n\n // TokenID => Token Smart-Basket Address\n mapping (uint256 => address) internal _baskets;\n\n // Prepared Amount\n uint256 internal _preparedAmount;\n\n // State of Basket Manager\n bool internal _paused;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _basketTemplate = address(new GenericSmartBasketB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n function getTokenTotalCount(\n address contractAddress,\n uint256 tokenId\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n if (basket == address(0)) { return 0; }\n return GenericSmartBasketB(basket).getNestedNftCount();\n }\n\n function getTokenCountByType(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n if (basket == address(0)) { return 0; }\n return GenericSmartBasketB(basket).getTokenCountByType(basketTokenAddress, basketTokenId);\n }\n\n function prepareTransferAmount(uint256 nftTokenAmount) external override onlyController {\n _preparedAmount = nftTokenAmount;\n }\n\n function addToBasket(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n whenNotPaused\n returns (bool added)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n uint256 nftTokenAmount = 1;\n if (_preparedAmount > 0) {\n nftTokenAmount = _preparedAmount;\n _preparedAmount = 0;\n }\n\n added = GenericSmartBasketB(basket).addToBasket(basketTokenAddress, basketTokenId, nftTokenAmount);\n if (added) {\n emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount);\n }\n }\n\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n returns (bool removed)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n uint256 nftTokenAmount = 1;\n if (_preparedAmount > 0) {\n nftTokenAmount = _preparedAmount;\n _preparedAmount = 0;\n }\n\n removed = GenericSmartBasketB(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId, nftTokenAmount);\n if (removed) {\n emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount);\n }\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyControllerOrExecutor\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartBasketB(basket).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit BasketRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n public\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n return GenericSmartBasketB(basket).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function getBasketAddressById(address contractAddress, uint256 tokenId)\n public\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n // Create Smart-Basket if none exists\n if (basket == address(0x0)) {\n basket = _createBasket();\n _baskets[uuid] = basket;\n\n emit NewSmartBasket(contractAddress, tokenId, basket);\n }\n\n return basket;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Basket Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n /**\n * @dev Connects to the ExecForAccount Controller\n */\n function setExecutor(address executor) external onlyOwner {\n _executor = executor;\n emit ExecutorSet(executor);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setTokenInfoProxy(address tokenInfoProxy) external onlyOwner {\n _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartBasket(basket).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createBasket()\n internal\n returns (address)\n {\n address newBasket = _createClone(_basketTemplate);\n GenericSmartBasketB(newBasket).initialize(_tokenInfoProxy);\n return newBasket;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"GBM:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Controller or Executor contract\n modifier onlyControllerOrExecutor() {\n require(_executor == msg.sender || _controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"GBM:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericSmartBasket.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/NftTokenType.sol\";\n\n\n/**\n * @notice Generic ERC721-Token Smart-Basket\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartBasket is ISmartBasket, BlackholePrevention, IERC721Receiver {\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableSet for EnumerableSet.AddressSet;\n using NftTokenType for address;\n\n address internal _basketManager;\n\n // NFT contract address => Token Ids in Basket\n mapping (address => mapping(uint256 => EnumerableSet.UintSet)) internal _nftContractTokens;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public {\n require(_basketManager == address(0x0), \"GSB:E-002\");\n _basketManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n return _nftContractTokens[contractAddress][nftType].length();\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver(0).onERC721Received.selector;\n }\n\n function addToBasket(address contractAddress, uint256 tokenId)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n require(!_nftContractTokens[contractAddress][nftType].contains(tokenId), \"GSB:E-425\");\n\n bool added = _nftContractTokens[contractAddress][nftType].add(tokenId);\n if (added) {\n // NFT should have been Transferred into here via Charged-Particles\n added = (IERC721(contractAddress).ownerOf(tokenId) == address(this));\n }\n return added;\n }\n\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n require(_nftContractTokens[contractAddress][nftType].contains(tokenId), \"GSB:E-426\");\n\n bool removed = _nftContractTokens[contractAddress][nftType].remove(tokenId);\n if (removed) {\n IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId);\n }\n return removed;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyBasketManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the basket manager\n modifier onlyBasketManager() {\n require(_basketManager == msg.sender, \"GSB:E-109\");\n _;\n }\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericSmartBasketB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155Receiver.sol\";\nimport \"../../../interfaces/ISmartBasketB.sol\";\nimport \"../../../interfaces/ITokenInfoProxy.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"../../../lib/NftTokenType.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\n\n/**\n * @notice Generic ERC721-Token Smart-Basket\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartBasketB is ISmartBasketB, BlackholePrevention, IERC721Receiver, ERC1155Receiver {\n using TokenInfo for address;\n using NftTokenType for address;\n\n address internal _basketManager;\n\n // NFT TokenUUID => ERC1155 Balance\n mapping (uint256 => uint256) internal _nftContractTokenBalance;\n uint256 internal _nestedNftCount;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(ITokenInfoProxy /* tokenInfoProxy */) public {\n require(_basketManager == address(0x0), \"GSB:E-002\");\n _basketManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getNestedNftCount() external view override returns (uint256) {\n return _nestedNftCount;\n }\n\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n return _nftContractTokenBalance[contractAddress.getTokenUUID(tokenId)];\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver(0).onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\n return IERC1155Receiver(0).onERC1155Received.selector;\n }\n\n // Unimplemented\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\n return \"\"; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector;\n }\n\n function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n _nftContractTokenBalance[uuid] += nftTokenAmount;\n _nestedNftCount += nftTokenAmount;\n return true;\n }\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n uint256 nftTokenAmount\n )\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n _nftContractTokenBalance[uuid] -= nftTokenAmount;\n _nestedNftCount -= nftTokenAmount;\n\n if (contractAddress.isERC1155()) {\n IERC1155(contractAddress).safeTransferFrom(address(this), receiver, tokenId, nftTokenAmount, \"\");\n } else {\n IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId);\n }\n return true;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyBasketManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSB:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyBasketManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the basket manager\n modifier onlyBasketManager() {\n require(_basketManager == msg.sender, \"GSB:E-109\");\n _;\n }\n}\n" + }, + "erc20permit/contracts/ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"./IERC2612.sol\";\n\n/**\n * @author Georgios Konstantopoulos\n * @dev Extension of {ERC20} that allows token holders to use their tokens\n * without sending any transactions by setting {IERC20-allowance} with a\n * signature using the {permit} method, and then spend them via\n * {IERC20-transferFrom}.\n *\n * The {permit} signature mechanism conforms to the {IERC2612} interface.\n */\nabstract contract ERC20Permit is ERC20, IERC2612 {\n mapping (address => uint256) public override nonces;\n\n bytes32 public immutable PERMIT_TYPEHASH = keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public immutable DOMAIN_SEPARATOR;\n\n constructor(string memory name_, string memory symbol_) internal ERC20(name_, symbol_) {\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name_)),\n keccak256(bytes(\"1\")),\n chainId,\n address(this)\n )\n );\n }\n\n /**\n * @dev See {IERC2612-permit}.\n *\n * In cases where the free option is not a concern, deadline can simply be\n * set to uint(-1), so it should be seen as an optional parameter\n */\n function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {\n require(deadline >= block.timestamp, \"ERC20Permit: expired deadline\");\n\n bytes32 hashStruct = keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n amount,\n nonces[owner]++,\n deadline\n )\n );\n\n bytes32 hash = keccak256(\n abi.encodePacked(\n '\\x19\\x01',\n DOMAIN_SEPARATOR,\n hashStruct\n )\n );\n\n address signer = ecrecover(hash, v, r, s);\n require(\n signer != address(0) && signer == owner,\n \"ERC20Permit: invalid signature\"\n );\n\n _approve(owner, spender, amount);\n }\n}\n" + }, + "erc20permit/contracts/IERC2612.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC2612 standard as defined in the EIP.\n *\n * Adds the {permit} method, which can be used to change one's\n * {IERC20-allowance} without having to send a transaction, by signing a\n * message. This allows users to spend tokens without having to hold Ether.\n *\n * See https://eips.ethereum.org/EIPS/eip-2612.\n */\ninterface IERC2612 {\n /**\n * @dev Sets `amount` 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 * - `owner` cannot be the zero address.\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(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n /**\n * @dev Returns the current ERC2612 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" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "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/deployments/mainnet/solcInputs/a391d2a1c9130e2e821ff2c29fb21b5f.json b/deployments/mainnet/solcInputs/a391d2a1c9130e2e821ff2c29fb21b5f.json new file mode 100644 index 0000000..f7ea409 --- /dev/null +++ b/deployments/mainnet/solcInputs/a391d2a1c9130e2e821ff2c29fb21b5f.json @@ -0,0 +1,458 @@ +{ + "language": "Solidity", + "sources": { + "@opengsn/gsn/contracts/BaseRelayRecipient.sol": { + "content": "// SPDX-License-Identifier:MIT\n// solhint-disable no-inline-assembly\npragma solidity ^0.6.2;\n\nimport \"./interfaces/IRelayRecipient.sol\";\n\n/**\n * A base contract to be inherited by any contract that want to receive relayed transactions\n * A subclass must use \"_msgSender()\" instead of \"msg.sender\"\n */\nabstract contract BaseRelayRecipient is IRelayRecipient {\n\n /*\n * Forwarder singleton we accept calls from\n */\n address public trustedForwarder;\n\n function isTrustedForwarder(address forwarder) public override view returns(bool) {\n return forwarder == trustedForwarder;\n }\n\n /**\n * return the sender of this call.\n * if the call came through our trusted forwarder, return the original sender.\n * otherwise, return `msg.sender`.\n * should be used in the contract anywhere instead of msg.sender\n */\n function _msgSender() internal override virtual view returns (address payable ret) {\n if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // so we trust that the last bytes of msg.data are the verified sender address.\n // extract sender address from the end of msg.data\n assembly {\n ret := shr(96,calldataload(sub(calldatasize(),20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n /**\n * return the msg.data of this call.\n * if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes\n * of the msg.data - so this method will strip those 20 bytes off.\n * otherwise, return `msg.data`\n * should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly\n * signing or hashing the\n */\n function _msgData() internal override virtual view returns (bytes memory ret) {\n if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // we copy the msg.data , except the last 20 bytes (and update the total length)\n assembly {\n let ptr := mload(0x40)\n // copy only size-20 bytes\n let size := sub(calldatasize(),20)\n // structure RLP data as \n mstore(ptr, 0x20)\n mstore(add(ptr,32), size)\n calldatacopy(add(ptr,64), 0, size)\n return(ptr, add(size,64))\n }\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "@opengsn/gsn/contracts/interfaces/IRelayRecipient.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.6.2;\n\n/**\n * a contract must implement this interface in order to support relayed transaction.\n * It is better to inherit the BaseRelayRecipient as its implementation.\n */\nabstract contract IRelayRecipient {\n\n /**\n * return if the forwarder is trusted to forward relayed transactions to us.\n * the forwarder is required to verify the sender's signature, and verify\n * the call is not a replay.\n */\n function isTrustedForwarder(address forwarder) public virtual view returns(bool);\n\n /**\n * return the sender of this call.\n * if the call came through our trusted forwarder, then the real sender is appended as the last 20 bytes\n * of the msg.data.\n * otherwise, return `msg.sender`\n * should be used in the contract anywhere instead of msg.sender\n */\n function _msgSender() internal virtual view returns (address payable);\n\n /**\n * return the msg.data of this call.\n * if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes\n * of the msg.data - so this method will strip those 20 bytes off.\n * otherwise, return `msg.data`\n * should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly\n * signing or hashing the\n */\n function _msgData() internal virtual view returns (bytes memory);\n\n function versionRecipient() external virtual view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\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 initializer {\n __Context_init_unchained();\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal initializer {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), 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 emit OwnershipTransferred(_owner, address(0));\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n function __ERC165_init() internal initializer {\n __ERC165_init_unchained();\n }\n\n function __ERC165_init_unchained() internal initializer {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMathUpgradeable {\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 uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\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 if (b > a) return (false, 0);\n return (true, a - b);\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 // 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 * @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 if (b == 0) return (false, 0);\n return (true, a / b);\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 if (b == 0) return (false, 0);\n return (true, a % b);\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 uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n return c;\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 require(b <= a, \"SafeMath: subtraction overflow\");\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 if (a == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n return c;\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. 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(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: division by zero\");\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 require(b > 0, \"SafeMath: modulo by zero\");\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n return a - b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a / b;\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.4.24 <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 {UpgradeableProxy-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 */\nabstract contract Initializable {\n\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 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 /// @dev Returns true if and only if the function is running in the constructor\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\n\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 )\n external\n 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 )\n external\n returns(bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC20Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../proxy/Initializable.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 guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable {\n using SafeMathUpgradeable for uint256;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal initializer {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer {\n _name = name_;\n _symbol = symbol_;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal virtual {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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(address sender, address recipient, uint256 amount) 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/ERC20/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.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 SafeERC20Upgradeable {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) 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(IERC20Upgradeable token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\n require((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(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\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(IERC20Upgradeable 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) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721MetadataUpgradeable.sol\";\nimport \"./IERC721EnumerableUpgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"../../introspection/ERC165Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/EnumerableSetUpgradeable.sol\";\nimport \"../../utils/EnumerableMapUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../proxy/Initializable.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable, IERC721EnumerableUpgradeable {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet;\n using EnumerableMapUpgradeable for EnumerableMapUpgradeable.UintToAddressMap;\n using StringsUpgradeable for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSetUpgradeable.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMapUpgradeable.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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 initializer {\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 initializer {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\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 _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\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 _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\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(_msgSender() == owner || ERC721Upgradeable.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 require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) 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(address from, address to, uint256 tokenId, bytes memory _data) 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 _tokenOwners.contains(tokenId);\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 || ERC721Upgradeable.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\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 _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(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); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(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(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721ReceiverUpgradeable(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); // internal owner\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(address from, address to, uint256 tokenId) internal virtual { }\n uint256[41] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721EnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 /**\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/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 /**\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\npragma solidity >=0.6.0 <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(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) 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 // solhint-disable-next-line avoid-low-level-calls\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(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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 // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/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 GSN 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 initializer {\n __Context_init_unchained();\n }\n\n function __Context_init_unchained() internal initializer {\n }\n function _msgSender() internal view virtual returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/EnumerableMapUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMapUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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 EnumerableSetUpgradeable {\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\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\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] = toDeleteIndex + 1; // All indexes are 1-based\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 require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\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 // 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 // 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" + }, + "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/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 initializer {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal initializer {\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 make 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/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n /**\n * @dev Converts a `uint256` to its ASCII `string` 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 uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = bytes1(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../GSN/Context.sol\";\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 */\ncontract 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 () internal {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), msgSender);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view 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 emit OwnershipTransferred(_owner, address(0));\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n" + }, + "@openzeppelin/contracts/cryptography/MerkleProof.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev These functions deal with verification of Merkle trees (hash trees),\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(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {\n bytes32 computedHash = leaf;\n\n for (uint256 i = 0; i < proof.length; i++) {\n bytes32 proofElement = proof[i];\n\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\n // Check if the computed hash (root) is equal to the provided root\n return computedHash == root;\n }\n}\n" + }, + "@openzeppelin/contracts/GSN/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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 GSN 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 payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\ncontract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () internal {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n" + }, + "@openzeppelin/contracts/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\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 uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\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 sub(a, b, \"SafeMath: subtraction overflow\");\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 * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\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 // 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) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts 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 mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\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 SafeMath for uint256;\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 * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri) public {\n _setURI(uri);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\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) external view 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 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(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\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 require(accounts[i] != address(0), \"ERC1155: batch balance query for the zero address\");\n batchBalances[i] = _balances[ids[i]][accounts[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 require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view 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 )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, 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 )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\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 _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(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 `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` 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(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, 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(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) 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 (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\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 `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, 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(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != 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, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\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 )\n internal virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).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 )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).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/token/ERC1155/ERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() public {\n _registerInterface(\n ERC1155Receiver(0).onERC1155Received.selector ^\n ERC1155Receiver(0).onERC1155BatchReceived.selector\n );\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\nimport \"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\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 )\n external\n 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 )\n external\n returns(bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.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 guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 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 {\n using SafeMath for uint256;\n using Address for address;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name, string memory symbol) public {\n _name = name;\n _symbol = symbol;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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/token/ERC20/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.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 SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\n require((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(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\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) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n\n // If there is no base URI, return the token URI.\n if (bytes(_baseURI).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(_baseURI, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(_baseURI, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_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 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 require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) 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(address from, address to, uint256 tokenId, bytes memory _data) 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 returns (bool) {\n return _tokenOwners.contains(tokenId);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = 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 d*\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\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 _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(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 = ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(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(address from, address to, uint256 tokenId) internal virtual {\n require(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 _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\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(address from, address to, uint256 tokenId) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\nimport \"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 /**\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/token/ERC721/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 /**\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/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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(address operator, address from, uint256 tokenId, bytes calldata data)\n external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 in 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 // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n return _functionCallWithValue(target, data, value, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\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 // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../math/SafeMath.sol\";\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented or decremented by one. 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 * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}\n * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never\n * directly accessed.\n */\nlibrary Counters {\n using SafeMath for uint256;\n\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 // The {SafeMath} overflow check can be skipped here, see the comment at the top\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableMap.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n return _get(map, key, \"EnumerableMap: nonexistent key\");\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(value)));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint256(value)));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint256(_get(map._inner, bytes32(key))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint256(_get(map._inner, bytes32(key), errorMessage)));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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.0.0, only sets of type `address` (`AddressSet`) and `uint256`\n * (`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\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\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] = toDeleteIndex + 1; // All indexes are 1-based\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 require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\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(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(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(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(uint256(_at(set._inner, index)));\n }\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" + }, + "@openzeppelin/contracts/utils/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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 */\ncontract 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 () internal {\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 make 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/utils/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value < 2**128, \"SafeCast: value doesn\\'t fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value < 2**64, \"SafeCast: value doesn\\'t fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value < 2**32, \"SafeCast: value doesn\\'t fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value < 2**16, \"SafeCast: value doesn\\'t fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value < 2**8, \"SafeCast: value doesn\\'t fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= -2**127 && value < 2**127, \"SafeCast: value doesn\\'t fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= -2**63 && value < 2**63, \"SafeCast: value doesn\\'t fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= -2**31 && value < 2**31, \"SafeCast: value doesn\\'t fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= -2**15 && value < 2**15, \"SafeCast: value doesn\\'t fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= -2**7 && value < 2**7, \"SafeCast: value doesn\\'t fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n require(value < 2**255, \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` 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 uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = byte(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n" + }, + "contracts/v1/ChargedManagers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Wallet-Managers Contract\n */\ncontract ChargedManagers is\n IChargedManagers,\n Initializable,\n OwnableUpgradeable,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n\n IChargedSettings internal _chargedSettings;\n IChargedState internal _chargedState;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // Wallet/Basket Managers (by Unique Manager ID)\n mapping (string => IWalletManager) internal _ftWalletManager;\n mapping (string => IBasketManager) internal _nftBasketManager;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n /// @notice Checks if an Account is the Owner of an NFT Contract\n /// When Custom Contracts are registered, only the \"owner\" or operator of the Contract\n /// is allowed to register them and define custom rules for how their tokens are \"Charged\".\n /// Otherwise, any token can be \"Charged\" according to the default rules of Charged Particles.\n /// @param contractAddress The Address to the External NFT Contract to check\n /// @param account The Account to check if it is the Owner of the specified Contract\n /// @return True if the account is the Owner of the _contract\n function isContractOwner(address contractAddress, address account) external view override virtual returns (bool) {\n return contractAddress.isContractOwner(account);\n }\n\n function isWalletManagerEnabled(string calldata walletManagerId) external virtual override view returns (bool) {\n return _isWalletManagerEnabled(walletManagerId);\n }\n\n function getWalletManager(string calldata walletManagerId) external virtual override view returns (IWalletManager) {\n return _ftWalletManager[walletManagerId];\n }\n\n function isNftBasketEnabled(string calldata basketId) external virtual override view returns (bool) {\n return _isNftBasketEnabled(basketId);\n }\n\n function getBasketManager(string calldata basketId) external virtual override view returns (IBasketManager) {\n return _nftBasketManager[basketId];\n }\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param sender The sender address to validate against\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external virtual override {\n _validateDeposit(sender, contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param sender The sender address to validate against\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external virtual override {\n _validateNftDeposit(sender, contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateDischarge(sender, contractAddress, tokenId);\n }\n\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateRelease(sender, contractAddress, tokenId);\n }\n\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateBreakBond(sender, contractAddress, tokenId);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"state\"))) {\n _chargedState = IChargedState(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n /// @dev Register Contracts as wallet managers with a unique liquidity provider ID\n function registerWalletManager(string calldata walletManagerId, address walletManager) external virtual onlyOwner {\n // Validate wallet manager\n IWalletManager newWalletMgr = IWalletManager(walletManager);\n require(newWalletMgr.isPaused() != true, \"CP:E-418\");\n\n // Register LP ID\n _ftWalletManager[walletManagerId] = newWalletMgr;\n emit WalletManagerRegistered(walletManagerId, walletManager);\n }\n\n /// @dev Register Contracts as basket managers with a unique basket ID\n function registerBasketManager(string calldata basketId, address basketManager) external virtual onlyOwner {\n // Validate basket manager\n IBasketManager newBasketMgr = IBasketManager(basketManager);\n require(newBasketMgr.isPaused() != true, \"CP:E-418\");\n\n // Register Basket ID\n _nftBasketManager[basketId] = newBasketMgr;\n emit BasketManagerRegistered(basketId, basketManager);\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev See {ChargedParticles-isWalletManagerEnabled}.\n function _isWalletManagerEnabled(string calldata walletManagerId) internal view virtual returns (bool) {\n return (address(_ftWalletManager[walletManagerId]) != address(0x0) && !_ftWalletManager[walletManagerId].isPaused());\n }\n\n /// @dev See {ChargedParticles-isNftBasketEnabled}.\n function _isNftBasketEnabled(string calldata basketId) internal view virtual returns (bool) {\n return (address(_nftBasketManager[basketId]) != address(0x0) && !_nftBasketManager[basketId].isPaused());\n }\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n internal\n virtual\n {\n if (_chargedState.isEnergizeRestricted(contractAddress, tokenId)) {\n bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender);\n require(isNFTOwnerOrOperator, \"CP:E-105\");\n }\n\n ( string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n ) = _chargedSettings.getAssetRequirements(contractAddress, assetToken);\n\n require(energizeEnabled, \"CP:E-417\");\n\n require(!invalidAsset, \"CP:E-424\");\n\n // Valid Wallet Manager?\n if (bytes(requiredWalletManager).length > 0) {\n require(keccak256(abi.encodePacked(requiredWalletManager)) == keccak256(abi.encodePacked(walletManagerId)), \"CP:E-419\");\n }\n\n // Valid Asset?\n if (restrictedAssets) {\n require(validAsset, \"CP:E-424\");\n }\n\n _validateDepositAmount(\n contractAddress,\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n depositCap,\n depositMin,\n depositMax\n );\n }\n\n /// @dev Validates a Deposit-Amount according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDepositAmount(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax\n )\n internal\n virtual\n {\n uint256 existingBalance = _ftWalletManager[walletManagerId].getPrincipal(contractAddress, tokenId, assetToken);\n uint256 newBalance = assetAmount.add(existingBalance);\n\n // Validate Deposit Cap\n if (depositCap > 0) {\n require(newBalance <= depositCap, \"CP:E-408\");\n }\n\n // Valid Amount for Deposit?\n if (depositMin > 0) {\n require(newBalance >= depositMin, \"CP:E-410\");\n }\n if (depositMax > 0) {\n require(newBalance <= depositMax, \"CP:E-410\");\n }\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n {\n // Prevent Ouroboros NFTs\n require(contractAddress.getTokenUUID(tokenId) != nftTokenAddress.getTokenUUID(nftTokenId), \"CP:E-433\");\n\n if (_chargedState.isCovalentBondRestricted(contractAddress, tokenId)) {\n bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender);\n require(isNFTOwnerOrOperator, \"CP:E-105\");\n }\n\n ( string memory requiredBasketManager,\n bool basketEnabled,\n uint256 maxNfts\n ) = _chargedSettings.getNftAssetRequirements(contractAddress, nftTokenAddress);\n\n require(basketEnabled, \"CP:E-417\");\n\n // Valid Basket Manager?\n if (bytes(requiredBasketManager).length > 0) {\n require(keccak256(abi.encodePacked(requiredBasketManager)) == keccak256(abi.encodePacked(basketManagerId)), \"CP:E-419\");\n }\n\n if (maxNfts > 0) {\n uint256 tokenCount = _nftBasketManager[basketManagerId].getTokenTotalCount(contractAddress, tokenId);\n require(maxNfts >= (tokenCount + nftTokenAmount), \"CP:E-427\");\n }\n }\n\n function _validateDischarge(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getDischargeState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateRelease(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getReleaseState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateBreakBond(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getBreakBondState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateState(\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n internal\n view\n virtual\n {\n if (!allowFromAll) {\n require(isApproved, \"CP:E-105\");\n }\n if (timelock > 0) {\n require(block.number >= timelock, \"CP:E-302\");\n }\n if (tempLockExpiry > 0) {\n require(block.number >= tempLockExpiry, \"CP:E-303\");\n }\n }\n}\n" + }, + "contracts/v1/ChargedParticles.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\n\nimport \"./interfaces/IUniverse.sol\";\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/IWalletManager.sol\";\nimport \"./interfaces/IBasketManager.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/RelayRecipient.sol\";\n\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles V2 Contract\n * @dev Upgradeable Contract\n */\ncontract ChargedParticles is\n IChargedParticles,\n Initializable,\n OwnableUpgradeable,\n ReentrancyGuardUpgradeable,\n RelayRecipient,\n IERC721ReceiverUpgradeable,\n BlackholePrevention,\n IERC1155ReceiverUpgradeable\n{\n using SafeMathUpgradeable for uint256;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using Bitwise for uint32;\n using AddressUpgradeable for address;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n //\n // Particle Terminology\n //\n // Particle - Non-fungible Token (NFT)\n // Mass - Underlying Asset of a Token (ex; DAI)\n // Charge - Accrued Interest on the Underlying Asset of a Token\n // Charged Particle - Any NFT that has a Mass and a Positive Charge\n // Neutral Particle - Any NFT that has a Mass and No Charge\n // Energize / Recharge - Deposit of an Underlying Asset into an NFT\n // Discharge - Withdraw the Accrued Interest of an NFT leaving the Particle with its initial Mass\n // Release - Withdraw the Underlying Asset & Accrued Interest of an NFT leaving the Particle with No Mass or Charge\n //\n // Proton - NFTs minted from the Charged Particle Accelerator\n // - A proton is a subatomic particle, symbol p or p⁺, with a positive electric charge of +1e elementary\n // charge and a mass slightly less than that of a neutron.\n // Ion - Platform Governance Token\n // - A charged subatomic particle. An atom or group of atoms that carries a positive or negative electric charge\n // as a result of having lost or gained one or more electrons.\n //\n\n // Linked Contracts\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n address internal _lepton;\n uint256 internal depositFee;\n ITokenInfoProxy internal _tokenInfoProxy;\n IChargedManagers internal _chargedManagers;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n __ReentrancyGuard_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getStateAddress() external view virtual override returns (address stateAddress) {\n return address(_chargedState);\n }\n\n function getSettingsAddress() external view virtual override returns (address settingsAddress) {\n return address(_chargedSettings);\n }\n\n function getManagersAddress() external view virtual override returns (address managersAddress) {\n return address(_chargedManagers);\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external virtual override returns (bytes4) {\n return IERC721ReceiverUpgradeable(0).onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external virtual override returns (bytes4) {\n return IERC1155ReceiverUpgradeable(0).onERC1155Received.selector;\n }\n\n // Unimplemented\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external virtual override returns (bytes4) {\n return \"\"; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector;\n }\n\n function supportsInterface(bytes4 /* interfaceId */) external view virtual override returns (bool) {\n return false;\n }\n\n /// @notice Calculates the amount of Fees to be paid for a specific deposit amount\n /// @param assetAmount The Amount of Assets to calculate Fees on\n /// @return protocolFee The amount of deposit fees for the protocol\n function getFeesForDeposit(\n uint256 assetAmount\n )\n external\n override\n view\n returns (uint256 protocolFee)\n {\n protocolFee = _getFeesForDeposit(assetAmount);\n }\n\n /// @notice Gets the Amount of Asset Tokens that have been Deposited into the Particle\n /// representing the Mass of the Particle.\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Asset balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The Amount of underlying Assets held within the Token\n function baseParticleMass(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _baseParticleMass(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the amount of Interest that the Particle has generated representing\n /// the Charge of the Particle\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Interest balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The amount of interest the Token has generated (in Asset Token)\n function currentParticleCharge(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _currentParticleCharge(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the amount of LP Tokens that the Particle has generated representing\n /// the Kinetics of the Particle\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Kinetics balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The amount of LP tokens that have been generated\n function currentParticleKinetics(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _currentParticleKinetics(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the total amount of ERC721 Tokens that the Particle holds\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param basketManagerId The ID of the BasketManager to check the token balance of\n /// @return The total amount of ERC721 tokens that are held within the Particle\n function currentParticleCovalentBonds(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId\n )\n external\n view\n virtual\n override\n basketEnabled(basketManagerId)\n returns (uint256)\n {\n return _currentParticleCovalentBonds(contractAddress, tokenId, basketManagerId);\n }\n\n\n /***********************************|\n | Energize Particles |\n |__________________________________*/\n\n /// @notice Fund Particle with Asset Token\n /// Must be called by the account providing the Asset\n /// Account must Approve THIS contract as Operator of Asset\n ///\n /// NOTE: DO NOT Energize an ERC20 Token, as anyone who holds any amount\n /// of the same ERC20 token could discharge or release the funds.\n /// All holders of the ERC20 token would essentially be owners of the Charged Particle.\n ///\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param walletManagerId The Asset-Pair to Energize the Token with\n /// @param assetToken The Address of the Asset Token being used\n /// @param assetAmount The Amount of Asset Token to Energize the Token with\n /// @return yieldTokensAmount The amount of Yield-bearing Tokens added to the escrow for the Token\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 yieldTokensAmount)\n {\n _validateDeposit(contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n\n // Transfer ERC20 Token from Caller to Contract (reverts on fail)\n uint256 feeAmount = _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n yieldTokensAmount = _depositIntoWalletManager(contractAddress, tokenId, walletManagerId, assetToken, assetAmount, feeAmount);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onEnergize(_msgSender(), referrer, contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n }\n\n\n /***********************************|\n | Discharge Particles |\n |__________________________________*/\n\n /// @notice Allows the owner or operator of the Token to collect or transfer the interest generated\n /// from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @return creatorAmount Amount of Asset Token discharged to the Creator\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateDischarge(contractAddress, tokenId);\n\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).discharge(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount);\n }\n }\n\n /// @notice Allows the owner or operator of the Token to collect or transfer a specific amount of the interest\n /// generated from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @param assetAmount The specific amount of Asset Token to Discharge from the Token\n /// @return creatorAmount Amount of Asset Token discharged to the Creator\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateDischarge(contractAddress, tokenId);\n\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).dischargeAmount(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n assetAmount,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount);\n }\n }\n\n /// @notice Allows the Creator of the Token to collect or transfer a their portion of the interest (if any)\n /// generated from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @param assetAmount The specific amount of Asset Token to Discharge from the Particle\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 receiverAmount)\n {\n address sender = _msgSender();\n address tokenCreator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId);\n require(sender == tokenCreator, \"CP:E-104\");\n\n receiverAmount = _chargedManagers.getWalletManager(walletManagerId).dischargeAmountForCreator(\n receiver,\n contractAddress,\n tokenId,\n sender,\n assetToken,\n assetAmount\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischargeForCreator(contractAddress, tokenId, walletManagerId, sender, assetToken, receiverAmount);\n }\n }\n\n\n /***********************************|\n | Release Particles |\n |__________________________________*/\n\n /// @notice Releases the Full amount of Asset + Interest held within the Particle by LP of the Assets\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Release\n /// @param tokenId The ID of the Token to Release\n /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token\n /// @param assetToken The Address of the Asset Token being released\n /// @return creatorAmount Amount of Asset Token released to the Creator\n /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount)\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateRelease(contractAddress, tokenId);\n\n // Release Particle to Receiver\n uint256 principalAmount;\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).release(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n }\n\n\n /// @notice Releases a partial amount of Asset + Interest held within the Particle by LP of the Assets\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Release\n /// @param tokenId The ID of the Token to Release\n /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token\n /// @param assetToken The Address of the Asset Token being released\n /// @param assetAmount The specific amount of Asset Token to Release from the Particle\n /// @return creatorAmount Amount of Asset Token released to the Creator\n /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount)\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateRelease(contractAddress, tokenId);\n\n // Release Particle to Receiver\n uint256 principalAmount;\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).releaseAmount(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n assetAmount,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n }\n\n\n /***********************************|\n | Covalent Bonding |\n |__________________________________*/\n\n /// @notice Deposit other NFT Assets into the Particle\n /// Must be called by the account providing the Asset\n /// Account must Approve THIS contract as Operator of Asset\n ///\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n basketEnabled(basketManagerId)\n nonReentrant\n returns (bool success)\n {\n _validateNftDeposit(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Transfer ERC721 Token from Caller to Contract (reverts on fail)\n _collectNftToken(_msgSender(), nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n success = _depositIntoBasketManager(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onCovalentBond(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n }\n\n /// @notice Release NFT Assets from the Particle\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Withdraw (ERC1155-specific)\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n basketEnabled(basketManagerId)\n nonReentrant\n returns (bool success)\n {\n _validateBreakBond(contractAddress, tokenId);\n\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked(\"generic\"))) {\n basketMgr.prepareTransferAmount(nftTokenAmount);\n }\n\n // Release Particle to Receiver\n success = basketMgr.removeFromBasket(\n receiver,\n contractAddress,\n tokenId,\n nftTokenAddress,\n nftTokenId\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onCovalentBreak(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"universe\"))) {\n _universe = IUniverse(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"state\"))) {\n _chargedState = IChargedState(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"managers\"))) {\n _chargedManagers = IChargedManagers(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"leptons\"))) {\n _lepton = controller;\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"forwarder\"))) {\n trustedForwarder = controller;\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n\n /***********************************|\n | Protocol Fees |\n |__________________________________*/\n\n /// @dev Setup the Base Deposit Fee for the Protocol\n function setDepositFee(uint256 fee) external onlyOwner {\n require(fee < PERCENTAGE_SCALE, \"CP:E-421\");\n depositFee = fee;\n emit DepositFeeSet(fee);\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n internal\n virtual\n {\n _chargedManagers.validateDeposit(_msgSender(), contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _validateNftDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n {\n _chargedManagers.validateNftDeposit(_msgSender(), contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function _validateDischarge(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateDischarge(_msgSender(), contractAddress, tokenId);\n }\n\n function _validateRelease(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateRelease(_msgSender(), contractAddress, tokenId);\n }\n\n function _validateBreakBond(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateBreakBond(_msgSender(), contractAddress, tokenId);\n }\n\n /// @dev Deposit Asset Tokens into an NFT via the Wallet Manager\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n /// @param feeAmount The Amount of Protocol Fees charged\n function _depositIntoWalletManager(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 feeAmount\n )\n internal\n virtual\n returns (uint256)\n {\n // Get Wallet-Manager for LP\n IWalletManager lpWalletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n address wallet = lpWalletMgr.getWalletAddressById(contractAddress, tokenId, creator, annuityPct);\n IERC20Upgradeable(assetToken).transfer(wallet, assetAmount);\n\n emit ProtocolFeesCollected(assetToken, assetAmount, feeAmount);\n\n return lpWalletMgr.energize(contractAddress, tokenId, assetToken, assetAmount);\n }\n\n /// @dev Deposit NFT Tokens into the Basket Manager\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @param basketManagerId The Wallet Manager of the Assets to Deposit\n /// @param nftTokenAddress The Address of the Asset Token to Deposit\n /// @param nftTokenId The specific amount of Asset Token to Deposit\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _depositIntoBasketManager(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n returns (bool)\n {\n // Deposit NFT Token directly into Smart Wallet (reverts on fail) and Update BasketManager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId);\n\n if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked(\"generic\"))) {\n basketMgr.prepareTransferAmount(nftTokenAmount);\n }\n\n if (_isERC1155(nftTokenAddress)) {\n if (nftTokenAmount == 0) { nftTokenAmount = 1; }\n IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(address(this), wallet, nftTokenId, nftTokenAmount, \"\");\n } else {\n IERC721Upgradeable(nftTokenAddress).transferFrom(address(this), wallet, nftTokenId);\n }\n return basketMgr.addToBasket(contractAddress, tokenId, nftTokenAddress, nftTokenId);\n }\n\n /**\n * @dev Calculates the amount of Fees to be paid for a specific deposit amount\n * Fees are calculated in Interest-Token as they are the type collected for Fees\n * @param assetAmount The Amount of Assets to calculate Fees on\n * @return protocolFee The amount of fees reserved for the protocol\n */\n function _getFeesForDeposit(\n uint256 assetAmount\n )\n internal\n view\n returns (uint256 protocolFee)\n {\n if (depositFee > 0) {\n protocolFee = assetAmount.mul(depositFee).div(PERCENTAGE_SCALE);\n }\n }\n\n /// @dev Collects the Required ERC20 Token(s) from the users wallet\n /// Be sure to Approve this Contract to transfer your Token(s)\n /// @param from The owner address to collect the tokens from\n /// @param tokenAddress The addres of the token to transfer\n /// @param tokenAmount The amount of tokens to collect\n function _collectAssetToken(address from, address tokenAddress, uint256 tokenAmount) internal virtual returns (uint256 protocolFee) {\n protocolFee = _getFeesForDeposit(tokenAmount);\n IERC20Upgradeable(tokenAddress).safeTransferFrom(from, address(this), tokenAmount.add(protocolFee));\n }\n\n /// @dev Collects the Required ERC721 Token(s) from the users wallet\n /// Be sure to Approve this Contract to transfer your Token(s)\n /// @param from The owner address to collect the tokens from\n /// @param nftTokenAddress The address of the NFT token to transfer\n /// @param nftTokenId The ID of the NFT token to transfer\n /// @param nftTokenAmount The amount of Tokens to Transfer (ERC1155-specific)\n function _collectNftToken(address from, address nftTokenAddress, uint256 nftTokenId, uint256 nftTokenAmount) internal virtual {\n if (_isERC1155(nftTokenAddress)) {\n IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId, nftTokenAmount, \"\");\n } else {\n IERC721Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId);\n }\n }\n\n /// @dev Checks if an NFT token contract supports the ERC1155 standard interface\n function _isERC1155(address nftTokenAddress) internal view virtual returns (bool) {\n bytes4 _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n return IERC165Upgradeable(nftTokenAddress).supportsInterface(_INTERFACE_ID_ERC1155);\n }\n\n /// @dev See {ChargedParticles-baseParticleMass}.\n function _baseParticleMass(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n return _chargedManagers.getWalletManager(walletManagerId).getPrincipal(contractAddress, tokenId, assetToken);\n }\n\n /// @dev See {ChargedParticles-currentParticleCharge}.\n function _currentParticleCharge(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n (, uint256 ownerInterest) = _chargedManagers.getWalletManager(walletManagerId).getInterest(contractAddress, tokenId, assetToken);\n return ownerInterest;\n }\n\n /// @dev See {ChargedParticles-currentParticleKinetics}.\n function _currentParticleKinetics(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n return _chargedManagers.getWalletManager(walletManagerId).getRewards(contractAddress, tokenId, assetToken);\n }\n\n /// @dev See {ChargedParticles-currentParticleCovalentBonds}.\n function _currentParticleCovalentBonds(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId\n )\n internal\n view\n virtual\n returns (uint256)\n {\n return _chargedManagers.getBasketManager(basketManagerId).getTokenTotalCount(contractAddress, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier managerEnabled(string calldata walletManagerId) {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"CP:E-419\");\n _;\n }\n\n modifier basketEnabled(string calldata basketManagerId) {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"CP:E-419\");\n _;\n }\n}\n" + }, + "contracts/v1/ChargedSettings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/RelayRecipient.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\nimport \"./lib/TokenInfoProxy.sol\";\n\n/**\n * @notice Charged Particles Settings Contract\n */\ncontract ChargedSettings is\n IChargedSettings,\n Initializable,\n OwnableUpgradeable,\n RelayRecipient,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using Bitwise for uint32;\n\n uint256 constant internal MAX_ANNUITIES = 1e4; // 10000 (100%)\n\n // NftSettings - actionPerms\n uint32 constant internal PERM_CHARGE_NFT = 1; // NFT Contracts that can have assets Deposited into them (Charged)\n uint32 constant internal PERM_BASKET_NFT = 2; // NFT Contracts that can have other NFTs Deposited into them\n uint32 constant internal PERM_TIMELOCK_ANY_NFT = 4; // NFT Contracts that can timelock any NFT on behalf of users (primarily used for Front-run Protection)\n uint32 constant internal PERM_TIMELOCK_OWN_NFT = 8; // NFT Contracts that can timelock their own NFTs on behalf of their users\n uint32 constant internal PERM_RESTRICTED_ASSETS = 16; // NFT Contracts that have restricted deposits to specific assets\n\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // Current Settings for External NFT Token Contracts;\n // - Any user can add any ERC721 or ERC1155 token as a Charged Particle without Limits,\n // unless the Owner of the ERC721 or ERC1155 token contract registers the token\n // and sets the Custom Settings for their token(s)\n mapping (address => uint32) internal _nftActionPerms;\n\n mapping (address => string) internal _nftRequiredWalletManager;\n mapping (address => string) internal _nftRequiredBasketManager;\n\n // ERC20\n mapping (address => mapping(address => bool)) internal _nftAllowedAssetTokens;\n mapping (address => mapping (address => uint256)) internal _nftDepositMin;\n mapping (address => mapping (address => uint256)) internal _nftDepositMax;\n\n // ERC721 / ERC1155\n mapping (address => mapping (address => uint256)) internal _nftMaxNfts; // NFT Token Address => Max\n\n // Optional Configs for individual NFTs set by NFT Creator (by Token UUID)\n mapping (uint256 => uint256) internal _creatorAnnuityPercent;\n mapping (uint256 => address) internal _creatorAnnuityRedirect;\n\n mapping (address => uint256) internal _depositCap;\n uint256 internal _tempLockExpiryBlocks;\n\n // Blacklist for non-compliant tokens\n mapping (address => bool) internal _invalidAssets;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n /// @dev Gets the amount of creator annuities reserved for the creator for the specified NFT\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @return creator The address of the creator\n /// @return annuityPct The percentage amount of annuities reserved for the creator\n function getCreatorAnnuities(\n address contractAddress,\n uint256 tokenId\n )\n external\n override\n virtual\n returns (address creator, uint256 annuityPct)\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n creator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId);\n annuityPct = _creatorAnnuityPercent[tokenUuid];\n }\n\n function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId)\n external\n view\n override\n virtual\n returns (address)\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _creatorAnnuityRedirect[tokenUuid];\n }\n\n function getTempLockExpiryBlocks() external view override virtual returns (uint256) {\n return _tempLockExpiryBlocks;\n }\n\n function getTimelockApprovals(address operator)\n external\n view\n override\n virtual\n returns (bool timelockAny, bool timelockOwn)\n {\n timelockAny = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_ANY_NFT);\n timelockOwn = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_OWN_NFT);\n }\n\n function getAssetRequirements(address contractAddress, address assetToken)\n external\n view\n override\n virtual\n returns (\n string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n )\n {\n requiredWalletManager = _nftRequiredWalletManager[contractAddress];\n energizeEnabled = _nftActionPerms[contractAddress].hasBit(PERM_CHARGE_NFT);\n restrictedAssets = _nftActionPerms[contractAddress].hasBit(PERM_RESTRICTED_ASSETS);\n validAsset = _nftAllowedAssetTokens[contractAddress][assetToken];\n depositCap = _depositCap[assetToken];\n depositMin = _nftDepositMin[contractAddress][assetToken];\n depositMax = _nftDepositMax[contractAddress][assetToken];\n invalidAsset = _invalidAssets[assetToken];\n }\n\n function getNftAssetRequirements(address contractAddress, address nftTokenAddress)\n external\n view\n override\n virtual\n returns (string memory requiredBasketManager, bool basketEnabled, uint256 maxNfts)\n {\n requiredBasketManager = _nftRequiredBasketManager[contractAddress];\n basketEnabled = _nftActionPerms[contractAddress].hasBit(PERM_BASKET_NFT);\n maxNfts = _nftMaxNfts[contractAddress][nftTokenAddress];\n }\n\n\n /***********************************|\n | Only NFT Creator |\n |__________________________________*/\n\n /// @notice Sets the Custom Configuration for Creators of Proton-based NFTs\n /// @param contractAddress The Address to the Proton-based NFT to configure\n /// @param tokenId The token ID of the Proton-based NFT to configure\n /// @param creator The creator of the Proton-based NFT\n /// @param annuityPercent The percentage of interest-annuities to reserve for the creator\n function setCreatorAnnuities(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent\n )\n external\n virtual\n override\n {\n require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), \"CP:E-104\");\n _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent);\n }\n\n /// @notice Sets a Custom Receiver Address for the Creator Annuities\n /// @param contractAddress The Address to the Proton-based NFT to configure\n /// @param tokenId The token ID of the Proton-based NFT to configure\n /// @param receiver The receiver of the Creator interest-annuities\n function setCreatorAnnuitiesRedirect(\n address contractAddress,\n uint256 tokenId,\n address receiver\n )\n external\n virtual\n override\n {\n require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), \"CP:E-104\");\n _setCreatorAnnuitiesRedirect(contractAddress, tokenId, receiver);\n }\n\n\n /***********************************|\n | Register Contract Settings |\n |(For External Contract Integration)|\n |__________________________________*/\n\n /// @notice Sets a Required Wallet-Manager for External NFT Contracts (otherwise set to \"none\" to allow any Wallet-Manager)\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param walletManager If set, will only allow deposits from this specific Wallet-Manager\n function setRequiredWalletManager(\n address contractAddress,\n string calldata walletManager\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (keccak256(bytes(walletManager)) == keccak256(bytes(\"none\"))) {\n _nftRequiredWalletManager[contractAddress] = \"\";\n } else {\n _nftRequiredWalletManager[contractAddress] = walletManager;\n }\n\n emit RequiredWalletManagerSet(\n contractAddress,\n walletManager\n );\n }\n\n /// @notice Sets a Required Basket-Manager for External NFT Contracts (otherwise set to \"none\" to allow any Basket-Manager)\n /// @param contractAddress The Address to the External Contract to configure\n /// @param basketManager If set, will only allow deposits from this specific Basket-Manager\n function setRequiredBasketManager(\n address contractAddress,\n string calldata basketManager\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (keccak256(bytes(basketManager)) == keccak256(bytes(\"none\"))) {\n _nftRequiredBasketManager[contractAddress] = \"\";\n } else {\n _nftRequiredBasketManager[contractAddress] = basketManager;\n }\n\n emit RequiredBasketManagerSet(\n contractAddress,\n basketManager\n );\n }\n\n /// @notice Enables or Disables Asset-Token Restrictions for External NFT Contracts\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param restrictionsEnabled If set, will only allow deposits from Allowed Asset Tokens\n function setAssetTokenRestrictions(\n address contractAddress,\n bool restrictionsEnabled\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (restrictionsEnabled) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_RESTRICTED_ASSETS);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_RESTRICTED_ASSETS);\n }\n\n emit AssetTokenRestrictionsSet(\n contractAddress,\n restrictionsEnabled\n );\n }\n\n /// @notice Enables or Disables Allowed Asset Tokens for External NFT Contracts\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param assetToken The Address of the Asset Token to Allow or Disallow\n /// @param isAllowed True if the Asset Token is allowed\n function setAllowedAssetToken(\n address contractAddress,\n address assetToken,\n bool isAllowed\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftAllowedAssetTokens[contractAddress][assetToken] = isAllowed;\n\n emit AllowedAssetTokenSet(\n contractAddress,\n assetToken,\n isAllowed\n );\n }\n\n /// @notice Sets the Custom Configuration for External Contracts\n /// @param contractAddress The Address to the External Contract to configure\n /// @param assetToken The address of the Asset Token to set Limits for\n /// @param depositMin If set, will define the minimum amount of Asset tokens the NFT may hold, otherwise any amount\n /// @param depositMax If set, will define the maximum amount of Asset tokens the NFT may hold, otherwise any amount\n function setAssetTokenLimits(\n address contractAddress,\n address assetToken,\n uint256 depositMin,\n uint256 depositMax\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftDepositMin[contractAddress][assetToken] = depositMin;\n _nftDepositMax[contractAddress][assetToken] = depositMax;\n\n emit AssetTokenLimitsSet(\n contractAddress,\n assetToken,\n depositMin,\n depositMax\n );\n }\n\n /// @notice Sets the Max Number of NFTs that can be held by a Charged Particle NFT\n /// @param contractAddress The Address to the External Contract to configure\n /// @param nftTokenAddress The address of the NFT Token to set a Max for\n /// @param maxNfts The maximum numbers of NFTs that can be held by a given NFT (0 = unlimited)\n function setMaxNfts(\n address contractAddress,\n address nftTokenAddress,\n uint256 maxNfts\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftMaxNfts[contractAddress][nftTokenAddress] = maxNfts;\n\n emit MaxNftsSet(\n contractAddress,\n nftTokenAddress,\n maxNfts\n );\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n function setAssetInvalidity(address assetToken, bool invalidity) external virtual override onlyOwner {\n _invalidAssets[assetToken] = invalidity;\n emit AssetInvaliditySet(assetToken, invalidity);\n }\n\n function setDepositCap(address assetToken, uint256 cap) external virtual onlyOwner {\n _depositCap[assetToken] = cap;\n emit DepositCapSet(assetToken, cap);\n }\n\n function setTempLockExpiryBlocks(uint256 numBlocks) external virtual onlyOwner {\n _tempLockExpiryBlocks = numBlocks;\n emit TempLockExpirySet(numBlocks);\n }\n\n function enableNftContracts(address[] calldata contracts) external override virtual onlyOwner {\n uint count = contracts.length;\n for (uint i = 0; i < count; i++) {\n address tokenContract = contracts[i];\n _setPermsForCharge(tokenContract, true);\n _setPermsForBasket(tokenContract, true);\n _setPermsForTimelockSelf(tokenContract, true);\n }\n }\n\n function migrateToken(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent,\n address annuityReceiver\n )\n external\n onlyOwner\n {\n _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent);\n if (annuityReceiver != address(0)) {\n _setCreatorAnnuitiesRedirect(contractAddress, tokenId, annuityReceiver);\n }\n }\n\n /// @dev Update the list of NFT contracts that can be Charged\n function setPermsForCharge(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForCharge(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can hold other NFTs\n function setPermsForBasket(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForBasket(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection\n function setPermsForTimelockAny(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForTimelockAny(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock their own tokens\n function setPermsForTimelockSelf(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForTimelockSelf(contractAddress, state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Update the list of NFT contracts that can be Charged\n function _setPermsForCharge(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_CHARGE_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_CHARGE_NFT);\n }\n emit PermsSetForCharge(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can hold other NFTs\n function _setPermsForBasket(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_BASKET_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_BASKET_NFT);\n }\n emit PermsSetForBasket(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection\n function _setPermsForTimelockAny(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_ANY_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_ANY_NFT);\n }\n emit PermsSetForTimelockAny(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock their own tokens\n function _setPermsForTimelockSelf(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_OWN_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_OWN_NFT);\n }\n emit PermsSetForTimelockSelf(contractAddress, state);\n }\n\n /// @dev see setCreatorAnnuities()\n function _setCreatorAnnuities(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent\n )\n internal\n virtual\n {\n require(annuityPercent <= MAX_ANNUITIES, \"CP:E-421\");\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Update Configs for External Token Creator\n _creatorAnnuityPercent[tokenUuid] = annuityPercent;\n\n emit TokenCreatorConfigsSet(\n contractAddress,\n tokenId,\n creator,\n annuityPercent\n );\n }\n\n /// @dev see setCreatorAnnuitiesRedirect()\n function _setCreatorAnnuitiesRedirect(\n address contractAddress,\n uint256 tokenId,\n address receiver\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _creatorAnnuityRedirect[tokenUuid] = receiver;\n emit TokenCreatorAnnuitiesRedirected(contractAddress, tokenId, receiver);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyValidExternalContract(address contractAddress) {\n require(contractAddress.isContract(), \"CP:E-420\");\n _;\n }\n\n modifier onlyContractOwnerOrAdmin(address contractAddress, address sender) {\n require(sender == owner() || contractAddress.isContractOwner(sender), \"CP:E-103\");\n _;\n }\n}\n" + }, + "contracts/v1/ChargedState.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedState.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/RelayRecipient.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Settings Contract\n */\ncontract ChargedState is\n IChargedState,\n Initializable,\n OwnableUpgradeable,\n RelayRecipient,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using Bitwise for uint32;\n\n // NftState - actionPerms\n uint32 constant internal PERM_RESTRICT_ENERGIZE_FROM_ALL = 1; // NFTs that have Restrictions on Energize\n uint32 constant internal PERM_ALLOW_DISCHARGE_FROM_ALL = 2; // NFTs that allow Discharge by anyone\n uint32 constant internal PERM_ALLOW_RELEASE_FROM_ALL = 4; // NFTs that allow Release by anyone\n uint32 constant internal PERM_RESTRICT_BOND_FROM_ALL = 8; // NFTs that have Restrictions on Covalent Bonds\n uint32 constant internal PERM_ALLOW_BREAK_BOND_FROM_ALL = 16; // NFTs that allow Breaking Covalent Bonds by anyone\n\n IChargedSettings internal _chargedSettings;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // NftTimelocks\n /// @dev discharge unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftDischargeTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftDischargeTimelockLockedBy;\n\n /// @dev release unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftReleaseTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftReleaseTimelockLockedBy;\n\n /// @dev release unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftBreakBondTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftBreakBondTimelockLockedBy;\n\n // NftState\n /// @dev maps nft by tokenId to actionPermissions uint32 which is a composite of all possible NftState - actionPerms\n mapping (uint256 => uint32) internal _nftActionPerms;\n\n /// @dev maps nft by tokenId to its tempLockExpiry\n mapping (uint256 => uint256) internal _nftTempLockExpiry;\n\n /// @dev maps tokenId to user address to operator address for approving various actions\n mapping (uint256 => mapping(address => address)) internal _nftDischargeApproval;\n mapping (uint256 => mapping(address => address)) internal _nftReleaseApproval;\n mapping (uint256 => mapping(address => address)) internal _nftBreakBondApproval;\n mapping (uint256 => mapping(address => address)) internal _nftTimelockApproval;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftDischargeTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftDischargeTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftReleaseTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftReleaseTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftBreakBondTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftBreakBondTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n\n /// @notice Checks if an operator is allowed to Discharge a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForDischarge(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Release a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForRelease(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Break Covalent Bonds on a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForBreakBond(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Timelock a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForTimelock(contractAddress, tokenId, operator);\n }\n\n\n function isEnergizeRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n }\n\n\n function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_BOND_FROM_ALL);\n }\n\n\n function getDischargeState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n isApproved = _isApprovedForDischarge(contractAddress, tokenId, sender);\n timelock = _nftDischargeTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n function getReleaseState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_RELEASE_FROM_ALL);\n isApproved = _isApprovedForRelease(contractAddress, tokenId, sender);\n timelock = _nftReleaseTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n function getBreakBondState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n isApproved = _isApprovedForBreakBond(contractAddress, tokenId, sender);\n timelock = _nftBreakBondTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n\n /***********************************|\n | Only NFT Owner/Operator |\n |__________________________________*/\n\n /// @notice Sets an Operator as Approved to Discharge a specific Token\n /// This allows an operator to withdraw the interest-portion only\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setDischargeApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Release a specific Token\n /// This allows an operator to withdraw the principal + interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setReleaseApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token\n /// This allows an operator to withdraw Basket NFTs\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setBreakBondApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Timelock a specific Token\n /// This allows an operator to timelock the principal or interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setTimelockApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Discharge/Release/Timelock a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setApprovalForAll(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @dev Updates Restrictions on Energizing an NFT\n function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForRestrictCharge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowDischarge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowRelease(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Restrictions on Covalent Bonds on an NFT\n function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForRestrictBond(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone\n function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowBreakBond(contractAddress, tokenId, state);\n }\n\n /// @notice Sets a Timelock on the ability to Discharge the Interest of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setDischargeTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftDischargeTimelockLockedBy[tokenUuid] == sender) {\n delete _nftDischargeTimelockUnlockBlock[tokenUuid];\n delete _nftDischargeTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftDischargeTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftDischargeTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftDischargeTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenDischargeTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n /// @notice Sets a Timelock on the ability to Release the Assets of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setReleaseTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftReleaseTimelockLockedBy[tokenUuid] == sender) {\n delete _nftReleaseTimelockUnlockBlock[tokenUuid];\n delete _nftReleaseTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftReleaseTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftReleaseTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftReleaseTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenReleaseTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n /// @notice Sets a Timelock on the ability to Break the Covalent Bond of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setBreakBondTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftBreakBondTimelockLockedBy[tokenUuid] == sender) {\n delete _nftBreakBondTimelockUnlockBlock[tokenUuid];\n delete _nftBreakBondTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftBreakBondTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftBreakBondTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftBreakBondTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenBreakBondTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n\n /***********************************|\n | Only NFT Contract |\n |__________________________________*/\n\n /// @notice Sets a Temporary-Lock on the ability to Release/Discharge the Assets of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param isLocked The locked state; contracts are expected to disable this lock before expiry\n function setTemporaryLock(\n address contractAddress,\n uint256 tokenId,\n bool isLocked\n )\n external\n override\n virtual\n {\n require(msg.sender == contractAddress, \"CP:E-112\");\n\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n uint256 unlockBlock;\n if (isLocked && _nftTempLockExpiry[tokenUuid] == 0) {\n unlockBlock = block.number.add(_chargedSettings.getTempLockExpiryBlocks());\n _nftTempLockExpiry[tokenUuid] = unlockBlock;\n }\n if (!isLocked) {\n _nftTempLockExpiry[tokenUuid] = 0;\n }\n\n emit TokenTempLock(contractAddress, tokenId, unlockBlock);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n function migrateToken(\n address contractAddress,\n uint256 tokenId,\n uint256 releaseTimelockExpiry,\n address releaseTimelockLockedBy,\n uint256 tempLockExpiry\n )\n external\n onlyOwner\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (releaseTimelockExpiry > block.number && releaseTimelockLockedBy != address(0)) {\n _nftReleaseTimelockUnlockBlock[tokenUuid] = releaseTimelockExpiry;\n _nftReleaseTimelockLockedBy[tokenUuid] = releaseTimelockLockedBy;\n emit TokenReleaseTimelock(contractAddress, tokenId, releaseTimelockLockedBy, releaseTimelockExpiry);\n }\n\n if (tempLockExpiry > 0) {\n _nftTempLockExpiry[tokenUuid] = tempLockExpiry;\n emit TokenTempLock(contractAddress, tokenId, tempLockExpiry);\n }\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev See {ChargedParticles-isApprovedForDischarge}.\n function _isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftDischargeApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForRelease}.\n function _isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftReleaseApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForBreakBond}.\n function _isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftBreakBondApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForTimelock}.\n function _isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n (bool timelockAny, bool timelockOwn) = _chargedSettings.getTimelockApprovals(operator);\n if (timelockAny || (timelockOwn && contractAddress == operator)) { return true; }\n\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return tokenOwner == operator || _nftTimelockApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @notice Sets an Operator as Approved to Discharge a specific Token\n /// This allows an operator to withdraw the interest-portion only\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setDischargeApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftDischargeApproval[tokenUuid][tokenOwner] = operator;\n emit DischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Release a specific Token\n /// This allows an operator to withdraw the principal + interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setReleaseApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftReleaseApproval[tokenUuid][tokenOwner] = operator;\n emit ReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token\n /// This allows an operator to withdraw Basket NFTs\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setBreakBondApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftBreakBondApproval[tokenUuid][tokenOwner] = operator;\n emit BreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Timelock a specific Token\n /// This allows an operator to timelock the principal or interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setTimelockApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftTimelockApproval[tokenUuid][tokenOwner] = operator;\n emit TimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @dev Updates Restrictions on Energizing an NFT\n function _setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n }\n emit PermsSetForRestrictCharge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function _setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n }\n emit PermsSetForAllowDischarge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function _setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_RELEASE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_RELEASE_FROM_ALL);\n }\n emit PermsSetForAllowRelease(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Restrictions on Covalent Bonds on an NFT\n function _setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_BOND_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_BOND_FROM_ALL);\n }\n emit PermsSetForRestrictBond(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone\n function _setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n }\n emit PermsSetForAllowBreakBond(contractAddress, tokenId, state);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) {\n require(_tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender), \"CP:E-105\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/CommunityVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract CommunityVault is Ownable, BlackholePrevention {\n\n IERC20 private immutable _ionx;\n\n constructor (address ionx) public {\n _ionx = IERC20(ionx);\n }\n\n event SetAllowance(address indexed caller, address indexed spender, uint256 amount);\n\n function setAllowance(address spender, uint amount) public onlyOwner {\n _ionx.approve(spender, amount);\n\n emit SetAllowance(msg.sender, spender, amount);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens other than IONX, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n require(tokenAddress != address(_ionx), \"CommunityVault: cannot withdraw IONX\");\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n}" + }, + "contracts/v1/incentives/MerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_) public {\n token = token_;\n merkleRoot = merkleRoot_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), 'MerkleDistributor: Drop already claimed.');\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), 'MerkleDistributor: Invalid proof.');\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), 'MerkleDistributor: Transfer failed.');\n\n emit Claimed(index, account, amount);\n }\n}\n" + }, + "contracts/v1/incentives/MerkleDistributor2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor2 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"MerkleDistributor2: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"MerkleDistributor2: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor2: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"MerkleDistributor2: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"MerkleDistributor2: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"MerkleDistributor2: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/MerkleDistributor3.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor3 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"MerkleDistributor3: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"MerkleDistributor3: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor3: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"MerkleDistributor3: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"MerkleDistributor3: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"MerkleDistributor3: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/RewardProgram.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// RewardProgram.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/IRewardProgram.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/introspection/IERC165.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"../interfaces/IUniverseRP.sol\";\nimport \"../interfaces/IChargedManagers.sol\";\nimport \"../interfaces/IWalletManager.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IERC20Detailed.sol\";\n\ncontract RewardProgram is\n IRewardProgram,\n BlackholePrevention,\n IERC165,\n ReentrancyGuard,\n IERC721Receiver,\n IERC1155Receiver\n{\n using SafeMath for uint256;\n using TokenInfo for address;\n using SafeERC20 for IERC20;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n\n address private _owner;\n IUniverseRP private _universe;\n IChargedManagers private _chargedManagers;\n ProgramRewardData private _programData;\n mapping(uint256 => AssetStake) private _assetStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public {}\n\n function initialize(\n address stakingToken,\n address rewardToken,\n uint256 baseMultiplier,\n address chargedManagers,\n address universe,\n address owner\n ) external override {\n require(_owner == address(0x0), \"Already initialized\");\n _owner = owner;\n\n // Prepare Reward Program\n _programData.stakingToken = stakingToken;\n _programData.rewardToken = rewardToken;\n _programData.baseMultiplier = baseMultiplier; // Basis Points\n\n // Connect to Charged Particles\n _chargedManagers = IChargedManagers(chargedManagers);\n _universe = IUniverseRP(universe);\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getProgramData() external view override returns (ProgramRewardData memory) {\n return _programData;\n }\n\n function getAssetStake(uint256 parentNftUuid) external view override returns (AssetStake memory) {\n return _assetStake[parentNftUuid];\n }\n\n function getFundBalance() external view override returns (uint256) {\n return _getFundBalance();\n }\n\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) public view override returns (uint256) {\n return _calculateRewardsEarned(parentNftUuid, interestAmount);\n }\n\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n return _assetStake[parentNftUuid].claimableRewards;\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\n return \"\";\n }\n\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(IERC165)\n returns (bool)\n {\n // default interface support\n if (\n interfaceId == type(IERC721Receiver).interfaceId ||\n interfaceId == type(IERC1155Receiver).interfaceId ||\n interfaceId == type(IERC165).interfaceId\n ) {\n return true;\n }\n }\n\n function owner() public view returns (address) {\n return _owner;\n }\n\n\n /***********************************|\n | Only Universe |\n |__________________________________*/\n\n function registerAssetDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n uint256 principalAmount\n )\n external\n override\n onlyUniverse\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n if (assetStake.start == 0) {\n assetStake.start = block.number;\n assetStake.walletManagerId = walletManagerId;\n }\n emit AssetDeposit(contractAddress, tokenId, walletManagerId, principalAmount);\n }\n\n function registerAssetRelease(\n address contractAddress,\n uint256 tokenId,\n uint256 interestAmount\n )\n external\n override\n onlyUniverse\n nonReentrant\n returns (uint256 rewards)\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n if (assetStake.start > 0) {\n // Update Claimable Rewards\n uint256 newRewards = _calculateRewardsEarned(parentNftUuid, interestAmount);\n assetStake.claimableRewards = assetStake.claimableRewards.add(newRewards);\n\n // Reset Stake if Principal Balance falls to Zero\n IWalletManager walletMgr = _chargedManagers.getWalletManager(assetStake.walletManagerId);\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\n if (principal == 0) {\n assetStake.start = 0;\n }\n\n // Issue Rewards to NFT Owner\n rewards = _claimRewards(contractAddress, tokenId);\n\n emit AssetRelease(contractAddress, tokenId, interestAmount);\n }\n }\n\n\n /***********************************|\n | Reward Calculation |\n |__________________________________*/\n\n function _calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) internal view returns (uint256 totalReward) {\n uint256 baseReward = _calculateBaseReward(interestAmount);\n uint256 leptonMultipliedReward = _calculateMultipliedReward(parentNftUuid, baseReward);\n totalReward = _convertDecimals(leptonMultipliedReward);\n }\n\n function _calculateBaseReward(uint256 amount) internal view returns(uint256 baseReward) {\n baseReward = amount.mul(_programData.baseMultiplier).div(PERCENTAGE_SCALE);\n }\n\n function _calculateMultipliedReward(uint256 parentNftUuid, uint256 baseReward) internal view returns(uint256) {\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n if (assetStake.start == 0) { return baseReward; }\n\n IUniverseRP.NftStake memory nftStake = _universe.getNftStake(parentNftUuid);\n uint256 multiplierBP = nftStake.multiplier;\n\n uint256 assetDepositLength = block.number.sub(assetStake.start);\n uint256 nftDepositLength = 0;\n if (nftStake.releaseBlockNumber > 0) {\n nftDepositLength = nftStake.releaseBlockNumber.sub(nftStake.depositBlockNumber);\n } else {\n nftDepositLength = block.number.sub(nftStake.depositBlockNumber);\n }\n\n if (multiplierBP == 0 || nftDepositLength == 0 || assetDepositLength == 0) {\n return baseReward;\n }\n\n if (nftDepositLength > assetDepositLength) {\n nftDepositLength = assetDepositLength;\n }\n\n // Percentage of the total program that the Multiplier Nft was deposited for\n uint256 nftRewardRatioBP = nftDepositLength.mul(PERCENTAGE_SCALE).div(assetDepositLength);\n\n // Amount of reward that the Multiplier Nft is responsible for\n uint256 amountGeneratedDuringNftDeposit = baseReward.mul(nftRewardRatioBP).div(PERCENTAGE_SCALE);\n\n // Amount of Multiplied Reward from NFT\n uint256 multipliedReward = amountGeneratedDuringNftDeposit.mul(multiplierBP.mul(LEPTON_MULTIPLIER_SCALE)).div(PERCENTAGE_SCALE);\n\n // Amount of Base Reward without Multiplied NFT Rewards\n uint256 amountGeneratedWithoutNftDeposit = baseReward.sub(amountGeneratedDuringNftDeposit);\n\n // Amount of Base Rewards + Multiplied NFT Rewards\n return amountGeneratedWithoutNftDeposit.add(multipliedReward);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function fundProgram(uint256 amount) external onlyOwner {\n require(_programData.rewardToken != address(0), \"RP:E-405\");\n IERC20(_programData.rewardToken).safeTransferFrom(msg.sender, address(this), amount);\n emit RewardProgramFunded(amount);\n }\n\n function setStakingToken(address newStakingToken) external onlyOwner {\n _programData.stakingToken = newStakingToken;\n }\n\n function setRewardToken(address newRewardToken) external onlyOwner {\n _programData.rewardToken = newRewardToken;\n }\n\n function setBaseMultiplier(uint256 newMultiplier) external onlyOwner {\n _programData.baseMultiplier = newMultiplier; // Basis Points\n }\n\n function setChargedManagers(address manager) external onlyOwner {\n _chargedManagers = IChargedManagers(manager);\n }\n\n function setUniverse(address universe) external onlyOwner {\n _universe = IUniverseRP(universe);\n }\n\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external override onlyOwner {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n\n // Initiate Asset Stake\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\n if (principal > 0) {\n _assetStake[parentNftUuid] = AssetStake(block.number, 0, walletManagerId);\n emit AssetRegistered(contractAddress, tokenId, walletManagerId, principal);\n }\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _claimRewards(\n address contractAddress,\n uint256 tokenId\n )\n internal\n returns (uint256 totalReward)\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n // Rewards Receiver\n address receiver = IERC721(contractAddress).ownerOf(tokenId);\n\n // Ensure Reward Pool has Sufficient Balance\n totalReward = assetStake.claimableRewards;\n uint256 fundBalance = _getFundBalance();\n uint256 unavailReward = totalReward > fundBalance ? totalReward.sub(fundBalance) : 0;\n\n // Determine amount of Rewards to Transfer\n if (unavailReward > 0) {\n totalReward = totalReward.sub(unavailReward);\n emit RewardProgramOutOfFunds();\n }\n\n // Update Asset Stake\n assetStake.claimableRewards = unavailReward;\n\n if (totalReward > 0) {\n // Transfer Available Rewards to Receiver\n IERC20(_programData.rewardToken).safeTransfer(receiver, totalReward);\n }\n\n emit RewardsClaimed(contractAddress, tokenId, receiver, totalReward, unavailReward);\n }\n\n function _convertDecimals(uint256 reward) internal view returns (uint256) {\n uint8 stakingTokenDecimals = IERC20Detailed(_programData.stakingToken).decimals();\n return reward.mul(10**(18 - uint256(stakingTokenDecimals)));\n }\n\n function _getFundBalance() internal view returns (uint256) {\n return IERC20Detailed(_programData.rewardToken).balanceOf(address(this));\n }\n\n\n modifier onlyOwner() {\n require(_owner == msg.sender, \"Caller is not the owner\");\n _;\n }\n\n modifier onlyUniverse() {\n require(msg.sender == address(_universe), \"RP:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/RewardProgramFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// RewardProgramFactory.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport \"./RewardProgram.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract RewardProgramFactory is BlackholePrevention, Ownable {\n event RewardProgramCreated(address indexed rewardProgram);\n\n address public _template;\n\n constructor () public {\n _template = address(new RewardProgram());\n }\n\n // function _msgSender() internal view override returns (address payable) {\n // return msg.sender;\n // }\n\n function createRewardProgram(\n address stakingToken,\n address rewardToken,\n uint256 baseMultiplier,\n address chargedManagers,\n address universe\n )\n external\n onlyOwner\n returns (address)\n {\n address newRewardProgram = _createClone(_template);\n RewardProgram rewardProgram = RewardProgram(newRewardProgram);\n rewardProgram.initialize(stakingToken, rewardToken, baseMultiplier, chargedManagers, universe, _msgSender());\n emit RewardProgramCreated(newRewardProgram);\n return newRewardProgram;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n}\n" + }, + "contracts/v1/incentives/Staking.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/Staking2.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking2 is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/Staking3.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking3 is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/YieldFarm.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/incentives/YieldFarm2.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm2 is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/incentives/YieldFarm3.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm3 is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/interfaces/IAaveBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IAaveBridge.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n\ninterface IAaveBridge {\n function getReserveInterestToken(address assetToken) external view returns (address aTokenAddress);\n function isReserveActive(address assetToken) external view returns (bool);\n\n function getTotalBalance(address account, address assetToken) external view returns (uint256);\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(address receiver, address assetToken, uint256 assetAmount) external;\n}\n" + }, + "contracts/v1/interfaces/IBaseProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IBaseProton is IERC721 {\n event PausedStateSet(bool isPaused);\n event SalePriceSet(uint256 indexed tokenId, uint256 salePrice);\n event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct);\n event FeesWithdrawn(address indexed receiver, uint256 amount);\n event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties);\n event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view returns (address);\n function getSalePrice(uint256 tokenId) external view returns (uint256);\n function getLastSellPrice(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyalties(address account) external view returns (uint256);\n function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address);\n\n function buyProton(uint256 tokenId, uint256 gasLimit) external payable returns (bool);\n function claimCreatorRoyalties() external returns (uint256);\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n ) external returns (uint256 newTokenId);\n\n function createProtons(\n address creator,\n address receiver,\n string[] calldata tokenMetaUris\n ) external returns (bool);\n\n function createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n ) external returns (bool);\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice) external;\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external;\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external;\n}" + }, + "contracts/v1/interfaces/IBasketManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Particle Basket Manager interface\n * @dev The basket-manager for underlying assets attached to Charged Particles\n * @dev Manages the link between NFTs and their respective Smart-Baskets\n */\ninterface IBasketManager {\n\n event ControllerSet(address indexed controller);\n event ExecutorSet(address indexed executor);\n event PausedStateSet(bool isPaused);\n event NewSmartBasket(address indexed contractAddress, uint256 indexed tokenId, address indexed smartBasket);\n event BasketAdd(address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\n event BasketRemove(address indexed receiver, address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\n event BasketRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\n event RewardProgramSet(address indexed rewardProgram);\n\n function isPaused() external view returns (bool);\n\n function getTokenTotalCount(address contractAddress, uint256 tokenId) external view returns (uint256);\n function getTokenCountByType(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (uint256);\n\n function prepareTransferAmount(uint256 nftTokenAmount) external;\n function addToBasket(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function getBasketAddressById(address contractAddress, uint256 tokenId) external returns (address);\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/IChargedManagers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IWalletManager.sol\";\nimport \"./IBasketManager.sol\";\n\n/**\n * @notice Interface for Charged Wallet-Managers\n */\ninterface IChargedManagers {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function isContractOwner(address contractAddress, address account) external view returns (bool);\n\n // ERC20\n function isWalletManagerEnabled(string calldata walletManagerId) external view returns (bool);\n function getWalletManager(string calldata walletManagerId) external view returns (IWalletManager);\n\n // ERC721\n function isNftBasketEnabled(string calldata basketId) external view returns (bool);\n function getBasketManager(string calldata basketId) external view returns (IBasketManager);\n\n // Validation\n function validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external;\n function validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external;\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external;\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event WalletManagerRegistered(string indexed walletManagerId, address indexed walletManager);\n event BasketManagerRegistered(string indexed basketId, address indexed basketManager);\n}\n" + }, + "contracts/v1/interfaces/IChargedParticles.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Charged Particles\n */\ninterface IChargedParticles {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getStateAddress() external view returns (address stateAddress);\n function getSettingsAddress() external view returns (address settingsAddress);\n function getManagersAddress() external view returns (address managersAddress);\n\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\n\n /***********************************|\n | Particle Mechanics |\n |__________________________________*/\n\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n ) external returns (uint256 yieldTokensAmount);\n\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 receiverAmount);\n\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositFeeSet(uint256 depositFee);\n event ProtocolFeesCollected(address indexed assetToken, uint256 depositAmount, uint256 feesCollected);\n}\n" + }, + "contracts/v1/interfaces/IChargedSettings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IWalletManager.sol\";\nimport \"./IBasketManager.sol\";\n\n/**\n * @notice Interface for Charged Settings\n */\ninterface IChargedSettings {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n // function isContractOwner(address contractAddress, address account) external view returns (bool);\n function getCreatorAnnuities(address contractAddress, uint256 tokenId) external returns (address creator, uint256 annuityPct);\n function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId) external view returns (address);\n function getTempLockExpiryBlocks() external view returns (uint256);\n function getTimelockApprovals(address operator) external view returns (bool timelockAny, bool timelockOwn);\n function getAssetRequirements(\n address contractAddress,\n address assetToken\n ) external view returns (\n string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n );\n function getNftAssetRequirements(\n address contractAddress,\n address nftTokenAddress\n ) external view returns (\n string memory requiredBasketManager,\n bool basketEnabled,\n uint256 maxNfts\n );\n\n /***********************************|\n | Only NFT Creator |\n |__________________________________*/\n\n function setCreatorAnnuities(address contractAddress, uint256 tokenId, address creator, uint256 annuityPercent) external;\n function setCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId, address receiver) external;\n\n\n /***********************************|\n | Only NFT Contract Owner |\n |__________________________________*/\n\n function setRequiredWalletManager(address contractAddress, string calldata walletManager) external;\n function setRequiredBasketManager(address contractAddress, string calldata basketManager) external;\n function setAssetTokenRestrictions(address contractAddress, bool restrictionsEnabled) external;\n function setAllowedAssetToken(address contractAddress, address assetToken, bool isAllowed) external;\n function setAssetTokenLimits(address contractAddress, address assetToken, uint256 depositMin, uint256 depositMax) external;\n function setMaxNfts(address contractAddress, address nftTokenAddress, uint256 maxNfts) external;\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAssetInvalidity(address assetToken, bool invalidity) external;\n function enableNftContracts(address[] calldata contracts) external;\n function setPermsForCharge(address contractAddress, bool state) external;\n function setPermsForBasket(address contractAddress, bool state) external;\n function setPermsForTimelockAny(address contractAddress, bool state) external;\n function setPermsForTimelockSelf(address contractAddress, bool state) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositCapSet(address assetToken, uint256 depositCap);\n event TempLockExpirySet(uint256 expiryBlocks);\n\n event RequiredWalletManagerSet(address indexed contractAddress, string walletManager);\n event RequiredBasketManagerSet(address indexed contractAddress, string basketManager);\n event AssetTokenRestrictionsSet(address indexed contractAddress, bool restrictionsEnabled);\n event AllowedAssetTokenSet(address indexed contractAddress, address assetToken, bool isAllowed);\n event AssetTokenLimitsSet(address indexed contractAddress, address assetToken, uint256 assetDepositMin, uint256 assetDepositMax);\n event MaxNftsSet(address indexed contractAddress, address indexed nftTokenAddress, uint256 maxNfts);\n event AssetInvaliditySet(address indexed assetToken, bool invalidity);\n\n event TokenCreatorConfigsSet(address indexed contractAddress, uint256 indexed tokenId, address indexed creatorAddress, uint256 annuityPercent);\n event TokenCreatorAnnuitiesRedirected(address indexed contractAddress, uint256 indexed tokenId, address indexed redirectAddress);\n\n event PermsSetForCharge(address indexed contractAddress, bool state);\n event PermsSetForBasket(address indexed contractAddress, bool state);\n event PermsSetForTimelockAny(address indexed contractAddress, bool state);\n event PermsSetForTimelockSelf(address indexed contractAddress, bool state);\n}\n" + }, + "contracts/v1/interfaces/IChargedState.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IChargedSettings.sol\";\n\n/**\n * @notice Interface for Charged State\n */\ninterface IChargedState {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n\n function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n\n function isEnergizeRestricted(address contractAddress, uint256 tokenId) external view returns (bool);\n function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external view returns (bool);\n\n function getDischargeState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n function getReleaseState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n function getBreakBondState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n\n /***********************************|\n | Only NFT Owner/Operator |\n |__________________________________*/\n\n function setDischargeApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setReleaseApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setBreakBondApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setTimelockApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setApprovalForAll(address contractAddress, uint256 tokenId, address operator) external;\n\n function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) external;\n\n function setDischargeTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n function setReleaseTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n function setBreakBondTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n /***********************************|\n | Only NFT Contract |\n |__________________________________*/\n\n function setTemporaryLock(\n address contractAddress,\n uint256 tokenId,\n bool isLocked\n ) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n\n event DischargeApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event ReleaseApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event BreakBondApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event TimelockApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n\n event TokenDischargeTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenReleaseTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenBreakBondTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenTempLock(address indexed contractAddress, uint256 indexed tokenId, uint256 unlockBlock);\n\n event PermsSetForRestrictCharge(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowDischarge(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowRelease(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForRestrictBond(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowBreakBond(address indexed contractAddress, uint256 indexed tokenId, bool state);\n}\n" + }, + "contracts/v1/interfaces/IDai.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\ninterface IDai is IERC20Upgradeable {\n // --- Approve by signature ---\n function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external;\n function transferFrom(address src, address dst, uint wad) external override returns (bool);\n}" + }, + "contracts/v1/interfaces/IERC20Detailed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Detailed {\n function decimals() external view returns (uint8);\n function symbol() external view returns (string memory);\n function name() external view returns (string memory);\n\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(address sender, address recipient, uint256 amount) 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" + }, + "contracts/v1/interfaces/IERC721Chargeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IERC721Chargeable.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\n\ninterface IERC721Chargeable is IERC165Upgradeable {\n function owner() external view returns (address);\n function creatorOf(uint256 tokenId) external view returns (address);\n function balanceOf(address tokenOwner) external view returns (uint256 balance);\n function ownerOf(uint256 tokenId) external view returns (address tokenOwner);\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n function transferFrom(address from, address to, uint256 tokenId) external;\n function approve(address to, uint256 tokenId) external;\n function getApproved(uint256 tokenId) external view returns (address operator);\n function setApprovalForAll(address operator, bool _approved) external;\n function isApprovedForAll(address tokenOwner, address operator) external view returns (bool);\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "contracts/v1/interfaces/ILepton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ILepton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Lepton Interface\n * @dev ...\n */\ninterface ILepton {\n\n struct Classification {\n string tokenUri;\n uint256 price;\n uint128 _upperBounds;\n uint32 supply;\n uint32 multiplier;\n uint32 bonus;\n }\n\n function mintLepton() external payable returns (uint256 newTokenId);\n function batchMintLepton(uint256 count) external payable;\n function getNextType() external view returns (uint256);\n function getNextPrice() external view returns (uint256);\n function getMultiplier(uint256 tokenId) external view returns (uint256);\n function getBonus(uint256 tokenId) external view returns (uint256);\n\n\n event MaxMintPerTxSet(uint256 maxAmount);\n event LeptonTypeAdded(string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\n event LeptonTypeUpdated(uint256 leptonIndex, string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\n event LeptonMinted(address indexed receiver, uint256 indexed tokenId, uint256 price, uint32 multiplier);\n event LeptonBatchMinted(address indexed receiver, uint256 indexed tokenId, uint256 count, uint256 price, uint32 multiplier);\n event PausedStateSet(bool isPaused);\n}\n" + }, + "contracts/v1/interfaces/IMerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.6.0;\n\n// Allows anyone to claim a token if they exist in a merkle root.\ninterface IMerkleDistributor {\n // Returns the address of the token distributed by this contract.\n function token() external view returns (address);\n // Returns the merkle root of the merkle tree containing account balances available to claim.\n function merkleRoot() external view returns (bytes32);\n // Returns true if the index has been marked claimed.\n function isClaimed(uint256 index) external view returns (bool);\n // Claim the given amount of the token to the given address. Reverts if the inputs are invalid.\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external;\n\n // This event is triggered whenever a call to #claim succeeds.\n event Claimed(uint256 index, address account, uint256 amount);\n}" + }, + "contracts/v1/interfaces/IParticleSplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IParticleSplitter.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Particle Splitter\n */\ninterface IParticleSplitter {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function executeForWallet(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address externalAddress,\n bytes memory encodedParams\n ) external payable returns (bytes memory);\n\n function executeForBasket(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address externalAddress,\n bytes memory encodedParams\n ) external payable returns (bytes memory);\n\n function withdrawWalletRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n ) external returns (uint256 amountWithdrawn);\n\n function withdrawBasketRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n ) external returns (uint256 amountWithdrawn);\n\n function refreshWalletPrincipal(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external;\n\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event ChargedManagersSet(address indexed chargedManagers);\n event TokenInfoProxySet(address indexed tokenInfoProxy);\n\n event ExecuteForWallet(\n address indexed contractAddress,\n uint256 tokenId,\n string walletManagerId,\n address indexed externalAddress,\n bytes encodedParams,\n uint256 ethValue\n );\n event ExecuteForBasket(\n address indexed contractAddress,\n uint256 tokenId,\n string basketManagerId,\n address indexed externalAddress,\n bytes encodedParams,\n uint256 ethValue\n );\n event PrincipalRefreshed(\n address contractAddress,\n uint256 tokenId,\n string walletManagerId,\n address assetToken\n );\n event PermsSetForExternal(\n address indexed contractAddress,\n bool state\n );\n}\n" + }, + "contracts/v1/interfaces/IProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IProton is IERC721 {\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n event PausedStateSet(bool isPaused);\n event SalePriceSet(uint256 indexed tokenId, uint256 salePrice);\n event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct);\n event FeesWithdrawn(address indexed receiver, uint256 amount);\n event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties);\n event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view returns (address);\n function getSalePrice(uint256 tokenId) external view returns (uint256);\n function getLastSellPrice(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyalties(address account) external view returns (uint256);\n function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address);\n\n function buyProton(uint256 tokenId) external payable returns (bool);\n function claimCreatorRoyalties() external returns (uint256);\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n ) external returns (uint256 newTokenId);\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n ) external returns (uint256 newTokenId);\n\n function batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n ) external;\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice) external;\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external;\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external;\n}" + }, + "contracts/v1/interfaces/IProtonB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IProtonB is IERC721 {\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n ) external returns (uint256 newTokenId);\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n}" + }, + "contracts/v1/interfaces/IRewardNft.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IRewardNft.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Reward-NFT Interface\n * @dev ...\n */\ninterface IRewardNft {\n function getMultiplier(uint256 tokenId) external view returns (uint256);\n function getBonus(uint256 tokenId) external view returns (uint256);\n}\n" + }, + "contracts/v1/interfaces/IRewardProgram.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IRewardProgram.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\ninterface IRewardProgram {\n /* admin events */\n event RewardProgramFunded(uint256 amount);\n event RewardProgramOutOfFunds();\n\n /* user events */\n event RewardsClaimed(address indexed contractAddress, uint256 tokenId, address indexed receiver, uint256 rewarded, uint256 remaining);\n\n event AssetRegistered(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\n event AssetDeposit(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\n event AssetRelease(address indexed contractAddress, uint256 tokenId, uint256 interestAmount);\n\n /* data types */\n struct ProgramRewardData {\n address stakingToken;\n address rewardToken;\n uint256 baseMultiplier; // Basis Points\n }\n\n struct AssetStake {\n uint256 start;\n uint256 claimableRewards;\n string walletManagerId;\n }\n\n function initialize(address stakingToken, address rewardToken, uint256 baseMultiplier, address chargedManagers, address universe, address owner) external;\n\n /* user functions */\n function getProgramData() external view returns (ProgramRewardData memory programData);\n function getAssetStake(uint256 uuid) external view returns (AssetStake memory);\n function getFundBalance() external view returns (uint256);\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) external view returns (uint256);\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external;\n function registerAssetDeposit(address contractAddress, uint256 tokenId, string calldata walletManagerId, uint256 principalAmount) external;\n function registerAssetRelease(address contractAddress, uint256 tokenId, uint256 interestAmount) external returns (uint256 rewards);\n}" + }, + "contracts/v1/interfaces/ISmartBasket.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartBasket.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Basket\n * @dev Manages holding and transferring NFTs within an NFT (if any),\n */\ninterface ISmartBasket {\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function addToBasket(address contractAddress, uint256 tokenId) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId) external returns (bool);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartBasketB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartBasketB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Basket \"B\"\n * @dev Manages holding and transferring NFTs within an NFT (if any),\n */\ninterface ISmartBasketB {\n function getNestedNftCount() external view returns (uint256);\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool);\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Wallet\n * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any),\n */\ninterface ISmartWallet {\n function getAssetTokenCount() external view returns (uint256);\n function getAssetTokenByIndex(uint256 index) external view returns (address);\n\n function setNftCreator(address creator, uint256 annuityPct) external;\n\n function isReserveActive(address assetToken) external view returns (bool);\n function getReserveInterestToken(address assetToken) external view returns (address);\n\n function getPrincipal(address assetToken) external returns (uint256);\n function getInterest(address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getTotal(address assetToken) external returns (uint256);\n function getRewards(address assetToken) external returns (uint256);\n\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(address receiver, address creatorRedirect, address assetToken) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function withdrawAmount(address receiver, address creatorRedirect, address assetToken, uint256 assetAmount) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function withdrawAmountForCreator(address receiver, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address assetToken) external;\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Wallet\n * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any),\n */\ninterface ISmartWalletB {\n function getAssetTokenCount() external view returns (uint256);\n function getAssetTokenByIndex(uint256 index) external view returns (address);\n\n function isReserveActive(address assetToken) external view returns (bool);\n function getReserveInterestToken(address assetToken) external view returns (address);\n\n function getPrincipal(address assetToken) external returns (uint256);\n function getInterest(address assetToken, uint256 creatorPct) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getTotal(address assetToken) external returns (uint256);\n function getRewards(address assetToken) external returns (uint256);\n\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken\n ) external returns (\n uint256 creatorAmount,\n uint256 receiverAmount\n );\n function withdrawAmount(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n ) external returns (\n uint256 creatorAmount,\n uint256 receiverAmount\n );\n function withdrawAmountForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n ) external returns (\n uint256 receiverAmount\n );\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address assetToken) external;\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/IStaking.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\ninterface IStaking {\n function manualEpochInit(address[] memory tokens, uint128 epochId) external;\n function getCurrentEpoch() external view returns (uint128);\n function getEpochId(uint timestamp) external view returns (uint); // get epoch id\n function getEpochUserBalance(address user, address token, uint128 epoch) external view returns(uint);\n function getEpochPoolSize(address token, uint128 epoch) external view returns (uint);\n function epoch1Start() external view returns (uint);\n function epochDuration() external view returns (uint);\n}" + }, + "contracts/v1/interfaces/ITokenInfoProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfoProxy.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\n\ninterface ITokenInfoProxy {\n\n event ContractFunctionSignatureSet(address indexed contractAddress, string fnName, bytes4 fnSig);\n\n struct FnSignatures {\n bytes4 ownerOf;\n bytes4 creatorOf;\n }\n\n function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external;\n function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external;\n\n function getTokenUUID(address contractAddress, uint256 tokenId) external pure returns (uint256);\n function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external returns (bool);\n function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external returns (bool);\n function getTokenOwner(address contractAddress, uint256 tokenId) external returns (address);\n function getTokenCreator(address contractAddress, uint256 tokenId) external returns (address);\n}\n" + }, + "contracts/v1/interfaces/IUniverse.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IUniverse.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Universal Controller interface\n * @dev ...\n */\ninterface IUniverse {\n\n event ChargedParticlesSet(address indexed chargedParticles);\n event PhotonSet(address indexed photonToken, uint256 maxSupply);\n event ProtonTokenSet(address indexed protonToken);\n event LeptonTokenSet(address indexed leptonToken);\n event QuarkTokenSet(address indexed quarkToken);\n event BosonTokenSet(address indexed bosonToken);\n event EsaMultiplierSet(address indexed assetToken, uint256 multiplier);\n event ElectrostaticAttraction(address indexed account, address photonSource, uint256 energy, uint256 multiplier);\n event ElectrostaticDischarge(address indexed account, address photonSource, uint256 energy);\n\n function onEnergize(\n address sender,\n address referrer,\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 assetEnergy\n ) external;\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n ) external;\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address creator,\n address assetToken,\n uint256 receiverEnergy\n ) external;\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 principalEnergy,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n ) external;\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n ) external;\n}\n" + }, + "contracts/v1/interfaces/IUniverseRP.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IUniverseRP.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport \"./IUniverse.sol\";\n\n/**\n * @title Universal Controller interface for Rewards Program\n * @dev ...\n */\ninterface IUniverseRP is IUniverse {\n event RewardProgramSet(address indexed assetToken, address indexed rewardProgram);\n event RewardProgramRemoved(address indexed assetToken);\n event NftDeposit(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\n event NftRelease(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\n\n struct NftStake {\n uint256 multiplier; // in Basis Points\n uint256 depositBlockNumber;\n uint256 releaseBlockNumber;\n }\n\n function getRewardProgram(address asset) external view returns (address);\n function getNftStake(uint256 uuid) external view returns (NftStake memory);\n}\n" + }, + "contracts/v1/interfaces/IWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Particle Wallet Manager interface\n * @dev The wallet-manager for underlying assets attached to Charged Particles\n * @dev Manages the link between NFTs and their respective Smart-Wallets\n */\ninterface IWalletManager {\n\n event ControllerSet(address indexed controller);\n event ExecutorSet(address indexed executor);\n event PausedStateSet(bool isPaused);\n event NewSmartWallet(address indexed contractAddress, uint256 indexed tokenId, address indexed smartWallet, address creator, uint256 annuityPct);\n event WalletEnergized(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 assetAmount, uint256 yieldTokensAmount);\n event WalletDischarged(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 creatorAmount, uint256 receiverAmount);\n event WalletDischargedForCreator(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, address creator, uint256 receiverAmount);\n event WalletReleased(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address assetToken, uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n event WalletRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\n\n function isPaused() external view returns (bool);\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view returns (bool);\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view returns (address);\n\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\n function getInterest(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken) external returns (uint256);\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount) external returns (uint256 yieldTokensAmount);\n function discharge(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function dischargeAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function dischargeAmountForCreator(address receiver, address contractAddress, uint256 tokenId, address creator, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\n function release(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n function releaseAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken) external;\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct) external returns (address);\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\n}\n" + }, + "contracts/v1/leptons/store.sol": { + "content": "pragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../tokens/Ionx.sol\";\nimport \"../tokens/Lepton2.sol\";\n\ninterface ILepsonsStore {\n function load(uint256 amount) external payable;\n function setLepton(address _lepton) external;\n}\n\ncontract LeptonsStore is ILepsonsStore, IERC721Receiver, Ownable, BlackholePrevention {\n using SafeMath for uint256;\n\n event SoldLepton(address indexed buyer, uint256 amount, uint256 price);\n\n Lepton2 public lepton;\n Ionx public ionx;\n\n uint256 public nextTokenId;\n uint256 public ionxPerLepton;\n\n constructor(address _lepton, address _ionx, uint256 _ionxPerLepton) public {\n lepton = Lepton2(_lepton);\n ionx = Ionx(_ionx);\n ionxPerLepton = _ionxPerLepton;\n }\n\n function buyWithIonx(\n uint256 leptonAmount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n uint256 ionxAmount = leptonAmount * ionxPerLepton;\n require(ionx.balanceOf(msg.sender) >= ionxAmount, \"Insufficient IONX balance\");\n\n ionx.permit(msg.sender, address(this), ionxAmount, deadline, v, r, s);\n ionx.transferFrom(msg.sender, address(this), ionxAmount);\n\n for (uint256 i = 0; i < leptonAmount; ++i) {\n uint256 tokenId = nextTokenId;\n nextTokenId = nextTokenId.add(1);\n\n lepton.safeTransferFrom(address(this), msg.sender, tokenId);\n }\n\n emit SoldLepton(msg.sender, leptonAmount, ionxAmount);\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function load(uint256 amount) external payable override onlyOwner {\n require(lepton.balanceOf(address(this)) == 0, \"store not empty\");\n nextTokenId = lepton.totalSupply().add(1);\n lepton.batchMintLepton{ value: msg.value }(amount);\n }\n\n function setLepton(address _lepton) external override onlyOwner {\n require(_lepton != address(0), \"Invalid address\");\n lepton = Lepton2(_lepton);\n }\n\n function setIonx(address _ionx) external onlyOwner {\n require(_ionx != address(0), \"Invalid address\");\n ionx = Ionx(_ionx);\n }\n\n function setIonxPerLepton(uint256 ionxAmount) external onlyOwner {\n ionxPerLepton = ionxAmount;\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n}" + }, + "contracts/v1/lib/BaseProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IBaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n/// @title Base Proton Contract for Charged Particles compatible ERC721 NFTs\n/// @dev MUST NOT be Upgradeable, as Upgradeable NFTs are incompatible with Charged Particles.\ncontract BaseProton is \n IBaseProton, \n ERC721, \n Ownable, \n RelayRecipient, \n ReentrancyGuard, \n BlackholePrevention \n{\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n event Received(address, uint);\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n /// @dev Sequential Token IDs storage\n Counters.Counter internal _tokenIds;\n\n /// @dev NFT Token Creator settings\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct;\n mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect;\n mapping (address => uint256) internal _tokenCreatorClaimableRoyalties;\n\n /// @dev NFT Token Sale settings\n mapping (uint256 => uint256) internal _tokenSalePrice;\n mapping (uint256 => uint256) internal _tokenLastSellPrice;\n\n /// @dev Whether of not the Contract is Paused\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n /// @dev Inherit from ERC721 standard\n constructor(string memory _name, string memory _symbol) public ERC721(_name, _symbol) {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n receive() external payable virtual {\n emit Received(msg.sender, msg.value);\n }\n\n /// Returns the Creator address of an NFT by Token ID\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The address of the Creator account\n function creatorOf(uint256 tokenId) external view virtual override returns (address) {\n return _tokenCreator[tokenId];\n }\n\n /// Returns the Sale Price of an NFT by Token ID\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The sale price of the NFT\n function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenSalePrice[tokenId];\n }\n\n /// Returns the Last Sale Price of an NFT by Token ID\n /// @notice This is used to determine any increase in sale price used in royalties calculations\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The last sale price of the NFT\n function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenLastSellPrice[tokenId];\n }\n\n /// Returns the Claimable Royalties for the NFT Creator\n /// @param account The address of the Creator account to lookup\n /// @return The amount of earned royalties for the creator account\n function getCreatorRoyalties(address account) external view virtual override returns (uint256) {\n return _tokenCreatorClaimableRoyalties[account];\n }\n\n /// Returns the Percentage of Royalties reserved for the NFT Creator\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The percentage of royalties reserved for the creator\n function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenCreatorRoyaltiesPct[tokenId];\n }\n\n /// Returns the Receiving address of the Creator Royalties (or Creator if not set)\n /// @dev Returns the creator address if a receiving address has not been configured\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The Receiving address of the Creator Royalties\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) {\n return _creatorRoyaltiesReceiver(tokenId);\n }\n\n /// Allows an NFT Creator to Claim any Royalties that have been earned from NFT sales\n /// @dev Must be called by the royalties receiver account (not neccessarily the creator)\n /// @return The amout of creator royalties claimed\n function claimCreatorRoyalties()\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256)\n {\n return _claimCreatorRoyalties(_msgSender());\n }\n\n\n /***********************************|\n | Create Single Protons |\n |__________________________________*/\n\n /// Creates a Basic NFT with no Royalties and no initial Sale Price\n /// @dev Royalties and Sale Price can be configured later\n /// @param creator The address of the NFT Creator (can be different from the caller)\n /// @param receiver The receiving address of the NFT (can be different from the caller)\n /// @param tokenMetaUri The unique metadata URI for the NFT\n /// @return newTokenId The newly minted NFT Token ID\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n\n /***********************************|\n | Create Multiple Protons |\n |__________________________________*/\n\n function createProtons(\n address creator,\n address receiver,\n string[] calldata tokenMetaUris\n )\n external\n virtual\n override\n whenNotPaused\n returns (bool)\n {\n _createProtons(\n creator,\n receiver,\n 0, // royaltiesPercent\n tokenMetaUris\n );\n return true;\n }\n\n function createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n external\n virtual\n override\n whenNotPaused\n returns (bool)\n {\n _createProtonsForSale(\n creator,\n receiver,\n royaltiesPercent,\n tokenMetaUris,\n salePrices\n );\n return true;\n }\n\n\n /***********************************|\n | Buy Protons |\n |__________________________________*/\n\n function buyProton(uint256 tokenId, uint256 gasLimit)\n external\n payable\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (bool)\n {\n _buyProton(tokenId, gasLimit);\n return true;\n }\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice)\n external\n virtual\n override\n whenNotPaused\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setSalePrice(tokenId, salePrice);\n }\n\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setRoyaltiesPct(tokenId, royaltiesPct);\n }\n\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n {\n _tokenCreatorRoyaltiesRedirect[tokenId] = receiver;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual {\n _tokenSalePrice[tokenId] = salePrice;\n emit SalePriceSet(tokenId, salePrice);\n }\n\n function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual {\n require(royaltiesPct <= PERCENTAGE_SCALE, \"PRT:E-421\");\n _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct;\n emit CreatorRoyaltiesSet(tokenId, royaltiesPct);\n }\n\n function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) {\n address receiver = _tokenCreatorRoyaltiesRedirect[tokenId];\n if (receiver == address(0x0)) {\n receiver = _tokenCreator[tokenId];\n }\n return receiver;\n }\n\n function _createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n _tokenIds.increment();\n\n newTokenId = _tokenIds.current();\n _safeMint(receiver, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUri);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n }\n\n function _createProtons(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris\n )\n internal\n virtual\n {\n uint256 count = tokenMetaUris.length;\n for (uint256 i; i < count; i++) {\n _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, 0);\n }\n }\n\n function _createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n internal\n virtual\n {\n require(tokenMetaUris.length == salePrices.length, \"PRT:E-202\");\n\n uint256 count = tokenMetaUris.length;\n for (uint256 i; i < count; i++) {\n _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, salePrices[i]);\n }\n }\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n contractAddress = address(this);\n tokenId = _tokenId;\n salePrice = _tokenSalePrice[_tokenId];\n require(salePrice > 0, \"PRT:E-416\");\n require(msg.value >= salePrice, \"PRT:E-414\");\n\n uint256 ownerAmount = salePrice;\n creatorAmount;\n oldOwner = ownerOf(_tokenId);\n newOwner = _msgSender();\n\n // Creator Royalties\n royaltiesReceiver = _creatorRoyaltiesReceiver(_tokenId);\n uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[_tokenId];\n uint256 lastSellPrice = _tokenLastSellPrice[_tokenId];\n if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) {\n creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE);\n ownerAmount = ownerAmount.sub(creatorAmount);\n }\n _tokenLastSellPrice[_tokenId] = salePrice;\n\n // Reserve Royalties for Creator\n if (creatorAmount > 0) {\n _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount);\n }\n\n // Transfer Token\n _transfer(oldOwner, newOwner, _tokenId);\n\n // Transfer Payment\n if (ownerAmount > 0) {\n payable(oldOwner).sendValue(ownerAmount, _gasLimit);\n }\n\n emit ProtonSold(_tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n\n _refundOverpayment(salePrice, _gasLimit);\n }\n\n /**\n * @dev Pays out the Creator Royalties of the calling account\n * @param receiver The receiver of the claimable royalties\n * @return The amount of Creator Royalties claimed\n */\n function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) {\n uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver];\n require(claimableAmount > 0, \"PRT:E-411\");\n\n delete _tokenCreatorClaimableRoyalties[receiver];\n payable(receiver).sendValue(claimableAmount, 0);\n\n emit RoyaltiesClaimed(receiver, claimableAmount);\n }\n\n /**\n * @dev Collects the Required Asset Token from the users wallet\n * @param from The owner address to collect the Assets from\n * @param assetAmount The Amount of Asset Tokens to Collect\n */\n function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual {\n uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from);\n require(assetAmount <= _userAssetBalance, \"PRT:E-411\");\n // Be sure to Approve this Contract to transfer your Asset Token\n require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), \"PRT:E-401\");\n }\n\n function _refundOverpayment(uint256 threshold, uint256 gasLimit) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage, gasLimit);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n _tokenSalePrice[tokenId] = 0;\n super._transfer(from, to, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"PRT:E-101\");\n _;\n }\n\n modifier onlyTokenOwnerOrApproved(uint256 tokenId) {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"PRT:E-105\");\n _;\n }\n\n modifier onlyTokenCreator(uint256 tokenId) {\n require(_tokenCreator[tokenId] == _msgSender(), \"PRT:E-104\");\n _;\n }\n}" + }, + "contracts/v1/lib/Bitwise.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Bitwise.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nlibrary Bitwise {\n function negate(uint32 a) internal pure returns (uint32) {\n return a ^ maxInt();\n }\n\n function shiftLeft(uint32 a, uint32 n) internal pure returns (uint32) {\n return a * uint32(2) ** n;\n }\n\n function shiftRight(uint32 a, uint32 n) internal pure returns (uint32) {\n return a / uint32(2) ** n;\n }\n\n function maxInt() internal pure returns (uint32) {\n return uint32(-1);\n }\n\n // Get bit value at position\n function hasBit(uint32 a, uint32 n) internal pure returns (bool) {\n return a & shiftLeft(0x01, n) != 0;\n }\n\n // Set bit value at position\n function setBit(uint32 a, uint32 n) internal pure returns (uint32) {\n return a | shiftLeft(0x01, n);\n }\n\n // Set the bit into state \"false\"\n function clearBit(uint32 a, uint32 n) internal pure returns (uint32) {\n uint32 mask = negate(shiftLeft(0x01, n));\n return a & mask;\n }\n}\n" + }, + "contracts/v1/lib/BlackholePrevention.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\n\n/**\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\n * the Owner/DAO to pull them out on behalf of a user\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\n */\ncontract BlackholePrevention {\n using Address for address payable;\n using SafeERC20 for IERC20;\n\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\n\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (address(this).balance >= amount) {\n receiver.sendValue(amount);\n emit WithdrawStuckEther(receiver, amount);\n }\n }\n\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\n IERC20(tokenAddress).safeTransfer(receiver, amount);\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\n }\n }\n\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\n }\n }\n\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \"\");\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\n }\n }\n}\n" + }, + "contracts/v1/lib/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/GSN/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableMap.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n /**\n * @dev Emitted when `tokenId` token is transfered from `from` to `to`.\n */\n event TransferBatch(address indexed from, address indexed to, uint256 startTokenId, uint256 count);\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721:E-403\");\n\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721:E-405\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"ERC721:E-405\");\n return _tokenURIs[tokenId];\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721:E-111\");\n\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \"ERC721:E-105\");\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view override returns (address) {\n require(_exists(tokenId), \"ERC721:E-405\");\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 require(operator != _msgSender(), \"ERC721:E-111\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721:E-402\");\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 returns (bool) {\n return _tokenOwners.contains(tokenId);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721:E-405\");\n address owner = ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721:E-402\");\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 _safeMintBatch(address to, uint256 startTokenId, uint256 count, bytes memory _data) internal virtual {\n _mintBatch(to, startTokenId, count);\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \"ERC721:E-402\");\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:E-403\");\n require(!_exists(tokenId), \"ERC721:E-407\");\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\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 _mintBatch(address to, uint256 startTokenId, uint256 count) internal virtual {\n require(to != address(0), \"ERC721:E-403\");\n require(!_exists(startTokenId), \"ERC721:E-407\");\n\n for (uint i = 0; i < count; i++) {\n uint256 tokenId = startTokenId.add(i);\n _holderTokens[to].add(tokenId);\n _tokenOwners.set(tokenId, to);\n }\n\n emit TransferBatch(address(0), to, startTokenId, count);\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(address from, address to, uint256 tokenId) internal virtual {\n require(ownerOf(tokenId) == from, \"ERC721:E-102\");\n require(to != address(0), \"ERC721:E-403\");\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721:E-405\");\n _tokenURIs[tokenId] = _tokenURI;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721:E-402\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\n }\n}\n" + }, + "contracts/v1/lib/ERC721Basic.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/GSN/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Basic is Context, ERC165, IERC721, IERC721Metadata {\n using SafeMath for uint256;\n using Address for address;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 internal constant _ERC721_RECEIVED = 0x150b7a02;\n\n // mapping from token ids to their owners\n mapping (uint256 => address) internal _tokenOwners;\n\n // mapping from owner to token balance\n mapping (address => uint256) internal _ownerBalance;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) internal _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) internal _operatorApprovals;\n\n // Token name\n string internal _name;\n\n // Token symbol\n string internal _symbol;\n\n // Token Count\n uint256 internal _tokenCount;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 internal constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 internal constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721:E-403\");\n return _ownerBalance[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners[tokenId];\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view 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 return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721:E-111\");\n\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \"ERC721:E-105\");\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view override returns (address) {\n require(_exists(tokenId), \"ERC721:E-405\");\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721:E-111\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721:E-402\");\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 returns (bool) {\n return _tokenOwners[tokenId] != address(0x0);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721:E-405\");\n address owner = ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\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(address to, bytes memory _data) internal virtual returns (uint256) {\n uint256 tokenId = _mint(to);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721:E-402\");\n return 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 _safeMintBatch(address to, uint256 count, bytes memory _data) internal virtual {\n uint256 startTokenId = _mintBatch(to, count);\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \"ERC721:E-402\");\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) internal virtual returns (uint256) {\n require(to != address(0), \"ERC721:E-403\");\n\n _tokenCount = _tokenCount.add(1);\n uint256 tokenId = _tokenCount;\n require(!_exists(tokenId), \"ERC721:E-407\");\n\n _tokenOwners[tokenId] = to;\n _ownerBalance[to] = _ownerBalance[to].add(1);\n\n emit Transfer(address(0), to, tokenId);\n return tokenId;\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 _mintBatch(address to, uint256 count) internal virtual returns (uint256) {\n require(to != address(0), \"ERC721:E-403\");\n\n uint256 startTokenId = _tokenCount.add(1);\n for (uint i = 1; i <= count; i++) {\n uint256 tokenId = _tokenCount.add(i);\n _tokenOwners[tokenId] = to;\n emit Transfer(address(0), to, tokenId);\n }\n\n _tokenCount = _tokenCount.add(count);\n _ownerBalance[to] = _ownerBalance[to].add(count);\n return startTokenId;\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(address from, address to, uint256 tokenId) internal virtual {\n require(ownerOf(tokenId) == from, \"ERC721:E-102\");\n require(to != address(0), \"ERC721:E-403\");\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _tokenOwners[tokenId] = to;\n _ownerBalance[from] = _ownerBalance[from].sub(1);\n _ownerBalance[to] = _ownerBalance[to].add(1);\n\n emit Transfer(from, to, tokenId);\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(address from, address to, uint256 tokenId, bytes memory _data)\n internal returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721:E-402\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) internal {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\n }\n}\n" + }, + "contracts/v1/lib/IERC5192.sol": { + "content": "// SPDX-License-Identifier: CC0-1.0\npragma solidity ^0.6.0;\n\ninterface IERC5192 {\n /// @notice Emitted when the locking status is changed to locked.\n /// @dev If a token is minted and the status is locked, this event should be emitted.\n /// @param tokenId The identifier for a token.\n event Locked(uint256 tokenId);\n\n /// @notice Emitted when the locking status is changed to unlocked.\n /// @dev If a token is minted and the status is unlocked, this event should be emitted.\n /// @param tokenId The identifier for a token.\n event Unlocked(uint256 tokenId);\n\n /// @notice Returns the locking status of an Soulbound Token\n /// @dev SBTs assigned to zero address are considered invalid, and queries\n /// about them do throw.\n /// @param tokenId The identifier for an SBT.\n function locked(uint256 tokenId) external view returns (bool);\n}\n" + }, + "contracts/v1/lib/NftTokenType.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// NftTokenType.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/introspection/IERC165.sol\";\n\nlibrary NftTokenType {\n bytes4 constant internal INTERFACE_SIGNATURE_ERC721 = 0x80ac58cd;\n bytes4 constant internal INTERFACE_SIGNATURE_ERC1155 = 0xd9b67a26;\n\n uint256 constant internal TYPE_MASK = uint256(uint128(~0)) << 128;\n uint256 constant internal TYPE_NFT_BIT = 1 << 255;\n\n function isERC721(address contractAddress) internal view returns (bool) {\n return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC721);\n }\n\n function isERC1155(address contractAddress) internal view returns (bool) {\n return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC1155);\n }\n\n function getTokenType(address contractAddress, uint256 tokenId) internal view returns (uint256) {\n IERC165 tokenInterface = IERC165(contractAddress);\n bool is1155 = tokenInterface.supportsInterface(INTERFACE_SIGNATURE_ERC1155);\n\n if (!is1155 || (tokenId & TYPE_NFT_BIT != TYPE_NFT_BIT)) { return 0; }\n\n return tokenId & TYPE_MASK;\n }\n}\n" + }, + "contracts/v1/lib/ReentrancyGuard.sol": { + "content": "pragma solidity 0.6.12;\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 () public {\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 _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\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 /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}" + }, + "contracts/v1/lib/RelayRecipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0;\n\nimport \"@opengsn/gsn/contracts/BaseRelayRecipient.sol\";\n\ncontract RelayRecipient is BaseRelayRecipient {\n function versionRecipient() external override view returns (string memory) {\n return \"1.0.0-beta.1/charged-particles.relay.recipient\";\n }\n}\n" + }, + "contracts/v1/lib/SmartWalletBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// SmartWalletBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../interfaces/ISmartWallet.sol\";\nimport \"./BlackholePrevention.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract SmartWalletBase is ISmartWallet, BlackholePrevention {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n address internal _walletManager;\n\n address internal nftCreator;\n uint256 internal nftCreatorAnnuityPct;\n uint256 internal nftCreatorAmountDischarged;\n\n EnumerableSet.AddressSet internal _assetTokens;\n\n // Asset Token => Principal Balance\n mapping (address => uint256) internal _assetPrincipalBalance;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initializeBase() public {\n require(_walletManager == address(0x0), \"SWB:E-002\");\n _walletManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getAssetTokenCount() external view virtual override returns (uint256) {\n return _assetTokens.length();\n }\n\n function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) {\n if (index >= _assetTokens.length()) {\n return address(0);\n }\n return _assetTokens.at(index);\n }\n\n function setNftCreator(address creator, uint256 annuityPct) external virtual override onlyWalletManager {\n nftCreator = creator;\n nftCreatorAnnuityPct = annuityPct;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyWalletManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n function refreshPrincipal(address assetToken)\n external\n virtual\n override\n onlyWalletManager\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getPrincipal(address assetToken) internal view virtual returns (uint256) {\n return _assetPrincipalBalance[assetToken];\n }\n\n function _trackAssetToken(address assetToken) internal virtual {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n }\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the wallet manager\n modifier onlyWalletManager() {\n require(_walletManager == msg.sender, \"SWB:E-109\");\n _;\n }\n}" + }, + "contracts/v1/lib/SmartWalletBaseB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// SmartWalletBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../interfaces/ISmartWalletB.sol\";\nimport \"./BlackholePrevention.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract SmartWalletBaseB is ISmartWalletB, BlackholePrevention {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n address internal _walletManager;\n\n EnumerableSet.AddressSet internal _assetTokens;\n\n // Asset Token => Principal Balance\n mapping (address => uint256) internal _assetPrincipalBalance;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initializeBase() public {\n require(_walletManager == address(0x0), \"SWB:E-002\");\n _walletManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getAssetTokenCount() external view virtual override returns (uint256) {\n return _assetTokens.length();\n }\n\n function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) {\n if (index >= _assetTokens.length()) {\n return address(0);\n }\n return _assetTokens.at(index);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyWalletManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getPrincipal(address assetToken) internal view virtual returns (uint256) {\n return _assetPrincipalBalance[assetToken];\n }\n\n function _trackAssetToken(address assetToken) internal virtual {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n }\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the wallet manager\n modifier onlyWalletManager() {\n require(_walletManager == msg.sender, \"SWB:E-109\");\n _;\n }\n}" + }, + "contracts/v1/lib/Soul.sol": { + "content": "// SPDX-License-Identifier: CC0-1.0\npragma solidity ^0.6.12;\n\nimport \"./IERC5192.sol\";\n\ncontract Soul is IERC5192 {\n \n mapping (uint256 => bool) public lockedTokens;\n\n function _lockToken(uint256 tokenId) internal {\n lockedTokens[tokenId] = true;\n emit Locked(tokenId);\n }\n\n function _unlockToken(uint256 tokenId) internal {\n lockedTokens[tokenId] = false;\n emit Unlocked(tokenId);\n }\n\n function locked(uint256 tokenId)\n external\n view\n override(IERC5192)\n returns (bool)\n {\n return lockedTokens[tokenId];\n }\n}\n" + }, + "contracts/v1/lib/TokenInfo.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfo.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"../interfaces/IERC721Chargeable.sol\";\n\nlibrary TokenInfo {\n function getTokenUUID(address contractAddress, uint256 tokenId) internal pure virtual returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n function getTokenOwner(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n return tokenInterface.ownerOf(tokenId);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n function getTokenCreator(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n return tokenInterface.creatorOf(tokenId);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Owner of an External NFT contract\n /// @param contractAddress The Address to the Contract of the NFT to check\n /// @param account The Address of the Account to check\n /// @return True if the account owns the contract\n function isContractOwner(address contractAddress, address account) internal view virtual returns (bool) {\n address contractOwner = IERC721Chargeable(contractAddress).owner();\n return contractOwner != address(0x0) && contractOwner == account;\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Creator of a Proton-based NFT\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the Proton-based NFT\n function isTokenCreator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenCreator = tokenInterface.creatorOf(tokenId);\n return (sender == tokenCreator);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the Proton-based NFT or the Contract itself\n function isTokenContractOrCreator(address contractAddress, uint256 tokenId, address creator, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenCreator = tokenInterface.creatorOf(tokenId);\n if (sender == contractAddress && creator == tokenCreator) { return true; }\n return (sender == tokenCreator);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Owner or Operator of an External NFT\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the Owner or Operator of the External NFT\n function isErc721OwnerOrOperator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenOwner = tokenInterface.ownerOf(tokenId);\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\n }\n\n /**\n * @dev Returns true if `account` is a contract.\n * @dev Taken from OpenZeppelin library\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\n // for accounts without code, i.e. `keccak256('')`\n bytes32 codehash;\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n // solhint-disable-next-line no-inline-assembly\n assembly { codehash := extcodehash(account) }\n return (codehash != accountHash && codehash != 0x0);\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 * @dev Taken from OpenZeppelin library\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, uint256 gasLimit) internal {\n require(address(this).balance >= amount, \"TokenInfo: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = (gasLimit > 0)\n ? recipient.call{ value: amount, gas: gasLimit }(\"\")\n : recipient.call{ value: amount }(\"\");\n require(success, \"TokenInfo: unable to send value, recipient may have reverted\");\n }\n}\n" + }, + "contracts/v1/lib/TokenInfoProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfoProxy.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../interfaces/ITokenInfoProxy.sol\";\nimport \"../interfaces/IERC721Chargeable.sol\";\n\n\ncontract TokenInfoProxy is ITokenInfoProxy, Ownable {\n using Address for address;\n\n mapping (address => FnSignatures) internal _remappedFnSigs;\n\n function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner {\n _remappedFnSigs[contractAddress].ownerOf = fnSig;\n emit ContractFunctionSignatureSet(contractAddress, \"ownerOf\", fnSig);\n }\n\n function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner {\n _remappedFnSigs[contractAddress].creatorOf = fnSig;\n emit ContractFunctionSignatureSet(contractAddress, \"creatorOf\", fnSig);\n }\n\n\n function getTokenUUID(address contractAddress, uint256 tokenId) external pure virtual override returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n function getTokenOwner(address contractAddress, uint256 tokenId) external virtual override returns (address) {\n return _getTokenOwner(contractAddress, tokenId);\n }\n\n function getTokenCreator(address contractAddress, uint256 tokenId) external virtual override returns (address) {\n return _getTokenCreator(contractAddress, tokenId);\n }\n\n function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenOwner = _getTokenOwner(contractAddress, tokenId);\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\n }\n\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the NFT or the Contract itself\n function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) {\n address tokenCreator = _getTokenCreator(contractAddress, tokenId);\n return (sender == tokenCreator || sender == contractAddress);\n }\n\n\n\n function _getTokenCreator(address contractAddress, uint256 tokenId) internal returns (address) {\n bytes4 fnSig = IERC721Chargeable.creatorOf.selector;\n if (_remappedFnSigs[contractAddress].creatorOf != bytes4(0)) {\n fnSig = _remappedFnSigs[contractAddress].creatorOf;\n }\n\n // solhint-disable-next-line\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n if (success) {\n return abi.decode(returnData, (address));\n } else {\n return address(0x0);\n }\n }\n\n function _getTokenOwner(address contractAddress, uint256 tokenId) internal returns (address) {\n bytes4 fnSig = IERC721Chargeable.ownerOf.selector;\n if (_remappedFnSigs[contractAddress].ownerOf != bytes4(0)) {\n fnSig = _remappedFnSigs[contractAddress].ownerOf;\n }\n\n // solhint-disable-next-line\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n if (success) {\n return abi.decode(returnData, (address));\n } else {\n return address(0x0);\n }\n }\n}\n" + }, + "contracts/v1/lib/WalletManagerBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// WalletManagerBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IWalletManager.sol\";\nimport \"../interfaces/ISmartWallet.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"./BlackholePrevention.sol\";\n\n\n/**\n * @notice Wallet-Manager Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract WalletManagerBase is Ownable, BlackholePrevention, IWalletManager {\n using TokenInfo for address;\n\n // The Controller Contract Address\n address internal _controller;\n\n // The Executor Contract Address\n address internal _executor;\n\n // Template Contract for creating Token Smart-Wallet Bridges\n address internal _walletTemplate;\n\n // TokenID => Token Smart-Wallet Address\n mapping (uint256 => address) internal _wallets;\n\n // State of Wallet Manager\n bool internal _paused;\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Wallet Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n /**\n * @dev Connects to the ExecForAccount Controller\n */\n function setExecutor(address executor) external onlyOwner {\n _executor = executor;\n emit ExecutorSet(executor);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartWallet(wallet).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartWallet(wallet).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartWallet(wallet).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Executor contract\n modifier onlyExecutor() {\n require(_executor == msg.sender, \"WMB:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Controller or Executor contract\n modifier onlyControllerOrExecutor() {\n require(_executor == msg.sender || _controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"WMB:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/ParticleSplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ParticleSplitter.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"./interfaces/IParticleSplitter.sol\";\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IWalletManager.sol\";\nimport \"./interfaces/IBasketManager.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Contract\n * @dev Upgradeable Contract\n */\ncontract ParticleSplitter is IParticleSplitter, Ownable, ReentrancyGuard, BlackholePrevention\n{\n IChargedManagers internal _chargedManagers;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n mapping (address => bool) internal _externalAddressesAllowed;\n\n\n /***********************************|\n | Execute for Account |\n |__________________________________*/\n\n /// @notice Executes an arbitrary command on an NFT Wallet\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Wallet Manager controlling the NFT Wallet to execute on\n /// @param externalAddress The Address of the External Contract to execute on\n /// @param encodedParams The encoded function call to execute\n function executeForWallet(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address externalAddress,\n bytes memory encodedParams\n )\n external\n payable\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (bytes memory)\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n require(_externalAddressesAllowed[externalAddress], \"PS:E-117\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Wallet Manager\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n // Get Address of Wallet to send any ETH into\n if (msg.value > 0) {\n address wallet = walletMgr.getWalletAddressById(contractAddress, tokenId, address(0), 0);\n payable(wallet).sendValue(msg.value);\n }\n\n emit ExecuteForWallet(contractAddress, tokenId, walletManagerId, externalAddress, encodedParams, msg.value);\n\n // Execute command for NFT Wallet\n return walletMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams);\n }\n\n /// @notice Executes an arbitrary command on an NFT Basket\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param basketManagerId The Basket Manager controlling the NFT Wallet to execute on\n /// @param externalAddress The Address of the External Contract to execute on\n /// @param encodedParams The encoded function call to execute\n function executeForBasket(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address externalAddress,\n bytes memory encodedParams\n )\n external\n payable\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (bytes memory)\n {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"PS:E-419\");\n require(_externalAddressesAllowed[externalAddress], \"PS:E-117\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Basket Manager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n\n // Get Address of Wallet to send any ETH into\n if (msg.value > 0) {\n address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId);\n payable(wallet).sendValue(msg.value);\n }\n\n emit ExecuteForBasket(contractAddress, tokenId, basketManagerId, externalAddress, encodedParams, msg.value);\n\n // Execute command for NFT Wallet\n return basketMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams);\n }\n\n function withdrawWalletRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (uint256 amountWithdrawn)\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Wallet Manager\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n // Withdraw Rewards for NFT Wallet\n return walletMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount);\n }\n\n function withdrawBasketRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (uint256 amountWithdrawn)\n {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"PS:E-419\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Basket Manager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n\n // Withdraw Rewards for NFT Basket\n return basketMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount);\n }\n\n function refreshWalletPrincipal(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n walletMgr.refreshPrincipal(contractAddress, tokenId, assetToken);\n\n emit PrincipalRefreshed(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedManagers Interface\n */\n function setChargedManagers(address chargedManagers) external virtual onlyOwner {\n _chargedManagers = IChargedManagers(chargedManagers);\n emit ChargedManagersSet(chargedManagers);\n }\n\n /**\n * @dev Setup the ChargedManagers Interface\n */\n function setTokenInfoProxy(address tokenInfoProxy) external virtual onlyOwner {\n _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy);\n emit TokenInfoProxySet(tokenInfoProxy);\n }\n\n /**\n * @dev Allows/Disallows execute from on specific contracts\n */\n function setExternalContracts(address[] calldata contracts, bool state) external onlyOwner {\n uint count = contracts.length;\n for (uint i; i < count; i++) {\n address externalContract = contracts[i];\n _externalAddressesAllowed[externalContract] = state;\n emit PermsSetForExternal(externalContract, state);\n }\n }\n\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyTokenOwner(address contractAddress, uint256 tokenId) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(msg.sender == tokenOwner, \"PS:E-102\");\n _;\n }\n}\n" + }, + "contracts/v1/test/Dai.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"../interfaces/IDai.sol\";\n\ncontract Dai is IDai {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (uint256 chainId_) public {\n string memory version = \"1\";\n\n _name = \"Dai Stablecoin\";\n _symbol = \"DAI\";\n _decimals = 18;\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(_name)),\n keccak256(bytes(version)),\n chainId_,\n address(this)\n )\n );\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view 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(msg.sender, 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(msg.sender, 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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(msg.sender, spender, _allowances[msg.sender][spender].add(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 _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20:E-403\");\n require(recipient != address(0), \"ERC20:E-403\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20:E-403\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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:E-403\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20:E-403\");\n require(spender != address(0), \"ERC20:E-403\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n\n mapping (address => uint) public nonces;\n\n // --- EIP712 niceties ---\n bytes32 public DOMAIN_SEPARATOR;\n // bytes32 public constant PERMIT_TYPEHASH = keccak256(\"Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)\");\n bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;\n\n // --- Approve by signature ---\n function permit(\n address holder, address spender, uint256 nonce, uint256 expiry,\n bool allowed, uint8 v, bytes32 r, bytes32 s) external override\n {\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n holder,\n spender,\n nonce,\n expiry,\n allowed\n )\n )\n )\n );\n\n require(holder != address(0), \"Dai/invalid-address-0\");\n require(holder == ecrecover(digest, v, r, s), \"Dai/invalid-permit\");\n require(expiry == 0 || now <= expiry, \"Dai/permit-expired\");\n require(nonce == nonces[holder]++, \"Dai/invalid-nonce\");\n uint wad = allowed ? uint(-1) : 0;\n _allowances[holder][spender] = wad;\n emit Approval(holder, spender, wad);\n }\n\n function mint(address to, uint256 amount) external {\n _mint(to, amount);\n }\n}" + }, + "contracts/v1/test/ERC20Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.7.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/**\n * @dev Extension of {ERC20} that adds a set of accounts with the {MinterRole},\n * which have permission to mint (create) new tokens as they see fit.\n *\n * At construction, the deployer of the contract is the only minter.\n */\ncontract ERC20Mintable is ERC20Upgradeable {\n\n constructor(string memory _name, string memory _symbol) public {\n __ERC20_init(_name, _symbol);\n }\n\n /**\n * @dev See {ERC20-_mint}.\n *\n * Requirements:\n *\n * - the caller must have the {MinterRole}.\n */\n function mint(address account, uint256 amount) public returns (bool) {\n _mint(account, amount);\n return true;\n }\n\n function burn(address account, uint256 amount) public returns (bool) {\n _burn(account, amount);\n return true;\n }\n}" + }, + "contracts/v1/test/ERC721Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.7.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\n\n/**\n * @dev Extension of {ERC721} for Minting/Burning\n */\ncontract ERC721Mintable is ERC721Upgradeable {\n\n constructor () public {\n __ERC721_init(\"ERC 721\", \"NFT\");\n }\n\n /**\n * @dev See {ERC721-_mint}.\n */\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n\n /**\n * @dev See {ERC721-_burn}.\n */\n function burn(uint256 tokenId) public {\n _burn(tokenId);\n }\n}\n" + }, + "contracts/v1/tokens/ExternalERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ExternalERC721.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\n\ncontract ExternalERC721 is ERC721 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n\n constructor() public ERC721(\"Charged Particles - ExternalERC721\", \"ExNFT\") {}\n\n function mintNft(address receiver, string memory tokenUri) external returns (uint256 newTokenId) {\n return _mintNft(receiver, tokenUri);\n }\n\n function _mintNft(address receiver, string memory tokenUri) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n\n _safeMint(receiver, newTokenId, \"\");\n\n _setTokenURI(newTokenId, tokenUri);\n }\n}\n" + }, + "contracts/v1/tokens/FungibleERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// FungibleERC1155.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract FungibleERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n\n constructor() public ERC1155(\"https://staging.app.charged.fi/erc1155/metadata.json\") {}\n\n function mintNft(address receiver, uint256 amount) external returns (uint256 newTokenId) {\n return _mintNft(receiver, amount);\n }\n\n function _mintNft(address receiver, uint256 amount) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n _mint(receiver, newTokenId, amount, \"\");\n }\n}\n" + }, + "contracts/v1/tokens/Ionx.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Ionx.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"erc20permit/contracts/ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\n\ncontract Ionx is ERC20Permit, Ownable, BlackholePrevention {\n using SafeMath for uint256;\n\n /// @notice An event thats emitted when the minter address is changed\n event MinterChanged(address minter, address newMinter);\n\n /// @notice Total number of tokens in circulation\n uint256 constant public INITIAL_SUPPLY = 1e8 ether;\n\n /// @notice Minimum time between mints\n uint32 public constant INFLATION_EPOCH = 1 days * 365;\n\n /// @notice Cap on the percentage of totalSupply that can be minted at each mint\n uint8 public constant INFLATION_CAP = 2;\n\n /// @notice Address which may mint new tokens\n address public minter;\n\n /// @notice The timestamp after which minting may occur\n uint256 public mintingAllowedAfter;\n\n\n constructor() public ERC20Permit(\"Charged Particles - IONX\", \"IONX\") {}\n\n\n /**\n * @notice Change the minter address\n * @param newMinter The address of the new minter\n */\n function setMinter(address newMinter) external onlyOwner {\n emit MinterChanged(minter, newMinter);\n minter = newMinter;\n }\n\n /**\n * @notice Mint new tokens\n * @param receiver The address of the destination account\n * @param amount The number of tokens to be minted\n */\n function mint(address receiver, uint256 amount) external onlyMinter {\n require(block.timestamp >= mintingAllowedAfter, \"Ionx:E-114\");\n require(receiver != address(0), \"Ionx:E-403\");\n\n uint256 amountToMint = amount;\n uint256 _totalSupply = totalSupply();\n\n // From Inflationary Supply\n if (_totalSupply >= INITIAL_SUPPLY) {\n mintingAllowedAfter = mintingAllowedAfter.add(INFLATION_EPOCH);\n amountToMint = _totalSupply.mul(INFLATION_CAP).div(100);\n }\n\n // From Initial Supply\n else {\n if (_totalSupply.add(amountToMint) > INITIAL_SUPPLY) {\n amountToMint = INITIAL_SUPPLY.sub(_totalSupply);\n }\n if (_totalSupply.add(amountToMint) == INITIAL_SUPPLY) {\n mintingAllowedAfter = block.timestamp.add(INFLATION_EPOCH);\n }\n }\n\n // transfer the amount to the recipient\n _mint(receiver, amountToMint);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n modifier onlyMinter() {\n require(msg.sender == minter, \"Ionx:E-113\");\n _;\n }\n}\n" + }, + "contracts/v1/tokens/Lepton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Lepton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/ILepton.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\n\ncontract Lepton is ILepton, ERC721, Ownable, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenIds;\n Classification[] internal _leptonTypes;\n mapping (uint256 => Classification) internal _leptonData;\n\n uint256 internal _typeIndex;\n uint256 internal _maxSupply;\n uint256 internal _maxMintPerTx;\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721(\"Charged Particles - Lepton\", \"LEPTON\") {\n _paused = true;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function mintLepton() external payable virtual override nonReentrant whenNotPaused returns (uint256 newTokenId) {\n newTokenId = _mintLepton(msg.sender);\n }\n\n function batchMintLepton(uint256 count) external payable virtual override nonReentrant whenNotPaused {\n _batchMintLepton(msg.sender, count);\n }\n\n function getNextType() external view virtual override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _typeIndex;\n }\n\n function getNextPrice() external view virtual override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _leptonTypes[_typeIndex].price;\n }\n\n function getMultiplier(uint256 tokenId) external view virtual override returns (uint256) {\n return _leptonData[tokenId].multiplier;\n }\n\n function getBonus(uint256 tokenId) external view virtual override returns (uint256) {\n return _leptonData[tokenId].bonus;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function addLeptonType(\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n virtual\n onlyOwner\n {\n _maxSupply = _maxSupply.add(uint256(supply));\n\n Classification memory lepton = Classification({\n tokenUri: tokenUri,\n price: price,\n supply: supply,\n multiplier: multiplier,\n bonus: bonus,\n _upperBounds: uint128(_maxSupply)\n });\n _leptonTypes.push(lepton);\n\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function updateLeptonType(\n uint256 leptonIndex,\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n virtual\n onlyOwner\n {\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\n _leptonTypes[leptonIndex].price = price;\n _leptonTypes[leptonIndex].supply = supply;\n _leptonTypes[leptonIndex].multiplier = multiplier;\n _leptonTypes[leptonIndex].bonus = bonus;\n\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function setMaxMintPerTx(uint256 maxAmount) external virtual onlyOwner {\n _maxMintPerTx = maxAmount;\n emit MaxMintPerTxSet(maxAmount);\n }\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _mintLepton(address receiver) internal virtual returns (uint256 newTokenId) {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n require(msg.value >= lepton.price, \"LPT:E-414\");\n\n _tokenIds.increment();\n newTokenId = _tokenIds.current();\n\n _leptonData[newTokenId] = lepton;\n _safeMint(receiver, newTokenId, \"\");\n _setTokenURI(newTokenId, lepton.tokenUri);\n\n // Distribute Next Type\n if (newTokenId == lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n emit LeptonMinted(receiver, newTokenId, lepton.price, lepton.multiplier);\n\n _refundOverpayment(lepton.price);\n }\n\n\n function _batchMintLepton(address receiver, uint256 count) internal virtual {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \"LPT:E-429\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n\n uint256 startTokenId = _tokenIds.current();\n uint256 endTokenId = startTokenId.add(count);\n if (endTokenId > lepton._upperBounds) {\n count = count.sub(endTokenId.sub(lepton._upperBounds));\n }\n\n uint256 salePrice = lepton.price.mul(count);\n require(msg.value >= salePrice, \"LPT:E-414\");\n\n _safeMintBatch(receiver, startTokenId.add(1), count, \"\");\n\n for (uint i = 0; i < count; i++) {\n _tokenIds.increment();\n startTokenId = _tokenIds.current();\n\n _leptonData[startTokenId] = lepton;\n _setTokenURI(startTokenId, lepton.tokenUri);\n }\n\n // Distribute Next Type\n if (startTokenId >= lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n emit LeptonBatchMinted(receiver, startTokenId, count, lepton.price, lepton.multiplier);\n\n _refundOverpayment(salePrice);\n }\n\n function _refundOverpayment(uint256 threshold) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"LPT:E-101\");\n _;\n }\n}" + }, + "contracts/v1/tokens/Lepton2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Lepton2.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"../lib/ERC721Basic.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\n\nimport \"../interfaces/ILepton.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Lepton2 is ILepton, ERC721Basic, Ownable, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n\n Classification[] internal _leptonTypes;\n\n uint256 internal _typeIndex;\n uint256 internal _maxSupply;\n uint256 internal _maxMintPerTx;\n uint256 internal _migratedCount;\n\n bool internal _paused;\n bool internal _migrationComplete;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721Basic(\"Charged Particles - Lepton2\", \"LEPTON2\") {\n _paused = true;\n _migrationComplete = false;\n _migratedCount = 0;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function mintLepton() external payable override nonReentrant whenNotPaused returns (uint256 newTokenId) {\n newTokenId = _mintLepton(msg.sender);\n }\n\n function batchMintLepton(uint256 count) external payable override nonReentrant whenNotPaused {\n _batchMintLepton(msg.sender, count);\n }\n\n function totalSupply() public view returns (uint256) {\n return _tokenCount;\n }\n\n function maxSupply() external view returns (uint256) {\n return _maxSupply;\n }\n\n function getNextType() external view override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _typeIndex;\n }\n\n function getNextPrice() external view override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _leptonTypes[_typeIndex].price;\n }\n\n function getMultiplier(uint256 tokenId) external view override returns (uint256) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).multiplier;\n }\n\n function getBonus(uint256 tokenId) external view override returns (uint256) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).bonus;\n }\n\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).tokenUri;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function addLeptonType(\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n onlyOwner\n {\n _maxSupply = _maxSupply.add(uint256(supply));\n\n Classification memory lepton = Classification({\n tokenUri: tokenUri,\n price: price,\n supply: supply,\n multiplier: multiplier,\n bonus: bonus,\n _upperBounds: uint128(_maxSupply)\n });\n _leptonTypes.push(lepton);\n\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function updateLeptonType(\n uint256 leptonIndex,\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n onlyOwner\n {\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\n _leptonTypes[leptonIndex].price = price;\n _leptonTypes[leptonIndex].supply = supply;\n _leptonTypes[leptonIndex].multiplier = multiplier;\n _leptonTypes[leptonIndex].bonus = bonus;\n\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function setMaxMintPerTx(uint256 maxAmount) external onlyOwner {\n _maxMintPerTx = maxAmount;\n emit MaxMintPerTxSet(maxAmount);\n }\n\n function setPausedState(bool state) external onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function migrateAccounts(address oldLeptonContract, uint256 count) external onlyOwner whenNotMigrated {\n uint256 oldSupply = IERC721Enumerable(oldLeptonContract).totalSupply();\n require(oldSupply == 0 || oldSupply > _migratedCount, \"LPT:E-004\");\n\n if (oldSupply > 0) {\n uint256 endTokenId = _migratedCount.add(count);\n if (endTokenId > oldSupply) {\n count = count.sub(endTokenId.sub(oldSupply));\n }\n\n for (uint256 i = 1; i <= count; i++) {\n uint256 tokenId = _migratedCount.add(i);\n address tokenOwner = IERC721(oldLeptonContract).ownerOf(tokenId);\n _mint(tokenOwner);\n }\n _migratedCount = _migratedCount.add(count);\n }\n\n if (oldSupply == _migratedCount) {\n _finalizeMigration();\n }\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getLepton(uint256 tokenId) internal view returns (Classification memory) {\n uint256 types = _leptonTypes.length;\n for (uint256 i = 0; i < types; i++) {\n Classification memory lepton = _leptonTypes[i];\n if (tokenId <= lepton._upperBounds) {\n return lepton;\n }\n }\n }\n\n function _mintLepton(address receiver) internal returns (uint256 newTokenId) {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n require(msg.value >= lepton.price, \"LPT:E-414\");\n\n newTokenId = _safeMint(receiver, \"\");\n\n // Determine Next Type\n if (newTokenId == lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n _refundOverpayment(lepton.price);\n }\n\n function _batchMintLepton(address receiver, uint256 count) internal {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \"LPT:E-429\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n\n uint256 endTokenId = _tokenCount.add(count);\n if (endTokenId > lepton._upperBounds) {\n count = count.sub(endTokenId.sub(lepton._upperBounds));\n }\n\n uint256 salePrice = lepton.price.mul(count);\n require(msg.value >= salePrice, \"LPT:E-414\");\n\n _safeMintBatch(receiver, count, \"\");\n\n // Determine Next Type\n if (endTokenId >= lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n _refundOverpayment(salePrice);\n }\n\n function _refundOverpayment(uint256 threshold) internal {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n function _finalizeMigration() internal {\n // Determine Next Type\n _typeIndex = 0;\n for (uint256 i = 0; i < _leptonTypes.length; i++) {\n Classification memory lepton = _leptonTypes[i];\n if (_migratedCount >= lepton._upperBounds) {\n _typeIndex = i + 1;\n }\n }\n _migrationComplete = true;\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotMigrated() {\n require(!_migrationComplete, \"LPT:E-004\");\n _;\n }\n\n modifier whenNotPaused() {\n require(!_paused, \"LPT:E-101\");\n _;\n }\n}" + }, + "contracts/v1/tokens/NonFungibleERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// NonFungibleERC1155.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract NonFungibleERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => address) internal _tokenOwner;\n\n constructor() public ERC1155(\"https://staging.app.charged.fi/erc1155/metadata.json\") {}\n\n function creatorOf(uint256 tokenId) external view returns (address) {\n return _tokenCreator[tokenId];\n }\n\n function ownerOf(uint256 tokenId) external view returns (address) {\n return _tokenOwner[tokenId];\n }\n\n function mintNft(address receiver) external returns (uint256 newTokenId) {\n return _mintNft(msg.sender, receiver);\n }\n\n function _mintNft(address creator, address receiver) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n\n _mint(receiver, newTokenId, 1, \"\");\n _tokenCreator[newTokenId] = creator;\n _tokenOwner[newTokenId] = receiver;\n }\n}\n" + }, + "contracts/v1/tokens/Proton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IProton.sol\";\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ncontract Proton is IProton, ERC721, Ownable, RelayRecipient, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n using Counters for Counters.Counter;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n uint256 constant internal MAX_ROYALTIES = 8e3; // 8000 (80%)\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n Counters.Counter internal _tokenIds;\n\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct;\n mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect;\n mapping (address => uint256) internal _tokenCreatorClaimableRoyalties;\n\n mapping (uint256 => uint256) internal _tokenSalePrice;\n mapping (uint256 => uint256) internal _tokenLastSellPrice;\n\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721(\"Charged Particles - Proton\", \"PROTON\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view virtual override returns (address) {\n return _tokenCreator[tokenId];\n }\n\n function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenSalePrice[tokenId];\n }\n\n function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenLastSellPrice[tokenId];\n }\n\n function getCreatorRoyalties(address account) external view virtual override returns (uint256) {\n return _tokenCreatorClaimableRoyalties[account];\n }\n\n function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenCreatorRoyaltiesPct[tokenId];\n }\n\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) {\n return _creatorRoyaltiesReceiver(tokenId);\n }\n\n function claimCreatorRoyalties()\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256)\n {\n return _claimCreatorRoyalties(_msgSender());\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // annuityPercent,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n royaltiesPercent,\n salePrice\n );\n }\n\n function batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n external\n virtual\n override\n whenNotPaused\n {\n _batchProtonsForSale(\n creator,\n annuityPercent,\n royaltiesPercent,\n tokenMetaUris,\n salePrices\n );\n }\n\n function buyProton(uint256 tokenId)\n external\n payable\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (bool)\n {\n return _buyProton(tokenId);\n }\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice)\n external\n virtual\n override\n whenNotPaused\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setSalePrice(tokenId, salePrice);\n }\n\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setRoyaltiesPct(tokenId, royaltiesPct);\n }\n\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n {\n _tokenCreatorRoyaltiesRedirect[tokenId] = receiver;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual {\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n\n _tokenSalePrice[tokenId] = salePrice;\n emit SalePriceSet(tokenId, salePrice);\n }\n\n function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual {\n require(royaltiesPct <= MAX_ROYALTIES, \"PRT:E-421\");\n _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct;\n emit CreatorRoyaltiesSet(tokenId, royaltiesPct);\n }\n\n function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) {\n address receiver = _tokenCreatorRoyaltiesRedirect[tokenId];\n if (receiver == address(0x0)) {\n receiver = _tokenCreator[tokenId];\n }\n return receiver;\n }\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, annuityPercent, 0, 0);\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n _tokenIds.increment();\n\n newTokenId = _tokenIds.current();\n _safeMint(receiver, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUri);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function _batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n internal\n virtual\n {\n require(tokenMetaUris.length == salePrices.length, \"PRT:E-202\");\n address self = address(this);\n\n uint256 count = tokenMetaUris.length;\n for (uint256 i = 0; i < count; i++) {\n _tokenIds.increment();\n uint256 newTokenId = _tokenIds.current();\n\n _safeMint(creator, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUris[i]);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n uint256 salePrice = salePrices[i];\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n self,\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n function _buyProton(uint256 tokenId)\n internal\n virtual\n returns (bool)\n {\n uint256 salePrice = _tokenSalePrice[tokenId];\n require(salePrice > 0, \"PRT:E-416\");\n require(msg.value >= salePrice, \"PRT:E-414\");\n\n uint256 ownerAmount = salePrice;\n uint256 creatorAmount;\n address oldOwner = ownerOf(tokenId);\n address newOwner = _msgSender();\n\n // Creator Royalties\n address royaltiesReceiver = _creatorRoyaltiesReceiver(tokenId);\n uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[tokenId];\n uint256 lastSellPrice = _tokenLastSellPrice[tokenId];\n if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) {\n creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE);\n ownerAmount = ownerAmount.sub(creatorAmount);\n }\n _tokenLastSellPrice[tokenId] = salePrice;\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(address(this), tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n\n // Reserve Royalties for Creator\n if (creatorAmount > 0) {\n _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount);\n }\n\n // Transfer Token\n _transfer(oldOwner, newOwner, tokenId);\n\n // Transfer Payment\n payable(oldOwner).sendValue(ownerAmount);\n\n emit ProtonSold(tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n\n _refundOverpayment(salePrice);\n return true;\n }\n\n /**\n * @dev Pays out the Creator Royalties of the calling account\n * @param receiver The receiver of the claimable royalties\n * @return The amount of Creator Royalties claimed\n */\n function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) {\n uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver];\n require(claimableAmount > 0, \"PRT:E-411\");\n\n delete _tokenCreatorClaimableRoyalties[receiver];\n payable(receiver).sendValue(claimableAmount);\n\n emit RoyaltiesClaimed(receiver, claimableAmount);\n }\n\n /**\n * @dev Collects the Required Asset Token from the users wallet\n * @param from The owner address to collect the Assets from\n * @param assetAmount The Amount of Asset Tokens to Collect\n */\n function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual {\n uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from);\n require(assetAmount <= _userAssetBalance, \"PRT:E-411\");\n // Be sure to Approve this Contract to transfer your Asset Token\n require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), \"PRT:E-401\");\n }\n\n function _refundOverpayment(uint256 threshold) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n _tokenSalePrice[tokenId] = 0;\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n super._transfer(from, to, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"PRT:E-101\");\n _;\n }\n\n modifier onlyTokenOwnerOrApproved(uint256 tokenId) {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"PRT:E-105\");\n _;\n }\n\n modifier onlyTokenCreator(uint256 tokenId) {\n require(_tokenCreator[tokenId] == _msgSender(), \"PRT:E-104\");\n _;\n }\n}" + }, + "contracts/v1/tokens/ProtonB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\nimport \"../interfaces/IProtonB.sol\";\n\nimport \"../lib/BaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ncontract ProtonB is BaseProton, IProtonB {\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public BaseProton(\"Charged Particles - ProtonB\", \"PROTON.B\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n external\n virtual\n override\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n royaltiesPercent,\n salePrice\n );\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n /// @dev for backwards compatibility with v1\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0);\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n\n /***********************************|\n | Function Overrides |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override {\n super._setSalePrice(tokenId, salePrice);\n\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n }\n\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n override\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n }\n\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n // Unlock NFT\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n\n super._transfer(from, to, tokenId);\n }\n}" + }, + "contracts/v1/tokens/ProtonC.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\nimport \"../lib/Soul.sol\";\n\n\ncontract ProtonC is BaseProton, Soul {\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public BaseProton(\"Charged Particles - ProtonC\", \"PROTON.C\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createBondedToken(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent\n )\n external\n virtual\n payable\n returns (uint256 newTokenId)\n {\n uint256 tokenId = createProtonForSale(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n royaltiesPercent,\n 0\n );\n lockToken(tokenId);\n\n return tokenId;\n }\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n public \n virtual\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n royaltiesPercent,\n salePrice\n );\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n nonReentrant\n whenNotPaused\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n /// @dev for backwards compatibility with v1\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n whenNotPaused\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function burn(uint256 tokenId) public {\n requireTokenOwner(tokenId); \n _burn(tokenId);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n function requireTokenOwner(uint256 tokenId) public view {\n require(ownerOf(tokenId) == msg.sender, \"Only token owner\");\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0);\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n function _burn(uint256 tokenId) internal {\n _unlockToken(tokenId);\n _transfer(ownerOf(tokenId), address(0x000000000000000000000000000000000000dEaD), tokenId);\n }\n\n /***********************************|\n | Soul bounded |\n |__________________________________*/\n\n function lockToken(uint256 tokenId) public {\n requireTokenOwner(tokenId);\n _lockToken(tokenId);\n }\n\n /***********************************|\n | Function Overrides |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override {\n super._setSalePrice(tokenId, salePrice);\n\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n }\n\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n override\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n require(lockedTokens[tokenId] == false, \"BondedToken: Token is locked\");\n\n // Unlock NFT\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n\n super._transfer(from, to, tokenId);\n }\n}" + }, + "contracts/v1/Universe.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\n\nimport \"./interfaces/IUniverse.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n\n/**\n * @notice Charged Particles Universe Contract\n * @dev Upgradeable Contract\n */\ncontract Universe is IUniverse, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n // The ChargedParticles Contract Address\n address public chargedParticles;\n address public proton;\n address public lepton;\n address public quark;\n address public boson;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // Positive Charge\n uint256 internal photonMaxSupply;\n uint256 internal totalPhotonDischarged;\n\n // Source of Positive Charge\n IERC20Upgradeable public photonSource;\n\n // Asset Token => Electrostatic Attraction Multiplier\n mapping (address => uint256) internal esaMultiplier;\n\n // Account => Electrostatic Attraction Levels\n mapping (address => uint256) internal esaLevel;\n\n // Energizing Account => Referral Source\n mapping (address => address) internal referralSource;\n\n // NFT Token UUID => Bonded Lepton Mass\n mapping (uint256 => uint256) internal bondedLeptonMass;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getStaticCharge(address /* account */) external pure virtual returns (uint256 positiveEnergy) {\n return 0;\n }\n\n function conductElectrostaticDischarge(address /* account */, uint256 /* amount */) external pure virtual returns (uint256 positiveEnergy) {\n return 0;\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n onlyProton\n {\n // no-op\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(controller)\n {\n chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setPhoton(\n address token,\n uint256 maxSupply\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n photonSource = IERC20Upgradeable(token);\n photonMaxSupply = maxSupply;\n emit PhotonSet(token, maxSupply);\n }\n\n function setProtonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n proton = token;\n emit ProtonTokenSet(token);\n }\n\n function setLeptonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n lepton = token;\n emit LeptonTokenSet(token);\n }\n\n function setQuarkToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n quark = token;\n emit QuarkTokenSet(token);\n }\n\n function setBosonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n boson = token;\n emit BosonTokenSet(token);\n }\n\n function setEsaMultiplier(\n address assetToken,\n uint256 multiplier\n )\n external\n virtual\n onlyOwner\n {\n esaMultiplier[assetToken] = multiplier;\n emit EsaMultiplierSet(assetToken, multiplier);\n }\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _electrostaticAttraction(uint256 tokenUuid, address receiver, address assetToken, uint256 baseAmount) internal virtual {\n }\n\n function _conductElectrostaticDischarge(address /* account */, uint256 /* energy */) internal virtual pure returns (uint256) {\n return 0;\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Proton NFT contract\n modifier onlyProton() {\n require(proton == msg.sender, \"UNI:E-110\");\n _;\n }\n}\n" + }, + "contracts/v1/UniverseRP.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"./interfaces/IUniverseRP.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./interfaces/IRewardNft.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\nimport \"./interfaces/IRewardProgram.sol\";\n\n/**\n * @notice Charged Particles Universe Contract with Rewards Program\n * @dev Upgradeable Contract\n */\ncontract UniverseRP is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // The ChargedParticles Contract Address\n address public _chargedParticles;\n\n // The Lepton NFT Contract Address\n address public _multiplierNft;\n\n // Asset Token => Reward Program\n mapping (address => address) internal _assetRewardPrograms;\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\n\n // Token UUID => NFT Staking Data\n mapping (uint256 => NftStake) private _nftStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n function getRewardProgram(address asset) external view override returns (address) {\n return _getRewardProgram(asset);\n }\n\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\n return _nftStake[uuid];\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetDeposit(\n contractAddress,\n tokenId,\n walletManagerId,\n assetAmount\n );\n }\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\n }\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n // \"receiverEnergy\" includes the \"principalAmount\"\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n onlyOwner\n onlyValidContractAddress(controller)\n {\n _chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setMultiplierNft(address nftTokenAddress)\n external\n onlyOwner\n onlyValidContractAddress(nftTokenAddress)\n {\n _multiplierNft = nftTokenAddress;\n }\n\n function setRewardProgram(\n address rewardProgam,\n address assetToken\n )\n external\n onlyOwner\n onlyValidContractAddress(rewardProgam)\n {\n require(assetToken != address(0x0), \"UNI:E-403\");\n _assetRewardPrograms[assetToken] = rewardProgam;\n emit RewardProgramSet(assetToken, rewardProgam);\n }\n\n function removeRewardProgram(address assetToken) external onlyOwner {\n delete _assetRewardPrograms[assetToken];\n emit RewardProgramRemoved(assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getRewardProgram(address assetToken) internal view returns (address) {\n return _assetRewardPrograms[assetToken];\n }\n\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != depositNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n uint256 multiplier = _getNftMultiplier(depositNftAddress, depositNftTokenId);\n\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\n // Add to Multipliers Set\n _multiplierNftsSet[parentNftUuid].add(multiplier);\n\n // Update NFT Stake\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\n } else {\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\n }\n }\n\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\n }\n\n function _registerNftRelease(\n address contractAddress,\n uint256 tokenId,\n address releaseNftAddress,\n uint256 releaseNftTokenId,\n uint256 /* nftTokenAmount */\n )\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != releaseNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n NftStake storage nftStake = _nftStake[parentNftUuid];\n\n // Remove from Multipliers Set\n uint256 multiplier = _getNftMultiplier(releaseNftAddress, releaseNftTokenId);\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\n\n // Determine New Multiplier or Mark as Released\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\n } else {\n nftStake.releaseBlockNumber = block.number;\n }\n\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\n }\n\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\n uint256 multiplier = 0;\n uint256 loss = 50;\n uint256 i = 0;\n\n for (; i < len; i++) {\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\n }\n if (len > 1) {\n multiplier = multiplier.sub(loss.mul(len));\n }\n return multiplier;\n }\n\n function _getNftMultiplier(address contractAddress, uint256 tokenId) internal returns (uint256) {\n bytes4 fnSig = IRewardNft.getMultiplier.selector;\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n\n if (success) {\n return abi.decode(returnData, (uint256));\n } else {\n return 0;\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(_chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/UniveserRPPolygon.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"./interfaces/IUniverseRP.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./interfaces/IRewardNft.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\nimport \"./interfaces/IRewardProgram.sol\";\n\n/**\n * @notice Charged Particles Universe Contract with Rewards Program\n * @dev Upgradeable Contract\n */\ncontract UniverseRPPolygon is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // The ChargedParticles Contract Address\n address public _chargedParticles;\n\n // The Lepton NFT Contract Address\n address public _multiplierNft;\n\n // Asset Token => Reward Program\n mapping (address => address) internal _assetRewardPrograms;\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\n\n // Token UUID => NFT Staking Data\n mapping (uint256 => NftStake) private _nftStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n function getRewardProgram(address asset) external view override returns (address) {\n return _getRewardProgram(asset);\n }\n\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\n return _nftStake[uuid];\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetDeposit(\n contractAddress,\n tokenId,\n walletManagerId,\n assetAmount\n );\n }\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\n }\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n // \"receiverEnergy\" includes the \"principalAmount\"\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n onlyOwner\n onlyValidContractAddress(controller)\n {\n _chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setMultiplierNft(address nftTokenAddress)\n external\n onlyOwner\n onlyValidContractAddress(nftTokenAddress)\n {\n _multiplierNft = nftTokenAddress;\n }\n\n function setRewardProgram(\n address rewardProgam,\n address assetToken\n )\n external\n onlyOwner\n onlyValidContractAddress(rewardProgam)\n {\n require(assetToken != address(0x0), \"UNI:E-403\");\n _assetRewardPrograms[assetToken] = rewardProgam;\n emit RewardProgramSet(assetToken, rewardProgam);\n }\n\n function removeRewardProgram(address assetToken) external onlyOwner {\n delete _assetRewardPrograms[assetToken];\n emit RewardProgramRemoved(assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getRewardProgram(address assetToken) internal view returns (address) {\n return _assetRewardPrograms[assetToken];\n }\n\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != depositNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n uint256 multiplier = _getNftMultiplier(depositNftTokenId);\n\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\n // Add to Multipliers Set\n _multiplierNftsSet[parentNftUuid].add(multiplier);\n\n // Update NFT Stake\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\n } else {\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\n }\n }\n\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\n }\n\n function _registerNftRelease(\n address contractAddress,\n uint256 tokenId,\n address releaseNftAddress,\n uint256 releaseNftTokenId,\n uint256 /* nftTokenAmount */\n )\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != releaseNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n NftStake storage nftStake = _nftStake[parentNftUuid];\n\n // Remove from Multipliers Set\n uint256 multiplier = _getNftMultiplier(releaseNftTokenId);\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\n\n // Determine New Multiplier or Mark as Released\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\n } else {\n nftStake.releaseBlockNumber = block.number;\n }\n\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\n }\n\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\n uint256 multiplier = 0;\n uint256 loss = 50;\n uint256 i = 0;\n\n for (; i < len; i++) {\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\n }\n if (len > 1) {\n multiplier = multiplier.sub(loss.mul(len));\n }\n return multiplier;\n }\n\n function _getNftMultiplier(uint256 tokenId) internal pure returns (uint256) {\n if (tokenId >= 1 && tokenId <= 721) {\n return 110;\n } else if (tokenId > 721 && tokenId <= 1122) {\n return 130;\n } else if (tokenId > 1122 && tokenId <= 1423) {\n return 150;\n } else if (tokenId > 1423 && tokenId <= 1624) {\n return 180;\n } else if (tokenId > 1624 && tokenId <= 1712) {\n return 230;\n } else if (tokenId > 1712 && tokenId <= 1733) {\n return 510;\n } else {\n return 1;\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(_chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/vesting/VestingClaim7.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract VestingClaim7 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"VestingClaim7: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"VestingClaim7: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"VestingClaim7: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"VestingClaim7: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"VestingClaim7: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"VestingClaim7: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveSmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\nimport \"../../interfaces/IAaveBridge.sol\";\nimport \"../../lib/SmartWalletBase.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet for Aave Assets\n * @dev Non-upgradeable Contract\n */\ncontract AaveSmartWallet is SmartWalletBase {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 constant internal RAY = 1e27;\n\n IAaveBridge internal _bridge;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(\n address aaveBridge\n )\n public\n {\n SmartWalletBase.initializeBase();\n _bridge = IAaveBridge(aaveBridge);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _bridge.isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address) {\n return _bridge.getReserveInterestToken(assetToken);\n }\n\n function getPrincipal(address assetToken) external override returns (uint256) {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address assetToken) external override returns (uint256 creatorInterest, uint256 ownerInterest) {\n return _getInterest(assetToken);\n }\n\n function getTotal(address assetToken) external override returns (uint256) {\n return _getTotal(assetToken);\n }\n\n function getRewards(address rewardToken) external override returns (uint256) {\n return IERC20(rewardToken).balanceOf(address(this));\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _deposit(assetToken, assetAmount, referralCode);\n }\n\n\n function withdraw(\n address receiver,\n address creatorRedirect,\n address assetToken\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (, uint256 ownerInterest) = _getInterest(assetToken);\n return _withdraw(receiver, creatorRedirect, assetToken, walletPrincipal.add(ownerInterest));\n }\n\n function withdrawAmount(\n address receiver,\n address creatorRedirect,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return _withdraw(receiver, creatorRedirect, assetToken, assetAmount);\n }\n\n function withdrawAmountForCreator(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return _withdrawForCreator(receiver, assetToken, assetAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _withdrawRewards(receiver, rewardsToken, rewardsAmount);\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n internal\n returns (uint256)\n {\n _trackAssetToken(assetToken);\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n\n // Deposit Assets into Aave (reverts on fail)\n _sendToken(address(_bridge), assetToken, assetAmount);\n uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function _withdraw(\n address receiver,\n address creatorRedirect,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken);\n\n // Withdraw from Interest only\n if (assetAmount < ownerInterest) {\n if (creatorInterest > 0) {\n uint256 ratio = assetAmount.mul(RAY).div(ownerInterest);\n creatorAmount = creatorInterest.add(nftCreatorAmountDischarged).mul(ratio).div(RAY);\n\n if (creatorAmount <= nftCreatorAmountDischarged) {\n nftCreatorAmountDischarged = nftCreatorAmountDischarged.sub(creatorAmount);\n creatorAmount = 0;\n }\n\n else {\n creatorAmount = creatorAmount.sub(nftCreatorAmountDischarged);\n nftCreatorAmountDischarged = 0;\n }\n }\n receiverAmount = assetAmount;\n }\n\n // Withdraw from Interest + Principal\n else {\n uint256 fromPrincipal = assetAmount.sub(ownerInterest);\n if (fromPrincipal > walletPrincipal) {\n fromPrincipal = walletPrincipal.sub(ownerInterest);\n }\n\n creatorAmount = creatorInterest;\n receiverAmount = ownerInterest.add(fromPrincipal);\n nftCreatorAmountDischarged = 0;\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal);\n }\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount));\n\n // Withdraw Assets for Creator\n if (creatorAmount > 0) {\n address receivesForCreator = (creatorRedirect != address(0x0)) ? creatorRedirect : nftCreator;\n _bridge.withdraw(receivesForCreator, assetToken, creatorAmount);\n }\n\n // Withdraw Assets for Receiver\n _bridge.withdraw(receiver, assetToken, receiverAmount);\n }\n\n function _withdrawForCreator(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 receiverAmount)\n {\n (uint256 creatorInterest,) = _getInterest(assetToken);\n if (creatorInterest == 0) { return 0; }\n if (assetAmount > creatorInterest) {\n assetAmount = creatorInterest;\n }\n\n nftCreatorAmountDischarged = nftCreatorAmountDischarged.add(assetAmount);\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, assetAmount);\n\n // Withdraw Assets for Receiver on behalf of Creator\n _bridge.withdraw(receiver, assetToken, assetAmount);\n }\n\n function _withdrawRewards(\n address receiver,\n address rewardsTokenAddress,\n uint256 rewardsAmount\n )\n internal\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"ASW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function _getTotal(address assetToken) internal view returns (uint256) {\n return _bridge.getTotalBalance(address(this), assetToken);\n }\n\n function _getInterest(address assetToken) internal view returns (uint256 creatorInterest, uint256 ownerInterest) {\n uint256 total = _getTotal(assetToken);\n uint256 principal = _getPrincipal(assetToken);\n uint256 interest = total.sub(principal);\n\n // Creator Royalties\n if (nftCreatorAnnuityPct > 0) {\n\n // Interest too small to calculate percentage;\n if (interest <= PERCENTAGE_SCALE) {\n // creatorInterest = interest.div(2); // split evenly?\n creatorInterest = 0; // All to owner\n }\n\n // Calculate percentage for Creator\n else {\n creatorInterest = interest\n .add(nftCreatorAmountDischarged)\n .mul(nftCreatorAnnuityPct)\n .div(PERCENTAGE_SCALE)\n .sub(nftCreatorAmountDischarged);\n }\n }\n\n // Owner Portion\n ownerInterest = interest.sub(creatorInterest);\n }\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveSmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\nimport \"../../interfaces/IAaveBridge.sol\";\nimport \"../../lib/SmartWalletBaseB.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet for Aave Assets\n * @dev Non-upgradeable Contract\n */\ncontract AaveSmartWalletB is SmartWalletBaseB {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 constant internal RAY = 1e27;\n\n IAaveBridge internal _bridge;\n\n uint256 internal _nftCreatorAmountDischarged;\n\n mapping (address => address) internal _assetATokens;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(\n address aaveBridge\n )\n public\n {\n SmartWalletBaseB.initializeBase();\n _bridge = IAaveBridge(aaveBridge);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _bridge.isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address) {\n return _bridge.getReserveInterestToken(assetToken);\n }\n\n function getPrincipal(address assetToken) external override returns (uint256) {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address assetToken, uint256 creatorPct) external override returns (uint256 creatorInterest, uint256 ownerInterest) {\n return _getInterest(assetToken, creatorPct);\n }\n\n function getTotal(address assetToken) external override returns (uint256) {\n return _getTotal(assetToken);\n }\n\n function getRewards(address rewardToken) external override returns (uint256) {\n return IERC20(rewardToken).balanceOf(address(this));\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _deposit(assetToken, assetAmount, referralCode);\n }\n\n\n function withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (, uint256 ownerInterest) = _getInterest(assetToken, creatorPct);\n return _withdraw(receiver, creator, creatorPct, assetToken, walletPrincipal.add(ownerInterest));\n }\n\n function withdrawAmount(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return _withdraw(receiver, creator, creatorPct, assetToken, assetAmount);\n }\n\n function withdrawAmountForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return _withdrawForCreator(receiver, creatorPct, assetToken, assetAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _withdrawRewards(receiver, rewardsToken, rewardsAmount);\n }\n\n function refreshPrincipal(address assetToken) external virtual override onlyWalletManager {\n uint256 aTokenBalance = IERC20(_assetATokens[assetToken]).balanceOf(address(this));\n if (_assetPrincipalBalance[assetToken] > aTokenBalance) {\n _assetPrincipalBalance[assetToken] = aTokenBalance;\n }\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n internal\n returns (uint256)\n {\n _trackAssetToken(assetToken);\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n\n // Deposit Assets into Aave (reverts on fail)\n _sendToken(address(_bridge), assetToken, assetAmount);\n uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function _withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken, creatorPct);\n\n // Withdraw from Interest only\n if (assetAmount < ownerInterest) {\n if (creatorInterest > 0) {\n uint256 ratio = assetAmount.mul(RAY).div(ownerInterest);\n creatorAmount = creatorInterest.add(_nftCreatorAmountDischarged).mul(ratio).div(RAY);\n\n if (creatorAmount <= _nftCreatorAmountDischarged) {\n _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.sub(creatorAmount);\n creatorAmount = 0;\n }\n else {\n creatorAmount = creatorAmount.sub(_nftCreatorAmountDischarged);\n _nftCreatorAmountDischarged = 0;\n }\n }\n receiverAmount = assetAmount;\n }\n\n // Withdraw from Interest + Principal\n else {\n uint256 fromPrincipal = assetAmount.sub(ownerInterest);\n if (fromPrincipal > walletPrincipal) {\n fromPrincipal = walletPrincipal.sub(ownerInterest);\n }\n\n creatorAmount = creatorInterest;\n receiverAmount = ownerInterest.add(fromPrincipal);\n _nftCreatorAmountDischarged = 0;\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal);\n }\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount));\n\n // Withdraw Assets for Creator\n if (creatorAmount > 0) {\n if (creator != address(0)) {\n _bridge.withdraw(creator, assetToken, creatorAmount);\n } else {\n receiverAmount = receiverAmount.add(creatorAmount);\n creatorAmount = 0;\n }\n }\n\n // Withdraw Assets for Receiver\n _bridge.withdraw(receiver, assetToken, receiverAmount);\n }\n\n function _withdrawForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 receiverAmount)\n {\n (uint256 creatorInterest,) = _getInterest(assetToken, creatorPct);\n if (creatorInterest == 0) { return 0; }\n if (assetAmount > creatorInterest) {\n assetAmount = creatorInterest;\n }\n\n _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.add(assetAmount);\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, assetAmount);\n\n // Withdraw Assets for Receiver on behalf of Creator\n _bridge.withdraw(receiver, assetToken, assetAmount);\n }\n\n function _withdrawRewards(\n address receiver,\n address rewardsTokenAddress,\n uint256 rewardsAmount\n )\n internal\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"ASW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function _getTotal(address assetToken) internal view returns (uint256) {\n return _bridge.getTotalBalance(address(this), assetToken);\n }\n\n function _getInterest(address assetToken, uint256 creatorPct) internal view returns (uint256 creatorInterest, uint256 ownerInterest) {\n uint256 total = _getTotal(assetToken);\n uint256 principal = _getPrincipal(assetToken);\n uint256 interest = total.sub(principal);\n\n // Creator Royalties\n if (creatorPct > 0) {\n\n // Interest too small to calculate percentage;\n if (interest <= PERCENTAGE_SCALE) {\n // creatorInterest = interest.div(2); // split evenly?\n creatorInterest = 0; // All to owner\n }\n\n // Calculate percentage for Creator\n else {\n creatorInterest = interest\n .add(_nftCreatorAmountDischarged)\n .mul(creatorPct)\n .div(PERCENTAGE_SCALE)\n .sub(_nftCreatorAmountDischarged);\n }\n }\n\n // Owner Portion\n ownerInterest = interest.sub(creatorInterest);\n }\n\n function _trackAssetToken(address assetToken) internal override {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _assetATokens[assetToken] = aTokenAddress;\n }\n }\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../lib/WalletManagerBase.sol\";\n\nimport \"./AaveSmartWallet.sol\";\n\n/**\n * @notice Wallet Manager for Aave\n * @dev Non-upgradeable Contract\n */\ncontract AaveWalletManager is WalletManagerBase {\n using SafeMath for uint256;\n\n event AaveBridgeSet(address indexed aaveBridge);\n event ValidRewardsTokenSet(address indexed rewardsToken, bool state);\n\n address internal _aaveBridge;\n uint256 internal _referralCode;\n\n mapping (address => bool) public rewardsTokenWhitelist;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new AaveSmartWallet());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return AaveSmartWallet(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return AaveSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return AaveSmartWallet(_wallets[uuid]).getInterest(assetToken);\n }\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getTotal(assetToken);\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getRewards(_rewardToken);\n }\n\n\n /***********************************|\n | Only Controller |\n |__________________________________*/\n\n function energize(\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = AaveSmartWallet(wallet).deposit(assetToken, assetAmount, _referralCode);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(ownerInterest > 0, \"AWM:E-412\");\n\n // Discharge the full amount of interest\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, ownerInterest);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(assetAmount > 0 && ownerInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmountForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address creator,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (uint256 creatorInterest,) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(assetAmount > 0 && creatorInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n receiverAmount = AaveSmartWallet(wallet).withdrawAmountForCreator(receiver, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount);\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = AaveSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0;\n\n // Release from interest first + principal if needed\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n require(rewardsTokenWhitelist[rewardsToken], \"AWM:E-423\");\n\n // Withdraw Rewards to Receiver\n amount = AaveSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 tokenId,\n address externalAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return AaveSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n // no-op\n }\n\n function getWalletAddressById(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPct\n )\n external\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n\n if (creator != address(0x0)) {\n AaveSmartWallet(wallet).setNftCreator(creator, annuityPct);\n }\n\n emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAaveBridge(address aaveBridge) external onlyOwner {\n require(aaveBridge != address(0x0), \"AWM:E-403\");\n _aaveBridge = aaveBridge;\n emit AaveBridgeSet(aaveBridge);\n }\n\n // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool\n function setReferralCode(uint256 referralCode) external onlyOwner {\n _referralCode = referralCode;\n }\n\n function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner {\n rewardsTokenWhitelist[rewardsToken] = state;\n emit ValidRewardsTokenSet(rewardsToken, state);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n AaveSmartWallet(newWallet).initialize(_aaveBridge);\n return newWallet;\n }\n}" + }, + "contracts/v1/yield/aave/AaveWalletManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../lib/WalletManagerBase.sol\";\nimport \"../../interfaces/IChargedSettings.sol\";\nimport \"./AaveSmartWalletB.sol\";\n\n/**\n * @notice Wallet Manager for Aave\n * @dev Non-upgradeable Contract\n */\ncontract AaveWalletManagerB is WalletManagerBase {\n using SafeMath for uint256;\n\n event AaveBridgeSet(address indexed aaveBridge);\n event ChargedSettingsSet(address indexed settings);\n event ValidRewardsTokenSet(address indexed rewardsToken, bool state);\n\n IChargedSettings internal _chargedSettings;\n\n address internal _aaveBridge;\n uint256 internal _referralCode;\n\n mapping (address => bool) public _rewardsTokenWhitelist;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new AaveSmartWalletB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return AaveSmartWalletB(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return AaveSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n return AaveSmartWalletB(_wallets[uuid]).getInterest(assetToken, annuityPct);\n }\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getTotal(assetToken);\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getRewards(_rewardToken);\n }\n\n\n /***********************************|\n | Only Controller |\n |__________________________________*/\n\n function energize(\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = AaveSmartWalletB(wallet).deposit(assetToken, assetAmount, _referralCode);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(ownerInterest > 0, \"AWM:E-412\");\n\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Discharge the full amount of interest\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, ownerInterest);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(assetAmount > 0 && ownerInterest >= assetAmount, \"AWM:E-412\");\n\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Discharge a portion of the interest\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmountForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address creator,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (uint256 creatorInterest,) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(assetAmount > 0 && creatorInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n receiverAmount = AaveSmartWalletB(wallet).withdrawAmountForCreator(receiver, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount);\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Release Principal + Interest\n principalAmount = AaveSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdraw(receiver, creator, annuityPct, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0;\n\n // Release from interest first + principal if needed\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n require(_rewardsTokenWhitelist[rewardsToken], \"AWM:E-423\");\n\n // Withdraw Rewards to Receiver\n amount = AaveSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 tokenId,\n address externalAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return AaveSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n AaveSmartWalletB(wallet).refreshPrincipal(assetToken);\n }\n\n function getWalletAddressById(\n address contractAddress,\n uint256 tokenId,\n address /* creator */,\n uint256 /* annuityPct */\n )\n external\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAaveBridge(address aaveBridge) external onlyOwner {\n require(aaveBridge != address(0x0), \"AWM:E-403\");\n _aaveBridge = aaveBridge;\n emit AaveBridgeSet(aaveBridge);\n }\n\n function setChargedSettings(address settings) external onlyOwner {\n require(settings != address(0x0), \"AWM:E-403\");\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool\n function setReferralCode(uint256 referralCode) external onlyOwner {\n _referralCode = referralCode;\n }\n\n function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner {\n _rewardsTokenWhitelist[rewardsToken] = state;\n emit ValidRewardsTokenSet(rewardsToken, state);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n AaveSmartWalletB(newWallet).initialize(_aaveBridge);\n return newWallet;\n }\n}" + }, + "contracts/v1/yield/aave/v2/AaveBridgeV2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveBridgeV2.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/SafeCast.sol\";\n\nimport \"./IATokenV2.sol\";\nimport \"./ILendingPoolV2.sol\";\nimport \"./ILendingPoolAddressesProviderV2.sol\";\n\nimport \"../../../interfaces/IAaveBridge.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\n\ncontract AaveBridgeV2 is Ownable, IAaveBridge, BlackholePrevention {\n using SafeMath for uint256;\n using SafeCast for uint256;\n using SafeERC20 for IERC20;\n using ReserveLogic for ReserveLogic.ReserveData;\n\n ILendingPoolAddressesProviderV2 public provider;\n ILendingPoolV2 public lendingPool;\n\n constructor (address lendingPoolProvider) public {\n provider = ILendingPoolAddressesProviderV2(lendingPoolProvider);\n lendingPool = ILendingPoolV2(provider.getLendingPool());\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address aTokenAddress) {\n return _getReserveInterestToken(assetToken);\n }\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _isReserveActive(assetToken);\n }\n\n function getTotalBalance(address account, address assetToken) external view override returns (uint256) {\n address aTokenAddress = _getReserveInterestToken(assetToken);\n if (aTokenAddress == address(0x0)) { return 0; }\n return IATokenV2(aTokenAddress).balanceOf(account);\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n returns (uint256)\n {\n address self = address(this);\n address aTokenAddress = _getReserveInterestToken(assetToken);\n require(_isReserveActive(assetToken), \"ABV2:E-424\");\n\n IERC20 token = IERC20(assetToken);\n IATokenV2 aToken = IATokenV2(aTokenAddress);\n\n if (token.allowance(address(this), address(lendingPool)) < assetAmount) {\n token.approve(address(lendingPool), uint256(-1));\n }\n\n // Deposit Assets into Aave\n uint256 preBalance = aToken.balanceOf(self);\n lendingPool.deposit(assetToken, assetAmount, self, referralCode.toUint16());\n uint256 postBalance = aToken.balanceOf(self);\n uint256 aTokensAmount = postBalance.sub(preBalance);\n\n // Transfer back the Interest Tokens\n _sendToken(msg.sender, aTokenAddress, aTokensAmount);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function withdraw(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n {\n address self = address(this);\n require(_isReserveActive(assetToken), \"ABV2:E-424\");\n\n // Redeem aTokens for Asset Tokens\n lendingPool.withdraw(assetToken, assetAmount, self);\n\n // Transfer back the Asset Tokens\n _sendToken(receiver, assetToken, assetAmount);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n\n function _getReserveInterestToken(address assetToken) internal view returns (address aTokenAddress) {\n ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken);\n return config.aTokenAddress;\n }\n\n function _isReserveActive(address assetToken) internal view returns (bool) {\n ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken);\n uint256 isActiveFlag = 2 ** 56; // bit 56: reserve is active\n return (config.configuration.data & isActiveFlag) == isActiveFlag;\n }\n}\n" + }, + "contracts/v1/yield/aave/v2/IATokenV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\n\ninterface IATokenV2 {\n function balanceOf(address account) external view returns (uint256);\n}\n" + }, + "contracts/v1/yield/aave/v2/ILendingPoolAddressesProviderV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\n\ninterface ILendingPoolAddressesProviderV2 {\n function getLendingPool() external view returns (address);\n}" + }, + "contracts/v1/yield/aave/v2/ILendingPoolV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport \"./ILendingPoolAddressesProviderV2.sol\";\n\nlibrary ReserveConfiguration {\n struct Map {\n uint256 data;\n }\n}\n\nlibrary ReserveLogic {\n struct ReserveData {\n ReserveConfiguration.Map configuration;\n uint128 liquidityIndex;\n uint128 variableBorrowIndex;\n uint128 currentLiquidityRate;\n uint128 currentVariableBorrowRate;\n uint128 currentStableBorrowRate;\n uint40 lastUpdateTimestamp;\n address aTokenAddress;\n address stableDebtTokenAddress;\n address variableDebtTokenAddress;\n address interestRateStrategyAddress;\n uint8 id;\n }\n}\n\ninterface ILendingPoolV2 {\n function deposit(address reserve, uint256 amount, address onBehalfOf, uint16 referralCode) external;\n function withdraw(address reserve, uint256 amount, address to) external;\n function getReserveData(address asset) external view returns (ReserveLogic.ReserveData memory);\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericSmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"../../../lib/SmartWalletBase.sol\";\n\n\n/**\n * @notice Generic ERC20-Token Smart-Wallet Bridge\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartWallet is SmartWalletBase {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize()\n public\n {\n SmartWalletBase.initializeBase();\n }\n\n function isReserveActive(address assetToken)\n external\n override\n view\n returns (bool)\n {\n return _getPrincipal(assetToken) == 0;\n }\n\n function getReserveInterestToken(address assetToken)\n external\n override\n view\n returns (address)\n {\n return assetToken;\n }\n\n function getPrincipal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address /* assetToken */)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n return (0, 0);\n }\n\n function getTotal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getRewards(address assetToken)\n external\n override\n returns (uint256)\n {\n return IERC20(assetToken).balanceOf(address(this));\n }\n\n function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n // Track Principal\n _trackAssetToken(assetToken);\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n }\n\n function withdraw(address receiver, address /* creatorRedirect */, address assetToken)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmount(address receiver, address /* creatorRedirect */, address assetToken, uint256 assetAmount)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n if (receiverAmount >= assetAmount) {\n receiverAmount = assetAmount;\n }\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmountForCreator(\n address /* receiver */,\n address /* assetToken */,\n uint256 /* assetID */\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericSmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWalletB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"../../../lib/SmartWalletBaseB.sol\";\n\n\n/**\n * @notice Generic ERC20-Token Smart-Wallet Bridge\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartWalletB is SmartWalletBaseB {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize()\n public\n {\n SmartWalletBaseB.initializeBase();\n }\n\n function isReserveActive(address assetToken)\n external\n override\n view\n returns (bool)\n {\n return _getPrincipal(assetToken) == 0;\n }\n\n function getReserveInterestToken(address assetToken)\n external\n override\n view\n returns (address)\n {\n return assetToken;\n }\n\n function getPrincipal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address /* assetToken */, uint256 /* creatorPct */)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n return (0, 0);\n }\n\n function getTotal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getRewards(address assetToken)\n external\n override\n returns (uint256)\n {\n return IERC20(assetToken).balanceOf(address(this));\n }\n\n function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n // Track Principal\n _trackAssetToken(assetToken);\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n }\n\n function withdraw(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmount(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken, uint256 assetAmount)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n if (receiverAmount >= assetAmount) {\n receiverAmount = assetAmount;\n }\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmountForCreator(\n address /* receiver */,\n uint256 /* creatorPct */,\n address /* assetToken */,\n uint256 /* assetID */\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function refreshPrincipal(address assetToken) external virtual override onlyWalletManager {\n _assetPrincipalBalance[assetToken] = IERC20(assetToken).balanceOf(address(this));\n }\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../../lib/WalletManagerBase.sol\";\nimport \"./GenericSmartWallet.sol\";\n\n/**\n * @notice Generic ERC20 Wallet Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericWalletManager is WalletManagerBase {\n using SafeMath for uint256;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new GenericSmartWallet());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return GenericSmartWallet(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return GenericSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getTotal(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return GenericSmartWallet(_wallets[uuid]).getInterest(assetToken);\n }\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getRewards(rewardToken);\n }\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount)\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = GenericSmartWallet(wallet).deposit(assetToken, assetAmount, 0);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmountForCreator(\n address /* receiver */,\n address /* contractAddress */,\n uint256 /* tokenId */,\n address /* creator */,\n address /* assetToken */,\n uint256 /* assetAmount */\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release from interest first + principal if needed\n principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n external\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return GenericSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n // no-op\n }\n\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct)\n external\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n\n if (creator != address(0x0)) {\n GenericSmartWallet(wallet).setNftCreator(creator, annuityPct);\n }\n\n emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n GenericSmartWallet(newWallet).initialize();\n return newWallet;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericWalletManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericWalletManagerB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../../lib/WalletManagerBase.sol\";\nimport \"./GenericSmartWalletB.sol\";\n\n/**\n * @notice Generic ERC20 Wallet Manager B\n * @dev Non-upgradeable Contract\n */\ncontract GenericWalletManagerB is WalletManagerBase {\n using SafeMath for uint256;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new GenericSmartWalletB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return GenericSmartWalletB(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return GenericSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getTotal(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return GenericSmartWalletB(_wallets[uuid]).getInterest(assetToken, 0);\n }\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getRewards(rewardToken);\n }\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount)\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = GenericSmartWalletB(wallet).deposit(assetToken, assetAmount, 0);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmountForCreator(\n address /* receiver */,\n address /* contractAddress */,\n uint256 /* tokenId */,\n address /* creator */,\n address /* assetToken */,\n uint256 /* assetAmount */\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdraw(receiver, creatorRedirect, 0, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release from interest first + principal if needed\n principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdrawAmount(receiver, creatorRedirect, 0, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyControllerOrExecutor\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n external\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return GenericSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n GenericSmartWalletB(wallet).refreshPrincipal(assetToken);\n }\n\n function getWalletAddressById(address contractAddress, uint256 tokenId, address /* creator */, uint256 /* annuityPct */)\n external\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n GenericSmartWalletB(newWallet).initialize();\n return newWallet;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericBasketManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"../../../interfaces/IBasketManager.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"./GenericSmartBasket.sol\";\n\n/**\n * @notice Generic ERC721 Basket Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericBasketManager is Ownable, BlackholePrevention, IBasketManager {\n using Counters for Counters.Counter;\n using TokenInfo for address;\n\n // The Controller Contract Address\n address internal _controller;\n\n // Template Contract for creating Token Smart-Baskets\n address internal _basketTemplate;\n\n // TokenID => Token Smart-Basket Address\n mapping (uint256 => address) internal _baskets;\n\n mapping (uint256 => Counters.Counter) internal _totalTokens;\n\n // State of Basket Manager\n bool internal _paused;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _basketTemplate = address(new GenericSmartBasket());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n function getTokenTotalCount(\n address contractAddress,\n uint256 tokenId\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n return _totalTokens[uuid].current();\n }\n\n function getTokenCountByType(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n external\n override\n returns (uint256)\n {\n address basket = getBasketAddressById(contractAddress, tokenId);\n return GenericSmartBasket(basket).getTokenCountByType(basketTokenAddress, basketTokenId);\n }\n\n function prepareTransferAmount(uint256 /* nftTokenAmount */) external override onlyController {\n // no-op\n }\n\n function addToBasket(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n whenNotPaused\n returns (bool added)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n added = GenericSmartBasket(basket).addToBasket(basketTokenAddress, basketTokenId);\n\n // Log Event\n if (added) {\n _totalTokens[uuid].increment();\n emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, 1);\n }\n }\n\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n returns (bool removed)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n removed = GenericSmartBasket(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId);\n\n // Log Event\n if (removed) {\n _totalTokens[uuid].decrement();\n emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, 1);\n }\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyController\n returns (uint256 amount)\n {\n // no-op\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n public\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n return GenericSmartBasket(basket).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function getBasketAddressById(address contractAddress, uint256 tokenId)\n public\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n // Create Smart-Basket if none exists\n if (basket == address(0x0)) {\n basket = _createBasket();\n _baskets[uuid] = basket;\n\n emit NewSmartBasket(contractAddress, tokenId, basket);\n }\n\n return basket;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Basket Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartBasket(basket).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n function _createBasket()\n internal\n returns (address)\n {\n address newBasket = _createClone(_basketTemplate);\n GenericSmartBasket(newBasket).initialize();\n return newBasket;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"GBM:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"GBM:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericBasketManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport \"../../../interfaces/IBasketManager.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../interfaces/ITokenInfoProxy.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"../../../lib/NftTokenType.sol\";\nimport \"./GenericSmartBasketB.sol\";\n\n/**\n * @notice Generic ERC721 Basket Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericBasketManagerB is Ownable, BlackholePrevention, IBasketManager {\n using Counters for Counters.Counter;\n using TokenInfo for address;\n using NftTokenType for address;\n\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // The Controller Contract Address\n address internal _controller;\n\n // The Executor Contract Address\n address internal _executor;\n\n // Template Contract for creating Token Smart-Baskets\n address internal _basketTemplate;\n\n // TokenID => Token Smart-Basket Address\n mapping (uint256 => address) internal _baskets;\n\n // Prepared Amount\n uint256 internal _preparedAmount;\n\n // State of Basket Manager\n bool internal _paused;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _basketTemplate = address(new GenericSmartBasketB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n function getTokenTotalCount(\n address contractAddress,\n uint256 tokenId\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n if (basket == address(0)) { return 0; }\n return GenericSmartBasketB(basket).getNestedNftCount();\n }\n\n function getTokenCountByType(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n if (basket == address(0)) { return 0; }\n return GenericSmartBasketB(basket).getTokenCountByType(basketTokenAddress, basketTokenId);\n }\n\n function prepareTransferAmount(uint256 nftTokenAmount) external override onlyController {\n _preparedAmount = nftTokenAmount;\n }\n\n function addToBasket(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n whenNotPaused\n returns (bool added)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n uint256 nftTokenAmount = 1;\n if (_preparedAmount > 0) {\n nftTokenAmount = _preparedAmount;\n _preparedAmount = 0;\n }\n\n added = GenericSmartBasketB(basket).addToBasket(basketTokenAddress, basketTokenId, nftTokenAmount);\n if (added) {\n emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount);\n }\n }\n\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n returns (bool removed)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n uint256 nftTokenAmount = 1;\n if (_preparedAmount > 0) {\n nftTokenAmount = _preparedAmount;\n _preparedAmount = 0;\n }\n\n removed = GenericSmartBasketB(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId, nftTokenAmount);\n if (removed) {\n emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount);\n }\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyControllerOrExecutor\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartBasketB(basket).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit BasketRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n public\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n return GenericSmartBasketB(basket).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function getBasketAddressById(address contractAddress, uint256 tokenId)\n public\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n // Create Smart-Basket if none exists\n if (basket == address(0x0)) {\n basket = _createBasket();\n _baskets[uuid] = basket;\n\n emit NewSmartBasket(contractAddress, tokenId, basket);\n }\n\n return basket;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Basket Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n /**\n * @dev Connects to the ExecForAccount Controller\n */\n function setExecutor(address executor) external onlyOwner {\n _executor = executor;\n emit ExecutorSet(executor);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setTokenInfoProxy(address tokenInfoProxy) external onlyOwner {\n _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartBasket(basket).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createBasket()\n internal\n returns (address)\n {\n address newBasket = _createClone(_basketTemplate);\n GenericSmartBasketB(newBasket).initialize(_tokenInfoProxy);\n return newBasket;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"GBM:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Controller or Executor contract\n modifier onlyControllerOrExecutor() {\n require(_executor == msg.sender || _controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"GBM:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericSmartBasket.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/NftTokenType.sol\";\n\n\n/**\n * @notice Generic ERC721-Token Smart-Basket\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartBasket is ISmartBasket, BlackholePrevention, IERC721Receiver {\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableSet for EnumerableSet.AddressSet;\n using NftTokenType for address;\n\n address internal _basketManager;\n\n // NFT contract address => Token Ids in Basket\n mapping (address => mapping(uint256 => EnumerableSet.UintSet)) internal _nftContractTokens;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public {\n require(_basketManager == address(0x0), \"GSB:E-002\");\n _basketManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n return _nftContractTokens[contractAddress][nftType].length();\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver(0).onERC721Received.selector;\n }\n\n function addToBasket(address contractAddress, uint256 tokenId)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n require(!_nftContractTokens[contractAddress][nftType].contains(tokenId), \"GSB:E-425\");\n\n bool added = _nftContractTokens[contractAddress][nftType].add(tokenId);\n if (added) {\n // NFT should have been Transferred into here via Charged-Particles\n added = (IERC721(contractAddress).ownerOf(tokenId) == address(this));\n }\n return added;\n }\n\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n require(_nftContractTokens[contractAddress][nftType].contains(tokenId), \"GSB:E-426\");\n\n bool removed = _nftContractTokens[contractAddress][nftType].remove(tokenId);\n if (removed) {\n IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId);\n }\n return removed;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyBasketManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the basket manager\n modifier onlyBasketManager() {\n require(_basketManager == msg.sender, \"GSB:E-109\");\n _;\n }\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericSmartBasketB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155Receiver.sol\";\nimport \"../../../interfaces/ISmartBasketB.sol\";\nimport \"../../../interfaces/ITokenInfoProxy.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"../../../lib/NftTokenType.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\n\n/**\n * @notice Generic ERC721-Token Smart-Basket\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartBasketB is ISmartBasketB, BlackholePrevention, IERC721Receiver, ERC1155Receiver {\n using TokenInfo for address;\n using NftTokenType for address;\n\n address internal _basketManager;\n\n // NFT TokenUUID => ERC1155 Balance\n mapping (uint256 => uint256) internal _nftContractTokenBalance;\n uint256 internal _nestedNftCount;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(ITokenInfoProxy /* tokenInfoProxy */) public {\n require(_basketManager == address(0x0), \"GSB:E-002\");\n _basketManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getNestedNftCount() external view override returns (uint256) {\n return _nestedNftCount;\n }\n\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n return _nftContractTokenBalance[contractAddress.getTokenUUID(tokenId)];\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver(0).onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\n return IERC1155Receiver(0).onERC1155Received.selector;\n }\n\n // Unimplemented\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\n return \"\"; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector;\n }\n\n function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n _nftContractTokenBalance[uuid] += nftTokenAmount;\n _nestedNftCount += nftTokenAmount;\n return true;\n }\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n uint256 nftTokenAmount\n )\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n _nftContractTokenBalance[uuid] -= nftTokenAmount;\n _nestedNftCount -= nftTokenAmount;\n\n if (contractAddress.isERC1155()) {\n IERC1155(contractAddress).safeTransferFrom(address(this), receiver, tokenId, nftTokenAmount, \"\");\n } else {\n IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId);\n }\n return true;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyBasketManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSB:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyBasketManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the basket manager\n modifier onlyBasketManager() {\n require(_basketManager == msg.sender, \"GSB:E-109\");\n _;\n }\n}\n" + }, + "erc20permit/contracts/ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"./IERC2612.sol\";\n\n/**\n * @author Georgios Konstantopoulos\n * @dev Extension of {ERC20} that allows token holders to use their tokens\n * without sending any transactions by setting {IERC20-allowance} with a\n * signature using the {permit} method, and then spend them via\n * {IERC20-transferFrom}.\n *\n * The {permit} signature mechanism conforms to the {IERC2612} interface.\n */\nabstract contract ERC20Permit is ERC20, IERC2612 {\n mapping (address => uint256) public override nonces;\n\n bytes32 public immutable PERMIT_TYPEHASH = keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public immutable DOMAIN_SEPARATOR;\n\n constructor(string memory name_, string memory symbol_) internal ERC20(name_, symbol_) {\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name_)),\n keccak256(bytes(\"1\")),\n chainId,\n address(this)\n )\n );\n }\n\n /**\n * @dev See {IERC2612-permit}.\n *\n * In cases where the free option is not a concern, deadline can simply be\n * set to uint(-1), so it should be seen as an optional parameter\n */\n function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {\n require(deadline >= block.timestamp, \"ERC20Permit: expired deadline\");\n\n bytes32 hashStruct = keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n amount,\n nonces[owner]++,\n deadline\n )\n );\n\n bytes32 hash = keccak256(\n abi.encodePacked(\n '\\x19\\x01',\n DOMAIN_SEPARATOR,\n hashStruct\n )\n );\n\n address signer = ecrecover(hash, v, r, s);\n require(\n signer != address(0) && signer == owner,\n \"ERC20Permit: invalid signature\"\n );\n\n _approve(owner, spender, amount);\n }\n}\n" + }, + "erc20permit/contracts/IERC2612.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC2612 standard as defined in the EIP.\n *\n * Adds the {permit} method, which can be used to change one's\n * {IERC20-allowance} without having to send a transaction, by signing a\n * message. This allows users to spend tokens without having to hold Ether.\n *\n * See https://eips.ethereum.org/EIPS/eip-2612.\n */\ninterface IERC2612 {\n /**\n * @dev Sets `amount` 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 * - `owner` cannot be the zero address.\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(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n /**\n * @dev Returns the current ERC2612 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" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "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/deployments/mainnet/solcInputs/e9994e7fbdc698929d4e56cc732a0db2.json b/deployments/mainnet/solcInputs/e9994e7fbdc698929d4e56cc732a0db2.json new file mode 100644 index 0000000..eaf5abe --- /dev/null +++ b/deployments/mainnet/solcInputs/e9994e7fbdc698929d4e56cc732a0db2.json @@ -0,0 +1,458 @@ +{ + "language": "Solidity", + "sources": { + "@opengsn/gsn/contracts/BaseRelayRecipient.sol": { + "content": "// SPDX-License-Identifier:MIT\n// solhint-disable no-inline-assembly\npragma solidity ^0.6.2;\n\nimport \"./interfaces/IRelayRecipient.sol\";\n\n/**\n * A base contract to be inherited by any contract that want to receive relayed transactions\n * A subclass must use \"_msgSender()\" instead of \"msg.sender\"\n */\nabstract contract BaseRelayRecipient is IRelayRecipient {\n\n /*\n * Forwarder singleton we accept calls from\n */\n address public trustedForwarder;\n\n function isTrustedForwarder(address forwarder) public override view returns(bool) {\n return forwarder == trustedForwarder;\n }\n\n /**\n * return the sender of this call.\n * if the call came through our trusted forwarder, return the original sender.\n * otherwise, return `msg.sender`.\n * should be used in the contract anywhere instead of msg.sender\n */\n function _msgSender() internal override virtual view returns (address payable ret) {\n if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // so we trust that the last bytes of msg.data are the verified sender address.\n // extract sender address from the end of msg.data\n assembly {\n ret := shr(96,calldataload(sub(calldatasize(),20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n /**\n * return the msg.data of this call.\n * if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes\n * of the msg.data - so this method will strip those 20 bytes off.\n * otherwise, return `msg.data`\n * should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly\n * signing or hashing the\n */\n function _msgData() internal override virtual view returns (bytes memory ret) {\n if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // we copy the msg.data , except the last 20 bytes (and update the total length)\n assembly {\n let ptr := mload(0x40)\n // copy only size-20 bytes\n let size := sub(calldatasize(),20)\n // structure RLP data as \n mstore(ptr, 0x20)\n mstore(add(ptr,32), size)\n calldatacopy(add(ptr,64), 0, size)\n return(ptr, add(size,64))\n }\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "@opengsn/gsn/contracts/interfaces/IRelayRecipient.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.6.2;\n\n/**\n * a contract must implement this interface in order to support relayed transaction.\n * It is better to inherit the BaseRelayRecipient as its implementation.\n */\nabstract contract IRelayRecipient {\n\n /**\n * return if the forwarder is trusted to forward relayed transactions to us.\n * the forwarder is required to verify the sender's signature, and verify\n * the call is not a replay.\n */\n function isTrustedForwarder(address forwarder) public virtual view returns(bool);\n\n /**\n * return the sender of this call.\n * if the call came through our trusted forwarder, then the real sender is appended as the last 20 bytes\n * of the msg.data.\n * otherwise, return `msg.sender`\n * should be used in the contract anywhere instead of msg.sender\n */\n function _msgSender() internal virtual view returns (address payable);\n\n /**\n * return the msg.data of this call.\n * if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes\n * of the msg.data - so this method will strip those 20 bytes off.\n * otherwise, return `msg.data`\n * should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly\n * signing or hashing the\n */\n function _msgData() internal virtual view returns (bytes memory);\n\n function versionRecipient() external virtual view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\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 initializer {\n __Context_init_unchained();\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal initializer {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), 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 emit OwnershipTransferred(_owner, address(0));\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n function __ERC165_init() internal initializer {\n __ERC165_init_unchained();\n }\n\n function __ERC165_init_unchained() internal initializer {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMathUpgradeable {\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 uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\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 if (b > a) return (false, 0);\n return (true, a - b);\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 // 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 * @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 if (b == 0) return (false, 0);\n return (true, a / b);\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 if (b == 0) return (false, 0);\n return (true, a % b);\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 uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n return c;\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 require(b <= a, \"SafeMath: subtraction overflow\");\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 if (a == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n return c;\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. 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(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: division by zero\");\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 require(b > 0, \"SafeMath: modulo by zero\");\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n return a - b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a / b;\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.4.24 <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 {UpgradeableProxy-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 */\nabstract contract Initializable {\n\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 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 /// @dev Returns true if and only if the function is running in the constructor\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\n\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 )\n external\n 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 )\n external\n returns(bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC20Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../proxy/Initializable.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 guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable {\n using SafeMathUpgradeable for uint256;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal initializer {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer {\n _name = name_;\n _symbol = symbol_;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal virtual {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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(address sender, address recipient, uint256 amount) 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/ERC20/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.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 SafeERC20Upgradeable {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) 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(IERC20Upgradeable token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\n require((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(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\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(IERC20Upgradeable 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) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721MetadataUpgradeable.sol\";\nimport \"./IERC721EnumerableUpgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"../../introspection/ERC165Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/EnumerableSetUpgradeable.sol\";\nimport \"../../utils/EnumerableMapUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../proxy/Initializable.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable, IERC721EnumerableUpgradeable {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet;\n using EnumerableMapUpgradeable for EnumerableMapUpgradeable.UintToAddressMap;\n using StringsUpgradeable for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSetUpgradeable.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMapUpgradeable.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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 initializer {\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 initializer {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\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 _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\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 _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\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(_msgSender() == owner || ERC721Upgradeable.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 require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) 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(address from, address to, uint256 tokenId, bytes memory _data) 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 _tokenOwners.contains(tokenId);\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 || ERC721Upgradeable.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\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 _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(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); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(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(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721ReceiverUpgradeable(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); // internal owner\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(address from, address to, uint256 tokenId) internal virtual { }\n uint256[41] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721EnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 /**\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/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 /**\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\npragma solidity >=0.6.0 <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(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) 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 // solhint-disable-next-line avoid-low-level-calls\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(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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 // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/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 GSN 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 initializer {\n __Context_init_unchained();\n }\n\n function __Context_init_unchained() internal initializer {\n }\n function _msgSender() internal view virtual returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/EnumerableMapUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMapUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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 EnumerableSetUpgradeable {\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\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\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] = toDeleteIndex + 1; // All indexes are 1-based\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 require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\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 // 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 // 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" + }, + "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/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 initializer {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal initializer {\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 make 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/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n /**\n * @dev Converts a `uint256` to its ASCII `string` 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 uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = bytes1(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../GSN/Context.sol\";\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 */\ncontract 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 () internal {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), msgSender);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view 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 emit OwnershipTransferred(_owner, address(0));\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n" + }, + "@openzeppelin/contracts/cryptography/MerkleProof.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev These functions deal with verification of Merkle trees (hash trees),\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(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {\n bytes32 computedHash = leaf;\n\n for (uint256 i = 0; i < proof.length; i++) {\n bytes32 proofElement = proof[i];\n\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\n // Check if the computed hash (root) is equal to the provided root\n return computedHash == root;\n }\n}\n" + }, + "@openzeppelin/contracts/GSN/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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 GSN 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 payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\ncontract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () internal {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n" + }, + "@openzeppelin/contracts/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\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 uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\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 sub(a, b, \"SafeMath: subtraction overflow\");\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 * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\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 // 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) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts 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 mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\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 SafeMath for uint256;\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 * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri) public {\n _setURI(uri);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\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) external view 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 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(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\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 require(accounts[i] != address(0), \"ERC1155: batch balance query for the zero address\");\n batchBalances[i] = _balances[ids[i]][accounts[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 require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view 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 )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, 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 )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\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 _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(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 `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` 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(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, 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(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) 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 (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\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 `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, 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(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != 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, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\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 )\n internal virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).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 )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).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/token/ERC1155/ERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() public {\n _registerInterface(\n ERC1155Receiver(0).onERC1155Received.selector ^\n ERC1155Receiver(0).onERC1155BatchReceived.selector\n );\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\nimport \"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\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 )\n external\n 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 )\n external\n returns(bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.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 guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 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 {\n using SafeMath for uint256;\n using Address for address;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name, string memory symbol) public {\n _name = name;\n _symbol = symbol;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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/token/ERC20/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.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 SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\n require((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(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\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) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n\n // If there is no base URI, return the token URI.\n if (bytes(_baseURI).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(_baseURI, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(_baseURI, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_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 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 require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) 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(address from, address to, uint256 tokenId, bytes memory _data) 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 returns (bool) {\n return _tokenOwners.contains(tokenId);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = 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 d*\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\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 _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(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 = ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(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(address from, address to, uint256 tokenId) internal virtual {\n require(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 _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\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(address from, address to, uint256 tokenId) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\nimport \"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 /**\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/token/ERC721/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 /**\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/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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(address operator, address from, uint256 tokenId, bytes calldata data)\n external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 in 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 // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n return _functionCallWithValue(target, data, value, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\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 // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../math/SafeMath.sol\";\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented or decremented by one. 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 * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}\n * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never\n * directly accessed.\n */\nlibrary Counters {\n using SafeMath for uint256;\n\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 // The {SafeMath} overflow check can be skipped here, see the comment at the top\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableMap.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n return _get(map, key, \"EnumerableMap: nonexistent key\");\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(value)));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint256(value)));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint256(_get(map._inner, bytes32(key))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint256(_get(map._inner, bytes32(key), errorMessage)));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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.0.0, only sets of type `address` (`AddressSet`) and `uint256`\n * (`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\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\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] = toDeleteIndex + 1; // All indexes are 1-based\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 require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\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(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(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(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(uint256(_at(set._inner, index)));\n }\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" + }, + "@openzeppelin/contracts/utils/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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 */\ncontract 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 () internal {\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 make 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/utils/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value < 2**128, \"SafeCast: value doesn\\'t fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value < 2**64, \"SafeCast: value doesn\\'t fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value < 2**32, \"SafeCast: value doesn\\'t fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value < 2**16, \"SafeCast: value doesn\\'t fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value < 2**8, \"SafeCast: value doesn\\'t fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= -2**127 && value < 2**127, \"SafeCast: value doesn\\'t fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= -2**63 && value < 2**63, \"SafeCast: value doesn\\'t fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= -2**31 && value < 2**31, \"SafeCast: value doesn\\'t fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= -2**15 && value < 2**15, \"SafeCast: value doesn\\'t fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= -2**7 && value < 2**7, \"SafeCast: value doesn\\'t fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n require(value < 2**255, \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` 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 uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = byte(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n" + }, + "contracts/v1/ChargedManagers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Wallet-Managers Contract\n */\ncontract ChargedManagers is\n IChargedManagers,\n Initializable,\n OwnableUpgradeable,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n\n IChargedSettings internal _chargedSettings;\n IChargedState internal _chargedState;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // Wallet/Basket Managers (by Unique Manager ID)\n mapping (string => IWalletManager) internal _ftWalletManager;\n mapping (string => IBasketManager) internal _nftBasketManager;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n /// @notice Checks if an Account is the Owner of an NFT Contract\n /// When Custom Contracts are registered, only the \"owner\" or operator of the Contract\n /// is allowed to register them and define custom rules for how their tokens are \"Charged\".\n /// Otherwise, any token can be \"Charged\" according to the default rules of Charged Particles.\n /// @param contractAddress The Address to the External NFT Contract to check\n /// @param account The Account to check if it is the Owner of the specified Contract\n /// @return True if the account is the Owner of the _contract\n function isContractOwner(address contractAddress, address account) external view override virtual returns (bool) {\n return contractAddress.isContractOwner(account);\n }\n\n function isWalletManagerEnabled(string calldata walletManagerId) external virtual override view returns (bool) {\n return _isWalletManagerEnabled(walletManagerId);\n }\n\n function getWalletManager(string calldata walletManagerId) external virtual override view returns (IWalletManager) {\n return _ftWalletManager[walletManagerId];\n }\n\n function isNftBasketEnabled(string calldata basketId) external virtual override view returns (bool) {\n return _isNftBasketEnabled(basketId);\n }\n\n function getBasketManager(string calldata basketId) external virtual override view returns (IBasketManager) {\n return _nftBasketManager[basketId];\n }\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param sender The sender address to validate against\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external virtual override {\n _validateDeposit(sender, contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param sender The sender address to validate against\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external virtual override {\n _validateNftDeposit(sender, contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateDischarge(sender, contractAddress, tokenId);\n }\n\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateRelease(sender, contractAddress, tokenId);\n }\n\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateBreakBond(sender, contractAddress, tokenId);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"state\"))) {\n _chargedState = IChargedState(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n /// @dev Register Contracts as wallet managers with a unique liquidity provider ID\n function registerWalletManager(string calldata walletManagerId, address walletManager) external virtual onlyOwner {\n // Validate wallet manager\n IWalletManager newWalletMgr = IWalletManager(walletManager);\n require(newWalletMgr.isPaused() != true, \"CP:E-418\");\n\n // Register LP ID\n _ftWalletManager[walletManagerId] = newWalletMgr;\n emit WalletManagerRegistered(walletManagerId, walletManager);\n }\n\n /// @dev Register Contracts as basket managers with a unique basket ID\n function registerBasketManager(string calldata basketId, address basketManager) external virtual onlyOwner {\n // Validate basket manager\n IBasketManager newBasketMgr = IBasketManager(basketManager);\n require(newBasketMgr.isPaused() != true, \"CP:E-418\");\n\n // Register Basket ID\n _nftBasketManager[basketId] = newBasketMgr;\n emit BasketManagerRegistered(basketId, basketManager);\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev See {ChargedParticles-isWalletManagerEnabled}.\n function _isWalletManagerEnabled(string calldata walletManagerId) internal view virtual returns (bool) {\n return (address(_ftWalletManager[walletManagerId]) != address(0x0) && !_ftWalletManager[walletManagerId].isPaused());\n }\n\n /// @dev See {ChargedParticles-isNftBasketEnabled}.\n function _isNftBasketEnabled(string calldata basketId) internal view virtual returns (bool) {\n return (address(_nftBasketManager[basketId]) != address(0x0) && !_nftBasketManager[basketId].isPaused());\n }\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n internal\n virtual\n {\n if (_chargedState.isEnergizeRestricted(contractAddress, tokenId)) {\n bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender);\n require(isNFTOwnerOrOperator, \"CP:E-105\");\n }\n\n ( string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n ) = _chargedSettings.getAssetRequirements(contractAddress, assetToken);\n\n require(energizeEnabled, \"CP:E-417\");\n\n require(!invalidAsset, \"CP:E-424\");\n\n // Valid Wallet Manager?\n if (bytes(requiredWalletManager).length > 0) {\n require(keccak256(abi.encodePacked(requiredWalletManager)) == keccak256(abi.encodePacked(walletManagerId)), \"CP:E-419\");\n }\n\n // Valid Asset?\n if (restrictedAssets) {\n require(validAsset, \"CP:E-424\");\n }\n\n _validateDepositAmount(\n contractAddress,\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n depositCap,\n depositMin,\n depositMax\n );\n }\n\n /// @dev Validates a Deposit-Amount according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDepositAmount(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax\n )\n internal\n virtual\n {\n uint256 existingBalance = _ftWalletManager[walletManagerId].getPrincipal(contractAddress, tokenId, assetToken);\n uint256 newBalance = assetAmount.add(existingBalance);\n\n // Validate Deposit Cap\n if (depositCap > 0) {\n require(newBalance <= depositCap, \"CP:E-408\");\n }\n\n // Valid Amount for Deposit?\n if (depositMin > 0) {\n require(newBalance >= depositMin, \"CP:E-410\");\n }\n if (depositMax > 0) {\n require(newBalance <= depositMax, \"CP:E-410\");\n }\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n {\n // Prevent Ouroboros NFTs\n require(contractAddress.getTokenUUID(tokenId) != nftTokenAddress.getTokenUUID(nftTokenId), \"CP:E-433\");\n\n if (_chargedState.isCovalentBondRestricted(contractAddress, tokenId)) {\n bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender);\n require(isNFTOwnerOrOperator, \"CP:E-105\");\n }\n\n ( string memory requiredBasketManager,\n bool basketEnabled,\n uint256 maxNfts\n ) = _chargedSettings.getNftAssetRequirements(contractAddress, nftTokenAddress);\n\n require(basketEnabled, \"CP:E-417\");\n\n // Valid Basket Manager?\n if (bytes(requiredBasketManager).length > 0) {\n require(keccak256(abi.encodePacked(requiredBasketManager)) == keccak256(abi.encodePacked(basketManagerId)), \"CP:E-419\");\n }\n\n if (maxNfts > 0) {\n uint256 tokenCount = _nftBasketManager[basketManagerId].getTokenTotalCount(contractAddress, tokenId);\n require(maxNfts >= (tokenCount + nftTokenAmount), \"CP:E-427\");\n }\n }\n\n function _validateDischarge(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getDischargeState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateRelease(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getReleaseState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateBreakBond(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getBreakBondState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateState(\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n internal\n view\n virtual\n {\n if (!allowFromAll) {\n require(isApproved, \"CP:E-105\");\n }\n if (timelock > 0) {\n require(block.number >= timelock, \"CP:E-302\");\n }\n if (tempLockExpiry > 0) {\n require(block.number >= tempLockExpiry, \"CP:E-303\");\n }\n }\n}\n" + }, + "contracts/v1/ChargedParticles.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\n\nimport \"./interfaces/IUniverse.sol\";\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/IWalletManager.sol\";\nimport \"./interfaces/IBasketManager.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/RelayRecipient.sol\";\n\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles V2 Contract\n * @dev Upgradeable Contract\n */\ncontract ChargedParticles is\n IChargedParticles,\n Initializable,\n OwnableUpgradeable,\n ReentrancyGuardUpgradeable,\n RelayRecipient,\n IERC721ReceiverUpgradeable,\n BlackholePrevention,\n IERC1155ReceiverUpgradeable\n{\n using SafeMathUpgradeable for uint256;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using Bitwise for uint32;\n using AddressUpgradeable for address;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n //\n // Particle Terminology\n //\n // Particle - Non-fungible Token (NFT)\n // Mass - Underlying Asset of a Token (ex; DAI)\n // Charge - Accrued Interest on the Underlying Asset of a Token\n // Charged Particle - Any NFT that has a Mass and a Positive Charge\n // Neutral Particle - Any NFT that has a Mass and No Charge\n // Energize / Recharge - Deposit of an Underlying Asset into an NFT\n // Discharge - Withdraw the Accrued Interest of an NFT leaving the Particle with its initial Mass\n // Release - Withdraw the Underlying Asset & Accrued Interest of an NFT leaving the Particle with No Mass or Charge\n //\n // Proton - NFTs minted from the Charged Particle Accelerator\n // - A proton is a subatomic particle, symbol p or p⁺, with a positive electric charge of +1e elementary\n // charge and a mass slightly less than that of a neutron.\n // Ion - Platform Governance Token\n // - A charged subatomic particle. An atom or group of atoms that carries a positive or negative electric charge\n // as a result of having lost or gained one or more electrons.\n //\n\n // Linked Contracts\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n address internal _lepton;\n uint256 internal depositFee;\n ITokenInfoProxy internal _tokenInfoProxy;\n IChargedManagers internal _chargedManagers;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n __ReentrancyGuard_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getStateAddress() external view virtual override returns (address stateAddress) {\n return address(_chargedState);\n }\n\n function getSettingsAddress() external view virtual override returns (address settingsAddress) {\n return address(_chargedSettings);\n }\n\n function getManagersAddress() external view virtual override returns (address managersAddress) {\n return address(_chargedManagers);\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external virtual override returns (bytes4) {\n return IERC721ReceiverUpgradeable(0).onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external virtual override returns (bytes4) {\n return IERC1155ReceiverUpgradeable(0).onERC1155Received.selector;\n }\n\n // Unimplemented\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external virtual override returns (bytes4) {\n return \"\"; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector;\n }\n\n function supportsInterface(bytes4 /* interfaceId */) external view virtual override returns (bool) {\n return false;\n }\n\n /// @notice Calculates the amount of Fees to be paid for a specific deposit amount\n /// @param assetAmount The Amount of Assets to calculate Fees on\n /// @return protocolFee The amount of deposit fees for the protocol\n function getFeesForDeposit(\n uint256 assetAmount\n )\n external\n override\n view\n returns (uint256 protocolFee)\n {\n protocolFee = _getFeesForDeposit(assetAmount);\n }\n\n /// @notice Gets the Amount of Asset Tokens that have been Deposited into the Particle\n /// representing the Mass of the Particle.\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Asset balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The Amount of underlying Assets held within the Token\n function baseParticleMass(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _baseParticleMass(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the amount of Interest that the Particle has generated representing\n /// the Charge of the Particle\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Interest balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The amount of interest the Token has generated (in Asset Token)\n function currentParticleCharge(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _currentParticleCharge(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the amount of LP Tokens that the Particle has generated representing\n /// the Kinetics of the Particle\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Kinetics balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The amount of LP tokens that have been generated\n function currentParticleKinetics(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _currentParticleKinetics(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the total amount of ERC721 Tokens that the Particle holds\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param basketManagerId The ID of the BasketManager to check the token balance of\n /// @return The total amount of ERC721 tokens that are held within the Particle\n function currentParticleCovalentBonds(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId\n )\n external\n view\n virtual\n override\n basketEnabled(basketManagerId)\n returns (uint256)\n {\n return _currentParticleCovalentBonds(contractAddress, tokenId, basketManagerId);\n }\n\n\n /***********************************|\n | Energize Particles |\n |__________________________________*/\n\n /// @notice Fund Particle with Asset Token\n /// Must be called by the account providing the Asset\n /// Account must Approve THIS contract as Operator of Asset\n ///\n /// NOTE: DO NOT Energize an ERC20 Token, as anyone who holds any amount\n /// of the same ERC20 token could discharge or release the funds.\n /// All holders of the ERC20 token would essentially be owners of the Charged Particle.\n ///\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param walletManagerId The Asset-Pair to Energize the Token with\n /// @param assetToken The Address of the Asset Token being used\n /// @param assetAmount The Amount of Asset Token to Energize the Token with\n /// @return yieldTokensAmount The amount of Yield-bearing Tokens added to the escrow for the Token\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 yieldTokensAmount)\n {\n _validateDeposit(contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n\n // Transfer ERC20 Token from Caller to Contract (reverts on fail)\n uint256 feeAmount = _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n yieldTokensAmount = _depositIntoWalletManager(contractAddress, tokenId, walletManagerId, assetToken, assetAmount, feeAmount);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onEnergize(_msgSender(), referrer, contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n }\n\n\n /***********************************|\n | Discharge Particles |\n |__________________________________*/\n\n /// @notice Allows the owner or operator of the Token to collect or transfer the interest generated\n /// from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @return creatorAmount Amount of Asset Token discharged to the Creator\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateDischarge(contractAddress, tokenId);\n\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).discharge(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount);\n }\n }\n\n /// @notice Allows the owner or operator of the Token to collect or transfer a specific amount of the interest\n /// generated from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @param assetAmount The specific amount of Asset Token to Discharge from the Token\n /// @return creatorAmount Amount of Asset Token discharged to the Creator\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateDischarge(contractAddress, tokenId);\n\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).dischargeAmount(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n assetAmount,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount);\n }\n }\n\n /// @notice Allows the Creator of the Token to collect or transfer a their portion of the interest (if any)\n /// generated from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @param assetAmount The specific amount of Asset Token to Discharge from the Particle\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 receiverAmount)\n {\n address sender = _msgSender();\n address tokenCreator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId);\n require(sender == tokenCreator, \"CP:E-104\");\n\n receiverAmount = _chargedManagers.getWalletManager(walletManagerId).dischargeAmountForCreator(\n receiver,\n contractAddress,\n tokenId,\n sender,\n assetToken,\n assetAmount\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischargeForCreator(contractAddress, tokenId, walletManagerId, sender, assetToken, receiverAmount);\n }\n }\n\n\n /***********************************|\n | Release Particles |\n |__________________________________*/\n\n /// @notice Releases the Full amount of Asset + Interest held within the Particle by LP of the Assets\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Release\n /// @param tokenId The ID of the Token to Release\n /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token\n /// @param assetToken The Address of the Asset Token being released\n /// @return creatorAmount Amount of Asset Token released to the Creator\n /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount)\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateRelease(contractAddress, tokenId);\n\n // Release Particle to Receiver\n uint256 principalAmount;\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).release(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n }\n\n\n /// @notice Releases a partial amount of Asset + Interest held within the Particle by LP of the Assets\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Release\n /// @param tokenId The ID of the Token to Release\n /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token\n /// @param assetToken The Address of the Asset Token being released\n /// @param assetAmount The specific amount of Asset Token to Release from the Particle\n /// @return creatorAmount Amount of Asset Token released to the Creator\n /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount)\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateRelease(contractAddress, tokenId);\n\n // Release Particle to Receiver\n uint256 principalAmount;\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).releaseAmount(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n assetAmount,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n }\n\n\n /***********************************|\n | Covalent Bonding |\n |__________________________________*/\n\n /// @notice Deposit other NFT Assets into the Particle\n /// Must be called by the account providing the Asset\n /// Account must Approve THIS contract as Operator of Asset\n ///\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n basketEnabled(basketManagerId)\n nonReentrant\n returns (bool success)\n {\n _validateNftDeposit(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Transfer ERC721 Token from Caller to Contract (reverts on fail)\n _collectNftToken(_msgSender(), nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n success = _depositIntoBasketManager(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onCovalentBond(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n }\n\n /// @notice Release NFT Assets from the Particle\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Withdraw (ERC1155-specific)\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n basketEnabled(basketManagerId)\n nonReentrant\n returns (bool success)\n {\n _validateBreakBond(contractAddress, tokenId);\n\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked(\"generic\"))) {\n basketMgr.prepareTransferAmount(nftTokenAmount);\n }\n\n // Release Particle to Receiver\n success = basketMgr.removeFromBasket(\n receiver,\n contractAddress,\n tokenId,\n nftTokenAddress,\n nftTokenId\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onCovalentBreak(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"universe\"))) {\n _universe = IUniverse(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"state\"))) {\n _chargedState = IChargedState(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"managers\"))) {\n _chargedManagers = IChargedManagers(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"leptons\"))) {\n _lepton = controller;\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"forwarder\"))) {\n trustedForwarder = controller;\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n\n /***********************************|\n | Protocol Fees |\n |__________________________________*/\n\n /// @dev Setup the Base Deposit Fee for the Protocol\n function setDepositFee(uint256 fee) external onlyOwner {\n require(fee < PERCENTAGE_SCALE, \"CP:E-421\");\n depositFee = fee;\n emit DepositFeeSet(fee);\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n internal\n virtual\n {\n _chargedManagers.validateDeposit(_msgSender(), contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _validateNftDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n {\n _chargedManagers.validateNftDeposit(_msgSender(), contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function _validateDischarge(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateDischarge(_msgSender(), contractAddress, tokenId);\n }\n\n function _validateRelease(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateRelease(_msgSender(), contractAddress, tokenId);\n }\n\n function _validateBreakBond(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateBreakBond(_msgSender(), contractAddress, tokenId);\n }\n\n /// @dev Deposit Asset Tokens into an NFT via the Wallet Manager\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n /// @param feeAmount The Amount of Protocol Fees charged\n function _depositIntoWalletManager(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 feeAmount\n )\n internal\n virtual\n returns (uint256)\n {\n // Get Wallet-Manager for LP\n IWalletManager lpWalletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n address wallet = lpWalletMgr.getWalletAddressById(contractAddress, tokenId, creator, annuityPct);\n IERC20Upgradeable(assetToken).transfer(wallet, assetAmount);\n\n emit ProtocolFeesCollected(assetToken, assetAmount, feeAmount);\n\n return lpWalletMgr.energize(contractAddress, tokenId, assetToken, assetAmount);\n }\n\n /// @dev Deposit NFT Tokens into the Basket Manager\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @param basketManagerId The Wallet Manager of the Assets to Deposit\n /// @param nftTokenAddress The Address of the Asset Token to Deposit\n /// @param nftTokenId The specific amount of Asset Token to Deposit\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _depositIntoBasketManager(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n returns (bool)\n {\n // Deposit NFT Token directly into Smart Wallet (reverts on fail) and Update BasketManager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId);\n\n if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked(\"generic\"))) {\n basketMgr.prepareTransferAmount(nftTokenAmount);\n }\n\n if (_isERC1155(nftTokenAddress)) {\n if (nftTokenAmount == 0) { nftTokenAmount = 1; }\n IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(address(this), wallet, nftTokenId, nftTokenAmount, \"\");\n } else {\n IERC721Upgradeable(nftTokenAddress).transferFrom(address(this), wallet, nftTokenId);\n }\n return basketMgr.addToBasket(contractAddress, tokenId, nftTokenAddress, nftTokenId);\n }\n\n /**\n * @dev Calculates the amount of Fees to be paid for a specific deposit amount\n * Fees are calculated in Interest-Token as they are the type collected for Fees\n * @param assetAmount The Amount of Assets to calculate Fees on\n * @return protocolFee The amount of fees reserved for the protocol\n */\n function _getFeesForDeposit(\n uint256 assetAmount\n )\n internal\n view\n returns (uint256 protocolFee)\n {\n if (depositFee > 0) {\n protocolFee = assetAmount.mul(depositFee).div(PERCENTAGE_SCALE);\n }\n }\n\n /// @dev Collects the Required ERC20 Token(s) from the users wallet\n /// Be sure to Approve this Contract to transfer your Token(s)\n /// @param from The owner address to collect the tokens from\n /// @param tokenAddress The addres of the token to transfer\n /// @param tokenAmount The amount of tokens to collect\n function _collectAssetToken(address from, address tokenAddress, uint256 tokenAmount) internal virtual returns (uint256 protocolFee) {\n protocolFee = _getFeesForDeposit(tokenAmount);\n IERC20Upgradeable(tokenAddress).safeTransferFrom(from, address(this), tokenAmount.add(protocolFee));\n }\n\n /// @dev Collects the Required ERC721 Token(s) from the users wallet\n /// Be sure to Approve this Contract to transfer your Token(s)\n /// @param from The owner address to collect the tokens from\n /// @param nftTokenAddress The address of the NFT token to transfer\n /// @param nftTokenId The ID of the NFT token to transfer\n /// @param nftTokenAmount The amount of Tokens to Transfer (ERC1155-specific)\n function _collectNftToken(address from, address nftTokenAddress, uint256 nftTokenId, uint256 nftTokenAmount) internal virtual {\n if (_isERC1155(nftTokenAddress)) {\n IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId, nftTokenAmount, \"\");\n } else {\n IERC721Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId);\n }\n }\n\n /// @dev Checks if an NFT token contract supports the ERC1155 standard interface\n function _isERC1155(address nftTokenAddress) internal view virtual returns (bool) {\n bytes4 _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n return IERC165Upgradeable(nftTokenAddress).supportsInterface(_INTERFACE_ID_ERC1155);\n }\n\n /// @dev See {ChargedParticles-baseParticleMass}.\n function _baseParticleMass(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n return _chargedManagers.getWalletManager(walletManagerId).getPrincipal(contractAddress, tokenId, assetToken);\n }\n\n /// @dev See {ChargedParticles-currentParticleCharge}.\n function _currentParticleCharge(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n (, uint256 ownerInterest) = _chargedManagers.getWalletManager(walletManagerId).getInterest(contractAddress, tokenId, assetToken);\n return ownerInterest;\n }\n\n /// @dev See {ChargedParticles-currentParticleKinetics}.\n function _currentParticleKinetics(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n return _chargedManagers.getWalletManager(walletManagerId).getRewards(contractAddress, tokenId, assetToken);\n }\n\n /// @dev See {ChargedParticles-currentParticleCovalentBonds}.\n function _currentParticleCovalentBonds(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId\n )\n internal\n view\n virtual\n returns (uint256)\n {\n return _chargedManagers.getBasketManager(basketManagerId).getTokenTotalCount(contractAddress, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier managerEnabled(string calldata walletManagerId) {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"CP:E-419\");\n _;\n }\n\n modifier basketEnabled(string calldata basketManagerId) {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"CP:E-419\");\n _;\n }\n}\n" + }, + "contracts/v1/ChargedSettings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/RelayRecipient.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\nimport \"./lib/TokenInfoProxy.sol\";\n\n/**\n * @notice Charged Particles Settings Contract\n */\ncontract ChargedSettings is\n IChargedSettings,\n Initializable,\n OwnableUpgradeable,\n RelayRecipient,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using Bitwise for uint32;\n\n uint256 constant internal MAX_ANNUITIES = 1e4; // 10000 (100%)\n\n // NftSettings - actionPerms\n uint32 constant internal PERM_CHARGE_NFT = 1; // NFT Contracts that can have assets Deposited into them (Charged)\n uint32 constant internal PERM_BASKET_NFT = 2; // NFT Contracts that can have other NFTs Deposited into them\n uint32 constant internal PERM_TIMELOCK_ANY_NFT = 4; // NFT Contracts that can timelock any NFT on behalf of users (primarily used for Front-run Protection)\n uint32 constant internal PERM_TIMELOCK_OWN_NFT = 8; // NFT Contracts that can timelock their own NFTs on behalf of their users\n uint32 constant internal PERM_RESTRICTED_ASSETS = 16; // NFT Contracts that have restricted deposits to specific assets\n\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // Current Settings for External NFT Token Contracts;\n // - Any user can add any ERC721 or ERC1155 token as a Charged Particle without Limits,\n // unless the Owner of the ERC721 or ERC1155 token contract registers the token\n // and sets the Custom Settings for their token(s)\n mapping (address => uint32) internal _nftActionPerms;\n\n mapping (address => string) internal _nftRequiredWalletManager;\n mapping (address => string) internal _nftRequiredBasketManager;\n\n // ERC20\n mapping (address => mapping(address => bool)) internal _nftAllowedAssetTokens;\n mapping (address => mapping (address => uint256)) internal _nftDepositMin;\n mapping (address => mapping (address => uint256)) internal _nftDepositMax;\n\n // ERC721 / ERC1155\n mapping (address => mapping (address => uint256)) internal _nftMaxNfts; // NFT Token Address => Max\n\n // Optional Configs for individual NFTs set by NFT Creator (by Token UUID)\n mapping (uint256 => uint256) internal _creatorAnnuityPercent;\n mapping (uint256 => address) internal _creatorAnnuityRedirect;\n\n mapping (address => uint256) internal _depositCap;\n uint256 internal _tempLockExpiryBlocks;\n\n // Blacklist for non-compliant tokens\n mapping (address => bool) internal _invalidAssets;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n /// @dev Gets the amount of creator annuities reserved for the creator for the specified NFT\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @return creator The address of the creator\n /// @return annuityPct The percentage amount of annuities reserved for the creator\n function getCreatorAnnuities(\n address contractAddress,\n uint256 tokenId\n )\n external\n override\n virtual\n returns (address creator, uint256 annuityPct)\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n creator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId);\n annuityPct = _creatorAnnuityPercent[tokenUuid];\n }\n\n function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId)\n external\n view\n override\n virtual\n returns (address)\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _creatorAnnuityRedirect[tokenUuid];\n }\n\n function getTempLockExpiryBlocks() external view override virtual returns (uint256) {\n return _tempLockExpiryBlocks;\n }\n\n function getTimelockApprovals(address operator)\n external\n view\n override\n virtual\n returns (bool timelockAny, bool timelockOwn)\n {\n timelockAny = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_ANY_NFT);\n timelockOwn = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_OWN_NFT);\n }\n\n function getAssetRequirements(address contractAddress, address assetToken)\n external\n view\n override\n virtual\n returns (\n string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n )\n {\n requiredWalletManager = _nftRequiredWalletManager[contractAddress];\n energizeEnabled = _nftActionPerms[contractAddress].hasBit(PERM_CHARGE_NFT);\n restrictedAssets = _nftActionPerms[contractAddress].hasBit(PERM_RESTRICTED_ASSETS);\n validAsset = _nftAllowedAssetTokens[contractAddress][assetToken];\n depositCap = _depositCap[assetToken];\n depositMin = _nftDepositMin[contractAddress][assetToken];\n depositMax = _nftDepositMax[contractAddress][assetToken];\n invalidAsset = _invalidAssets[assetToken];\n }\n\n function getNftAssetRequirements(address contractAddress, address nftTokenAddress)\n external\n view\n override\n virtual\n returns (string memory requiredBasketManager, bool basketEnabled, uint256 maxNfts)\n {\n requiredBasketManager = _nftRequiredBasketManager[contractAddress];\n basketEnabled = _nftActionPerms[contractAddress].hasBit(PERM_BASKET_NFT);\n maxNfts = _nftMaxNfts[contractAddress][nftTokenAddress];\n }\n\n\n /***********************************|\n | Only NFT Creator |\n |__________________________________*/\n\n /// @notice Sets the Custom Configuration for Creators of Proton-based NFTs\n /// @param contractAddress The Address to the Proton-based NFT to configure\n /// @param tokenId The token ID of the Proton-based NFT to configure\n /// @param creator The creator of the Proton-based NFT\n /// @param annuityPercent The percentage of interest-annuities to reserve for the creator\n function setCreatorAnnuities(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent\n )\n external\n virtual\n override\n {\n require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), \"CP:E-104\");\n _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent);\n }\n\n /// @notice Sets a Custom Receiver Address for the Creator Annuities\n /// @param contractAddress The Address to the Proton-based NFT to configure\n /// @param tokenId The token ID of the Proton-based NFT to configure\n /// @param receiver The receiver of the Creator interest-annuities\n function setCreatorAnnuitiesRedirect(\n address contractAddress,\n uint256 tokenId,\n address receiver\n )\n external\n virtual\n override\n {\n require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), \"CP:E-104\");\n _setCreatorAnnuitiesRedirect(contractAddress, tokenId, receiver);\n }\n\n\n /***********************************|\n | Register Contract Settings |\n |(For External Contract Integration)|\n |__________________________________*/\n\n /// @notice Sets a Required Wallet-Manager for External NFT Contracts (otherwise set to \"none\" to allow any Wallet-Manager)\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param walletManager If set, will only allow deposits from this specific Wallet-Manager\n function setRequiredWalletManager(\n address contractAddress,\n string calldata walletManager\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (keccak256(bytes(walletManager)) == keccak256(bytes(\"none\"))) {\n _nftRequiredWalletManager[contractAddress] = \"\";\n } else {\n _nftRequiredWalletManager[contractAddress] = walletManager;\n }\n\n emit RequiredWalletManagerSet(\n contractAddress,\n walletManager\n );\n }\n\n /// @notice Sets a Required Basket-Manager for External NFT Contracts (otherwise set to \"none\" to allow any Basket-Manager)\n /// @param contractAddress The Address to the External Contract to configure\n /// @param basketManager If set, will only allow deposits from this specific Basket-Manager\n function setRequiredBasketManager(\n address contractAddress,\n string calldata basketManager\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (keccak256(bytes(basketManager)) == keccak256(bytes(\"none\"))) {\n _nftRequiredBasketManager[contractAddress] = \"\";\n } else {\n _nftRequiredBasketManager[contractAddress] = basketManager;\n }\n\n emit RequiredBasketManagerSet(\n contractAddress,\n basketManager\n );\n }\n\n /// @notice Enables or Disables Asset-Token Restrictions for External NFT Contracts\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param restrictionsEnabled If set, will only allow deposits from Allowed Asset Tokens\n function setAssetTokenRestrictions(\n address contractAddress,\n bool restrictionsEnabled\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (restrictionsEnabled) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_RESTRICTED_ASSETS);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_RESTRICTED_ASSETS);\n }\n\n emit AssetTokenRestrictionsSet(\n contractAddress,\n restrictionsEnabled\n );\n }\n\n /// @notice Enables or Disables Allowed Asset Tokens for External NFT Contracts\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param assetToken The Address of the Asset Token to Allow or Disallow\n /// @param isAllowed True if the Asset Token is allowed\n function setAllowedAssetToken(\n address contractAddress,\n address assetToken,\n bool isAllowed\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftAllowedAssetTokens[contractAddress][assetToken] = isAllowed;\n\n emit AllowedAssetTokenSet(\n contractAddress,\n assetToken,\n isAllowed\n );\n }\n\n /// @notice Sets the Custom Configuration for External Contracts\n /// @param contractAddress The Address to the External Contract to configure\n /// @param assetToken The address of the Asset Token to set Limits for\n /// @param depositMin If set, will define the minimum amount of Asset tokens the NFT may hold, otherwise any amount\n /// @param depositMax If set, will define the maximum amount of Asset tokens the NFT may hold, otherwise any amount\n function setAssetTokenLimits(\n address contractAddress,\n address assetToken,\n uint256 depositMin,\n uint256 depositMax\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftDepositMin[contractAddress][assetToken] = depositMin;\n _nftDepositMax[contractAddress][assetToken] = depositMax;\n\n emit AssetTokenLimitsSet(\n contractAddress,\n assetToken,\n depositMin,\n depositMax\n );\n }\n\n /// @notice Sets the Max Number of NFTs that can be held by a Charged Particle NFT\n /// @param contractAddress The Address to the External Contract to configure\n /// @param nftTokenAddress The address of the NFT Token to set a Max for\n /// @param maxNfts The maximum numbers of NFTs that can be held by a given NFT (0 = unlimited)\n function setMaxNfts(\n address contractAddress,\n address nftTokenAddress,\n uint256 maxNfts\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftMaxNfts[contractAddress][nftTokenAddress] = maxNfts;\n\n emit MaxNftsSet(\n contractAddress,\n nftTokenAddress,\n maxNfts\n );\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n function setAssetInvalidity(address assetToken, bool invalidity) external virtual override onlyOwner {\n _invalidAssets[assetToken] = invalidity;\n emit AssetInvaliditySet(assetToken, invalidity);\n }\n\n function setDepositCap(address assetToken, uint256 cap) external virtual onlyOwner {\n _depositCap[assetToken] = cap;\n emit DepositCapSet(assetToken, cap);\n }\n\n function setTempLockExpiryBlocks(uint256 numBlocks) external virtual onlyOwner {\n _tempLockExpiryBlocks = numBlocks;\n emit TempLockExpirySet(numBlocks);\n }\n\n function enableNftContracts(address[] calldata contracts) external override virtual onlyOwner {\n uint count = contracts.length;\n for (uint i = 0; i < count; i++) {\n address tokenContract = contracts[i];\n _setPermsForCharge(tokenContract, true);\n _setPermsForBasket(tokenContract, true);\n _setPermsForTimelockSelf(tokenContract, true);\n }\n }\n\n function migrateToken(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent,\n address annuityReceiver\n )\n external\n onlyOwner\n {\n _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent);\n if (annuityReceiver != address(0)) {\n _setCreatorAnnuitiesRedirect(contractAddress, tokenId, annuityReceiver);\n }\n }\n\n /// @dev Update the list of NFT contracts that can be Charged\n function setPermsForCharge(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForCharge(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can hold other NFTs\n function setPermsForBasket(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForBasket(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection\n function setPermsForTimelockAny(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForTimelockAny(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock their own tokens\n function setPermsForTimelockSelf(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForTimelockSelf(contractAddress, state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Update the list of NFT contracts that can be Charged\n function _setPermsForCharge(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_CHARGE_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_CHARGE_NFT);\n }\n emit PermsSetForCharge(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can hold other NFTs\n function _setPermsForBasket(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_BASKET_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_BASKET_NFT);\n }\n emit PermsSetForBasket(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection\n function _setPermsForTimelockAny(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_ANY_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_ANY_NFT);\n }\n emit PermsSetForTimelockAny(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock their own tokens\n function _setPermsForTimelockSelf(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_OWN_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_OWN_NFT);\n }\n emit PermsSetForTimelockSelf(contractAddress, state);\n }\n\n /// @dev see setCreatorAnnuities()\n function _setCreatorAnnuities(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent\n )\n internal\n virtual\n {\n require(annuityPercent <= MAX_ANNUITIES, \"CP:E-421\");\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Update Configs for External Token Creator\n _creatorAnnuityPercent[tokenUuid] = annuityPercent;\n\n emit TokenCreatorConfigsSet(\n contractAddress,\n tokenId,\n creator,\n annuityPercent\n );\n }\n\n /// @dev see setCreatorAnnuitiesRedirect()\n function _setCreatorAnnuitiesRedirect(\n address contractAddress,\n uint256 tokenId,\n address receiver\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _creatorAnnuityRedirect[tokenUuid] = receiver;\n emit TokenCreatorAnnuitiesRedirected(contractAddress, tokenId, receiver);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyValidExternalContract(address contractAddress) {\n require(contractAddress.isContract(), \"CP:E-420\");\n _;\n }\n\n modifier onlyContractOwnerOrAdmin(address contractAddress, address sender) {\n require(sender == owner() || contractAddress.isContractOwner(sender), \"CP:E-103\");\n _;\n }\n}\n" + }, + "contracts/v1/ChargedState.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedState.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/RelayRecipient.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Settings Contract\n */\ncontract ChargedState is\n IChargedState,\n Initializable,\n OwnableUpgradeable,\n RelayRecipient,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using Bitwise for uint32;\n\n // NftState - actionPerms\n uint32 constant internal PERM_RESTRICT_ENERGIZE_FROM_ALL = 1; // NFTs that have Restrictions on Energize\n uint32 constant internal PERM_ALLOW_DISCHARGE_FROM_ALL = 2; // NFTs that allow Discharge by anyone\n uint32 constant internal PERM_ALLOW_RELEASE_FROM_ALL = 4; // NFTs that allow Release by anyone\n uint32 constant internal PERM_RESTRICT_BOND_FROM_ALL = 8; // NFTs that have Restrictions on Covalent Bonds\n uint32 constant internal PERM_ALLOW_BREAK_BOND_FROM_ALL = 16; // NFTs that allow Breaking Covalent Bonds by anyone\n\n IChargedSettings internal _chargedSettings;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // NftTimelocks\n /// @dev discharge unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftDischargeTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftDischargeTimelockLockedBy;\n\n /// @dev release unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftReleaseTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftReleaseTimelockLockedBy;\n\n /// @dev release unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftBreakBondTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftBreakBondTimelockLockedBy;\n\n // NftState\n /// @dev maps nft by tokenId to actionPermissions uint32 which is a composite of all possible NftState - actionPerms\n mapping (uint256 => uint32) internal _nftActionPerms;\n\n /// @dev maps nft by tokenId to its tempLockExpiry\n mapping (uint256 => uint256) internal _nftTempLockExpiry;\n\n /// @dev maps tokenId to user address to operator address for approving various actions\n mapping (uint256 => mapping(address => address)) internal _nftDischargeApproval;\n mapping (uint256 => mapping(address => address)) internal _nftReleaseApproval;\n mapping (uint256 => mapping(address => address)) internal _nftBreakBondApproval;\n mapping (uint256 => mapping(address => address)) internal _nftTimelockApproval;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftDischargeTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftDischargeTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftReleaseTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftReleaseTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftBreakBondTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftBreakBondTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n\n /// @notice Checks if an operator is allowed to Discharge a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForDischarge(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Release a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForRelease(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Break Covalent Bonds on a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForBreakBond(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Timelock a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForTimelock(contractAddress, tokenId, operator);\n }\n\n\n function isEnergizeRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n }\n\n\n function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_BOND_FROM_ALL);\n }\n\n\n function getDischargeState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n isApproved = _isApprovedForDischarge(contractAddress, tokenId, sender);\n timelock = _nftDischargeTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n function getReleaseState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_RELEASE_FROM_ALL);\n isApproved = _isApprovedForRelease(contractAddress, tokenId, sender);\n timelock = _nftReleaseTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n function getBreakBondState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n isApproved = _isApprovedForBreakBond(contractAddress, tokenId, sender);\n timelock = _nftBreakBondTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n\n /***********************************|\n | Only NFT Owner/Operator |\n |__________________________________*/\n\n /// @notice Sets an Operator as Approved to Discharge a specific Token\n /// This allows an operator to withdraw the interest-portion only\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setDischargeApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Release a specific Token\n /// This allows an operator to withdraw the principal + interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setReleaseApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token\n /// This allows an operator to withdraw Basket NFTs\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setBreakBondApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Timelock a specific Token\n /// This allows an operator to timelock the principal or interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setTimelockApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Discharge/Release/Timelock a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setApprovalForAll(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @dev Updates Restrictions on Energizing an NFT\n function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForRestrictCharge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowDischarge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowRelease(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Restrictions on Covalent Bonds on an NFT\n function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForRestrictBond(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone\n function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowBreakBond(contractAddress, tokenId, state);\n }\n\n /// @notice Sets a Timelock on the ability to Discharge the Interest of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setDischargeTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftDischargeTimelockLockedBy[tokenUuid] == sender) {\n delete _nftDischargeTimelockUnlockBlock[tokenUuid];\n delete _nftDischargeTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftDischargeTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftDischargeTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftDischargeTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenDischargeTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n /// @notice Sets a Timelock on the ability to Release the Assets of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setReleaseTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftReleaseTimelockLockedBy[tokenUuid] == sender) {\n delete _nftReleaseTimelockUnlockBlock[tokenUuid];\n delete _nftReleaseTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftReleaseTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftReleaseTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftReleaseTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenReleaseTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n /// @notice Sets a Timelock on the ability to Break the Covalent Bond of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setBreakBondTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftBreakBondTimelockLockedBy[tokenUuid] == sender) {\n delete _nftBreakBondTimelockUnlockBlock[tokenUuid];\n delete _nftBreakBondTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftBreakBondTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftBreakBondTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftBreakBondTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenBreakBondTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n\n /***********************************|\n | Only NFT Contract |\n |__________________________________*/\n\n /// @notice Sets a Temporary-Lock on the ability to Release/Discharge the Assets of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param isLocked The locked state; contracts are expected to disable this lock before expiry\n function setTemporaryLock(\n address contractAddress,\n uint256 tokenId,\n bool isLocked\n )\n external\n override\n virtual\n {\n require(msg.sender == contractAddress, \"CP:E-112\");\n\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n uint256 unlockBlock;\n if (isLocked && _nftTempLockExpiry[tokenUuid] == 0) {\n unlockBlock = block.number.add(_chargedSettings.getTempLockExpiryBlocks());\n _nftTempLockExpiry[tokenUuid] = unlockBlock;\n }\n if (!isLocked) {\n _nftTempLockExpiry[tokenUuid] = 0;\n }\n\n emit TokenTempLock(contractAddress, tokenId, unlockBlock);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n function migrateToken(\n address contractAddress,\n uint256 tokenId,\n uint256 releaseTimelockExpiry,\n address releaseTimelockLockedBy,\n uint256 tempLockExpiry\n )\n external\n onlyOwner\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (releaseTimelockExpiry > block.number && releaseTimelockLockedBy != address(0)) {\n _nftReleaseTimelockUnlockBlock[tokenUuid] = releaseTimelockExpiry;\n _nftReleaseTimelockLockedBy[tokenUuid] = releaseTimelockLockedBy;\n emit TokenReleaseTimelock(contractAddress, tokenId, releaseTimelockLockedBy, releaseTimelockExpiry);\n }\n\n if (tempLockExpiry > 0) {\n _nftTempLockExpiry[tokenUuid] = tempLockExpiry;\n emit TokenTempLock(contractAddress, tokenId, tempLockExpiry);\n }\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev See {ChargedParticles-isApprovedForDischarge}.\n function _isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftDischargeApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForRelease}.\n function _isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftReleaseApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForBreakBond}.\n function _isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftBreakBondApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForTimelock}.\n function _isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n (bool timelockAny, bool timelockOwn) = _chargedSettings.getTimelockApprovals(operator);\n if (timelockAny || (timelockOwn && contractAddress == operator)) { return true; }\n\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return tokenOwner == operator || _nftTimelockApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @notice Sets an Operator as Approved to Discharge a specific Token\n /// This allows an operator to withdraw the interest-portion only\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setDischargeApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftDischargeApproval[tokenUuid][tokenOwner] = operator;\n emit DischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Release a specific Token\n /// This allows an operator to withdraw the principal + interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setReleaseApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftReleaseApproval[tokenUuid][tokenOwner] = operator;\n emit ReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token\n /// This allows an operator to withdraw Basket NFTs\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setBreakBondApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftBreakBondApproval[tokenUuid][tokenOwner] = operator;\n emit BreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Timelock a specific Token\n /// This allows an operator to timelock the principal or interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setTimelockApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftTimelockApproval[tokenUuid][tokenOwner] = operator;\n emit TimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @dev Updates Restrictions on Energizing an NFT\n function _setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n }\n emit PermsSetForRestrictCharge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function _setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n }\n emit PermsSetForAllowDischarge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function _setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_RELEASE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_RELEASE_FROM_ALL);\n }\n emit PermsSetForAllowRelease(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Restrictions on Covalent Bonds on an NFT\n function _setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_BOND_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_BOND_FROM_ALL);\n }\n emit PermsSetForRestrictBond(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone\n function _setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n }\n emit PermsSetForAllowBreakBond(contractAddress, tokenId, state);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) {\n require(_tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender), \"CP:E-105\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/CommunityVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract CommunityVault is Ownable, BlackholePrevention {\n\n IERC20 private immutable _ionx;\n\n constructor (address ionx) public {\n _ionx = IERC20(ionx);\n }\n\n event SetAllowance(address indexed caller, address indexed spender, uint256 amount);\n\n function setAllowance(address spender, uint amount) public onlyOwner {\n _ionx.approve(spender, amount);\n\n emit SetAllowance(msg.sender, spender, amount);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens other than IONX, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n require(tokenAddress != address(_ionx), \"CommunityVault: cannot withdraw IONX\");\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n}" + }, + "contracts/v1/incentives/MerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_) public {\n token = token_;\n merkleRoot = merkleRoot_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), 'MerkleDistributor: Drop already claimed.');\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), 'MerkleDistributor: Invalid proof.');\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), 'MerkleDistributor: Transfer failed.');\n\n emit Claimed(index, account, amount);\n }\n}\n" + }, + "contracts/v1/incentives/MerkleDistributor2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor2 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"MerkleDistributor2: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"MerkleDistributor2: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor2: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"MerkleDistributor2: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"MerkleDistributor2: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"MerkleDistributor2: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/MerkleDistributor3.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor3 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"MerkleDistributor3: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"MerkleDistributor3: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor3: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"MerkleDistributor3: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"MerkleDistributor3: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"MerkleDistributor3: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/RewardProgram.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// RewardProgram.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/IRewardProgram.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/introspection/IERC165.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"../interfaces/IUniverseRP.sol\";\nimport \"../interfaces/IChargedManagers.sol\";\nimport \"../interfaces/IWalletManager.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IERC20Detailed.sol\";\n\ncontract RewardProgram is\n IRewardProgram,\n BlackholePrevention,\n IERC165,\n ReentrancyGuard,\n IERC721Receiver,\n IERC1155Receiver\n{\n using SafeMath for uint256;\n using TokenInfo for address;\n using SafeERC20 for IERC20;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n\n address private _owner;\n IUniverseRP private _universe;\n IChargedManagers private _chargedManagers;\n ProgramRewardData private _programData;\n mapping(uint256 => AssetStake) private _assetStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public {}\n\n function initialize(\n address stakingToken,\n address rewardToken,\n uint256 baseMultiplier,\n address chargedManagers,\n address universe,\n address owner\n ) external override {\n require(_owner == address(0x0), \"Already initialized\");\n _owner = owner;\n\n // Prepare Reward Program\n _programData.stakingToken = stakingToken;\n _programData.rewardToken = rewardToken;\n _programData.baseMultiplier = baseMultiplier; // Basis Points\n\n // Connect to Charged Particles\n _chargedManagers = IChargedManagers(chargedManagers);\n _universe = IUniverseRP(universe);\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getProgramData() external view override returns (ProgramRewardData memory) {\n return _programData;\n }\n\n function getAssetStake(uint256 parentNftUuid) external view override returns (AssetStake memory) {\n return _assetStake[parentNftUuid];\n }\n\n function getFundBalance() external view override returns (uint256) {\n return _getFundBalance();\n }\n\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) public view override returns (uint256) {\n return _calculateRewardsEarned(parentNftUuid, interestAmount);\n }\n\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n return _assetStake[parentNftUuid].claimableRewards;\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\n return \"\";\n }\n\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(IERC165)\n returns (bool)\n {\n // default interface support\n if (\n interfaceId == type(IERC721Receiver).interfaceId ||\n interfaceId == type(IERC1155Receiver).interfaceId ||\n interfaceId == type(IERC165).interfaceId\n ) {\n return true;\n }\n }\n\n function owner() public view returns (address) {\n return _owner;\n }\n\n\n /***********************************|\n | Only Universe |\n |__________________________________*/\n\n function registerAssetDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n uint256 principalAmount\n )\n external\n override\n onlyUniverse\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n if (assetStake.start == 0) {\n assetStake.start = block.number;\n assetStake.walletManagerId = walletManagerId;\n }\n emit AssetDeposit(contractAddress, tokenId, walletManagerId, principalAmount);\n }\n\n function registerAssetRelease(\n address contractAddress,\n uint256 tokenId,\n uint256 interestAmount\n )\n external\n override\n onlyUniverse\n nonReentrant\n returns (uint256 rewards)\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n if (assetStake.start > 0) {\n // Update Claimable Rewards\n uint256 newRewards = _calculateRewardsEarned(parentNftUuid, interestAmount);\n assetStake.claimableRewards = assetStake.claimableRewards.add(newRewards);\n\n // Reset Stake if Principal Balance falls to Zero\n IWalletManager walletMgr = _chargedManagers.getWalletManager(assetStake.walletManagerId);\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\n if (principal == 0) {\n assetStake.start = 0;\n }\n\n // Issue Rewards to NFT Owner\n rewards = _claimRewards(contractAddress, tokenId);\n\n emit AssetRelease(contractAddress, tokenId, interestAmount);\n }\n }\n\n\n /***********************************|\n | Reward Calculation |\n |__________________________________*/\n\n function _calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) internal view returns (uint256 totalReward) {\n uint256 baseReward = _calculateBaseReward(interestAmount);\n uint256 leptonMultipliedReward = _calculateMultipliedReward(parentNftUuid, baseReward);\n totalReward = _convertDecimals(leptonMultipliedReward);\n }\n\n function _calculateBaseReward(uint256 amount) internal view returns(uint256 baseReward) {\n baseReward = amount.mul(_programData.baseMultiplier).div(PERCENTAGE_SCALE);\n }\n\n function _calculateMultipliedReward(uint256 parentNftUuid, uint256 baseReward) internal view returns(uint256) {\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n if (assetStake.start == 0) { return baseReward; }\n\n IUniverseRP.NftStake memory nftStake = _universe.getNftStake(parentNftUuid);\n uint256 multiplierBP = nftStake.multiplier;\n\n uint256 assetDepositLength = block.number.sub(assetStake.start);\n uint256 nftDepositLength = 0;\n if (nftStake.releaseBlockNumber > 0) {\n nftDepositLength = nftStake.releaseBlockNumber.sub(nftStake.depositBlockNumber);\n } else {\n nftDepositLength = block.number.sub(nftStake.depositBlockNumber);\n }\n\n if (multiplierBP == 0 || nftDepositLength == 0 || assetDepositLength == 0) {\n return baseReward;\n }\n\n if (nftDepositLength > assetDepositLength) {\n nftDepositLength = assetDepositLength;\n }\n\n // Percentage of the total program that the Multiplier Nft was deposited for\n uint256 nftRewardRatioBP = nftDepositLength.mul(PERCENTAGE_SCALE).div(assetDepositLength);\n\n // Amount of reward that the Multiplier Nft is responsible for\n uint256 amountGeneratedDuringNftDeposit = baseReward.mul(nftRewardRatioBP).div(PERCENTAGE_SCALE);\n\n // Amount of Multiplied Reward from NFT\n uint256 multipliedReward = amountGeneratedDuringNftDeposit.mul(multiplierBP.mul(LEPTON_MULTIPLIER_SCALE)).div(PERCENTAGE_SCALE);\n\n // Amount of Base Reward without Multiplied NFT Rewards\n uint256 amountGeneratedWithoutNftDeposit = baseReward.sub(amountGeneratedDuringNftDeposit);\n\n // Amount of Base Rewards + Multiplied NFT Rewards\n return amountGeneratedWithoutNftDeposit.add(multipliedReward);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function fundProgram(uint256 amount) external onlyOwner {\n require(_programData.rewardToken != address(0), \"RP:E-405\");\n IERC20(_programData.rewardToken).safeTransferFrom(msg.sender, address(this), amount);\n emit RewardProgramFunded(amount);\n }\n\n function setStakingToken(address newStakingToken) external onlyOwner {\n _programData.stakingToken = newStakingToken;\n }\n\n function setRewardToken(address newRewardToken) external onlyOwner {\n _programData.rewardToken = newRewardToken;\n }\n\n function setBaseMultiplier(uint256 newMultiplier) external onlyOwner {\n _programData.baseMultiplier = newMultiplier; // Basis Points\n }\n\n function setChargedManagers(address manager) external onlyOwner {\n _chargedManagers = IChargedManagers(manager);\n }\n\n function setUniverse(address universe) external onlyOwner {\n _universe = IUniverseRP(universe);\n }\n\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external override onlyOwner {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n\n // Initiate Asset Stake\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\n if (principal > 0) {\n _assetStake[parentNftUuid] = AssetStake(block.number, 0, walletManagerId);\n emit AssetRegistered(contractAddress, tokenId, walletManagerId, principal);\n }\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _claimRewards(\n address contractAddress,\n uint256 tokenId\n )\n internal\n returns (uint256 totalReward)\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n // Rewards Receiver\n address receiver = IERC721(contractAddress).ownerOf(tokenId);\n\n // Ensure Reward Pool has Sufficient Balance\n totalReward = assetStake.claimableRewards;\n uint256 fundBalance = _getFundBalance();\n uint256 unavailReward = totalReward > fundBalance ? totalReward.sub(fundBalance) : 0;\n\n // Determine amount of Rewards to Transfer\n if (unavailReward > 0) {\n totalReward = totalReward.sub(unavailReward);\n emit RewardProgramOutOfFunds();\n }\n\n // Update Asset Stake\n assetStake.claimableRewards = unavailReward;\n\n if (totalReward > 0) {\n // Transfer Available Rewards to Receiver\n IERC20(_programData.rewardToken).safeTransfer(receiver, totalReward);\n }\n\n emit RewardsClaimed(contractAddress, tokenId, receiver, totalReward, unavailReward);\n }\n\n function _convertDecimals(uint256 reward) internal view returns (uint256) {\n uint8 stakingTokenDecimals = IERC20Detailed(_programData.stakingToken).decimals();\n return reward.mul(10**(18 - uint256(stakingTokenDecimals)));\n }\n\n function _getFundBalance() internal view returns (uint256) {\n return IERC20Detailed(_programData.rewardToken).balanceOf(address(this));\n }\n\n\n modifier onlyOwner() {\n require(_owner == msg.sender, \"Caller is not the owner\");\n _;\n }\n\n modifier onlyUniverse() {\n require(msg.sender == address(_universe), \"RP:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/RewardProgramFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// RewardProgramFactory.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport \"./RewardProgram.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract RewardProgramFactory is BlackholePrevention, Ownable {\n event RewardProgramCreated(address indexed rewardProgram);\n\n address public _template;\n\n constructor () public {\n _template = address(new RewardProgram());\n }\n\n // function _msgSender() internal view override returns (address payable) {\n // return msg.sender;\n // }\n\n function createRewardProgram(\n address stakingToken,\n address rewardToken,\n uint256 baseMultiplier,\n address chargedManagers,\n address universe\n )\n external\n onlyOwner\n returns (address)\n {\n address newRewardProgram = _createClone(_template);\n RewardProgram rewardProgram = RewardProgram(newRewardProgram);\n rewardProgram.initialize(stakingToken, rewardToken, baseMultiplier, chargedManagers, universe, _msgSender());\n emit RewardProgramCreated(newRewardProgram);\n return newRewardProgram;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n}\n" + }, + "contracts/v1/incentives/Staking.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/Staking2.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking2 is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/Staking3.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking3 is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/YieldFarm.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/incentives/YieldFarm2.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm2 is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/incentives/YieldFarm3.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm3 is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/interfaces/IAaveBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IAaveBridge.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n\ninterface IAaveBridge {\n function getReserveInterestToken(address assetToken) external view returns (address aTokenAddress);\n function isReserveActive(address assetToken) external view returns (bool);\n\n function getTotalBalance(address account, address assetToken) external view returns (uint256);\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(address receiver, address assetToken, uint256 assetAmount) external;\n}\n" + }, + "contracts/v1/interfaces/IBaseProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IBaseProton is IERC721 {\n event PausedStateSet(bool isPaused);\n event SalePriceSet(uint256 indexed tokenId, uint256 salePrice);\n event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct);\n event FeesWithdrawn(address indexed receiver, uint256 amount);\n event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties);\n event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view returns (address);\n function getSalePrice(uint256 tokenId) external view returns (uint256);\n function getLastSellPrice(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyalties(address account) external view returns (uint256);\n function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address);\n\n function buyProton(uint256 tokenId, uint256 gasLimit) external payable returns (bool);\n function claimCreatorRoyalties() external returns (uint256);\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n ) external returns (uint256 newTokenId);\n\n function createProtons(\n address creator,\n address receiver,\n string[] calldata tokenMetaUris\n ) external returns (bool);\n\n function createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n ) external returns (bool);\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice) external;\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external;\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external;\n}" + }, + "contracts/v1/interfaces/IBasketManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Particle Basket Manager interface\n * @dev The basket-manager for underlying assets attached to Charged Particles\n * @dev Manages the link between NFTs and their respective Smart-Baskets\n */\ninterface IBasketManager {\n\n event ControllerSet(address indexed controller);\n event ExecutorSet(address indexed executor);\n event PausedStateSet(bool isPaused);\n event NewSmartBasket(address indexed contractAddress, uint256 indexed tokenId, address indexed smartBasket);\n event BasketAdd(address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\n event BasketRemove(address indexed receiver, address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\n event BasketRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\n event RewardProgramSet(address indexed rewardProgram);\n\n function isPaused() external view returns (bool);\n\n function getTokenTotalCount(address contractAddress, uint256 tokenId) external view returns (uint256);\n function getTokenCountByType(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (uint256);\n\n function prepareTransferAmount(uint256 nftTokenAmount) external;\n function addToBasket(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function getBasketAddressById(address contractAddress, uint256 tokenId) external returns (address);\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/IChargedManagers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IWalletManager.sol\";\nimport \"./IBasketManager.sol\";\n\n/**\n * @notice Interface for Charged Wallet-Managers\n */\ninterface IChargedManagers {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function isContractOwner(address contractAddress, address account) external view returns (bool);\n\n // ERC20\n function isWalletManagerEnabled(string calldata walletManagerId) external view returns (bool);\n function getWalletManager(string calldata walletManagerId) external view returns (IWalletManager);\n\n // ERC721\n function isNftBasketEnabled(string calldata basketId) external view returns (bool);\n function getBasketManager(string calldata basketId) external view returns (IBasketManager);\n\n // Validation\n function validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external;\n function validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external;\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external;\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event WalletManagerRegistered(string indexed walletManagerId, address indexed walletManager);\n event BasketManagerRegistered(string indexed basketId, address indexed basketManager);\n}\n" + }, + "contracts/v1/interfaces/IChargedParticles.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Charged Particles\n */\ninterface IChargedParticles {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getStateAddress() external view returns (address stateAddress);\n function getSettingsAddress() external view returns (address settingsAddress);\n function getManagersAddress() external view returns (address managersAddress);\n\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\n\n /***********************************|\n | Particle Mechanics |\n |__________________________________*/\n\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n ) external returns (uint256 yieldTokensAmount);\n\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 receiverAmount);\n\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositFeeSet(uint256 depositFee);\n event ProtocolFeesCollected(address indexed assetToken, uint256 depositAmount, uint256 feesCollected);\n}\n" + }, + "contracts/v1/interfaces/IChargedSettings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IWalletManager.sol\";\nimport \"./IBasketManager.sol\";\n\n/**\n * @notice Interface for Charged Settings\n */\ninterface IChargedSettings {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n // function isContractOwner(address contractAddress, address account) external view returns (bool);\n function getCreatorAnnuities(address contractAddress, uint256 tokenId) external returns (address creator, uint256 annuityPct);\n function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId) external view returns (address);\n function getTempLockExpiryBlocks() external view returns (uint256);\n function getTimelockApprovals(address operator) external view returns (bool timelockAny, bool timelockOwn);\n function getAssetRequirements(\n address contractAddress,\n address assetToken\n ) external view returns (\n string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n );\n function getNftAssetRequirements(\n address contractAddress,\n address nftTokenAddress\n ) external view returns (\n string memory requiredBasketManager,\n bool basketEnabled,\n uint256 maxNfts\n );\n\n /***********************************|\n | Only NFT Creator |\n |__________________________________*/\n\n function setCreatorAnnuities(address contractAddress, uint256 tokenId, address creator, uint256 annuityPercent) external;\n function setCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId, address receiver) external;\n\n\n /***********************************|\n | Only NFT Contract Owner |\n |__________________________________*/\n\n function setRequiredWalletManager(address contractAddress, string calldata walletManager) external;\n function setRequiredBasketManager(address contractAddress, string calldata basketManager) external;\n function setAssetTokenRestrictions(address contractAddress, bool restrictionsEnabled) external;\n function setAllowedAssetToken(address contractAddress, address assetToken, bool isAllowed) external;\n function setAssetTokenLimits(address contractAddress, address assetToken, uint256 depositMin, uint256 depositMax) external;\n function setMaxNfts(address contractAddress, address nftTokenAddress, uint256 maxNfts) external;\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAssetInvalidity(address assetToken, bool invalidity) external;\n function enableNftContracts(address[] calldata contracts) external;\n function setPermsForCharge(address contractAddress, bool state) external;\n function setPermsForBasket(address contractAddress, bool state) external;\n function setPermsForTimelockAny(address contractAddress, bool state) external;\n function setPermsForTimelockSelf(address contractAddress, bool state) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositCapSet(address assetToken, uint256 depositCap);\n event TempLockExpirySet(uint256 expiryBlocks);\n\n event RequiredWalletManagerSet(address indexed contractAddress, string walletManager);\n event RequiredBasketManagerSet(address indexed contractAddress, string basketManager);\n event AssetTokenRestrictionsSet(address indexed contractAddress, bool restrictionsEnabled);\n event AllowedAssetTokenSet(address indexed contractAddress, address assetToken, bool isAllowed);\n event AssetTokenLimitsSet(address indexed contractAddress, address assetToken, uint256 assetDepositMin, uint256 assetDepositMax);\n event MaxNftsSet(address indexed contractAddress, address indexed nftTokenAddress, uint256 maxNfts);\n event AssetInvaliditySet(address indexed assetToken, bool invalidity);\n\n event TokenCreatorConfigsSet(address indexed contractAddress, uint256 indexed tokenId, address indexed creatorAddress, uint256 annuityPercent);\n event TokenCreatorAnnuitiesRedirected(address indexed contractAddress, uint256 indexed tokenId, address indexed redirectAddress);\n\n event PermsSetForCharge(address indexed contractAddress, bool state);\n event PermsSetForBasket(address indexed contractAddress, bool state);\n event PermsSetForTimelockAny(address indexed contractAddress, bool state);\n event PermsSetForTimelockSelf(address indexed contractAddress, bool state);\n}\n" + }, + "contracts/v1/interfaces/IChargedState.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IChargedSettings.sol\";\n\n/**\n * @notice Interface for Charged State\n */\ninterface IChargedState {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n\n function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n\n function isEnergizeRestricted(address contractAddress, uint256 tokenId) external view returns (bool);\n function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external view returns (bool);\n\n function getDischargeState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n function getReleaseState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n function getBreakBondState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n\n /***********************************|\n | Only NFT Owner/Operator |\n |__________________________________*/\n\n function setDischargeApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setReleaseApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setBreakBondApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setTimelockApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setApprovalForAll(address contractAddress, uint256 tokenId, address operator) external;\n\n function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) external;\n\n function setDischargeTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n function setReleaseTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n function setBreakBondTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n /***********************************|\n | Only NFT Contract |\n |__________________________________*/\n\n function setTemporaryLock(\n address contractAddress,\n uint256 tokenId,\n bool isLocked\n ) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n\n event DischargeApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event ReleaseApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event BreakBondApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event TimelockApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n\n event TokenDischargeTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenReleaseTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenBreakBondTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenTempLock(address indexed contractAddress, uint256 indexed tokenId, uint256 unlockBlock);\n\n event PermsSetForRestrictCharge(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowDischarge(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowRelease(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForRestrictBond(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowBreakBond(address indexed contractAddress, uint256 indexed tokenId, bool state);\n}\n" + }, + "contracts/v1/interfaces/IDai.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\ninterface IDai is IERC20Upgradeable {\n // --- Approve by signature ---\n function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external;\n function transferFrom(address src, address dst, uint wad) external override returns (bool);\n}" + }, + "contracts/v1/interfaces/IERC20Detailed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Detailed {\n function decimals() external view returns (uint8);\n function symbol() external view returns (string memory);\n function name() external view returns (string memory);\n\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(address sender, address recipient, uint256 amount) 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" + }, + "contracts/v1/interfaces/IERC721Chargeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IERC721Chargeable.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\n\ninterface IERC721Chargeable is IERC165Upgradeable {\n function owner() external view returns (address);\n function creatorOf(uint256 tokenId) external view returns (address);\n function balanceOf(address tokenOwner) external view returns (uint256 balance);\n function ownerOf(uint256 tokenId) external view returns (address tokenOwner);\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n function transferFrom(address from, address to, uint256 tokenId) external;\n function approve(address to, uint256 tokenId) external;\n function getApproved(uint256 tokenId) external view returns (address operator);\n function setApprovalForAll(address operator, bool _approved) external;\n function isApprovedForAll(address tokenOwner, address operator) external view returns (bool);\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "contracts/v1/interfaces/ILepton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ILepton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Lepton Interface\n * @dev ...\n */\ninterface ILepton {\n\n struct Classification {\n string tokenUri;\n uint256 price;\n uint128 _upperBounds;\n uint32 supply;\n uint32 multiplier;\n uint32 bonus;\n }\n\n function mintLepton() external payable returns (uint256 newTokenId);\n function batchMintLepton(uint256 count) external payable;\n function getNextType() external view returns (uint256);\n function getNextPrice() external view returns (uint256);\n function getMultiplier(uint256 tokenId) external view returns (uint256);\n function getBonus(uint256 tokenId) external view returns (uint256);\n\n\n event MaxMintPerTxSet(uint256 maxAmount);\n event LeptonTypeAdded(string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\n event LeptonTypeUpdated(uint256 leptonIndex, string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\n event LeptonMinted(address indexed receiver, uint256 indexed tokenId, uint256 price, uint32 multiplier);\n event LeptonBatchMinted(address indexed receiver, uint256 indexed tokenId, uint256 count, uint256 price, uint32 multiplier);\n event PausedStateSet(bool isPaused);\n}\n" + }, + "contracts/v1/interfaces/IMerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.6.0;\n\n// Allows anyone to claim a token if they exist in a merkle root.\ninterface IMerkleDistributor {\n // Returns the address of the token distributed by this contract.\n function token() external view returns (address);\n // Returns the merkle root of the merkle tree containing account balances available to claim.\n function merkleRoot() external view returns (bytes32);\n // Returns true if the index has been marked claimed.\n function isClaimed(uint256 index) external view returns (bool);\n // Claim the given amount of the token to the given address. Reverts if the inputs are invalid.\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external;\n\n // This event is triggered whenever a call to #claim succeeds.\n event Claimed(uint256 index, address account, uint256 amount);\n}" + }, + "contracts/v1/interfaces/IParticleSplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IParticleSplitter.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Particle Splitter\n */\ninterface IParticleSplitter {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function executeForWallet(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address externalAddress,\n bytes memory encodedParams\n ) external payable returns (bytes memory);\n\n function executeForBasket(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address externalAddress,\n bytes memory encodedParams\n ) external payable returns (bytes memory);\n\n function withdrawWalletRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n ) external returns (uint256 amountWithdrawn);\n\n function withdrawBasketRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n ) external returns (uint256 amountWithdrawn);\n\n function refreshWalletPrincipal(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external;\n\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event ChargedManagersSet(address indexed chargedManagers);\n event TokenInfoProxySet(address indexed tokenInfoProxy);\n\n event ExecuteForWallet(\n address indexed contractAddress,\n uint256 tokenId,\n string walletManagerId,\n address indexed externalAddress,\n bytes encodedParams,\n uint256 ethValue\n );\n event ExecuteForBasket(\n address indexed contractAddress,\n uint256 tokenId,\n string basketManagerId,\n address indexed externalAddress,\n bytes encodedParams,\n uint256 ethValue\n );\n event PrincipalRefreshed(\n address contractAddress,\n uint256 tokenId,\n string walletManagerId,\n address assetToken\n );\n event PermsSetForExternal(\n address indexed contractAddress,\n bool state\n );\n}\n" + }, + "contracts/v1/interfaces/IProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IProton is IERC721 {\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n event PausedStateSet(bool isPaused);\n event SalePriceSet(uint256 indexed tokenId, uint256 salePrice);\n event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct);\n event FeesWithdrawn(address indexed receiver, uint256 amount);\n event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties);\n event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view returns (address);\n function getSalePrice(uint256 tokenId) external view returns (uint256);\n function getLastSellPrice(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyalties(address account) external view returns (uint256);\n function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address);\n\n function buyProton(uint256 tokenId) external payable returns (bool);\n function claimCreatorRoyalties() external returns (uint256);\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n ) external returns (uint256 newTokenId);\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n ) external returns (uint256 newTokenId);\n\n function batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n ) external;\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice) external;\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external;\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external;\n}" + }, + "contracts/v1/interfaces/IProtonB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IProtonB is IERC721 {\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n ) external returns (uint256 newTokenId);\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n}" + }, + "contracts/v1/interfaces/IRewardNft.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IRewardNft.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Reward-NFT Interface\n * @dev ...\n */\ninterface IRewardNft {\n function getMultiplier(uint256 tokenId) external view returns (uint256);\n function getBonus(uint256 tokenId) external view returns (uint256);\n}\n" + }, + "contracts/v1/interfaces/IRewardProgram.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IRewardProgram.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\ninterface IRewardProgram {\n /* admin events */\n event RewardProgramFunded(uint256 amount);\n event RewardProgramOutOfFunds();\n\n /* user events */\n event RewardsClaimed(address indexed contractAddress, uint256 tokenId, address indexed receiver, uint256 rewarded, uint256 remaining);\n\n event AssetRegistered(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\n event AssetDeposit(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\n event AssetRelease(address indexed contractAddress, uint256 tokenId, uint256 interestAmount);\n\n /* data types */\n struct ProgramRewardData {\n address stakingToken;\n address rewardToken;\n uint256 baseMultiplier; // Basis Points\n }\n\n struct AssetStake {\n uint256 start;\n uint256 claimableRewards;\n string walletManagerId;\n }\n\n function initialize(address stakingToken, address rewardToken, uint256 baseMultiplier, address chargedManagers, address universe, address owner) external;\n\n /* user functions */\n function getProgramData() external view returns (ProgramRewardData memory programData);\n function getAssetStake(uint256 uuid) external view returns (AssetStake memory);\n function getFundBalance() external view returns (uint256);\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) external view returns (uint256);\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external;\n function registerAssetDeposit(address contractAddress, uint256 tokenId, string calldata walletManagerId, uint256 principalAmount) external;\n function registerAssetRelease(address contractAddress, uint256 tokenId, uint256 interestAmount) external returns (uint256 rewards);\n}" + }, + "contracts/v1/interfaces/ISmartBasket.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartBasket.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Basket\n * @dev Manages holding and transferring NFTs within an NFT (if any),\n */\ninterface ISmartBasket {\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function addToBasket(address contractAddress, uint256 tokenId) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId) external returns (bool);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartBasketB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartBasketB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Basket \"B\"\n * @dev Manages holding and transferring NFTs within an NFT (if any),\n */\ninterface ISmartBasketB {\n function getNestedNftCount() external view returns (uint256);\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool);\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Wallet\n * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any),\n */\ninterface ISmartWallet {\n function getAssetTokenCount() external view returns (uint256);\n function getAssetTokenByIndex(uint256 index) external view returns (address);\n\n function setNftCreator(address creator, uint256 annuityPct) external;\n\n function isReserveActive(address assetToken) external view returns (bool);\n function getReserveInterestToken(address assetToken) external view returns (address);\n\n function getPrincipal(address assetToken) external returns (uint256);\n function getInterest(address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getTotal(address assetToken) external returns (uint256);\n function getRewards(address assetToken) external returns (uint256);\n\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(address receiver, address creatorRedirect, address assetToken) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function withdrawAmount(address receiver, address creatorRedirect, address assetToken, uint256 assetAmount) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function withdrawAmountForCreator(address receiver, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address assetToken) external;\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Wallet\n * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any),\n */\ninterface ISmartWalletB {\n function getAssetTokenCount() external view returns (uint256);\n function getAssetTokenByIndex(uint256 index) external view returns (address);\n\n function isReserveActive(address assetToken) external view returns (bool);\n function getReserveInterestToken(address assetToken) external view returns (address);\n\n function getPrincipal(address assetToken) external returns (uint256);\n function getInterest(address assetToken, uint256 creatorPct) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getTotal(address assetToken) external returns (uint256);\n function getRewards(address assetToken) external returns (uint256);\n\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken\n ) external returns (\n uint256 creatorAmount,\n uint256 receiverAmount\n );\n function withdrawAmount(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n ) external returns (\n uint256 creatorAmount,\n uint256 receiverAmount\n );\n function withdrawAmountForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n ) external returns (\n uint256 receiverAmount\n );\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address assetToken) external;\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/IStaking.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\ninterface IStaking {\n function manualEpochInit(address[] memory tokens, uint128 epochId) external;\n function getCurrentEpoch() external view returns (uint128);\n function getEpochId(uint timestamp) external view returns (uint); // get epoch id\n function getEpochUserBalance(address user, address token, uint128 epoch) external view returns(uint);\n function getEpochPoolSize(address token, uint128 epoch) external view returns (uint);\n function epoch1Start() external view returns (uint);\n function epochDuration() external view returns (uint);\n}" + }, + "contracts/v1/interfaces/ITokenInfoProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfoProxy.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\n\ninterface ITokenInfoProxy {\n\n event ContractFunctionSignatureSet(address indexed contractAddress, string fnName, bytes4 fnSig);\n\n struct FnSignatures {\n bytes4 ownerOf;\n bytes4 creatorOf;\n }\n\n function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external;\n function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external;\n\n function getTokenUUID(address contractAddress, uint256 tokenId) external pure returns (uint256);\n function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external returns (bool);\n function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external returns (bool);\n function getTokenOwner(address contractAddress, uint256 tokenId) external returns (address);\n function getTokenCreator(address contractAddress, uint256 tokenId) external returns (address);\n}\n" + }, + "contracts/v1/interfaces/IUniverse.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IUniverse.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Universal Controller interface\n * @dev ...\n */\ninterface IUniverse {\n\n event ChargedParticlesSet(address indexed chargedParticles);\n event PhotonSet(address indexed photonToken, uint256 maxSupply);\n event ProtonTokenSet(address indexed protonToken);\n event LeptonTokenSet(address indexed leptonToken);\n event QuarkTokenSet(address indexed quarkToken);\n event BosonTokenSet(address indexed bosonToken);\n event EsaMultiplierSet(address indexed assetToken, uint256 multiplier);\n event ElectrostaticAttraction(address indexed account, address photonSource, uint256 energy, uint256 multiplier);\n event ElectrostaticDischarge(address indexed account, address photonSource, uint256 energy);\n\n function onEnergize(\n address sender,\n address referrer,\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 assetEnergy\n ) external;\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n ) external;\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address creator,\n address assetToken,\n uint256 receiverEnergy\n ) external;\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 principalEnergy,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n ) external;\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n ) external;\n}\n" + }, + "contracts/v1/interfaces/IUniverseRP.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IUniverseRP.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport \"./IUniverse.sol\";\n\n/**\n * @title Universal Controller interface for Rewards Program\n * @dev ...\n */\ninterface IUniverseRP is IUniverse {\n event RewardProgramSet(address indexed assetToken, address indexed rewardProgram);\n event RewardProgramRemoved(address indexed assetToken);\n event NftDeposit(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\n event NftRelease(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\n\n struct NftStake {\n uint256 multiplier; // in Basis Points\n uint256 depositBlockNumber;\n uint256 releaseBlockNumber;\n }\n\n function getRewardProgram(address asset) external view returns (address);\n function getNftStake(uint256 uuid) external view returns (NftStake memory);\n}\n" + }, + "contracts/v1/interfaces/IWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Particle Wallet Manager interface\n * @dev The wallet-manager for underlying assets attached to Charged Particles\n * @dev Manages the link between NFTs and their respective Smart-Wallets\n */\ninterface IWalletManager {\n\n event ControllerSet(address indexed controller);\n event ExecutorSet(address indexed executor);\n event PausedStateSet(bool isPaused);\n event NewSmartWallet(address indexed contractAddress, uint256 indexed tokenId, address indexed smartWallet, address creator, uint256 annuityPct);\n event WalletEnergized(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 assetAmount, uint256 yieldTokensAmount);\n event WalletDischarged(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 creatorAmount, uint256 receiverAmount);\n event WalletDischargedForCreator(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, address creator, uint256 receiverAmount);\n event WalletReleased(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address assetToken, uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n event WalletRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\n\n function isPaused() external view returns (bool);\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view returns (bool);\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view returns (address);\n\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\n function getInterest(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken) external returns (uint256);\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount) external returns (uint256 yieldTokensAmount);\n function discharge(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function dischargeAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function dischargeAmountForCreator(address receiver, address contractAddress, uint256 tokenId, address creator, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\n function release(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n function releaseAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken) external;\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct) external returns (address);\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\n}\n" + }, + "contracts/v1/leptons/store.sol": { + "content": "pragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../tokens/Ionx.sol\";\nimport \"../tokens/Lepton2.sol\";\n\ninterface ILepsonsStore {\n function getLeptonBalance() external view returns (uint256);\n function getIonxBalance() external view returns (uint256);\n function buyWithIonx(uint256 leptonAmount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n function load(uint256 amount) external payable;\n function setNextTokenId(uint256 tokenId) external;\n function setLepton(address _lepton) external;\n function setIonx(address _ionx) external;\n function setIonxPerLepton(uint256 ionxAmount) external;\n}\n\ncontract LeptonsStore is ILepsonsStore, IERC721Receiver, Ownable, BlackholePrevention {\n using SafeMath for uint256;\n\n event SoldLepton(address indexed buyer, uint256 amount, uint256 price);\n\n Lepton2 public lepton;\n Ionx public ionx;\n\n uint256 public nextTokenId;\n uint256 public ionxPerLepton;\n\n constructor(address _lepton, address _ionx, uint256 _ionxPerLepton) public {\n lepton = Lepton2(_lepton);\n ionx = Ionx(_ionx);\n ionxPerLepton = _ionxPerLepton;\n }\n\n function getLeptonBalance() external view override returns (uint256) {\n return lepton.balanceOf(address(this));\n }\n\n function getIonxBalance() external view override returns (uint256) {\n return ionx.balanceOf(address(this));\n }\n\n function buyWithIonx(\n uint256 leptonAmount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external override {\n uint256 ionxAmount = leptonAmount * ionxPerLepton;\n require(ionx.balanceOf(msg.sender) >= ionxAmount, \"Insufficient IONX balance\");\n require(lepton.balanceOf(address(this)) >= leptonAmount, \"Insufficient Lepton balance\");\n\n ionx.permit(msg.sender, address(this), ionxAmount, deadline, v, r, s);\n ionx.transferFrom(msg.sender, address(this), ionxAmount);\n\n for (uint256 i = 0; i < leptonAmount; ++i) {\n uint256 tokenId = nextTokenId;\n nextTokenId = nextTokenId.add(1);\n\n lepton.safeTransferFrom(address(this), msg.sender, tokenId);\n }\n\n emit SoldLepton(msg.sender, leptonAmount, ionxAmount);\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function load(uint256 amount) external payable override onlyOwner {\n lepton.batchMintLepton{ value: msg.value }(amount);\n }\n\n function setNextTokenId(uint256 tokenId) external override onlyOwner {\n nextTokenId = (tokenId == 0) ? lepton.totalSupply().add(1) : tokenId;\n }\n\n function setLepton(address _lepton) external override onlyOwner {\n require(_lepton != address(0), \"Invalid address\");\n lepton = Lepton2(_lepton);\n }\n\n function setIonx(address _ionx) external override onlyOwner {\n require(_ionx != address(0), \"Invalid address\");\n ionx = Ionx(_ionx);\n }\n\n function setIonxPerLepton(uint256 ionxAmount) external override onlyOwner {\n ionxPerLepton = ionxAmount;\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n}" + }, + "contracts/v1/lib/BaseProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IBaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n/// @title Base Proton Contract for Charged Particles compatible ERC721 NFTs\n/// @dev MUST NOT be Upgradeable, as Upgradeable NFTs are incompatible with Charged Particles.\ncontract BaseProton is \n IBaseProton, \n ERC721, \n Ownable, \n RelayRecipient, \n ReentrancyGuard, \n BlackholePrevention \n{\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n event Received(address, uint);\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n /// @dev Sequential Token IDs storage\n Counters.Counter internal _tokenIds;\n\n /// @dev NFT Token Creator settings\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct;\n mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect;\n mapping (address => uint256) internal _tokenCreatorClaimableRoyalties;\n\n /// @dev NFT Token Sale settings\n mapping (uint256 => uint256) internal _tokenSalePrice;\n mapping (uint256 => uint256) internal _tokenLastSellPrice;\n\n /// @dev Whether of not the Contract is Paused\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n /// @dev Inherit from ERC721 standard\n constructor(string memory _name, string memory _symbol) public ERC721(_name, _symbol) {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n receive() external payable virtual {\n emit Received(msg.sender, msg.value);\n }\n\n /// Returns the Creator address of an NFT by Token ID\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The address of the Creator account\n function creatorOf(uint256 tokenId) external view virtual override returns (address) {\n return _tokenCreator[tokenId];\n }\n\n /// Returns the Sale Price of an NFT by Token ID\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The sale price of the NFT\n function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenSalePrice[tokenId];\n }\n\n /// Returns the Last Sale Price of an NFT by Token ID\n /// @notice This is used to determine any increase in sale price used in royalties calculations\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The last sale price of the NFT\n function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenLastSellPrice[tokenId];\n }\n\n /// Returns the Claimable Royalties for the NFT Creator\n /// @param account The address of the Creator account to lookup\n /// @return The amount of earned royalties for the creator account\n function getCreatorRoyalties(address account) external view virtual override returns (uint256) {\n return _tokenCreatorClaimableRoyalties[account];\n }\n\n /// Returns the Percentage of Royalties reserved for the NFT Creator\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The percentage of royalties reserved for the creator\n function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenCreatorRoyaltiesPct[tokenId];\n }\n\n /// Returns the Receiving address of the Creator Royalties (or Creator if not set)\n /// @dev Returns the creator address if a receiving address has not been configured\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The Receiving address of the Creator Royalties\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) {\n return _creatorRoyaltiesReceiver(tokenId);\n }\n\n /// Allows an NFT Creator to Claim any Royalties that have been earned from NFT sales\n /// @dev Must be called by the royalties receiver account (not neccessarily the creator)\n /// @return The amout of creator royalties claimed\n function claimCreatorRoyalties()\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256)\n {\n return _claimCreatorRoyalties(_msgSender());\n }\n\n\n /***********************************|\n | Create Single Protons |\n |__________________________________*/\n\n /// Creates a Basic NFT with no Royalties and no initial Sale Price\n /// @dev Royalties and Sale Price can be configured later\n /// @param creator The address of the NFT Creator (can be different from the caller)\n /// @param receiver The receiving address of the NFT (can be different from the caller)\n /// @param tokenMetaUri The unique metadata URI for the NFT\n /// @return newTokenId The newly minted NFT Token ID\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n\n /***********************************|\n | Create Multiple Protons |\n |__________________________________*/\n\n function createProtons(\n address creator,\n address receiver,\n string[] calldata tokenMetaUris\n )\n external\n virtual\n override\n whenNotPaused\n returns (bool)\n {\n _createProtons(\n creator,\n receiver,\n 0, // royaltiesPercent\n tokenMetaUris\n );\n return true;\n }\n\n function createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n external\n virtual\n override\n whenNotPaused\n returns (bool)\n {\n _createProtonsForSale(\n creator,\n receiver,\n royaltiesPercent,\n tokenMetaUris,\n salePrices\n );\n return true;\n }\n\n\n /***********************************|\n | Buy Protons |\n |__________________________________*/\n\n function buyProton(uint256 tokenId, uint256 gasLimit)\n external\n payable\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (bool)\n {\n _buyProton(tokenId, gasLimit);\n return true;\n }\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice)\n external\n virtual\n override\n whenNotPaused\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setSalePrice(tokenId, salePrice);\n }\n\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setRoyaltiesPct(tokenId, royaltiesPct);\n }\n\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n {\n _tokenCreatorRoyaltiesRedirect[tokenId] = receiver;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual {\n _tokenSalePrice[tokenId] = salePrice;\n emit SalePriceSet(tokenId, salePrice);\n }\n\n function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual {\n require(royaltiesPct <= PERCENTAGE_SCALE, \"PRT:E-421\");\n _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct;\n emit CreatorRoyaltiesSet(tokenId, royaltiesPct);\n }\n\n function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) {\n address receiver = _tokenCreatorRoyaltiesRedirect[tokenId];\n if (receiver == address(0x0)) {\n receiver = _tokenCreator[tokenId];\n }\n return receiver;\n }\n\n function _createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n _tokenIds.increment();\n\n newTokenId = _tokenIds.current();\n _safeMint(receiver, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUri);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n }\n\n function _createProtons(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris\n )\n internal\n virtual\n {\n uint256 count = tokenMetaUris.length;\n for (uint256 i; i < count; i++) {\n _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, 0);\n }\n }\n\n function _createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n internal\n virtual\n {\n require(tokenMetaUris.length == salePrices.length, \"PRT:E-202\");\n\n uint256 count = tokenMetaUris.length;\n for (uint256 i; i < count; i++) {\n _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, salePrices[i]);\n }\n }\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n contractAddress = address(this);\n tokenId = _tokenId;\n salePrice = _tokenSalePrice[_tokenId];\n require(salePrice > 0, \"PRT:E-416\");\n require(msg.value >= salePrice, \"PRT:E-414\");\n\n uint256 ownerAmount = salePrice;\n creatorAmount;\n oldOwner = ownerOf(_tokenId);\n newOwner = _msgSender();\n\n // Creator Royalties\n royaltiesReceiver = _creatorRoyaltiesReceiver(_tokenId);\n uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[_tokenId];\n uint256 lastSellPrice = _tokenLastSellPrice[_tokenId];\n if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) {\n creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE);\n ownerAmount = ownerAmount.sub(creatorAmount);\n }\n _tokenLastSellPrice[_tokenId] = salePrice;\n\n // Reserve Royalties for Creator\n if (creatorAmount > 0) {\n _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount);\n }\n\n // Transfer Token\n _transfer(oldOwner, newOwner, _tokenId);\n\n // Transfer Payment\n if (ownerAmount > 0) {\n payable(oldOwner).sendValue(ownerAmount, _gasLimit);\n }\n\n emit ProtonSold(_tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n\n _refundOverpayment(salePrice, _gasLimit);\n }\n\n /**\n * @dev Pays out the Creator Royalties of the calling account\n * @param receiver The receiver of the claimable royalties\n * @return The amount of Creator Royalties claimed\n */\n function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) {\n uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver];\n require(claimableAmount > 0, \"PRT:E-411\");\n\n delete _tokenCreatorClaimableRoyalties[receiver];\n payable(receiver).sendValue(claimableAmount, 0);\n\n emit RoyaltiesClaimed(receiver, claimableAmount);\n }\n\n /**\n * @dev Collects the Required Asset Token from the users wallet\n * @param from The owner address to collect the Assets from\n * @param assetAmount The Amount of Asset Tokens to Collect\n */\n function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual {\n uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from);\n require(assetAmount <= _userAssetBalance, \"PRT:E-411\");\n // Be sure to Approve this Contract to transfer your Asset Token\n require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), \"PRT:E-401\");\n }\n\n function _refundOverpayment(uint256 threshold, uint256 gasLimit) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage, gasLimit);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n _tokenSalePrice[tokenId] = 0;\n super._transfer(from, to, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"PRT:E-101\");\n _;\n }\n\n modifier onlyTokenOwnerOrApproved(uint256 tokenId) {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"PRT:E-105\");\n _;\n }\n\n modifier onlyTokenCreator(uint256 tokenId) {\n require(_tokenCreator[tokenId] == _msgSender(), \"PRT:E-104\");\n _;\n }\n}" + }, + "contracts/v1/lib/Bitwise.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Bitwise.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nlibrary Bitwise {\n function negate(uint32 a) internal pure returns (uint32) {\n return a ^ maxInt();\n }\n\n function shiftLeft(uint32 a, uint32 n) internal pure returns (uint32) {\n return a * uint32(2) ** n;\n }\n\n function shiftRight(uint32 a, uint32 n) internal pure returns (uint32) {\n return a / uint32(2) ** n;\n }\n\n function maxInt() internal pure returns (uint32) {\n return uint32(-1);\n }\n\n // Get bit value at position\n function hasBit(uint32 a, uint32 n) internal pure returns (bool) {\n return a & shiftLeft(0x01, n) != 0;\n }\n\n // Set bit value at position\n function setBit(uint32 a, uint32 n) internal pure returns (uint32) {\n return a | shiftLeft(0x01, n);\n }\n\n // Set the bit into state \"false\"\n function clearBit(uint32 a, uint32 n) internal pure returns (uint32) {\n uint32 mask = negate(shiftLeft(0x01, n));\n return a & mask;\n }\n}\n" + }, + "contracts/v1/lib/BlackholePrevention.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\n\n/**\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\n * the Owner/DAO to pull them out on behalf of a user\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\n */\ncontract BlackholePrevention {\n using Address for address payable;\n using SafeERC20 for IERC20;\n\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\n\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (address(this).balance >= amount) {\n receiver.sendValue(amount);\n emit WithdrawStuckEther(receiver, amount);\n }\n }\n\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\n IERC20(tokenAddress).safeTransfer(receiver, amount);\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\n }\n }\n\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\n }\n }\n\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \"\");\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\n }\n }\n}\n" + }, + "contracts/v1/lib/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/GSN/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableMap.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n /**\n * @dev Emitted when `tokenId` token is transfered from `from` to `to`.\n */\n event TransferBatch(address indexed from, address indexed to, uint256 startTokenId, uint256 count);\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721:E-403\");\n\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721:E-405\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"ERC721:E-405\");\n return _tokenURIs[tokenId];\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721:E-111\");\n\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \"ERC721:E-105\");\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view override returns (address) {\n require(_exists(tokenId), \"ERC721:E-405\");\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 require(operator != _msgSender(), \"ERC721:E-111\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721:E-402\");\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 returns (bool) {\n return _tokenOwners.contains(tokenId);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721:E-405\");\n address owner = ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721:E-402\");\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 _safeMintBatch(address to, uint256 startTokenId, uint256 count, bytes memory _data) internal virtual {\n _mintBatch(to, startTokenId, count);\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \"ERC721:E-402\");\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:E-403\");\n require(!_exists(tokenId), \"ERC721:E-407\");\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\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 _mintBatch(address to, uint256 startTokenId, uint256 count) internal virtual {\n require(to != address(0), \"ERC721:E-403\");\n require(!_exists(startTokenId), \"ERC721:E-407\");\n\n for (uint i = 0; i < count; i++) {\n uint256 tokenId = startTokenId.add(i);\n _holderTokens[to].add(tokenId);\n _tokenOwners.set(tokenId, to);\n }\n\n emit TransferBatch(address(0), to, startTokenId, count);\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(address from, address to, uint256 tokenId) internal virtual {\n require(ownerOf(tokenId) == from, \"ERC721:E-102\");\n require(to != address(0), \"ERC721:E-403\");\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721:E-405\");\n _tokenURIs[tokenId] = _tokenURI;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721:E-402\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\n }\n}\n" + }, + "contracts/v1/lib/ERC721Basic.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/GSN/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Basic is Context, ERC165, IERC721, IERC721Metadata {\n using SafeMath for uint256;\n using Address for address;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 internal constant _ERC721_RECEIVED = 0x150b7a02;\n\n // mapping from token ids to their owners\n mapping (uint256 => address) internal _tokenOwners;\n\n // mapping from owner to token balance\n mapping (address => uint256) internal _ownerBalance;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) internal _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) internal _operatorApprovals;\n\n // Token name\n string internal _name;\n\n // Token symbol\n string internal _symbol;\n\n // Token Count\n uint256 internal _tokenCount;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 internal constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 internal constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721:E-403\");\n return _ownerBalance[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners[tokenId];\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view 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 return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721:E-111\");\n\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \"ERC721:E-105\");\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view override returns (address) {\n require(_exists(tokenId), \"ERC721:E-405\");\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721:E-111\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721:E-402\");\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 returns (bool) {\n return _tokenOwners[tokenId] != address(0x0);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721:E-405\");\n address owner = ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\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(address to, bytes memory _data) internal virtual returns (uint256) {\n uint256 tokenId = _mint(to);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721:E-402\");\n return 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 _safeMintBatch(address to, uint256 count, bytes memory _data) internal virtual {\n uint256 startTokenId = _mintBatch(to, count);\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \"ERC721:E-402\");\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) internal virtual returns (uint256) {\n require(to != address(0), \"ERC721:E-403\");\n\n _tokenCount = _tokenCount.add(1);\n uint256 tokenId = _tokenCount;\n require(!_exists(tokenId), \"ERC721:E-407\");\n\n _tokenOwners[tokenId] = to;\n _ownerBalance[to] = _ownerBalance[to].add(1);\n\n emit Transfer(address(0), to, tokenId);\n return tokenId;\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 _mintBatch(address to, uint256 count) internal virtual returns (uint256) {\n require(to != address(0), \"ERC721:E-403\");\n\n uint256 startTokenId = _tokenCount.add(1);\n for (uint i = 1; i <= count; i++) {\n uint256 tokenId = _tokenCount.add(i);\n _tokenOwners[tokenId] = to;\n emit Transfer(address(0), to, tokenId);\n }\n\n _tokenCount = _tokenCount.add(count);\n _ownerBalance[to] = _ownerBalance[to].add(count);\n return startTokenId;\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(address from, address to, uint256 tokenId) internal virtual {\n require(ownerOf(tokenId) == from, \"ERC721:E-102\");\n require(to != address(0), \"ERC721:E-403\");\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _tokenOwners[tokenId] = to;\n _ownerBalance[from] = _ownerBalance[from].sub(1);\n _ownerBalance[to] = _ownerBalance[to].add(1);\n\n emit Transfer(from, to, tokenId);\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(address from, address to, uint256 tokenId, bytes memory _data)\n internal returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721:E-402\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) internal {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\n }\n}\n" + }, + "contracts/v1/lib/IERC5192.sol": { + "content": "// SPDX-License-Identifier: CC0-1.0\npragma solidity ^0.6.0;\n\ninterface IERC5192 {\n /// @notice Emitted when the locking status is changed to locked.\n /// @dev If a token is minted and the status is locked, this event should be emitted.\n /// @param tokenId The identifier for a token.\n event Locked(uint256 tokenId);\n\n /// @notice Emitted when the locking status is changed to unlocked.\n /// @dev If a token is minted and the status is unlocked, this event should be emitted.\n /// @param tokenId The identifier for a token.\n event Unlocked(uint256 tokenId);\n\n /// @notice Returns the locking status of an Soulbound Token\n /// @dev SBTs assigned to zero address are considered invalid, and queries\n /// about them do throw.\n /// @param tokenId The identifier for an SBT.\n function locked(uint256 tokenId) external view returns (bool);\n}\n" + }, + "contracts/v1/lib/NftTokenType.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// NftTokenType.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/introspection/IERC165.sol\";\n\nlibrary NftTokenType {\n bytes4 constant internal INTERFACE_SIGNATURE_ERC721 = 0x80ac58cd;\n bytes4 constant internal INTERFACE_SIGNATURE_ERC1155 = 0xd9b67a26;\n\n uint256 constant internal TYPE_MASK = uint256(uint128(~0)) << 128;\n uint256 constant internal TYPE_NFT_BIT = 1 << 255;\n\n function isERC721(address contractAddress) internal view returns (bool) {\n return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC721);\n }\n\n function isERC1155(address contractAddress) internal view returns (bool) {\n return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC1155);\n }\n\n function getTokenType(address contractAddress, uint256 tokenId) internal view returns (uint256) {\n IERC165 tokenInterface = IERC165(contractAddress);\n bool is1155 = tokenInterface.supportsInterface(INTERFACE_SIGNATURE_ERC1155);\n\n if (!is1155 || (tokenId & TYPE_NFT_BIT != TYPE_NFT_BIT)) { return 0; }\n\n return tokenId & TYPE_MASK;\n }\n}\n" + }, + "contracts/v1/lib/ReentrancyGuard.sol": { + "content": "pragma solidity 0.6.12;\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 () public {\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 _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\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 /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}" + }, + "contracts/v1/lib/RelayRecipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0;\n\nimport \"@opengsn/gsn/contracts/BaseRelayRecipient.sol\";\n\ncontract RelayRecipient is BaseRelayRecipient {\n function versionRecipient() external override view returns (string memory) {\n return \"1.0.0-beta.1/charged-particles.relay.recipient\";\n }\n}\n" + }, + "contracts/v1/lib/SmartWalletBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// SmartWalletBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../interfaces/ISmartWallet.sol\";\nimport \"./BlackholePrevention.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract SmartWalletBase is ISmartWallet, BlackholePrevention {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n address internal _walletManager;\n\n address internal nftCreator;\n uint256 internal nftCreatorAnnuityPct;\n uint256 internal nftCreatorAmountDischarged;\n\n EnumerableSet.AddressSet internal _assetTokens;\n\n // Asset Token => Principal Balance\n mapping (address => uint256) internal _assetPrincipalBalance;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initializeBase() public {\n require(_walletManager == address(0x0), \"SWB:E-002\");\n _walletManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getAssetTokenCount() external view virtual override returns (uint256) {\n return _assetTokens.length();\n }\n\n function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) {\n if (index >= _assetTokens.length()) {\n return address(0);\n }\n return _assetTokens.at(index);\n }\n\n function setNftCreator(address creator, uint256 annuityPct) external virtual override onlyWalletManager {\n nftCreator = creator;\n nftCreatorAnnuityPct = annuityPct;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyWalletManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n function refreshPrincipal(address assetToken)\n external\n virtual\n override\n onlyWalletManager\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getPrincipal(address assetToken) internal view virtual returns (uint256) {\n return _assetPrincipalBalance[assetToken];\n }\n\n function _trackAssetToken(address assetToken) internal virtual {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n }\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the wallet manager\n modifier onlyWalletManager() {\n require(_walletManager == msg.sender, \"SWB:E-109\");\n _;\n }\n}" + }, + "contracts/v1/lib/SmartWalletBaseB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// SmartWalletBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../interfaces/ISmartWalletB.sol\";\nimport \"./BlackholePrevention.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract SmartWalletBaseB is ISmartWalletB, BlackholePrevention {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n address internal _walletManager;\n\n EnumerableSet.AddressSet internal _assetTokens;\n\n // Asset Token => Principal Balance\n mapping (address => uint256) internal _assetPrincipalBalance;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initializeBase() public {\n require(_walletManager == address(0x0), \"SWB:E-002\");\n _walletManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getAssetTokenCount() external view virtual override returns (uint256) {\n return _assetTokens.length();\n }\n\n function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) {\n if (index >= _assetTokens.length()) {\n return address(0);\n }\n return _assetTokens.at(index);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyWalletManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getPrincipal(address assetToken) internal view virtual returns (uint256) {\n return _assetPrincipalBalance[assetToken];\n }\n\n function _trackAssetToken(address assetToken) internal virtual {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n }\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the wallet manager\n modifier onlyWalletManager() {\n require(_walletManager == msg.sender, \"SWB:E-109\");\n _;\n }\n}" + }, + "contracts/v1/lib/Soul.sol": { + "content": "// SPDX-License-Identifier: CC0-1.0\npragma solidity ^0.6.12;\n\nimport \"./IERC5192.sol\";\n\ncontract Soul is IERC5192 {\n \n mapping (uint256 => bool) public lockedTokens;\n\n function _lockToken(uint256 tokenId) internal {\n lockedTokens[tokenId] = true;\n emit Locked(tokenId);\n }\n\n function _unlockToken(uint256 tokenId) internal {\n lockedTokens[tokenId] = false;\n emit Unlocked(tokenId);\n }\n\n function locked(uint256 tokenId)\n external\n view\n override(IERC5192)\n returns (bool)\n {\n return lockedTokens[tokenId];\n }\n}\n" + }, + "contracts/v1/lib/TokenInfo.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfo.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"../interfaces/IERC721Chargeable.sol\";\n\nlibrary TokenInfo {\n function getTokenUUID(address contractAddress, uint256 tokenId) internal pure virtual returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n function getTokenOwner(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n return tokenInterface.ownerOf(tokenId);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n function getTokenCreator(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n return tokenInterface.creatorOf(tokenId);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Owner of an External NFT contract\n /// @param contractAddress The Address to the Contract of the NFT to check\n /// @param account The Address of the Account to check\n /// @return True if the account owns the contract\n function isContractOwner(address contractAddress, address account) internal view virtual returns (bool) {\n address contractOwner = IERC721Chargeable(contractAddress).owner();\n return contractOwner != address(0x0) && contractOwner == account;\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Creator of a Proton-based NFT\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the Proton-based NFT\n function isTokenCreator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenCreator = tokenInterface.creatorOf(tokenId);\n return (sender == tokenCreator);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the Proton-based NFT or the Contract itself\n function isTokenContractOrCreator(address contractAddress, uint256 tokenId, address creator, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenCreator = tokenInterface.creatorOf(tokenId);\n if (sender == contractAddress && creator == tokenCreator) { return true; }\n return (sender == tokenCreator);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Owner or Operator of an External NFT\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the Owner or Operator of the External NFT\n function isErc721OwnerOrOperator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenOwner = tokenInterface.ownerOf(tokenId);\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\n }\n\n /**\n * @dev Returns true if `account` is a contract.\n * @dev Taken from OpenZeppelin library\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\n // for accounts without code, i.e. `keccak256('')`\n bytes32 codehash;\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n // solhint-disable-next-line no-inline-assembly\n assembly { codehash := extcodehash(account) }\n return (codehash != accountHash && codehash != 0x0);\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 * @dev Taken from OpenZeppelin library\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, uint256 gasLimit) internal {\n require(address(this).balance >= amount, \"TokenInfo: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = (gasLimit > 0)\n ? recipient.call{ value: amount, gas: gasLimit }(\"\")\n : recipient.call{ value: amount }(\"\");\n require(success, \"TokenInfo: unable to send value, recipient may have reverted\");\n }\n}\n" + }, + "contracts/v1/lib/TokenInfoProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfoProxy.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../interfaces/ITokenInfoProxy.sol\";\nimport \"../interfaces/IERC721Chargeable.sol\";\n\n\ncontract TokenInfoProxy is ITokenInfoProxy, Ownable {\n using Address for address;\n\n mapping (address => FnSignatures) internal _remappedFnSigs;\n\n function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner {\n _remappedFnSigs[contractAddress].ownerOf = fnSig;\n emit ContractFunctionSignatureSet(contractAddress, \"ownerOf\", fnSig);\n }\n\n function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner {\n _remappedFnSigs[contractAddress].creatorOf = fnSig;\n emit ContractFunctionSignatureSet(contractAddress, \"creatorOf\", fnSig);\n }\n\n\n function getTokenUUID(address contractAddress, uint256 tokenId) external pure virtual override returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n function getTokenOwner(address contractAddress, uint256 tokenId) external virtual override returns (address) {\n return _getTokenOwner(contractAddress, tokenId);\n }\n\n function getTokenCreator(address contractAddress, uint256 tokenId) external virtual override returns (address) {\n return _getTokenCreator(contractAddress, tokenId);\n }\n\n function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenOwner = _getTokenOwner(contractAddress, tokenId);\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\n }\n\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the NFT or the Contract itself\n function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) {\n address tokenCreator = _getTokenCreator(contractAddress, tokenId);\n return (sender == tokenCreator || sender == contractAddress);\n }\n\n\n\n function _getTokenCreator(address contractAddress, uint256 tokenId) internal returns (address) {\n bytes4 fnSig = IERC721Chargeable.creatorOf.selector;\n if (_remappedFnSigs[contractAddress].creatorOf != bytes4(0)) {\n fnSig = _remappedFnSigs[contractAddress].creatorOf;\n }\n\n // solhint-disable-next-line\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n if (success) {\n return abi.decode(returnData, (address));\n } else {\n return address(0x0);\n }\n }\n\n function _getTokenOwner(address contractAddress, uint256 tokenId) internal returns (address) {\n bytes4 fnSig = IERC721Chargeable.ownerOf.selector;\n if (_remappedFnSigs[contractAddress].ownerOf != bytes4(0)) {\n fnSig = _remappedFnSigs[contractAddress].ownerOf;\n }\n\n // solhint-disable-next-line\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n if (success) {\n return abi.decode(returnData, (address));\n } else {\n return address(0x0);\n }\n }\n}\n" + }, + "contracts/v1/lib/WalletManagerBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// WalletManagerBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IWalletManager.sol\";\nimport \"../interfaces/ISmartWallet.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"./BlackholePrevention.sol\";\n\n\n/**\n * @notice Wallet-Manager Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract WalletManagerBase is Ownable, BlackholePrevention, IWalletManager {\n using TokenInfo for address;\n\n // The Controller Contract Address\n address internal _controller;\n\n // The Executor Contract Address\n address internal _executor;\n\n // Template Contract for creating Token Smart-Wallet Bridges\n address internal _walletTemplate;\n\n // TokenID => Token Smart-Wallet Address\n mapping (uint256 => address) internal _wallets;\n\n // State of Wallet Manager\n bool internal _paused;\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Wallet Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n /**\n * @dev Connects to the ExecForAccount Controller\n */\n function setExecutor(address executor) external onlyOwner {\n _executor = executor;\n emit ExecutorSet(executor);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartWallet(wallet).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartWallet(wallet).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartWallet(wallet).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Executor contract\n modifier onlyExecutor() {\n require(_executor == msg.sender, \"WMB:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Controller or Executor contract\n modifier onlyControllerOrExecutor() {\n require(_executor == msg.sender || _controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"WMB:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/ParticleSplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ParticleSplitter.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"./interfaces/IParticleSplitter.sol\";\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IWalletManager.sol\";\nimport \"./interfaces/IBasketManager.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Contract\n * @dev Upgradeable Contract\n */\ncontract ParticleSplitter is IParticleSplitter, Ownable, ReentrancyGuard, BlackholePrevention\n{\n IChargedManagers internal _chargedManagers;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n mapping (address => bool) internal _externalAddressesAllowed;\n\n\n /***********************************|\n | Execute for Account |\n |__________________________________*/\n\n /// @notice Executes an arbitrary command on an NFT Wallet\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Wallet Manager controlling the NFT Wallet to execute on\n /// @param externalAddress The Address of the External Contract to execute on\n /// @param encodedParams The encoded function call to execute\n function executeForWallet(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address externalAddress,\n bytes memory encodedParams\n )\n external\n payable\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (bytes memory)\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n require(_externalAddressesAllowed[externalAddress], \"PS:E-117\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Wallet Manager\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n // Get Address of Wallet to send any ETH into\n if (msg.value > 0) {\n address wallet = walletMgr.getWalletAddressById(contractAddress, tokenId, address(0), 0);\n payable(wallet).sendValue(msg.value);\n }\n\n emit ExecuteForWallet(contractAddress, tokenId, walletManagerId, externalAddress, encodedParams, msg.value);\n\n // Execute command for NFT Wallet\n return walletMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams);\n }\n\n /// @notice Executes an arbitrary command on an NFT Basket\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param basketManagerId The Basket Manager controlling the NFT Wallet to execute on\n /// @param externalAddress The Address of the External Contract to execute on\n /// @param encodedParams The encoded function call to execute\n function executeForBasket(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address externalAddress,\n bytes memory encodedParams\n )\n external\n payable\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (bytes memory)\n {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"PS:E-419\");\n require(_externalAddressesAllowed[externalAddress], \"PS:E-117\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Basket Manager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n\n // Get Address of Wallet to send any ETH into\n if (msg.value > 0) {\n address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId);\n payable(wallet).sendValue(msg.value);\n }\n\n emit ExecuteForBasket(contractAddress, tokenId, basketManagerId, externalAddress, encodedParams, msg.value);\n\n // Execute command for NFT Wallet\n return basketMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams);\n }\n\n function withdrawWalletRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (uint256 amountWithdrawn)\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Wallet Manager\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n // Withdraw Rewards for NFT Wallet\n return walletMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount);\n }\n\n function withdrawBasketRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (uint256 amountWithdrawn)\n {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"PS:E-419\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Basket Manager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n\n // Withdraw Rewards for NFT Basket\n return basketMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount);\n }\n\n function refreshWalletPrincipal(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n walletMgr.refreshPrincipal(contractAddress, tokenId, assetToken);\n\n emit PrincipalRefreshed(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedManagers Interface\n */\n function setChargedManagers(address chargedManagers) external virtual onlyOwner {\n _chargedManagers = IChargedManagers(chargedManagers);\n emit ChargedManagersSet(chargedManagers);\n }\n\n /**\n * @dev Setup the ChargedManagers Interface\n */\n function setTokenInfoProxy(address tokenInfoProxy) external virtual onlyOwner {\n _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy);\n emit TokenInfoProxySet(tokenInfoProxy);\n }\n\n /**\n * @dev Allows/Disallows execute from on specific contracts\n */\n function setExternalContracts(address[] calldata contracts, bool state) external onlyOwner {\n uint count = contracts.length;\n for (uint i; i < count; i++) {\n address externalContract = contracts[i];\n _externalAddressesAllowed[externalContract] = state;\n emit PermsSetForExternal(externalContract, state);\n }\n }\n\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyTokenOwner(address contractAddress, uint256 tokenId) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(msg.sender == tokenOwner, \"PS:E-102\");\n _;\n }\n}\n" + }, + "contracts/v1/test/Dai.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"../interfaces/IDai.sol\";\n\ncontract Dai is IDai {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (uint256 chainId_) public {\n string memory version = \"1\";\n\n _name = \"Dai Stablecoin\";\n _symbol = \"DAI\";\n _decimals = 18;\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(_name)),\n keccak256(bytes(version)),\n chainId_,\n address(this)\n )\n );\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view 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(msg.sender, 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(msg.sender, 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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(msg.sender, spender, _allowances[msg.sender][spender].add(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 _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20:E-403\");\n require(recipient != address(0), \"ERC20:E-403\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20:E-403\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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:E-403\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20:E-403\");\n require(spender != address(0), \"ERC20:E-403\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n\n mapping (address => uint) public nonces;\n\n // --- EIP712 niceties ---\n bytes32 public DOMAIN_SEPARATOR;\n // bytes32 public constant PERMIT_TYPEHASH = keccak256(\"Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)\");\n bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;\n\n // --- Approve by signature ---\n function permit(\n address holder, address spender, uint256 nonce, uint256 expiry,\n bool allowed, uint8 v, bytes32 r, bytes32 s) external override\n {\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n holder,\n spender,\n nonce,\n expiry,\n allowed\n )\n )\n )\n );\n\n require(holder != address(0), \"Dai/invalid-address-0\");\n require(holder == ecrecover(digest, v, r, s), \"Dai/invalid-permit\");\n require(expiry == 0 || now <= expiry, \"Dai/permit-expired\");\n require(nonce == nonces[holder]++, \"Dai/invalid-nonce\");\n uint wad = allowed ? uint(-1) : 0;\n _allowances[holder][spender] = wad;\n emit Approval(holder, spender, wad);\n }\n\n function mint(address to, uint256 amount) external {\n _mint(to, amount);\n }\n}" + }, + "contracts/v1/test/ERC20Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.7.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/**\n * @dev Extension of {ERC20} that adds a set of accounts with the {MinterRole},\n * which have permission to mint (create) new tokens as they see fit.\n *\n * At construction, the deployer of the contract is the only minter.\n */\ncontract ERC20Mintable is ERC20Upgradeable {\n\n constructor(string memory _name, string memory _symbol) public {\n __ERC20_init(_name, _symbol);\n }\n\n /**\n * @dev See {ERC20-_mint}.\n *\n * Requirements:\n *\n * - the caller must have the {MinterRole}.\n */\n function mint(address account, uint256 amount) public returns (bool) {\n _mint(account, amount);\n return true;\n }\n\n function burn(address account, uint256 amount) public returns (bool) {\n _burn(account, amount);\n return true;\n }\n}" + }, + "contracts/v1/test/ERC721Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.7.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\n\n/**\n * @dev Extension of {ERC721} for Minting/Burning\n */\ncontract ERC721Mintable is ERC721Upgradeable {\n\n constructor () public {\n __ERC721_init(\"ERC 721\", \"NFT\");\n }\n\n /**\n * @dev See {ERC721-_mint}.\n */\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n\n /**\n * @dev See {ERC721-_burn}.\n */\n function burn(uint256 tokenId) public {\n _burn(tokenId);\n }\n}\n" + }, + "contracts/v1/tokens/ExternalERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ExternalERC721.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\n\ncontract ExternalERC721 is ERC721 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n\n constructor() public ERC721(\"Charged Particles - ExternalERC721\", \"ExNFT\") {}\n\n function mintNft(address receiver, string memory tokenUri) external returns (uint256 newTokenId) {\n return _mintNft(receiver, tokenUri);\n }\n\n function _mintNft(address receiver, string memory tokenUri) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n\n _safeMint(receiver, newTokenId, \"\");\n\n _setTokenURI(newTokenId, tokenUri);\n }\n}\n" + }, + "contracts/v1/tokens/FungibleERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// FungibleERC1155.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract FungibleERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n\n constructor() public ERC1155(\"https://staging.app.charged.fi/erc1155/metadata.json\") {}\n\n function mintNft(address receiver, uint256 amount) external returns (uint256 newTokenId) {\n return _mintNft(receiver, amount);\n }\n\n function _mintNft(address receiver, uint256 amount) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n _mint(receiver, newTokenId, amount, \"\");\n }\n}\n" + }, + "contracts/v1/tokens/Ionx.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Ionx.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"erc20permit/contracts/ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\n\ncontract Ionx is ERC20Permit, Ownable, BlackholePrevention {\n using SafeMath for uint256;\n\n /// @notice An event thats emitted when the minter address is changed\n event MinterChanged(address minter, address newMinter);\n\n /// @notice Total number of tokens in circulation\n uint256 constant public INITIAL_SUPPLY = 1e8 ether;\n\n /// @notice Minimum time between mints\n uint32 public constant INFLATION_EPOCH = 1 days * 365;\n\n /// @notice Cap on the percentage of totalSupply that can be minted at each mint\n uint8 public constant INFLATION_CAP = 2;\n\n /// @notice Address which may mint new tokens\n address public minter;\n\n /// @notice The timestamp after which minting may occur\n uint256 public mintingAllowedAfter;\n\n\n constructor() public ERC20Permit(\"Charged Particles - IONX\", \"IONX\") {}\n\n\n /**\n * @notice Change the minter address\n * @param newMinter The address of the new minter\n */\n function setMinter(address newMinter) external onlyOwner {\n emit MinterChanged(minter, newMinter);\n minter = newMinter;\n }\n\n /**\n * @notice Mint new tokens\n * @param receiver The address of the destination account\n * @param amount The number of tokens to be minted\n */\n function mint(address receiver, uint256 amount) external onlyMinter {\n require(block.timestamp >= mintingAllowedAfter, \"Ionx:E-114\");\n require(receiver != address(0), \"Ionx:E-403\");\n\n uint256 amountToMint = amount;\n uint256 _totalSupply = totalSupply();\n\n // From Inflationary Supply\n if (_totalSupply >= INITIAL_SUPPLY) {\n mintingAllowedAfter = mintingAllowedAfter.add(INFLATION_EPOCH);\n amountToMint = _totalSupply.mul(INFLATION_CAP).div(100);\n }\n\n // From Initial Supply\n else {\n if (_totalSupply.add(amountToMint) > INITIAL_SUPPLY) {\n amountToMint = INITIAL_SUPPLY.sub(_totalSupply);\n }\n if (_totalSupply.add(amountToMint) == INITIAL_SUPPLY) {\n mintingAllowedAfter = block.timestamp.add(INFLATION_EPOCH);\n }\n }\n\n // transfer the amount to the recipient\n _mint(receiver, amountToMint);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n modifier onlyMinter() {\n require(msg.sender == minter, \"Ionx:E-113\");\n _;\n }\n}\n" + }, + "contracts/v1/tokens/Lepton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Lepton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/ILepton.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\n\ncontract Lepton is ILepton, ERC721, Ownable, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenIds;\n Classification[] internal _leptonTypes;\n mapping (uint256 => Classification) internal _leptonData;\n\n uint256 internal _typeIndex;\n uint256 internal _maxSupply;\n uint256 internal _maxMintPerTx;\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721(\"Charged Particles - Lepton\", \"LEPTON\") {\n _paused = true;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function mintLepton() external payable virtual override nonReentrant whenNotPaused returns (uint256 newTokenId) {\n newTokenId = _mintLepton(msg.sender);\n }\n\n function batchMintLepton(uint256 count) external payable virtual override nonReentrant whenNotPaused {\n _batchMintLepton(msg.sender, count);\n }\n\n function getNextType() external view virtual override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _typeIndex;\n }\n\n function getNextPrice() external view virtual override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _leptonTypes[_typeIndex].price;\n }\n\n function getMultiplier(uint256 tokenId) external view virtual override returns (uint256) {\n return _leptonData[tokenId].multiplier;\n }\n\n function getBonus(uint256 tokenId) external view virtual override returns (uint256) {\n return _leptonData[tokenId].bonus;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function addLeptonType(\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n virtual\n onlyOwner\n {\n _maxSupply = _maxSupply.add(uint256(supply));\n\n Classification memory lepton = Classification({\n tokenUri: tokenUri,\n price: price,\n supply: supply,\n multiplier: multiplier,\n bonus: bonus,\n _upperBounds: uint128(_maxSupply)\n });\n _leptonTypes.push(lepton);\n\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function updateLeptonType(\n uint256 leptonIndex,\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n virtual\n onlyOwner\n {\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\n _leptonTypes[leptonIndex].price = price;\n _leptonTypes[leptonIndex].supply = supply;\n _leptonTypes[leptonIndex].multiplier = multiplier;\n _leptonTypes[leptonIndex].bonus = bonus;\n\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function setMaxMintPerTx(uint256 maxAmount) external virtual onlyOwner {\n _maxMintPerTx = maxAmount;\n emit MaxMintPerTxSet(maxAmount);\n }\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _mintLepton(address receiver) internal virtual returns (uint256 newTokenId) {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n require(msg.value >= lepton.price, \"LPT:E-414\");\n\n _tokenIds.increment();\n newTokenId = _tokenIds.current();\n\n _leptonData[newTokenId] = lepton;\n _safeMint(receiver, newTokenId, \"\");\n _setTokenURI(newTokenId, lepton.tokenUri);\n\n // Distribute Next Type\n if (newTokenId == lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n emit LeptonMinted(receiver, newTokenId, lepton.price, lepton.multiplier);\n\n _refundOverpayment(lepton.price);\n }\n\n\n function _batchMintLepton(address receiver, uint256 count) internal virtual {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \"LPT:E-429\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n\n uint256 startTokenId = _tokenIds.current();\n uint256 endTokenId = startTokenId.add(count);\n if (endTokenId > lepton._upperBounds) {\n count = count.sub(endTokenId.sub(lepton._upperBounds));\n }\n\n uint256 salePrice = lepton.price.mul(count);\n require(msg.value >= salePrice, \"LPT:E-414\");\n\n _safeMintBatch(receiver, startTokenId.add(1), count, \"\");\n\n for (uint i = 0; i < count; i++) {\n _tokenIds.increment();\n startTokenId = _tokenIds.current();\n\n _leptonData[startTokenId] = lepton;\n _setTokenURI(startTokenId, lepton.tokenUri);\n }\n\n // Distribute Next Type\n if (startTokenId >= lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n emit LeptonBatchMinted(receiver, startTokenId, count, lepton.price, lepton.multiplier);\n\n _refundOverpayment(salePrice);\n }\n\n function _refundOverpayment(uint256 threshold) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"LPT:E-101\");\n _;\n }\n}" + }, + "contracts/v1/tokens/Lepton2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Lepton2.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"../lib/ERC721Basic.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\n\nimport \"../interfaces/ILepton.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Lepton2 is ILepton, ERC721Basic, Ownable, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n\n Classification[] internal _leptonTypes;\n\n uint256 internal _typeIndex;\n uint256 internal _maxSupply;\n uint256 internal _maxMintPerTx;\n uint256 internal _migratedCount;\n\n bool internal _paused;\n bool internal _migrationComplete;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721Basic(\"Charged Particles - Lepton2\", \"LEPTON2\") {\n _paused = true;\n _migrationComplete = false;\n _migratedCount = 0;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function mintLepton() external payable override nonReentrant whenNotPaused returns (uint256 newTokenId) {\n newTokenId = _mintLepton(msg.sender);\n }\n\n function batchMintLepton(uint256 count) external payable override nonReentrant whenNotPaused {\n _batchMintLepton(msg.sender, count);\n }\n\n function totalSupply() public view returns (uint256) {\n return _tokenCount;\n }\n\n function maxSupply() external view returns (uint256) {\n return _maxSupply;\n }\n\n function getNextType() external view override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _typeIndex;\n }\n\n function getNextPrice() external view override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _leptonTypes[_typeIndex].price;\n }\n\n function getMultiplier(uint256 tokenId) external view override returns (uint256) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).multiplier;\n }\n\n function getBonus(uint256 tokenId) external view override returns (uint256) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).bonus;\n }\n\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).tokenUri;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function addLeptonType(\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n onlyOwner\n {\n _maxSupply = _maxSupply.add(uint256(supply));\n\n Classification memory lepton = Classification({\n tokenUri: tokenUri,\n price: price,\n supply: supply,\n multiplier: multiplier,\n bonus: bonus,\n _upperBounds: uint128(_maxSupply)\n });\n _leptonTypes.push(lepton);\n\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function updateLeptonType(\n uint256 leptonIndex,\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n onlyOwner\n {\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\n _leptonTypes[leptonIndex].price = price;\n _leptonTypes[leptonIndex].supply = supply;\n _leptonTypes[leptonIndex].multiplier = multiplier;\n _leptonTypes[leptonIndex].bonus = bonus;\n\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function setMaxMintPerTx(uint256 maxAmount) external onlyOwner {\n _maxMintPerTx = maxAmount;\n emit MaxMintPerTxSet(maxAmount);\n }\n\n function setPausedState(bool state) external onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function migrateAccounts(address oldLeptonContract, uint256 count) external onlyOwner whenNotMigrated {\n uint256 oldSupply = IERC721Enumerable(oldLeptonContract).totalSupply();\n require(oldSupply == 0 || oldSupply > _migratedCount, \"LPT:E-004\");\n\n if (oldSupply > 0) {\n uint256 endTokenId = _migratedCount.add(count);\n if (endTokenId > oldSupply) {\n count = count.sub(endTokenId.sub(oldSupply));\n }\n\n for (uint256 i = 1; i <= count; i++) {\n uint256 tokenId = _migratedCount.add(i);\n address tokenOwner = IERC721(oldLeptonContract).ownerOf(tokenId);\n _mint(tokenOwner);\n }\n _migratedCount = _migratedCount.add(count);\n }\n\n if (oldSupply == _migratedCount) {\n _finalizeMigration();\n }\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getLepton(uint256 tokenId) internal view returns (Classification memory) {\n uint256 types = _leptonTypes.length;\n for (uint256 i = 0; i < types; i++) {\n Classification memory lepton = _leptonTypes[i];\n if (tokenId <= lepton._upperBounds) {\n return lepton;\n }\n }\n }\n\n function _mintLepton(address receiver) internal returns (uint256 newTokenId) {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n require(msg.value >= lepton.price, \"LPT:E-414\");\n\n newTokenId = _safeMint(receiver, \"\");\n\n // Determine Next Type\n if (newTokenId == lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n _refundOverpayment(lepton.price);\n }\n\n function _batchMintLepton(address receiver, uint256 count) internal {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \"LPT:E-429\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n\n uint256 endTokenId = _tokenCount.add(count);\n if (endTokenId > lepton._upperBounds) {\n count = count.sub(endTokenId.sub(lepton._upperBounds));\n }\n\n uint256 salePrice = lepton.price.mul(count);\n require(msg.value >= salePrice, \"LPT:E-414\");\n\n _safeMintBatch(receiver, count, \"\");\n\n // Determine Next Type\n if (endTokenId >= lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n _refundOverpayment(salePrice);\n }\n\n function _refundOverpayment(uint256 threshold) internal {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n function _finalizeMigration() internal {\n // Determine Next Type\n _typeIndex = 0;\n for (uint256 i = 0; i < _leptonTypes.length; i++) {\n Classification memory lepton = _leptonTypes[i];\n if (_migratedCount >= lepton._upperBounds) {\n _typeIndex = i + 1;\n }\n }\n _migrationComplete = true;\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotMigrated() {\n require(!_migrationComplete, \"LPT:E-004\");\n _;\n }\n\n modifier whenNotPaused() {\n require(!_paused, \"LPT:E-101\");\n _;\n }\n}" + }, + "contracts/v1/tokens/NonFungibleERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// NonFungibleERC1155.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract NonFungibleERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => address) internal _tokenOwner;\n\n constructor() public ERC1155(\"https://staging.app.charged.fi/erc1155/metadata.json\") {}\n\n function creatorOf(uint256 tokenId) external view returns (address) {\n return _tokenCreator[tokenId];\n }\n\n function ownerOf(uint256 tokenId) external view returns (address) {\n return _tokenOwner[tokenId];\n }\n\n function mintNft(address receiver) external returns (uint256 newTokenId) {\n return _mintNft(msg.sender, receiver);\n }\n\n function _mintNft(address creator, address receiver) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n\n _mint(receiver, newTokenId, 1, \"\");\n _tokenCreator[newTokenId] = creator;\n _tokenOwner[newTokenId] = receiver;\n }\n}\n" + }, + "contracts/v1/tokens/Proton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IProton.sol\";\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ncontract Proton is IProton, ERC721, Ownable, RelayRecipient, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n using Counters for Counters.Counter;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n uint256 constant internal MAX_ROYALTIES = 8e3; // 8000 (80%)\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n Counters.Counter internal _tokenIds;\n\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct;\n mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect;\n mapping (address => uint256) internal _tokenCreatorClaimableRoyalties;\n\n mapping (uint256 => uint256) internal _tokenSalePrice;\n mapping (uint256 => uint256) internal _tokenLastSellPrice;\n\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721(\"Charged Particles - Proton\", \"PROTON\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view virtual override returns (address) {\n return _tokenCreator[tokenId];\n }\n\n function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenSalePrice[tokenId];\n }\n\n function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenLastSellPrice[tokenId];\n }\n\n function getCreatorRoyalties(address account) external view virtual override returns (uint256) {\n return _tokenCreatorClaimableRoyalties[account];\n }\n\n function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenCreatorRoyaltiesPct[tokenId];\n }\n\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) {\n return _creatorRoyaltiesReceiver(tokenId);\n }\n\n function claimCreatorRoyalties()\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256)\n {\n return _claimCreatorRoyalties(_msgSender());\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // annuityPercent,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n royaltiesPercent,\n salePrice\n );\n }\n\n function batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n external\n virtual\n override\n whenNotPaused\n {\n _batchProtonsForSale(\n creator,\n annuityPercent,\n royaltiesPercent,\n tokenMetaUris,\n salePrices\n );\n }\n\n function buyProton(uint256 tokenId)\n external\n payable\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (bool)\n {\n return _buyProton(tokenId);\n }\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice)\n external\n virtual\n override\n whenNotPaused\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setSalePrice(tokenId, salePrice);\n }\n\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setRoyaltiesPct(tokenId, royaltiesPct);\n }\n\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n {\n _tokenCreatorRoyaltiesRedirect[tokenId] = receiver;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual {\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n\n _tokenSalePrice[tokenId] = salePrice;\n emit SalePriceSet(tokenId, salePrice);\n }\n\n function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual {\n require(royaltiesPct <= MAX_ROYALTIES, \"PRT:E-421\");\n _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct;\n emit CreatorRoyaltiesSet(tokenId, royaltiesPct);\n }\n\n function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) {\n address receiver = _tokenCreatorRoyaltiesRedirect[tokenId];\n if (receiver == address(0x0)) {\n receiver = _tokenCreator[tokenId];\n }\n return receiver;\n }\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, annuityPercent, 0, 0);\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n _tokenIds.increment();\n\n newTokenId = _tokenIds.current();\n _safeMint(receiver, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUri);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function _batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n internal\n virtual\n {\n require(tokenMetaUris.length == salePrices.length, \"PRT:E-202\");\n address self = address(this);\n\n uint256 count = tokenMetaUris.length;\n for (uint256 i = 0; i < count; i++) {\n _tokenIds.increment();\n uint256 newTokenId = _tokenIds.current();\n\n _safeMint(creator, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUris[i]);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n uint256 salePrice = salePrices[i];\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n self,\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n function _buyProton(uint256 tokenId)\n internal\n virtual\n returns (bool)\n {\n uint256 salePrice = _tokenSalePrice[tokenId];\n require(salePrice > 0, \"PRT:E-416\");\n require(msg.value >= salePrice, \"PRT:E-414\");\n\n uint256 ownerAmount = salePrice;\n uint256 creatorAmount;\n address oldOwner = ownerOf(tokenId);\n address newOwner = _msgSender();\n\n // Creator Royalties\n address royaltiesReceiver = _creatorRoyaltiesReceiver(tokenId);\n uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[tokenId];\n uint256 lastSellPrice = _tokenLastSellPrice[tokenId];\n if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) {\n creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE);\n ownerAmount = ownerAmount.sub(creatorAmount);\n }\n _tokenLastSellPrice[tokenId] = salePrice;\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(address(this), tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n\n // Reserve Royalties for Creator\n if (creatorAmount > 0) {\n _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount);\n }\n\n // Transfer Token\n _transfer(oldOwner, newOwner, tokenId);\n\n // Transfer Payment\n payable(oldOwner).sendValue(ownerAmount);\n\n emit ProtonSold(tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n\n _refundOverpayment(salePrice);\n return true;\n }\n\n /**\n * @dev Pays out the Creator Royalties of the calling account\n * @param receiver The receiver of the claimable royalties\n * @return The amount of Creator Royalties claimed\n */\n function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) {\n uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver];\n require(claimableAmount > 0, \"PRT:E-411\");\n\n delete _tokenCreatorClaimableRoyalties[receiver];\n payable(receiver).sendValue(claimableAmount);\n\n emit RoyaltiesClaimed(receiver, claimableAmount);\n }\n\n /**\n * @dev Collects the Required Asset Token from the users wallet\n * @param from The owner address to collect the Assets from\n * @param assetAmount The Amount of Asset Tokens to Collect\n */\n function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual {\n uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from);\n require(assetAmount <= _userAssetBalance, \"PRT:E-411\");\n // Be sure to Approve this Contract to transfer your Asset Token\n require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), \"PRT:E-401\");\n }\n\n function _refundOverpayment(uint256 threshold) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n _tokenSalePrice[tokenId] = 0;\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n super._transfer(from, to, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"PRT:E-101\");\n _;\n }\n\n modifier onlyTokenOwnerOrApproved(uint256 tokenId) {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"PRT:E-105\");\n _;\n }\n\n modifier onlyTokenCreator(uint256 tokenId) {\n require(_tokenCreator[tokenId] == _msgSender(), \"PRT:E-104\");\n _;\n }\n}" + }, + "contracts/v1/tokens/ProtonB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\nimport \"../interfaces/IProtonB.sol\";\n\nimport \"../lib/BaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ncontract ProtonB is BaseProton, IProtonB {\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public BaseProton(\"Charged Particles - ProtonB\", \"PROTON.B\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n external\n virtual\n override\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n royaltiesPercent,\n salePrice\n );\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n /// @dev for backwards compatibility with v1\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0);\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n\n /***********************************|\n | Function Overrides |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override {\n super._setSalePrice(tokenId, salePrice);\n\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n }\n\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n override\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n }\n\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n // Unlock NFT\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n\n super._transfer(from, to, tokenId);\n }\n}" + }, + "contracts/v1/tokens/ProtonC.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\nimport \"../lib/Soul.sol\";\n\n\ncontract ProtonC is BaseProton, Soul {\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public BaseProton(\"Charged Particles - ProtonC\", \"PROTON.C\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createBondedToken(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent\n )\n external\n virtual\n payable\n returns (uint256 newTokenId)\n {\n uint256 tokenId = createProtonForSale(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n royaltiesPercent,\n 0\n );\n lockToken(tokenId);\n\n return tokenId;\n }\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n public \n virtual\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n royaltiesPercent,\n salePrice\n );\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n nonReentrant\n whenNotPaused\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n /// @dev for backwards compatibility with v1\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n whenNotPaused\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function burn(uint256 tokenId) public {\n requireTokenOwner(tokenId); \n _burn(tokenId);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n function requireTokenOwner(uint256 tokenId) public view {\n require(ownerOf(tokenId) == msg.sender, \"Only token owner\");\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0);\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n function _burn(uint256 tokenId) internal {\n _unlockToken(tokenId);\n _transfer(ownerOf(tokenId), address(0x000000000000000000000000000000000000dEaD), tokenId);\n }\n\n /***********************************|\n | Soul bounded |\n |__________________________________*/\n\n function lockToken(uint256 tokenId) public {\n requireTokenOwner(tokenId);\n _lockToken(tokenId);\n }\n\n /***********************************|\n | Function Overrides |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override {\n super._setSalePrice(tokenId, salePrice);\n\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n }\n\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n override\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n require(lockedTokens[tokenId] == false, \"BondedToken: Token is locked\");\n\n // Unlock NFT\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n\n super._transfer(from, to, tokenId);\n }\n}" + }, + "contracts/v1/Universe.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\n\nimport \"./interfaces/IUniverse.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n\n/**\n * @notice Charged Particles Universe Contract\n * @dev Upgradeable Contract\n */\ncontract Universe is IUniverse, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n // The ChargedParticles Contract Address\n address public chargedParticles;\n address public proton;\n address public lepton;\n address public quark;\n address public boson;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // Positive Charge\n uint256 internal photonMaxSupply;\n uint256 internal totalPhotonDischarged;\n\n // Source of Positive Charge\n IERC20Upgradeable public photonSource;\n\n // Asset Token => Electrostatic Attraction Multiplier\n mapping (address => uint256) internal esaMultiplier;\n\n // Account => Electrostatic Attraction Levels\n mapping (address => uint256) internal esaLevel;\n\n // Energizing Account => Referral Source\n mapping (address => address) internal referralSource;\n\n // NFT Token UUID => Bonded Lepton Mass\n mapping (uint256 => uint256) internal bondedLeptonMass;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getStaticCharge(address /* account */) external pure virtual returns (uint256 positiveEnergy) {\n return 0;\n }\n\n function conductElectrostaticDischarge(address /* account */, uint256 /* amount */) external pure virtual returns (uint256 positiveEnergy) {\n return 0;\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n onlyProton\n {\n // no-op\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(controller)\n {\n chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setPhoton(\n address token,\n uint256 maxSupply\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n photonSource = IERC20Upgradeable(token);\n photonMaxSupply = maxSupply;\n emit PhotonSet(token, maxSupply);\n }\n\n function setProtonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n proton = token;\n emit ProtonTokenSet(token);\n }\n\n function setLeptonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n lepton = token;\n emit LeptonTokenSet(token);\n }\n\n function setQuarkToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n quark = token;\n emit QuarkTokenSet(token);\n }\n\n function setBosonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n boson = token;\n emit BosonTokenSet(token);\n }\n\n function setEsaMultiplier(\n address assetToken,\n uint256 multiplier\n )\n external\n virtual\n onlyOwner\n {\n esaMultiplier[assetToken] = multiplier;\n emit EsaMultiplierSet(assetToken, multiplier);\n }\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _electrostaticAttraction(uint256 tokenUuid, address receiver, address assetToken, uint256 baseAmount) internal virtual {\n }\n\n function _conductElectrostaticDischarge(address /* account */, uint256 /* energy */) internal virtual pure returns (uint256) {\n return 0;\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Proton NFT contract\n modifier onlyProton() {\n require(proton == msg.sender, \"UNI:E-110\");\n _;\n }\n}\n" + }, + "contracts/v1/UniverseRP.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"./interfaces/IUniverseRP.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./interfaces/IRewardNft.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\nimport \"./interfaces/IRewardProgram.sol\";\n\n/**\n * @notice Charged Particles Universe Contract with Rewards Program\n * @dev Upgradeable Contract\n */\ncontract UniverseRP is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // The ChargedParticles Contract Address\n address public _chargedParticles;\n\n // The Lepton NFT Contract Address\n address public _multiplierNft;\n\n // Asset Token => Reward Program\n mapping (address => address) internal _assetRewardPrograms;\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\n\n // Token UUID => NFT Staking Data\n mapping (uint256 => NftStake) private _nftStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n function getRewardProgram(address asset) external view override returns (address) {\n return _getRewardProgram(asset);\n }\n\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\n return _nftStake[uuid];\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetDeposit(\n contractAddress,\n tokenId,\n walletManagerId,\n assetAmount\n );\n }\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\n }\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n // \"receiverEnergy\" includes the \"principalAmount\"\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n onlyOwner\n onlyValidContractAddress(controller)\n {\n _chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setMultiplierNft(address nftTokenAddress)\n external\n onlyOwner\n onlyValidContractAddress(nftTokenAddress)\n {\n _multiplierNft = nftTokenAddress;\n }\n\n function setRewardProgram(\n address rewardProgam,\n address assetToken\n )\n external\n onlyOwner\n onlyValidContractAddress(rewardProgam)\n {\n require(assetToken != address(0x0), \"UNI:E-403\");\n _assetRewardPrograms[assetToken] = rewardProgam;\n emit RewardProgramSet(assetToken, rewardProgam);\n }\n\n function removeRewardProgram(address assetToken) external onlyOwner {\n delete _assetRewardPrograms[assetToken];\n emit RewardProgramRemoved(assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getRewardProgram(address assetToken) internal view returns (address) {\n return _assetRewardPrograms[assetToken];\n }\n\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != depositNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n uint256 multiplier = _getNftMultiplier(depositNftAddress, depositNftTokenId);\n\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\n // Add to Multipliers Set\n _multiplierNftsSet[parentNftUuid].add(multiplier);\n\n // Update NFT Stake\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\n } else {\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\n }\n }\n\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\n }\n\n function _registerNftRelease(\n address contractAddress,\n uint256 tokenId,\n address releaseNftAddress,\n uint256 releaseNftTokenId,\n uint256 /* nftTokenAmount */\n )\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != releaseNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n NftStake storage nftStake = _nftStake[parentNftUuid];\n\n // Remove from Multipliers Set\n uint256 multiplier = _getNftMultiplier(releaseNftAddress, releaseNftTokenId);\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\n\n // Determine New Multiplier or Mark as Released\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\n } else {\n nftStake.releaseBlockNumber = block.number;\n }\n\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\n }\n\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\n uint256 multiplier = 0;\n uint256 loss = 50;\n uint256 i = 0;\n\n for (; i < len; i++) {\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\n }\n if (len > 1) {\n multiplier = multiplier.sub(loss.mul(len));\n }\n return multiplier;\n }\n\n function _getNftMultiplier(address contractAddress, uint256 tokenId) internal returns (uint256) {\n bytes4 fnSig = IRewardNft.getMultiplier.selector;\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n\n if (success) {\n return abi.decode(returnData, (uint256));\n } else {\n return 0;\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(_chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/UniveserRPPolygon.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"./interfaces/IUniverseRP.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./interfaces/IRewardNft.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\nimport \"./interfaces/IRewardProgram.sol\";\n\n/**\n * @notice Charged Particles Universe Contract with Rewards Program\n * @dev Upgradeable Contract\n */\ncontract UniverseRPPolygon is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // The ChargedParticles Contract Address\n address public _chargedParticles;\n\n // The Lepton NFT Contract Address\n address public _multiplierNft;\n\n // Asset Token => Reward Program\n mapping (address => address) internal _assetRewardPrograms;\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\n\n // Token UUID => NFT Staking Data\n mapping (uint256 => NftStake) private _nftStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n function getRewardProgram(address asset) external view override returns (address) {\n return _getRewardProgram(asset);\n }\n\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\n return _nftStake[uuid];\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetDeposit(\n contractAddress,\n tokenId,\n walletManagerId,\n assetAmount\n );\n }\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\n }\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n // \"receiverEnergy\" includes the \"principalAmount\"\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n onlyOwner\n onlyValidContractAddress(controller)\n {\n _chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setMultiplierNft(address nftTokenAddress)\n external\n onlyOwner\n onlyValidContractAddress(nftTokenAddress)\n {\n _multiplierNft = nftTokenAddress;\n }\n\n function setRewardProgram(\n address rewardProgam,\n address assetToken\n )\n external\n onlyOwner\n onlyValidContractAddress(rewardProgam)\n {\n require(assetToken != address(0x0), \"UNI:E-403\");\n _assetRewardPrograms[assetToken] = rewardProgam;\n emit RewardProgramSet(assetToken, rewardProgam);\n }\n\n function removeRewardProgram(address assetToken) external onlyOwner {\n delete _assetRewardPrograms[assetToken];\n emit RewardProgramRemoved(assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getRewardProgram(address assetToken) internal view returns (address) {\n return _assetRewardPrograms[assetToken];\n }\n\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != depositNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n uint256 multiplier = _getNftMultiplier(depositNftTokenId);\n\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\n // Add to Multipliers Set\n _multiplierNftsSet[parentNftUuid].add(multiplier);\n\n // Update NFT Stake\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\n } else {\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\n }\n }\n\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\n }\n\n function _registerNftRelease(\n address contractAddress,\n uint256 tokenId,\n address releaseNftAddress,\n uint256 releaseNftTokenId,\n uint256 /* nftTokenAmount */\n )\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != releaseNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n NftStake storage nftStake = _nftStake[parentNftUuid];\n\n // Remove from Multipliers Set\n uint256 multiplier = _getNftMultiplier(releaseNftTokenId);\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\n\n // Determine New Multiplier or Mark as Released\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\n } else {\n nftStake.releaseBlockNumber = block.number;\n }\n\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\n }\n\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\n uint256 multiplier = 0;\n uint256 loss = 50;\n uint256 i = 0;\n\n for (; i < len; i++) {\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\n }\n if (len > 1) {\n multiplier = multiplier.sub(loss.mul(len));\n }\n return multiplier;\n }\n\n function _getNftMultiplier(uint256 tokenId) internal pure returns (uint256) {\n if (tokenId >= 1 && tokenId <= 721) {\n return 110;\n } else if (tokenId > 721 && tokenId <= 1122) {\n return 130;\n } else if (tokenId > 1122 && tokenId <= 1423) {\n return 150;\n } else if (tokenId > 1423 && tokenId <= 1624) {\n return 180;\n } else if (tokenId > 1624 && tokenId <= 1712) {\n return 230;\n } else if (tokenId > 1712 && tokenId <= 1733) {\n return 510;\n } else {\n return 1;\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(_chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/vesting/VestingClaim7.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract VestingClaim7 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"VestingClaim7: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"VestingClaim7: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"VestingClaim7: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"VestingClaim7: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"VestingClaim7: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"VestingClaim7: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveSmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\nimport \"../../interfaces/IAaveBridge.sol\";\nimport \"../../lib/SmartWalletBase.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet for Aave Assets\n * @dev Non-upgradeable Contract\n */\ncontract AaveSmartWallet is SmartWalletBase {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 constant internal RAY = 1e27;\n\n IAaveBridge internal _bridge;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(\n address aaveBridge\n )\n public\n {\n SmartWalletBase.initializeBase();\n _bridge = IAaveBridge(aaveBridge);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _bridge.isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address) {\n return _bridge.getReserveInterestToken(assetToken);\n }\n\n function getPrincipal(address assetToken) external override returns (uint256) {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address assetToken) external override returns (uint256 creatorInterest, uint256 ownerInterest) {\n return _getInterest(assetToken);\n }\n\n function getTotal(address assetToken) external override returns (uint256) {\n return _getTotal(assetToken);\n }\n\n function getRewards(address rewardToken) external override returns (uint256) {\n return IERC20(rewardToken).balanceOf(address(this));\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _deposit(assetToken, assetAmount, referralCode);\n }\n\n\n function withdraw(\n address receiver,\n address creatorRedirect,\n address assetToken\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (, uint256 ownerInterest) = _getInterest(assetToken);\n return _withdraw(receiver, creatorRedirect, assetToken, walletPrincipal.add(ownerInterest));\n }\n\n function withdrawAmount(\n address receiver,\n address creatorRedirect,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return _withdraw(receiver, creatorRedirect, assetToken, assetAmount);\n }\n\n function withdrawAmountForCreator(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return _withdrawForCreator(receiver, assetToken, assetAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _withdrawRewards(receiver, rewardsToken, rewardsAmount);\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n internal\n returns (uint256)\n {\n _trackAssetToken(assetToken);\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n\n // Deposit Assets into Aave (reverts on fail)\n _sendToken(address(_bridge), assetToken, assetAmount);\n uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function _withdraw(\n address receiver,\n address creatorRedirect,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken);\n\n // Withdraw from Interest only\n if (assetAmount < ownerInterest) {\n if (creatorInterest > 0) {\n uint256 ratio = assetAmount.mul(RAY).div(ownerInterest);\n creatorAmount = creatorInterest.add(nftCreatorAmountDischarged).mul(ratio).div(RAY);\n\n if (creatorAmount <= nftCreatorAmountDischarged) {\n nftCreatorAmountDischarged = nftCreatorAmountDischarged.sub(creatorAmount);\n creatorAmount = 0;\n }\n\n else {\n creatorAmount = creatorAmount.sub(nftCreatorAmountDischarged);\n nftCreatorAmountDischarged = 0;\n }\n }\n receiverAmount = assetAmount;\n }\n\n // Withdraw from Interest + Principal\n else {\n uint256 fromPrincipal = assetAmount.sub(ownerInterest);\n if (fromPrincipal > walletPrincipal) {\n fromPrincipal = walletPrincipal.sub(ownerInterest);\n }\n\n creatorAmount = creatorInterest;\n receiverAmount = ownerInterest.add(fromPrincipal);\n nftCreatorAmountDischarged = 0;\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal);\n }\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount));\n\n // Withdraw Assets for Creator\n if (creatorAmount > 0) {\n address receivesForCreator = (creatorRedirect != address(0x0)) ? creatorRedirect : nftCreator;\n _bridge.withdraw(receivesForCreator, assetToken, creatorAmount);\n }\n\n // Withdraw Assets for Receiver\n _bridge.withdraw(receiver, assetToken, receiverAmount);\n }\n\n function _withdrawForCreator(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 receiverAmount)\n {\n (uint256 creatorInterest,) = _getInterest(assetToken);\n if (creatorInterest == 0) { return 0; }\n if (assetAmount > creatorInterest) {\n assetAmount = creatorInterest;\n }\n\n nftCreatorAmountDischarged = nftCreatorAmountDischarged.add(assetAmount);\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, assetAmount);\n\n // Withdraw Assets for Receiver on behalf of Creator\n _bridge.withdraw(receiver, assetToken, assetAmount);\n }\n\n function _withdrawRewards(\n address receiver,\n address rewardsTokenAddress,\n uint256 rewardsAmount\n )\n internal\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"ASW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function _getTotal(address assetToken) internal view returns (uint256) {\n return _bridge.getTotalBalance(address(this), assetToken);\n }\n\n function _getInterest(address assetToken) internal view returns (uint256 creatorInterest, uint256 ownerInterest) {\n uint256 total = _getTotal(assetToken);\n uint256 principal = _getPrincipal(assetToken);\n uint256 interest = total.sub(principal);\n\n // Creator Royalties\n if (nftCreatorAnnuityPct > 0) {\n\n // Interest too small to calculate percentage;\n if (interest <= PERCENTAGE_SCALE) {\n // creatorInterest = interest.div(2); // split evenly?\n creatorInterest = 0; // All to owner\n }\n\n // Calculate percentage for Creator\n else {\n creatorInterest = interest\n .add(nftCreatorAmountDischarged)\n .mul(nftCreatorAnnuityPct)\n .div(PERCENTAGE_SCALE)\n .sub(nftCreatorAmountDischarged);\n }\n }\n\n // Owner Portion\n ownerInterest = interest.sub(creatorInterest);\n }\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveSmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\nimport \"../../interfaces/IAaveBridge.sol\";\nimport \"../../lib/SmartWalletBaseB.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet for Aave Assets\n * @dev Non-upgradeable Contract\n */\ncontract AaveSmartWalletB is SmartWalletBaseB {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 constant internal RAY = 1e27;\n\n IAaveBridge internal _bridge;\n\n uint256 internal _nftCreatorAmountDischarged;\n\n mapping (address => address) internal _assetATokens;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(\n address aaveBridge\n )\n public\n {\n SmartWalletBaseB.initializeBase();\n _bridge = IAaveBridge(aaveBridge);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _bridge.isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address) {\n return _bridge.getReserveInterestToken(assetToken);\n }\n\n function getPrincipal(address assetToken) external override returns (uint256) {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address assetToken, uint256 creatorPct) external override returns (uint256 creatorInterest, uint256 ownerInterest) {\n return _getInterest(assetToken, creatorPct);\n }\n\n function getTotal(address assetToken) external override returns (uint256) {\n return _getTotal(assetToken);\n }\n\n function getRewards(address rewardToken) external override returns (uint256) {\n return IERC20(rewardToken).balanceOf(address(this));\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _deposit(assetToken, assetAmount, referralCode);\n }\n\n\n function withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (, uint256 ownerInterest) = _getInterest(assetToken, creatorPct);\n return _withdraw(receiver, creator, creatorPct, assetToken, walletPrincipal.add(ownerInterest));\n }\n\n function withdrawAmount(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return _withdraw(receiver, creator, creatorPct, assetToken, assetAmount);\n }\n\n function withdrawAmountForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return _withdrawForCreator(receiver, creatorPct, assetToken, assetAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _withdrawRewards(receiver, rewardsToken, rewardsAmount);\n }\n\n function refreshPrincipal(address assetToken) external virtual override onlyWalletManager {\n uint256 aTokenBalance = IERC20(_assetATokens[assetToken]).balanceOf(address(this));\n if (_assetPrincipalBalance[assetToken] > aTokenBalance) {\n _assetPrincipalBalance[assetToken] = aTokenBalance;\n }\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n internal\n returns (uint256)\n {\n _trackAssetToken(assetToken);\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n\n // Deposit Assets into Aave (reverts on fail)\n _sendToken(address(_bridge), assetToken, assetAmount);\n uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function _withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken, creatorPct);\n\n // Withdraw from Interest only\n if (assetAmount < ownerInterest) {\n if (creatorInterest > 0) {\n uint256 ratio = assetAmount.mul(RAY).div(ownerInterest);\n creatorAmount = creatorInterest.add(_nftCreatorAmountDischarged).mul(ratio).div(RAY);\n\n if (creatorAmount <= _nftCreatorAmountDischarged) {\n _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.sub(creatorAmount);\n creatorAmount = 0;\n }\n else {\n creatorAmount = creatorAmount.sub(_nftCreatorAmountDischarged);\n _nftCreatorAmountDischarged = 0;\n }\n }\n receiverAmount = assetAmount;\n }\n\n // Withdraw from Interest + Principal\n else {\n uint256 fromPrincipal = assetAmount.sub(ownerInterest);\n if (fromPrincipal > walletPrincipal) {\n fromPrincipal = walletPrincipal.sub(ownerInterest);\n }\n\n creatorAmount = creatorInterest;\n receiverAmount = ownerInterest.add(fromPrincipal);\n _nftCreatorAmountDischarged = 0;\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal);\n }\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount));\n\n // Withdraw Assets for Creator\n if (creatorAmount > 0) {\n if (creator != address(0)) {\n _bridge.withdraw(creator, assetToken, creatorAmount);\n } else {\n receiverAmount = receiverAmount.add(creatorAmount);\n creatorAmount = 0;\n }\n }\n\n // Withdraw Assets for Receiver\n _bridge.withdraw(receiver, assetToken, receiverAmount);\n }\n\n function _withdrawForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 receiverAmount)\n {\n (uint256 creatorInterest,) = _getInterest(assetToken, creatorPct);\n if (creatorInterest == 0) { return 0; }\n if (assetAmount > creatorInterest) {\n assetAmount = creatorInterest;\n }\n\n _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.add(assetAmount);\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, assetAmount);\n\n // Withdraw Assets for Receiver on behalf of Creator\n _bridge.withdraw(receiver, assetToken, assetAmount);\n }\n\n function _withdrawRewards(\n address receiver,\n address rewardsTokenAddress,\n uint256 rewardsAmount\n )\n internal\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"ASW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function _getTotal(address assetToken) internal view returns (uint256) {\n return _bridge.getTotalBalance(address(this), assetToken);\n }\n\n function _getInterest(address assetToken, uint256 creatorPct) internal view returns (uint256 creatorInterest, uint256 ownerInterest) {\n uint256 total = _getTotal(assetToken);\n uint256 principal = _getPrincipal(assetToken);\n uint256 interest = total.sub(principal);\n\n // Creator Royalties\n if (creatorPct > 0) {\n\n // Interest too small to calculate percentage;\n if (interest <= PERCENTAGE_SCALE) {\n // creatorInterest = interest.div(2); // split evenly?\n creatorInterest = 0; // All to owner\n }\n\n // Calculate percentage for Creator\n else {\n creatorInterest = interest\n .add(_nftCreatorAmountDischarged)\n .mul(creatorPct)\n .div(PERCENTAGE_SCALE)\n .sub(_nftCreatorAmountDischarged);\n }\n }\n\n // Owner Portion\n ownerInterest = interest.sub(creatorInterest);\n }\n\n function _trackAssetToken(address assetToken) internal override {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _assetATokens[assetToken] = aTokenAddress;\n }\n }\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../lib/WalletManagerBase.sol\";\n\nimport \"./AaveSmartWallet.sol\";\n\n/**\n * @notice Wallet Manager for Aave\n * @dev Non-upgradeable Contract\n */\ncontract AaveWalletManager is WalletManagerBase {\n using SafeMath for uint256;\n\n event AaveBridgeSet(address indexed aaveBridge);\n event ValidRewardsTokenSet(address indexed rewardsToken, bool state);\n\n address internal _aaveBridge;\n uint256 internal _referralCode;\n\n mapping (address => bool) public rewardsTokenWhitelist;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new AaveSmartWallet());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return AaveSmartWallet(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return AaveSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return AaveSmartWallet(_wallets[uuid]).getInterest(assetToken);\n }\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getTotal(assetToken);\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getRewards(_rewardToken);\n }\n\n\n /***********************************|\n | Only Controller |\n |__________________________________*/\n\n function energize(\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = AaveSmartWallet(wallet).deposit(assetToken, assetAmount, _referralCode);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(ownerInterest > 0, \"AWM:E-412\");\n\n // Discharge the full amount of interest\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, ownerInterest);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(assetAmount > 0 && ownerInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmountForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address creator,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (uint256 creatorInterest,) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(assetAmount > 0 && creatorInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n receiverAmount = AaveSmartWallet(wallet).withdrawAmountForCreator(receiver, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount);\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = AaveSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0;\n\n // Release from interest first + principal if needed\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n require(rewardsTokenWhitelist[rewardsToken], \"AWM:E-423\");\n\n // Withdraw Rewards to Receiver\n amount = AaveSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 tokenId,\n address externalAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return AaveSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n // no-op\n }\n\n function getWalletAddressById(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPct\n )\n external\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n\n if (creator != address(0x0)) {\n AaveSmartWallet(wallet).setNftCreator(creator, annuityPct);\n }\n\n emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAaveBridge(address aaveBridge) external onlyOwner {\n require(aaveBridge != address(0x0), \"AWM:E-403\");\n _aaveBridge = aaveBridge;\n emit AaveBridgeSet(aaveBridge);\n }\n\n // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool\n function setReferralCode(uint256 referralCode) external onlyOwner {\n _referralCode = referralCode;\n }\n\n function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner {\n rewardsTokenWhitelist[rewardsToken] = state;\n emit ValidRewardsTokenSet(rewardsToken, state);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n AaveSmartWallet(newWallet).initialize(_aaveBridge);\n return newWallet;\n }\n}" + }, + "contracts/v1/yield/aave/AaveWalletManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../lib/WalletManagerBase.sol\";\nimport \"../../interfaces/IChargedSettings.sol\";\nimport \"./AaveSmartWalletB.sol\";\n\n/**\n * @notice Wallet Manager for Aave\n * @dev Non-upgradeable Contract\n */\ncontract AaveWalletManagerB is WalletManagerBase {\n using SafeMath for uint256;\n\n event AaveBridgeSet(address indexed aaveBridge);\n event ChargedSettingsSet(address indexed settings);\n event ValidRewardsTokenSet(address indexed rewardsToken, bool state);\n\n IChargedSettings internal _chargedSettings;\n\n address internal _aaveBridge;\n uint256 internal _referralCode;\n\n mapping (address => bool) public _rewardsTokenWhitelist;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new AaveSmartWalletB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return AaveSmartWalletB(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return AaveSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n return AaveSmartWalletB(_wallets[uuid]).getInterest(assetToken, annuityPct);\n }\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getTotal(assetToken);\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getRewards(_rewardToken);\n }\n\n\n /***********************************|\n | Only Controller |\n |__________________________________*/\n\n function energize(\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = AaveSmartWalletB(wallet).deposit(assetToken, assetAmount, _referralCode);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(ownerInterest > 0, \"AWM:E-412\");\n\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Discharge the full amount of interest\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, ownerInterest);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(assetAmount > 0 && ownerInterest >= assetAmount, \"AWM:E-412\");\n\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Discharge a portion of the interest\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmountForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address creator,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (uint256 creatorInterest,) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(assetAmount > 0 && creatorInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n receiverAmount = AaveSmartWalletB(wallet).withdrawAmountForCreator(receiver, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount);\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Release Principal + Interest\n principalAmount = AaveSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdraw(receiver, creator, annuityPct, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0;\n\n // Release from interest first + principal if needed\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n require(_rewardsTokenWhitelist[rewardsToken], \"AWM:E-423\");\n\n // Withdraw Rewards to Receiver\n amount = AaveSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 tokenId,\n address externalAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return AaveSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n AaveSmartWalletB(wallet).refreshPrincipal(assetToken);\n }\n\n function getWalletAddressById(\n address contractAddress,\n uint256 tokenId,\n address /* creator */,\n uint256 /* annuityPct */\n )\n external\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAaveBridge(address aaveBridge) external onlyOwner {\n require(aaveBridge != address(0x0), \"AWM:E-403\");\n _aaveBridge = aaveBridge;\n emit AaveBridgeSet(aaveBridge);\n }\n\n function setChargedSettings(address settings) external onlyOwner {\n require(settings != address(0x0), \"AWM:E-403\");\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool\n function setReferralCode(uint256 referralCode) external onlyOwner {\n _referralCode = referralCode;\n }\n\n function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner {\n _rewardsTokenWhitelist[rewardsToken] = state;\n emit ValidRewardsTokenSet(rewardsToken, state);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n AaveSmartWalletB(newWallet).initialize(_aaveBridge);\n return newWallet;\n }\n}" + }, + "contracts/v1/yield/aave/v2/AaveBridgeV2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveBridgeV2.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/SafeCast.sol\";\n\nimport \"./IATokenV2.sol\";\nimport \"./ILendingPoolV2.sol\";\nimport \"./ILendingPoolAddressesProviderV2.sol\";\n\nimport \"../../../interfaces/IAaveBridge.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\n\ncontract AaveBridgeV2 is Ownable, IAaveBridge, BlackholePrevention {\n using SafeMath for uint256;\n using SafeCast for uint256;\n using SafeERC20 for IERC20;\n using ReserveLogic for ReserveLogic.ReserveData;\n\n ILendingPoolAddressesProviderV2 public provider;\n ILendingPoolV2 public lendingPool;\n\n constructor (address lendingPoolProvider) public {\n provider = ILendingPoolAddressesProviderV2(lendingPoolProvider);\n lendingPool = ILendingPoolV2(provider.getLendingPool());\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address aTokenAddress) {\n return _getReserveInterestToken(assetToken);\n }\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _isReserveActive(assetToken);\n }\n\n function getTotalBalance(address account, address assetToken) external view override returns (uint256) {\n address aTokenAddress = _getReserveInterestToken(assetToken);\n if (aTokenAddress == address(0x0)) { return 0; }\n return IATokenV2(aTokenAddress).balanceOf(account);\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n returns (uint256)\n {\n address self = address(this);\n address aTokenAddress = _getReserveInterestToken(assetToken);\n require(_isReserveActive(assetToken), \"ABV2:E-424\");\n\n IERC20 token = IERC20(assetToken);\n IATokenV2 aToken = IATokenV2(aTokenAddress);\n\n if (token.allowance(address(this), address(lendingPool)) < assetAmount) {\n token.approve(address(lendingPool), uint256(-1));\n }\n\n // Deposit Assets into Aave\n uint256 preBalance = aToken.balanceOf(self);\n lendingPool.deposit(assetToken, assetAmount, self, referralCode.toUint16());\n uint256 postBalance = aToken.balanceOf(self);\n uint256 aTokensAmount = postBalance.sub(preBalance);\n\n // Transfer back the Interest Tokens\n _sendToken(msg.sender, aTokenAddress, aTokensAmount);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function withdraw(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n {\n address self = address(this);\n require(_isReserveActive(assetToken), \"ABV2:E-424\");\n\n // Redeem aTokens for Asset Tokens\n lendingPool.withdraw(assetToken, assetAmount, self);\n\n // Transfer back the Asset Tokens\n _sendToken(receiver, assetToken, assetAmount);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n\n function _getReserveInterestToken(address assetToken) internal view returns (address aTokenAddress) {\n ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken);\n return config.aTokenAddress;\n }\n\n function _isReserveActive(address assetToken) internal view returns (bool) {\n ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken);\n uint256 isActiveFlag = 2 ** 56; // bit 56: reserve is active\n return (config.configuration.data & isActiveFlag) == isActiveFlag;\n }\n}\n" + }, + "contracts/v1/yield/aave/v2/IATokenV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\n\ninterface IATokenV2 {\n function balanceOf(address account) external view returns (uint256);\n}\n" + }, + "contracts/v1/yield/aave/v2/ILendingPoolAddressesProviderV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\n\ninterface ILendingPoolAddressesProviderV2 {\n function getLendingPool() external view returns (address);\n}" + }, + "contracts/v1/yield/aave/v2/ILendingPoolV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport \"./ILendingPoolAddressesProviderV2.sol\";\n\nlibrary ReserveConfiguration {\n struct Map {\n uint256 data;\n }\n}\n\nlibrary ReserveLogic {\n struct ReserveData {\n ReserveConfiguration.Map configuration;\n uint128 liquidityIndex;\n uint128 variableBorrowIndex;\n uint128 currentLiquidityRate;\n uint128 currentVariableBorrowRate;\n uint128 currentStableBorrowRate;\n uint40 lastUpdateTimestamp;\n address aTokenAddress;\n address stableDebtTokenAddress;\n address variableDebtTokenAddress;\n address interestRateStrategyAddress;\n uint8 id;\n }\n}\n\ninterface ILendingPoolV2 {\n function deposit(address reserve, uint256 amount, address onBehalfOf, uint16 referralCode) external;\n function withdraw(address reserve, uint256 amount, address to) external;\n function getReserveData(address asset) external view returns (ReserveLogic.ReserveData memory);\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericSmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"../../../lib/SmartWalletBase.sol\";\n\n\n/**\n * @notice Generic ERC20-Token Smart-Wallet Bridge\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartWallet is SmartWalletBase {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize()\n public\n {\n SmartWalletBase.initializeBase();\n }\n\n function isReserveActive(address assetToken)\n external\n override\n view\n returns (bool)\n {\n return _getPrincipal(assetToken) == 0;\n }\n\n function getReserveInterestToken(address assetToken)\n external\n override\n view\n returns (address)\n {\n return assetToken;\n }\n\n function getPrincipal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address /* assetToken */)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n return (0, 0);\n }\n\n function getTotal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getRewards(address assetToken)\n external\n override\n returns (uint256)\n {\n return IERC20(assetToken).balanceOf(address(this));\n }\n\n function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n // Track Principal\n _trackAssetToken(assetToken);\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n }\n\n function withdraw(address receiver, address /* creatorRedirect */, address assetToken)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmount(address receiver, address /* creatorRedirect */, address assetToken, uint256 assetAmount)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n if (receiverAmount >= assetAmount) {\n receiverAmount = assetAmount;\n }\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmountForCreator(\n address /* receiver */,\n address /* assetToken */,\n uint256 /* assetID */\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericSmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWalletB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"../../../lib/SmartWalletBaseB.sol\";\n\n\n/**\n * @notice Generic ERC20-Token Smart-Wallet Bridge\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartWalletB is SmartWalletBaseB {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize()\n public\n {\n SmartWalletBaseB.initializeBase();\n }\n\n function isReserveActive(address assetToken)\n external\n override\n view\n returns (bool)\n {\n return _getPrincipal(assetToken) == 0;\n }\n\n function getReserveInterestToken(address assetToken)\n external\n override\n view\n returns (address)\n {\n return assetToken;\n }\n\n function getPrincipal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address /* assetToken */, uint256 /* creatorPct */)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n return (0, 0);\n }\n\n function getTotal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getRewards(address assetToken)\n external\n override\n returns (uint256)\n {\n return IERC20(assetToken).balanceOf(address(this));\n }\n\n function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n // Track Principal\n _trackAssetToken(assetToken);\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n }\n\n function withdraw(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmount(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken, uint256 assetAmount)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n if (receiverAmount >= assetAmount) {\n receiverAmount = assetAmount;\n }\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmountForCreator(\n address /* receiver */,\n uint256 /* creatorPct */,\n address /* assetToken */,\n uint256 /* assetID */\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function refreshPrincipal(address assetToken) external virtual override onlyWalletManager {\n _assetPrincipalBalance[assetToken] = IERC20(assetToken).balanceOf(address(this));\n }\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../../lib/WalletManagerBase.sol\";\nimport \"./GenericSmartWallet.sol\";\n\n/**\n * @notice Generic ERC20 Wallet Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericWalletManager is WalletManagerBase {\n using SafeMath for uint256;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new GenericSmartWallet());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return GenericSmartWallet(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return GenericSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getTotal(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return GenericSmartWallet(_wallets[uuid]).getInterest(assetToken);\n }\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getRewards(rewardToken);\n }\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount)\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = GenericSmartWallet(wallet).deposit(assetToken, assetAmount, 0);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmountForCreator(\n address /* receiver */,\n address /* contractAddress */,\n uint256 /* tokenId */,\n address /* creator */,\n address /* assetToken */,\n uint256 /* assetAmount */\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release from interest first + principal if needed\n principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n external\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return GenericSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n // no-op\n }\n\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct)\n external\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n\n if (creator != address(0x0)) {\n GenericSmartWallet(wallet).setNftCreator(creator, annuityPct);\n }\n\n emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n GenericSmartWallet(newWallet).initialize();\n return newWallet;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericWalletManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericWalletManagerB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../../lib/WalletManagerBase.sol\";\nimport \"./GenericSmartWalletB.sol\";\n\n/**\n * @notice Generic ERC20 Wallet Manager B\n * @dev Non-upgradeable Contract\n */\ncontract GenericWalletManagerB is WalletManagerBase {\n using SafeMath for uint256;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new GenericSmartWalletB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return GenericSmartWalletB(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return GenericSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getTotal(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return GenericSmartWalletB(_wallets[uuid]).getInterest(assetToken, 0);\n }\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getRewards(rewardToken);\n }\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount)\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = GenericSmartWalletB(wallet).deposit(assetToken, assetAmount, 0);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmountForCreator(\n address /* receiver */,\n address /* contractAddress */,\n uint256 /* tokenId */,\n address /* creator */,\n address /* assetToken */,\n uint256 /* assetAmount */\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdraw(receiver, creatorRedirect, 0, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release from interest first + principal if needed\n principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdrawAmount(receiver, creatorRedirect, 0, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyControllerOrExecutor\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n external\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return GenericSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n GenericSmartWalletB(wallet).refreshPrincipal(assetToken);\n }\n\n function getWalletAddressById(address contractAddress, uint256 tokenId, address /* creator */, uint256 /* annuityPct */)\n external\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n GenericSmartWalletB(newWallet).initialize();\n return newWallet;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericBasketManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"../../../interfaces/IBasketManager.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"./GenericSmartBasket.sol\";\n\n/**\n * @notice Generic ERC721 Basket Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericBasketManager is Ownable, BlackholePrevention, IBasketManager {\n using Counters for Counters.Counter;\n using TokenInfo for address;\n\n // The Controller Contract Address\n address internal _controller;\n\n // Template Contract for creating Token Smart-Baskets\n address internal _basketTemplate;\n\n // TokenID => Token Smart-Basket Address\n mapping (uint256 => address) internal _baskets;\n\n mapping (uint256 => Counters.Counter) internal _totalTokens;\n\n // State of Basket Manager\n bool internal _paused;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _basketTemplate = address(new GenericSmartBasket());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n function getTokenTotalCount(\n address contractAddress,\n uint256 tokenId\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n return _totalTokens[uuid].current();\n }\n\n function getTokenCountByType(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n external\n override\n returns (uint256)\n {\n address basket = getBasketAddressById(contractAddress, tokenId);\n return GenericSmartBasket(basket).getTokenCountByType(basketTokenAddress, basketTokenId);\n }\n\n function prepareTransferAmount(uint256 /* nftTokenAmount */) external override onlyController {\n // no-op\n }\n\n function addToBasket(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n whenNotPaused\n returns (bool added)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n added = GenericSmartBasket(basket).addToBasket(basketTokenAddress, basketTokenId);\n\n // Log Event\n if (added) {\n _totalTokens[uuid].increment();\n emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, 1);\n }\n }\n\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n returns (bool removed)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n removed = GenericSmartBasket(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId);\n\n // Log Event\n if (removed) {\n _totalTokens[uuid].decrement();\n emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, 1);\n }\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyController\n returns (uint256 amount)\n {\n // no-op\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n public\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n return GenericSmartBasket(basket).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function getBasketAddressById(address contractAddress, uint256 tokenId)\n public\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n // Create Smart-Basket if none exists\n if (basket == address(0x0)) {\n basket = _createBasket();\n _baskets[uuid] = basket;\n\n emit NewSmartBasket(contractAddress, tokenId, basket);\n }\n\n return basket;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Basket Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartBasket(basket).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n function _createBasket()\n internal\n returns (address)\n {\n address newBasket = _createClone(_basketTemplate);\n GenericSmartBasket(newBasket).initialize();\n return newBasket;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"GBM:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"GBM:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericBasketManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport \"../../../interfaces/IBasketManager.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../interfaces/ITokenInfoProxy.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"../../../lib/NftTokenType.sol\";\nimport \"./GenericSmartBasketB.sol\";\n\n/**\n * @notice Generic ERC721 Basket Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericBasketManagerB is Ownable, BlackholePrevention, IBasketManager {\n using Counters for Counters.Counter;\n using TokenInfo for address;\n using NftTokenType for address;\n\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // The Controller Contract Address\n address internal _controller;\n\n // The Executor Contract Address\n address internal _executor;\n\n // Template Contract for creating Token Smart-Baskets\n address internal _basketTemplate;\n\n // TokenID => Token Smart-Basket Address\n mapping (uint256 => address) internal _baskets;\n\n // Prepared Amount\n uint256 internal _preparedAmount;\n\n // State of Basket Manager\n bool internal _paused;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _basketTemplate = address(new GenericSmartBasketB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n function getTokenTotalCount(\n address contractAddress,\n uint256 tokenId\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n if (basket == address(0)) { return 0; }\n return GenericSmartBasketB(basket).getNestedNftCount();\n }\n\n function getTokenCountByType(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n if (basket == address(0)) { return 0; }\n return GenericSmartBasketB(basket).getTokenCountByType(basketTokenAddress, basketTokenId);\n }\n\n function prepareTransferAmount(uint256 nftTokenAmount) external override onlyController {\n _preparedAmount = nftTokenAmount;\n }\n\n function addToBasket(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n whenNotPaused\n returns (bool added)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n uint256 nftTokenAmount = 1;\n if (_preparedAmount > 0) {\n nftTokenAmount = _preparedAmount;\n _preparedAmount = 0;\n }\n\n added = GenericSmartBasketB(basket).addToBasket(basketTokenAddress, basketTokenId, nftTokenAmount);\n if (added) {\n emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount);\n }\n }\n\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n returns (bool removed)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n uint256 nftTokenAmount = 1;\n if (_preparedAmount > 0) {\n nftTokenAmount = _preparedAmount;\n _preparedAmount = 0;\n }\n\n removed = GenericSmartBasketB(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId, nftTokenAmount);\n if (removed) {\n emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount);\n }\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyControllerOrExecutor\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartBasketB(basket).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit BasketRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n public\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n return GenericSmartBasketB(basket).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function getBasketAddressById(address contractAddress, uint256 tokenId)\n public\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n // Create Smart-Basket if none exists\n if (basket == address(0x0)) {\n basket = _createBasket();\n _baskets[uuid] = basket;\n\n emit NewSmartBasket(contractAddress, tokenId, basket);\n }\n\n return basket;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Basket Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n /**\n * @dev Connects to the ExecForAccount Controller\n */\n function setExecutor(address executor) external onlyOwner {\n _executor = executor;\n emit ExecutorSet(executor);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setTokenInfoProxy(address tokenInfoProxy) external onlyOwner {\n _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartBasket(basket).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createBasket()\n internal\n returns (address)\n {\n address newBasket = _createClone(_basketTemplate);\n GenericSmartBasketB(newBasket).initialize(_tokenInfoProxy);\n return newBasket;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"GBM:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Controller or Executor contract\n modifier onlyControllerOrExecutor() {\n require(_executor == msg.sender || _controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"GBM:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericSmartBasket.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/NftTokenType.sol\";\n\n\n/**\n * @notice Generic ERC721-Token Smart-Basket\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartBasket is ISmartBasket, BlackholePrevention, IERC721Receiver {\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableSet for EnumerableSet.AddressSet;\n using NftTokenType for address;\n\n address internal _basketManager;\n\n // NFT contract address => Token Ids in Basket\n mapping (address => mapping(uint256 => EnumerableSet.UintSet)) internal _nftContractTokens;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public {\n require(_basketManager == address(0x0), \"GSB:E-002\");\n _basketManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n return _nftContractTokens[contractAddress][nftType].length();\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver(0).onERC721Received.selector;\n }\n\n function addToBasket(address contractAddress, uint256 tokenId)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n require(!_nftContractTokens[contractAddress][nftType].contains(tokenId), \"GSB:E-425\");\n\n bool added = _nftContractTokens[contractAddress][nftType].add(tokenId);\n if (added) {\n // NFT should have been Transferred into here via Charged-Particles\n added = (IERC721(contractAddress).ownerOf(tokenId) == address(this));\n }\n return added;\n }\n\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n require(_nftContractTokens[contractAddress][nftType].contains(tokenId), \"GSB:E-426\");\n\n bool removed = _nftContractTokens[contractAddress][nftType].remove(tokenId);\n if (removed) {\n IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId);\n }\n return removed;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyBasketManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the basket manager\n modifier onlyBasketManager() {\n require(_basketManager == msg.sender, \"GSB:E-109\");\n _;\n }\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericSmartBasketB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155Receiver.sol\";\nimport \"../../../interfaces/ISmartBasketB.sol\";\nimport \"../../../interfaces/ITokenInfoProxy.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"../../../lib/NftTokenType.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\n\n/**\n * @notice Generic ERC721-Token Smart-Basket\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartBasketB is ISmartBasketB, BlackholePrevention, IERC721Receiver, ERC1155Receiver {\n using TokenInfo for address;\n using NftTokenType for address;\n\n address internal _basketManager;\n\n // NFT TokenUUID => ERC1155 Balance\n mapping (uint256 => uint256) internal _nftContractTokenBalance;\n uint256 internal _nestedNftCount;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(ITokenInfoProxy /* tokenInfoProxy */) public {\n require(_basketManager == address(0x0), \"GSB:E-002\");\n _basketManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getNestedNftCount() external view override returns (uint256) {\n return _nestedNftCount;\n }\n\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n return _nftContractTokenBalance[contractAddress.getTokenUUID(tokenId)];\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver(0).onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\n return IERC1155Receiver(0).onERC1155Received.selector;\n }\n\n // Unimplemented\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\n return \"\"; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector;\n }\n\n function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n _nftContractTokenBalance[uuid] += nftTokenAmount;\n _nestedNftCount += nftTokenAmount;\n return true;\n }\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n uint256 nftTokenAmount\n )\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n _nftContractTokenBalance[uuid] -= nftTokenAmount;\n _nestedNftCount -= nftTokenAmount;\n\n if (contractAddress.isERC1155()) {\n IERC1155(contractAddress).safeTransferFrom(address(this), receiver, tokenId, nftTokenAmount, \"\");\n } else {\n IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId);\n }\n return true;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyBasketManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSB:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyBasketManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the basket manager\n modifier onlyBasketManager() {\n require(_basketManager == msg.sender, \"GSB:E-109\");\n _;\n }\n}\n" + }, + "erc20permit/contracts/ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"./IERC2612.sol\";\n\n/**\n * @author Georgios Konstantopoulos\n * @dev Extension of {ERC20} that allows token holders to use their tokens\n * without sending any transactions by setting {IERC20-allowance} with a\n * signature using the {permit} method, and then spend them via\n * {IERC20-transferFrom}.\n *\n * The {permit} signature mechanism conforms to the {IERC2612} interface.\n */\nabstract contract ERC20Permit is ERC20, IERC2612 {\n mapping (address => uint256) public override nonces;\n\n bytes32 public immutable PERMIT_TYPEHASH = keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public immutable DOMAIN_SEPARATOR;\n\n constructor(string memory name_, string memory symbol_) internal ERC20(name_, symbol_) {\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name_)),\n keccak256(bytes(\"1\")),\n chainId,\n address(this)\n )\n );\n }\n\n /**\n * @dev See {IERC2612-permit}.\n *\n * In cases where the free option is not a concern, deadline can simply be\n * set to uint(-1), so it should be seen as an optional parameter\n */\n function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {\n require(deadline >= block.timestamp, \"ERC20Permit: expired deadline\");\n\n bytes32 hashStruct = keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n amount,\n nonces[owner]++,\n deadline\n )\n );\n\n bytes32 hash = keccak256(\n abi.encodePacked(\n '\\x19\\x01',\n DOMAIN_SEPARATOR,\n hashStruct\n )\n );\n\n address signer = ecrecover(hash, v, r, s);\n require(\n signer != address(0) && signer == owner,\n \"ERC20Permit: invalid signature\"\n );\n\n _approve(owner, spender, amount);\n }\n}\n" + }, + "erc20permit/contracts/IERC2612.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC2612 standard as defined in the EIP.\n *\n * Adds the {permit} method, which can be used to change one's\n * {IERC20-allowance} without having to send a transaction, by signing a\n * message. This allows users to spend tokens without having to hold Ether.\n *\n * See https://eips.ethereum.org/EIPS/eip-2612.\n */\ninterface IERC2612 {\n /**\n * @dev Sets `amount` 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 * - `owner` cannot be the zero address.\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(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n /**\n * @dev Returns the current ERC2612 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" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "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/deployments/mumbai/.chainId b/deployments/mumbai/.chainId new file mode 100644 index 0000000..d7e2f72 --- /dev/null +++ b/deployments/mumbai/.chainId @@ -0,0 +1 @@ +80001 \ No newline at end of file diff --git a/deployments/mumbai/DefaultProxyAdmin.json b/deployments/mumbai/DefaultProxyAdmin.json new file mode 100644 index 0000000..b268174 --- /dev/null +++ b/deployments/mumbai/DefaultProxyAdmin.json @@ -0,0 +1,274 @@ +{ + "address": "0x6f23A65878cd6A71b87B7F72C4F2870090F711b0", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "initialOwner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "upgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ], + "transactionHash": "0xde5e1f10cba7a0c97507000cf4217f9305980c5753b800348220b96c769141cc", + "receipt": { + "to": null, + "from": "0x6d46b37708dA7Ed4E5C4509495768Fecd3D17C01", + "contractAddress": "0x6f23A65878cd6A71b87B7F72C4F2870090F711b0", + "transactionIndex": 0, + "gasUsed": "643983", + "logsBloom": "0x00000000000000000000000010000000000000000000000000800000000000000000000020000000000000000000000000008000002000000008000000000000000000000000000000000000000020800001000000000000040100000000000000000000020000000000000000000800000000000000000080000000000000400000000000000000000000000000000000000000040000000400000000000000200000000000000000000000000000000000000000000000000040000000004000000000000000000001000000000000000000000000000000100000000020000000000000000000000000000000000000000000000000000000000000100000", + "blockHash": "0x964f51b9852b83d7ccd2d3c27084ff5c453b00645e51a62e43b1d7ab87e289ab", + "transactionHash": "0xde5e1f10cba7a0c97507000cf4217f9305980c5753b800348220b96c769141cc", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 39278940, + "transactionHash": "0xde5e1f10cba7a0c97507000cf4217f9305980c5753b800348220b96c769141cc", + "address": "0x6f23A65878cd6A71b87B7F72C4F2870090F711b0", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000006d46b37708da7ed4e5c4509495768fecd3d17c01" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x964f51b9852b83d7ccd2d3c27084ff5c453b00645e51a62e43b1d7ab87e289ab" + }, + { + "transactionIndex": 0, + "blockNumber": 39278940, + "transactionHash": "0xde5e1f10cba7a0c97507000cf4217f9305980c5753b800348220b96c769141cc", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000006d46b37708da7ed4e5c4509495768fecd3d17c01", + "0x000000000000000000000000c275dc8be39f50d12f66b6a63629c39da5bae5bd" + ], + "data": "0x0000000000000000000000000000000000000000000000000016e0fdc2df7bf2000000000000000000000000000000000000000000000000a51fe1c8afd30677000000000000000000000000000000000000000000001299d85893db1a713ab9000000000000000000000000000000000000000000000000a50900caecf38a85000000000000000000000000000000000000000000001299d86f74d8dd50b6ab", + "logIndex": 1, + "blockHash": "0x964f51b9852b83d7ccd2d3c27084ff5c453b00645e51a62e43b1d7ab87e289ab" + } + ], + "blockNumber": 39278940, + "cumulativeGasUsed": "643983", + "status": 1, + "byzantium": true + }, + "args": [ + "0x6d46b37708dA7Ed4E5C4509495768Fecd3D17C01" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"initialOwner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\",\"kind\":\"dev\",\"methods\":{\"changeProxyAdmin(address,address)\":{\"details\":\"Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`.\"},\"getProxyAdmin(address)\":{\"details\":\"Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"getProxyImplementation(address)\":{\"details\":\"Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"upgrade(address,address)\":{\"details\":\"Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`.\"},\"upgradeAndCall(address,address,bytes)\":{\"details\":\"Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol\":\"ProxyAdmin\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/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 (address initialOwner) {\\n _transferOwnership(initialOwner);\\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\",\"keccak256\":\"0x9b2bbba5bb04f53f277739c1cdff896ba8b3bf591cfc4eab2098c655e8ac251e\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./TransparentUpgradeableProxy.sol\\\";\\nimport \\\"../../access/Ownable.sol\\\";\\n\\n/**\\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\\n */\\ncontract ProxyAdmin is Ownable {\\n\\n constructor (address initialOwner) Ownable(initialOwner) {}\\n\\n /**\\n * @dev Returns the current implementation of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"implementation()\\\")) == 0x5c60da1b\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"5c60da1b\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Returns the current admin of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"admin()\\\")) == 0xf851a440\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"f851a440\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Changes the admin of `proxy` to `newAdmin`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the current admin of `proxy`.\\n */\\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\\n proxy.changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\\n proxy.upgradeTo(implementation);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgradeAndCall(\\n TransparentUpgradeableProxy proxy,\\n address implementation,\\n bytes memory data\\n ) public payable virtual onlyOwner {\\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\\n }\\n}\\n\",\"keccak256\":\"0x754888b9c9ab5525343460b0a4fa2e2f4fca9b6a7e0e7ddea4154e2b1182a45d\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev 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\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/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\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50604051610b17380380610b1783398101604081905261002f91610090565b8061003981610040565b50506100c0565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156100a257600080fd5b81516001600160a01b03811681146100b957600080fd5b9392505050565b610a48806100cf6000396000f3fe60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461012b57806399a88ec41461013e578063f2fde38b1461015e578063f3b7dead1461017e57600080fd5b8063204e1c7a14610080578063715018a6146100c95780637eff275e146100e05780638da5cb5b14610100575b600080fd5b34801561008c57600080fd5b506100a061009b3660046107e4565b61019e565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d557600080fd5b506100de610255565b005b3480156100ec57600080fd5b506100de6100fb366004610808565b6102e7565b34801561010c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100a0565b6100de610139366004610870565b6103ee565b34801561014a57600080fd5b506100de610159366004610808565b6104fc565b34801561016a57600080fd5b506100de6101793660046107e4565b6105d1565b34801561018a57600080fd5b506100a06101993660046107e4565b610701565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b600060405180830381855afa9150503d8060008114610225576040519150601f19603f3d011682016040523d82523d6000602084013e61022a565b606091505b50915091508161023957600080fd5b8080602001905181019061024d9190610964565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6102e5600061074d565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610368576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b600060405180830381600087803b1580156103d257600080fd5b505af11580156103e6573d6000803e3d6000fd5b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461046f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef2869034906104c59086908690600401610981565b6000604051808303818588803b1580156104de57600080fd5b505af11580156104f2573d6000803e3d6000fd5b5050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461057d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016103b8565b60005473ffffffffffffffffffffffffffffffffffffffff163314610652576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b73ffffffffffffffffffffffffffffffffffffffff81166106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102d2565b6106fe8161074d565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146106fe57600080fd5b6000602082840312156107f657600080fd5b8135610801816107c2565b9392505050565b6000806040838503121561081b57600080fd5b8235610826816107c2565b91506020830135610836816107c2565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561088557600080fd5b8335610890816107c2565b925060208401356108a0816107c2565b9150604084013567ffffffffffffffff808211156108bd57600080fd5b818601915086601f8301126108d157600080fd5b8135818111156108e3576108e3610841565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561092957610929610841565b8160405282815289602084870101111561094257600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561097657600080fd5b8151610801816107c2565b73ffffffffffffffffffffffffffffffffffffffff8316815260006020604081840152835180604085015260005b818110156109cb578581018301518582016060015282016109af565b818111156109dd576000606083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160600194935050505056fea2646970667358221220bd6c09ab03bfaf9ec60a4bf8cd98903cecb891974e17e2d76a3b2002c97eeb8964736f6c634300080a0033", + "deployedBytecode": "0x60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461012b57806399a88ec41461013e578063f2fde38b1461015e578063f3b7dead1461017e57600080fd5b8063204e1c7a14610080578063715018a6146100c95780637eff275e146100e05780638da5cb5b14610100575b600080fd5b34801561008c57600080fd5b506100a061009b3660046107e4565b61019e565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d557600080fd5b506100de610255565b005b3480156100ec57600080fd5b506100de6100fb366004610808565b6102e7565b34801561010c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100a0565b6100de610139366004610870565b6103ee565b34801561014a57600080fd5b506100de610159366004610808565b6104fc565b34801561016a57600080fd5b506100de6101793660046107e4565b6105d1565b34801561018a57600080fd5b506100a06101993660046107e4565b610701565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b600060405180830381855afa9150503d8060008114610225576040519150601f19603f3d011682016040523d82523d6000602084013e61022a565b606091505b50915091508161023957600080fd5b8080602001905181019061024d9190610964565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6102e5600061074d565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610368576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b600060405180830381600087803b1580156103d257600080fd5b505af11580156103e6573d6000803e3d6000fd5b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461046f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef2869034906104c59086908690600401610981565b6000604051808303818588803b1580156104de57600080fd5b505af11580156104f2573d6000803e3d6000fd5b5050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461057d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016103b8565b60005473ffffffffffffffffffffffffffffffffffffffff163314610652576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b73ffffffffffffffffffffffffffffffffffffffff81166106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102d2565b6106fe8161074d565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146106fe57600080fd5b6000602082840312156107f657600080fd5b8135610801816107c2565b9392505050565b6000806040838503121561081b57600080fd5b8235610826816107c2565b91506020830135610836816107c2565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561088557600080fd5b8335610890816107c2565b925060208401356108a0816107c2565b9150604084013567ffffffffffffffff808211156108bd57600080fd5b818601915086601f8301126108d157600080fd5b8135818111156108e3576108e3610841565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561092957610929610841565b8160405282815289602084870101111561094257600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561097657600080fd5b8151610801816107c2565b73ffffffffffffffffffffffffffffffffffffffff8316815260006020604081840152835180604085015260005b818110156109cb578581018301518582016060015282016109af565b818111156109dd576000606083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160600194935050505056fea2646970667358221220bd6c09ab03bfaf9ec60a4bf8cd98903cecb891974e17e2d76a3b2002c97eeb8964736f6c634300080a0033", + "devdoc": { + "details": "This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.", + "kind": "dev", + "methods": { + "changeProxyAdmin(address,address)": { + "details": "Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`." + }, + "getProxyAdmin(address)": { + "details": "Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`." + }, + "getProxyImplementation(address)": { + "details": "Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`." + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + }, + "upgrade(address,address)": { + "details": "Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`." + }, + "upgradeAndCall(address,address,bytes)": { + "details": "Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 7, + "contract": "solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol:ProxyAdmin", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + } + } + } +} \ No newline at end of file diff --git a/deployments/mumbai/Ionx.json b/deployments/mumbai/Ionx.json new file mode 100644 index 0000000..54cafd4 --- /dev/null +++ b/deployments/mumbai/Ionx.json @@ -0,0 +1,965 @@ +{ + "address": "0x2fe0A013b7DBAD803BdC3ad19231259e9675dD24", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newMinter", + "type": "address" + } + ], + "name": "MinterChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INFLATION_CAP", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INFLATION_EPOCH", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIAL_SUPPLY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "minter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mintingAllowedAfter", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newMinter", + "type": "address" + } + ], + "name": "setMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xa75f715aa210a34a5a40ff455226cadc7e74be40bfdefa7a97d26910ff3a822c", + "receipt": { + "to": null, + "from": "0x6d46b37708dA7Ed4E5C4509495768Fecd3D17C01", + "contractAddress": "0x2fe0A013b7DBAD803BdC3ad19231259e9675dD24", + "transactionIndex": 0, + "gasUsed": "1853116", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000008000002000000000000000000000000000000000000000000000000020800001000000000000040100000000000000000000020000000000000000000800000000000000000080000000000000400000000000000000000000000000000000000000040000000400000000000000200000000000000000000040000000000000000000000000000040000080004000000000000000000001000000000000000000000000000000100000000020000000001000000000000000000000000000000000000000000000000000100000", + "blockHash": "0x3e7900057abc21e7c1a3bbf125560e40ce171f7696a48e1a027296ad5e6deaad", + "transactionHash": "0xa75f715aa210a34a5a40ff455226cadc7e74be40bfdefa7a97d26910ff3a822c", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 39278931, + "transactionHash": "0xa75f715aa210a34a5a40ff455226cadc7e74be40bfdefa7a97d26910ff3a822c", + "address": "0x2fe0A013b7DBAD803BdC3ad19231259e9675dD24", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000006d46b37708da7ed4e5c4509495768fecd3d17c01" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x3e7900057abc21e7c1a3bbf125560e40ce171f7696a48e1a027296ad5e6deaad" + }, + { + "transactionIndex": 0, + "blockNumber": 39278931, + "transactionHash": "0xa75f715aa210a34a5a40ff455226cadc7e74be40bfdefa7a97d26910ff3a822c", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000006d46b37708da7ed4e5c4509495768fecd3d17c01", + "0x000000000000000000000000c275dc8be39f50d12f66b6a63629c39da5bae5bd" + ], + "data": "0x0000000000000000000000000000000000000000000000000041d5fde71676c8000000000000000000000000000000000000000000000000a566b9bc5fd9ba77000000000000000000000000000000000000000000001299d74f15c96470eed6000000000000000000000000000000000000000000000000a524e3be78c343af000000000000000000000000000000000000000000001299d790ebc74b87659e", + "logIndex": 1, + "blockHash": "0x3e7900057abc21e7c1a3bbf125560e40ce171f7696a48e1a027296ad5e6deaad" + } + ], + "blockNumber": 39278931, + "cumulativeGasUsed": "1853116", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "3c4a4867d03c114eb5175ff04b48a99d", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newMinter\",\"type\":\"address\"}],\"name\":\"MinterChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC1155\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckEther\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INFLATION_CAP\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INFLATION_EPOCH\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIAL_SUPPLY\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PERMIT_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"mintingAllowedAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newMinter\",\"type\":\"address\"}],\"name\":\"setMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawErc20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawEther\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5,05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is called. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"mint(address,uint256)\":{\"params\":{\"amount\":\"The number of tokens to be minted\",\"receiver\":\"The address of the destination account\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC2612-permit}. In cases where the free option is not a concern, deadline can simply be set to uint(-1), so it should be seen as an optional parameter\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"setMinter(address)\":{\"params\":{\"newMinter\":\"The address of the new minter\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}; Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"events\":{\"MinterChanged(address,address)\":{\"notice\":\"An event thats emitted when the minter address is changed\"}},\"kind\":\"user\",\"methods\":{\"INFLATION_CAP()\":{\"notice\":\"Cap on the percentage of totalSupply that can be minted at each mint\"},\"INFLATION_EPOCH()\":{\"notice\":\"Minimum time between mints\"},\"INITIAL_SUPPLY()\":{\"notice\":\"Total number of tokens in circulation\"},\"mint(address,uint256)\":{\"notice\":\"Mint new tokens\"},\"minter()\":{\"notice\":\"Address which may mint new tokens\"},\"mintingAllowedAfter()\":{\"notice\":\"The timestamp after which minting may occur\"},\"setMinter(address)\":{\"notice\":\"Change the minter address\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/v1/tokens/Ionx.sol\":\"Ionx\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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 GSN 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 payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xdb26cbf4d028490f49831a7865c2fe1b28db44b535ca8d343785a3b768aae183\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"../GSN/Context.sol\\\";\\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 */\\ncontract 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 () internal {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view 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 emit OwnershipTransferred(_owner, address(0));\\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x4bd6402ca6b3419008c2b482aff54e66836e8cb4eba2680e42ac5884ae6424fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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\",\"keccak256\":\"0xfa152b6e88a1dc50780e8f1580426dc23ad2e1e2c2f086a088adf206a202f453\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\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 uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\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 sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\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 * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\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 // 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) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts 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 mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9a9cf02622cd7a64261b10534fc3260449da25c98c9e96d1b4ae8110a20e5806\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x31691ad0817f8cb338531b78d2ab2989027d9f27e6f8e62492b754fed9429b10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"../../GSN/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.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 guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 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 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\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 uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name, string memory symbol) public {\\n _name = name;\\n _symbol = symbol;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view 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 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 {_setupDecimals} is\\n * called.\\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 returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal {\\n _decimals = decimals_;\\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 to 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(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0x91e0bd6a6762d2a1700dab0849de8422611355100576c4beef1e80d82a4104a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0x5c26b39d26f7ed489e555d955dcd3e01872972e71fdd1528e93ec164e4f23385\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.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 SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf3b30f8a49631420635a8c35daacfcaa338012755f18a76fdd118730256f9a27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0xaf936da92f3a9a4f98b237323b5eb1d813fb86c4d07a184beba7027cf0509ba3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 in 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 // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n return _functionCallWithValue(target, data, value, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\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 // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf5fa8cbdffa5ef8be49b246b5628facc30b71707e78a45d80d93b64eff3fe390\",\"license\":\"MIT\"},\"contracts/v1/lib/BlackholePrevention.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\\\";\\n\\n/**\\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\\n * the Owner/DAO to pull them out on behalf of a user\\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\\n */\\ncontract BlackholePrevention {\\n using Address for address payable;\\n using SafeERC20 for IERC20;\\n\\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\\n\\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (address(this).balance >= amount) {\\n receiver.sendValue(amount);\\n emit WithdrawStuckEther(receiver, amount);\\n }\\n }\\n\\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\\n IERC20(tokenAddress).safeTransfer(receiver, amount);\\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\\n }\\n }\\n\\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\\n }\\n }\\n\\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \\\"\\\");\\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6a664c8a1c1d7fb32ade2c11f75756b1fdb4c489daa32c1d58e6b867ea2ba8d6\",\"license\":\"MIT\"},\"contracts/v1/tokens/Ionx.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// Ionx.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\n\\nimport \\\"erc20permit/contracts/ERC20Permit.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"../lib/BlackholePrevention.sol\\\";\\n\\n\\ncontract Ionx is ERC20Permit, Ownable, BlackholePrevention {\\n using SafeMath for uint256;\\n\\n /// @notice An event thats emitted when the minter address is changed\\n event MinterChanged(address minter, address newMinter);\\n\\n /// @notice Total number of tokens in circulation\\n uint256 constant public INITIAL_SUPPLY = 1e8 ether;\\n\\n /// @notice Minimum time between mints\\n uint32 public constant INFLATION_EPOCH = 1 days * 365;\\n\\n /// @notice Cap on the percentage of totalSupply that can be minted at each mint\\n uint8 public constant INFLATION_CAP = 2;\\n\\n /// @notice Address which may mint new tokens\\n address public minter;\\n\\n /// @notice The timestamp after which minting may occur\\n uint256 public mintingAllowedAfter;\\n\\n\\n constructor() public ERC20Permit(\\\"Charged Particles - IONX\\\", \\\"IONX\\\") {}\\n\\n\\n /**\\n * @notice Change the minter address\\n * @param newMinter The address of the new minter\\n */\\n function setMinter(address newMinter) external onlyOwner {\\n emit MinterChanged(minter, newMinter);\\n minter = newMinter;\\n }\\n\\n /**\\n * @notice Mint new tokens\\n * @param receiver The address of the destination account\\n * @param amount The number of tokens to be minted\\n */\\n function mint(address receiver, uint256 amount) external onlyMinter {\\n require(block.timestamp >= mintingAllowedAfter, \\\"Ionx:E-114\\\");\\n require(receiver != address(0), \\\"Ionx:E-403\\\");\\n\\n uint256 amountToMint = amount;\\n uint256 _totalSupply = totalSupply();\\n\\n // From Inflationary Supply\\n if (_totalSupply >= INITIAL_SUPPLY) {\\n mintingAllowedAfter = mintingAllowedAfter.add(INFLATION_EPOCH);\\n amountToMint = _totalSupply.mul(INFLATION_CAP).div(100);\\n }\\n\\n // From Initial Supply\\n else {\\n if (_totalSupply.add(amountToMint) > INITIAL_SUPPLY) {\\n amountToMint = INITIAL_SUPPLY.sub(_totalSupply);\\n }\\n if (_totalSupply.add(amountToMint) == INITIAL_SUPPLY) {\\n mintingAllowedAfter = block.timestamp.add(INFLATION_EPOCH);\\n }\\n }\\n\\n // transfer the amount to the recipient\\n _mint(receiver, amountToMint);\\n }\\n\\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n modifier onlyMinter() {\\n require(msg.sender == minter, \\\"Ionx:E-113\\\");\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x248e7f30883795c45e37a90aa8e7cd94cd09fb618122b09d83fd98d2d63fd37d\",\"license\":\"MIT\"},\"erc20permit/contracts/ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\\npragma solidity ^0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"./IERC2612.sol\\\";\\n\\n/**\\n * @author Georgios Konstantopoulos\\n * @dev Extension of {ERC20} that allows token holders to use their tokens\\n * without sending any transactions by setting {IERC20-allowance} with a\\n * signature using the {permit} method, and then spend them via\\n * {IERC20-transferFrom}.\\n *\\n * The {permit} signature mechanism conforms to the {IERC2612} interface.\\n */\\nabstract contract ERC20Permit is ERC20, IERC2612 {\\n mapping (address => uint256) public override nonces;\\n\\n bytes32 public immutable PERMIT_TYPEHASH = keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n bytes32 public immutable DOMAIN_SEPARATOR;\\n\\n constructor(string memory name_, string memory symbol_) internal ERC20(name_, symbol_) {\\n uint256 chainId;\\n assembly {\\n chainId := chainid()\\n }\\n\\n DOMAIN_SEPARATOR = keccak256(\\n abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"),\\n keccak256(bytes(name_)),\\n keccak256(bytes(\\\"1\\\")),\\n chainId,\\n address(this)\\n )\\n );\\n }\\n\\n /**\\n * @dev See {IERC2612-permit}.\\n *\\n * In cases where the free option is not a concern, deadline can simply be\\n * set to uint(-1), so it should be seen as an optional parameter\\n */\\n function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {\\n require(deadline >= block.timestamp, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 hashStruct = keccak256(\\n abi.encode(\\n PERMIT_TYPEHASH,\\n owner,\\n spender,\\n amount,\\n nonces[owner]++,\\n deadline\\n )\\n );\\n\\n bytes32 hash = keccak256(\\n abi.encodePacked(\\n '\\\\x19\\\\x01',\\n DOMAIN_SEPARATOR,\\n hashStruct\\n )\\n );\\n\\n address signer = ecrecover(hash, v, r, s);\\n require(\\n signer != address(0) && signer == owner,\\n \\\"ERC20Permit: invalid signature\\\"\\n );\\n\\n _approve(owner, spender, amount);\\n }\\n}\\n\",\"keccak256\":\"0x2207175c262cdffe2f4e0a31d0c35e02a0ebf2528f21009be6b7743eeb474eaa\",\"license\":\"GPL-3.0-or-later\"},\"erc20permit/contracts/IERC2612.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n// Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Interface of the ERC2612 standard as defined in the EIP.\\n *\\n * Adds the {permit} method, which can be used to change one's\\n * {IERC20-allowance} without having to send a transaction, by signing a\\n * message. This allows users to spend tokens without having to hold Ether.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2612.\\n */\\ninterface IERC2612 {\\n /**\\n * @dev Sets `amount` 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 * - `owner` cannot be the zero address.\\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(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\\n\\n /**\\n * @dev Returns the current ERC2612 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\",\"keccak256\":\"0xe79dd739aaa881172ede4d81472ded9db3a0b4183573c0c01541b4084033b222\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x60c06040527f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c96080523480156200003557600080fd5b50604080518082018252601881527f43686172676564205061727469636c6573202d20494f4e5800000000000000006020808301918252835180850190945260048452630929e9cb60e31b908401528151919291839183916200009b91600391620001c2565b508051620000b1906004906020840190620001c2565b50506005805460ff191660121790555050805160209182012060408051808201825260018152603160f81b9084015280517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81850152808201929092527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608301524660808301523060a08084019190915281518084038201815260c090930190915281519190920120905260006200016a620001be565b600780546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506200025e565b3390565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200020557805160ff191683800117855562000235565b8280016001018555821562000235579182015b828111156200023557825182559160200191906001019062000218565b506200024392915062000247565b5090565b5b8082111562000243576000815560010162000248565b60805160a051611ec16200028c600039806107e35280610d5d5250806107b05280610cf05250611ec16000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80634025feb2116100f957806395d89b4111610097578063d505accf11610071578063d505accf1461050f578063dd62ed3e14610560578063f2fde38b1461058e578063fca3b5aa146105b4576101c4565b806395d89b41146104af578063a457c2d7146104b7578063a9059cbb146104e3576101c4565b806370a08231116100d357806370a0823114610453578063715018a6146104795780637ecebe00146104815780638da5cb5b146104a7576101c4565b80634025feb2146103c557806340c10f19146103fb578063522f681514610427576101c4565b806323b872dd1161016657806330b36cef1161014057806330b36cef14610381578063313ce567146103895780633644e515146103915780633950935114610399576101c4565b806323b872dd1461033b5780632ff2e9dc1461037157806330adf81f14610379576101c4565b80630d1715be116101a25780630d1715be146102aa5780631593dee1146102cb57806318160ddd146103035780631dcb3a3c1461031d576101c4565b806306fdde03146101c95780630754617214610246578063095ea7b31461026a575b600080fd5b6101d16105da565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561020b5781810151838201526020016101f3565b50505050905090810190601f1680156102385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61024e610670565b604080516001600160a01b039092168252519081900360200190f35b6102966004803603604081101561028057600080fd5b506001600160a01b03813516906020013561067f565b604080519115158252519081900360200190f35b6102b261069d565b6040805163ffffffff9092168252519081900360200190f35b610301600480360360608110156102e157600080fd5b506001600160a01b038135811691602081013590911690604001356106a5565b005b61030b61070d565b60408051918252519081900360200190f35b610325610713565b6040805160ff9092168252519081900360200190f35b6102966004803603606081101561035157600080fd5b506001600160a01b03813581169160208101359091169060400135610718565b61030b61079f565b61030b6107ae565b61030b6107d2565b6103256107d8565b61030b6107e1565b610296600480360360408110156103af57600080fd5b506001600160a01b038135169060200135610805565b610301600480360360608110156103db57600080fd5b506001600160a01b03813581169160208101359091169060400135610853565b6103016004803603604081101561041157600080fd5b506001600160a01b0381351690602001356108b6565b6103016004803603604081101561043d57600080fd5b506001600160a01b038135169060200135610a50565b61030b6004803603602081101561046957600080fd5b50356001600160a01b0316610ab6565b610301610ad1565b61030b6004803603602081101561049757600080fd5b50356001600160a01b0316610b73565b61024e610b85565b6101d1610b94565b610296600480360360408110156104cd57600080fd5b506001600160a01b038135169060200135610bf5565b610296600480360360408110156104f957600080fd5b506001600160a01b038135169060200135610c5d565b610301600480360360e081101561052557600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c00135610c71565b61030b6004803603604081101561057657600080fd5b506001600160a01b0381358116916020013516610e9f565b610301600480360360208110156105a457600080fd5b50356001600160a01b0316610eca565b610301600480360360208110156105ca57600080fd5b50356001600160a01b0316610fc3565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106665780601f1061063b57610100808354040283529160200191610666565b820191906000526020600020905b81548152906001019060200180831161064957829003601f168201915b5050505050905090565b6008546001600160a01b031681565b600061069361068c611085565b8484611089565b5060015b92915050565b6301e1338081565b6106ad611085565b6007546001600160a01b039081169116146106fd576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b610708838383611175565b505050565b60025490565b600281565b600061072584848461129f565b61079584610731611085565b61079085604051806060016040528060288152602001611dac602891396001600160a01b038a1660009081526001602052604081209061076f611085565b6001600160a01b0316815260208101919091526040016000205491906113fa565b611089565b5060019392505050565b6a52b7d2dcc80cd2e400000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60095481565b60055460ff1690565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000610693610812611085565b846107908560016000610823611085565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490611491565b61085b611085565b6007546001600160a01b039081169116146108ab576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b6107088383836114f2565b6008546001600160a01b03163314610902576040805162461bcd60e51b815260206004820152600a602482015269496f6e783a452d31313360b01b604482015290519081900360640190fd5b600954421015610946576040805162461bcd60e51b815260206004820152600a602482015269125bdb9e0e914b4c4c4d60b21b604482015290519081900360640190fd5b6001600160a01b03821661098e576040805162461bcd60e51b815260206004820152600a602482015269496f6e783a452d34303360b01b604482015290519081900360640190fd5b80600061099961070d565b90506a52b7d2dcc80cd2e400000081106109de576009546109be906301e13380611491565b6009556109d760646109d1836002611678565b906116d1565b9150610a40565b6a52b7d2dcc80cd2e40000006109f48284611491565b1115610a1257610a0f6a52b7d2dcc80cd2e400000082611713565b91505b6a52b7d2dcc80cd2e4000000610a288284611491565b1415610a4057610a3c426301e13380611491565b6009555b610a4a8483611755565b50505050565b610a58611085565b6007546001600160a01b03908116911614610aa8576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b610ab28282611845565b5050565b6001600160a01b031660009081526020819052604090205490565b610ad9611085565b6007546001600160a01b03908116911614610b29576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b6007546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600780546001600160a01b0319169055565b60066020526000908152604090205481565b6007546001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106665780601f1061063b57610100808354040283529160200191610666565b6000610693610c02611085565b8461079085604051806060016040528060258152602001611e676025913960016000610c2c611085565b6001600160a01b03908116825260208083019390935260409182016000908120918d168152925290205491906113fa565b6000610693610c6a611085565b848461129f565b42841015610cc6576040805162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e65000000604482015290519081900360640190fd5b6001600160a01b0380881660008181526006602090815260408083208054600180820190925582517f00000000000000000000000000000000000000000000000000000000000000008186015280840196909652958c166060860152608085018b905260a085019590955260c08085018a90528151808603909101815260e08501825280519083012061190160f01b6101008601527f000000000000000000000000000000000000000000000000000000000000000061010286015261012280860182905282518087039091018152610142860180845281519185019190912090859052610162860180845281905260ff8a166101828701526101a286018990526101c2860188905291519095919491926101e2808401939192601f1981019281900390910190855afa158015610e01573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610e375750896001600160a01b0316816001600160a01b0316145b610e88576040805162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e61747572650000604482015290519081900360640190fd5b610e938a8a8a611089565b50505050505050505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610ed2611085565b6007546001600160a01b03908116911614610f22576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b6001600160a01b038116610f675760405162461bcd60e51b8152600401808060200182810382526026815260200180611ce36026913960400191505060405180910390fd5b6007546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600780546001600160a01b0319166001600160a01b0392909216919091179055565b610fcb611085565b6007546001600160a01b0390811691161461101b576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b600854604080516001600160a01b039283168152918316602083015280517f3b0007eb941cf645526cbb3a4fdaecda9d28ce4843167d9263b536a1f1edc0f69281900390910190a1600880546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b0383166110ce5760405162461bcd60e51b8152600401808060200182810382526024815260200180611e196024913960400191505060405180910390fd5b6001600160a01b0382166111135760405162461bcd60e51b8152600401808060200182810382526022815260200180611d096022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0383166111bc576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b80826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561120a57600080fd5b505afa15801561121e573d6000803e3d6000fd5b505050506040513d602081101561123457600080fd5b5051106107085761124f6001600160a01b03831684836118e8565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b836040518082815260200191505060405180910390a3505050565b6001600160a01b0383166112e45760405162461bcd60e51b8152600401808060200182810382526025815260200180611df46025913960400191505060405180910390fd5b6001600160a01b0382166113295760405162461bcd60e51b8152600401808060200182810382526023815260200180611cc06023913960400191505060405180910390fd5b611334838383610708565b61137181604051806060016040528060268152602001611d2b602691396001600160a01b03861660009081526020819052604090205491906113fa565b6001600160a01b0380851660009081526020819052604080822093909355908416815220546113a09082611491565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600081848411156114895760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561144e578181015183820152602001611436565b50505050905090810190601f16801561147b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000828201838110156114eb576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038316611539576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b306001600160a01b0316826001600160a01b0316636352211e836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561158757600080fd5b505afa15801561159b573d6000803e3d6000fd5b505050506040513d60208110156115b157600080fd5b50516001600160a01b0316141561070857604080516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018490529151918416916323b872dd9160648082019260009290919082900301818387803b15801561161a57600080fd5b505af115801561162e573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b60008261168757506000610697565b8282028284828161169457fe5b04146114eb5760405162461bcd60e51b8152600401808060200182810382526021815260200180611d8b6021913960400191505060405180910390fd5b60006114eb83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061193a565b60006114eb83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506113fa565b6001600160a01b0382166117b0576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b6117bc60008383610708565b6002546117c99082611491565b6002556001600160a01b0382166000908152602081905260409020546117ef9082611491565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6001600160a01b03821661188c576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b804710610ab2576118a66001600160a01b0383168261199f565b6040805182815290516001600160a01b038416917eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd919081900360200190a25050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610708908490611a84565b600081836119895760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561144e578181015183820152602001611436565b50600083858161199557fe5b0495945050505050565b804710156119f4576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015290519081900360640190fd5b6040516000906001600160a01b0384169083908381818185875af1925050503d8060008114611a3f576040519150601f19603f3d011682016040523d82523d6000602084013e611a44565b606091505b50509050806107085760405162461bcd60e51b815260040180806020018281038252603a815260200180611d51603a913960400191505060405180910390fd5b6060611ad9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611b359092919063ffffffff16565b80519091501561070857808060200190516020811015611af857600080fd5b50516107085760405162461bcd60e51b815260040180806020018281038252602a815260200180611e3d602a913960400191505060405180910390fd5b6060611b448484600085611b4c565b949350505050565b6060611b5785611cb9565b611ba8576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310611be75780518252601f199092019160209182019101611bc8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114611c49576040519150601f19603f3d011682016040523d82523d6000602084013e611c4e565b606091505b50915091508115611c62579150611b449050565b805115611c725780518082602001fd5b60405162461bcd60e51b815260206004820181815286516024840152865187939192839260440191908501908083836000831561144e578181015183820152602001611436565b3b15159056fe45524332303a207472616e7366657220746f20746865207a65726f20616464726573734f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365416464726573733a20756e61626c6520746f2073656e642076616c75652c20726563697069656e74206d61792068617665207265766572746564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657245524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656445524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220bd76b10c65c03359bbab1305b5a901ae77e87d8d92a0ee8769ed8d6354c54b8364736f6c634300060c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101c45760003560e01c80634025feb2116100f957806395d89b4111610097578063d505accf11610071578063d505accf1461050f578063dd62ed3e14610560578063f2fde38b1461058e578063fca3b5aa146105b4576101c4565b806395d89b41146104af578063a457c2d7146104b7578063a9059cbb146104e3576101c4565b806370a08231116100d357806370a0823114610453578063715018a6146104795780637ecebe00146104815780638da5cb5b146104a7576101c4565b80634025feb2146103c557806340c10f19146103fb578063522f681514610427576101c4565b806323b872dd1161016657806330b36cef1161014057806330b36cef14610381578063313ce567146103895780633644e515146103915780633950935114610399576101c4565b806323b872dd1461033b5780632ff2e9dc1461037157806330adf81f14610379576101c4565b80630d1715be116101a25780630d1715be146102aa5780631593dee1146102cb57806318160ddd146103035780631dcb3a3c1461031d576101c4565b806306fdde03146101c95780630754617214610246578063095ea7b31461026a575b600080fd5b6101d16105da565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561020b5781810151838201526020016101f3565b50505050905090810190601f1680156102385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61024e610670565b604080516001600160a01b039092168252519081900360200190f35b6102966004803603604081101561028057600080fd5b506001600160a01b03813516906020013561067f565b604080519115158252519081900360200190f35b6102b261069d565b6040805163ffffffff9092168252519081900360200190f35b610301600480360360608110156102e157600080fd5b506001600160a01b038135811691602081013590911690604001356106a5565b005b61030b61070d565b60408051918252519081900360200190f35b610325610713565b6040805160ff9092168252519081900360200190f35b6102966004803603606081101561035157600080fd5b506001600160a01b03813581169160208101359091169060400135610718565b61030b61079f565b61030b6107ae565b61030b6107d2565b6103256107d8565b61030b6107e1565b610296600480360360408110156103af57600080fd5b506001600160a01b038135169060200135610805565b610301600480360360608110156103db57600080fd5b506001600160a01b03813581169160208101359091169060400135610853565b6103016004803603604081101561041157600080fd5b506001600160a01b0381351690602001356108b6565b6103016004803603604081101561043d57600080fd5b506001600160a01b038135169060200135610a50565b61030b6004803603602081101561046957600080fd5b50356001600160a01b0316610ab6565b610301610ad1565b61030b6004803603602081101561049757600080fd5b50356001600160a01b0316610b73565b61024e610b85565b6101d1610b94565b610296600480360360408110156104cd57600080fd5b506001600160a01b038135169060200135610bf5565b610296600480360360408110156104f957600080fd5b506001600160a01b038135169060200135610c5d565b610301600480360360e081101561052557600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c00135610c71565b61030b6004803603604081101561057657600080fd5b506001600160a01b0381358116916020013516610e9f565b610301600480360360208110156105a457600080fd5b50356001600160a01b0316610eca565b610301600480360360208110156105ca57600080fd5b50356001600160a01b0316610fc3565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106665780601f1061063b57610100808354040283529160200191610666565b820191906000526020600020905b81548152906001019060200180831161064957829003601f168201915b5050505050905090565b6008546001600160a01b031681565b600061069361068c611085565b8484611089565b5060015b92915050565b6301e1338081565b6106ad611085565b6007546001600160a01b039081169116146106fd576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b610708838383611175565b505050565b60025490565b600281565b600061072584848461129f565b61079584610731611085565b61079085604051806060016040528060288152602001611dac602891396001600160a01b038a1660009081526001602052604081209061076f611085565b6001600160a01b0316815260208101919091526040016000205491906113fa565b611089565b5060019392505050565b6a52b7d2dcc80cd2e400000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60095481565b60055460ff1690565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000610693610812611085565b846107908560016000610823611085565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490611491565b61085b611085565b6007546001600160a01b039081169116146108ab576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b6107088383836114f2565b6008546001600160a01b03163314610902576040805162461bcd60e51b815260206004820152600a602482015269496f6e783a452d31313360b01b604482015290519081900360640190fd5b600954421015610946576040805162461bcd60e51b815260206004820152600a602482015269125bdb9e0e914b4c4c4d60b21b604482015290519081900360640190fd5b6001600160a01b03821661098e576040805162461bcd60e51b815260206004820152600a602482015269496f6e783a452d34303360b01b604482015290519081900360640190fd5b80600061099961070d565b90506a52b7d2dcc80cd2e400000081106109de576009546109be906301e13380611491565b6009556109d760646109d1836002611678565b906116d1565b9150610a40565b6a52b7d2dcc80cd2e40000006109f48284611491565b1115610a1257610a0f6a52b7d2dcc80cd2e400000082611713565b91505b6a52b7d2dcc80cd2e4000000610a288284611491565b1415610a4057610a3c426301e13380611491565b6009555b610a4a8483611755565b50505050565b610a58611085565b6007546001600160a01b03908116911614610aa8576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b610ab28282611845565b5050565b6001600160a01b031660009081526020819052604090205490565b610ad9611085565b6007546001600160a01b03908116911614610b29576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b6007546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600780546001600160a01b0319169055565b60066020526000908152604090205481565b6007546001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106665780601f1061063b57610100808354040283529160200191610666565b6000610693610c02611085565b8461079085604051806060016040528060258152602001611e676025913960016000610c2c611085565b6001600160a01b03908116825260208083019390935260409182016000908120918d168152925290205491906113fa565b6000610693610c6a611085565b848461129f565b42841015610cc6576040805162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e65000000604482015290519081900360640190fd5b6001600160a01b0380881660008181526006602090815260408083208054600180820190925582517f00000000000000000000000000000000000000000000000000000000000000008186015280840196909652958c166060860152608085018b905260a085019590955260c08085018a90528151808603909101815260e08501825280519083012061190160f01b6101008601527f000000000000000000000000000000000000000000000000000000000000000061010286015261012280860182905282518087039091018152610142860180845281519185019190912090859052610162860180845281905260ff8a166101828701526101a286018990526101c2860188905291519095919491926101e2808401939192601f1981019281900390910190855afa158015610e01573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610e375750896001600160a01b0316816001600160a01b0316145b610e88576040805162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e61747572650000604482015290519081900360640190fd5b610e938a8a8a611089565b50505050505050505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610ed2611085565b6007546001600160a01b03908116911614610f22576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b6001600160a01b038116610f675760405162461bcd60e51b8152600401808060200182810382526026815260200180611ce36026913960400191505060405180910390fd5b6007546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600780546001600160a01b0319166001600160a01b0392909216919091179055565b610fcb611085565b6007546001600160a01b0390811691161461101b576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b600854604080516001600160a01b039283168152918316602083015280517f3b0007eb941cf645526cbb3a4fdaecda9d28ce4843167d9263b536a1f1edc0f69281900390910190a1600880546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b0383166110ce5760405162461bcd60e51b8152600401808060200182810382526024815260200180611e196024913960400191505060405180910390fd5b6001600160a01b0382166111135760405162461bcd60e51b8152600401808060200182810382526022815260200180611d096022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0383166111bc576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b80826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561120a57600080fd5b505afa15801561121e573d6000803e3d6000fd5b505050506040513d602081101561123457600080fd5b5051106107085761124f6001600160a01b03831684836118e8565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b836040518082815260200191505060405180910390a3505050565b6001600160a01b0383166112e45760405162461bcd60e51b8152600401808060200182810382526025815260200180611df46025913960400191505060405180910390fd5b6001600160a01b0382166113295760405162461bcd60e51b8152600401808060200182810382526023815260200180611cc06023913960400191505060405180910390fd5b611334838383610708565b61137181604051806060016040528060268152602001611d2b602691396001600160a01b03861660009081526020819052604090205491906113fa565b6001600160a01b0380851660009081526020819052604080822093909355908416815220546113a09082611491565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600081848411156114895760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561144e578181015183820152602001611436565b50505050905090810190601f16801561147b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000828201838110156114eb576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038316611539576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b306001600160a01b0316826001600160a01b0316636352211e836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561158757600080fd5b505afa15801561159b573d6000803e3d6000fd5b505050506040513d60208110156115b157600080fd5b50516001600160a01b0316141561070857604080516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018490529151918416916323b872dd9160648082019260009290919082900301818387803b15801561161a57600080fd5b505af115801561162e573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b60008261168757506000610697565b8282028284828161169457fe5b04146114eb5760405162461bcd60e51b8152600401808060200182810382526021815260200180611d8b6021913960400191505060405180910390fd5b60006114eb83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061193a565b60006114eb83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506113fa565b6001600160a01b0382166117b0576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b6117bc60008383610708565b6002546117c99082611491565b6002556001600160a01b0382166000908152602081905260409020546117ef9082611491565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6001600160a01b03821661188c576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b804710610ab2576118a66001600160a01b0383168261199f565b6040805182815290516001600160a01b038416917eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd919081900360200190a25050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610708908490611a84565b600081836119895760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561144e578181015183820152602001611436565b50600083858161199557fe5b0495945050505050565b804710156119f4576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015290519081900360640190fd5b6040516000906001600160a01b0384169083908381818185875af1925050503d8060008114611a3f576040519150601f19603f3d011682016040523d82523d6000602084013e611a44565b606091505b50509050806107085760405162461bcd60e51b815260040180806020018281038252603a815260200180611d51603a913960400191505060405180910390fd5b6060611ad9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611b359092919063ffffffff16565b80519091501561070857808060200190516020811015611af857600080fd5b50516107085760405162461bcd60e51b815260040180806020018281038252602a815260200180611e3d602a913960400191505060405180910390fd5b6060611b448484600085611b4c565b949350505050565b6060611b5785611cb9565b611ba8576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310611be75780518252601f199092019160209182019101611bc8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114611c49576040519150601f19603f3d011682016040523d82523d6000602084013e611c4e565b606091505b50915091508115611c62579150611b449050565b805115611c725780518082602001fd5b60405162461bcd60e51b815260206004820181815286516024840152865187939192839260440191908501908083836000831561144e578181015183820152602001611436565b3b15159056fe45524332303a207472616e7366657220746f20746865207a65726f20616464726573734f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365416464726573733a20756e61626c6520746f2073656e642076616c75652c20726563697069656e74206d61792068617665207265766572746564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657245524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656445524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220bd76b10c65c03359bbab1305b5a901ae77e87d8d92a0ee8769ed8d6354c54b8364736f6c634300060c0033", + "devdoc": { + "kind": "dev", + "methods": { + "allowance(address,address)": { + "details": "See {IERC20-allowance}." + }, + "approve(address,uint256)": { + "details": "See {IERC20-approve}. Requirements: - `spender` cannot be the zero address." + }, + "balanceOf(address)": { + "details": "See {IERC20-balanceOf}." + }, + "decimals()": { + "details": "Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5,05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is called. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}." + }, + "decreaseAllowance(address,uint256)": { + "details": "Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`." + }, + "increaseAllowance(address,uint256)": { + "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." + }, + "mint(address,uint256)": { + "params": { + "amount": "The number of tokens to be minted", + "receiver": "The address of the destination account" + } + }, + "name()": { + "details": "Returns the name of the token." + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "permit(address,address,uint256,uint256,uint8,bytes32,bytes32)": { + "details": "See {IERC2612-permit}. In cases where the free option is not a concern, deadline can simply be set to uint(-1), so it should be seen as an optional parameter" + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "setMinter(address)": { + "params": { + "newMinter": "The address of the new minter" + } + }, + "symbol()": { + "details": "Returns the symbol of the token, usually a shorter version of the name." + }, + "totalSupply()": { + "details": "See {IERC20-totalSupply}." + }, + "transfer(address,uint256)": { + "details": "See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`." + }, + "transferFrom(address,address,uint256)": { + "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}; Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "MinterChanged(address,address)": { + "notice": "An event thats emitted when the minter address is changed" + } + }, + "kind": "user", + "methods": { + "INFLATION_CAP()": { + "notice": "Cap on the percentage of totalSupply that can be minted at each mint" + }, + "INFLATION_EPOCH()": { + "notice": "Minimum time between mints" + }, + "INITIAL_SUPPLY()": { + "notice": "Total number of tokens in circulation" + }, + "mint(address,uint256)": { + "notice": "Mint new tokens" + }, + "minter()": { + "notice": "Address which may mint new tokens" + }, + "mintingAllowedAfter()": { + "notice": "The timestamp after which minting may occur" + }, + "setMinter(address)": { + "notice": "Change the minter address" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 6091, + "contract": "contracts/v1/tokens/Ionx.sol:Ionx", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 6097, + "contract": "contracts/v1/tokens/Ionx.sol:Ionx", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 6099, + "contract": "contracts/v1/tokens/Ionx.sol:Ionx", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 6101, + "contract": "contracts/v1/tokens/Ionx.sol:Ionx", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "t_string_storage" + }, + { + "astId": 6103, + "contract": "contracts/v1/tokens/Ionx.sol:Ionx", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "t_string_storage" + }, + { + "astId": 6105, + "contract": "contracts/v1/tokens/Ionx.sol:Ionx", + "label": "_decimals", + "offset": 0, + "slot": "5", + "type": "t_uint8" + }, + { + "astId": 48635, + "contract": "contracts/v1/tokens/Ionx.sol:Ionx", + "label": "nonces", + "offset": 0, + "slot": "6", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 4406, + "contract": "contracts/v1/tokens/Ionx.sol:Ionx", + "label": "_owner", + "offset": 0, + "slot": "7", + "type": "t_address" + }, + { + "astId": 35504, + "contract": "contracts/v1/tokens/Ionx.sol:Ionx", + "label": "minter", + "offset": 0, + "slot": "8", + "type": "t_address" + }, + { + "astId": 35507, + "contract": "contracts/v1/tokens/Ionx.sol:Ionx", + "label": "mintingAllowedAfter", + "offset": 0, + "slot": "9", + "type": "t_uint256" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/mumbai/Lepton2.json b/deployments/mumbai/Lepton2.json new file mode 100644 index 0000000..937d08f --- /dev/null +++ b/deployments/mumbai/Lepton2.json @@ -0,0 +1,1354 @@ +{ + "address": "0xF771BC29B5CD8d1Fdc82997101f904C3808B4a42", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "count", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "multiplier", + "type": "uint32" + } + ], + "name": "LeptonBatchMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "multiplier", + "type": "uint32" + } + ], + "name": "LeptonMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "tokenUri", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "supply", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "multiplier", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "bonus", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "upperBounds", + "type": "uint256" + } + ], + "name": "LeptonTypeAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "leptonIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "tokenUri", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "supply", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "multiplier", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "bonus", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "upperBounds", + "type": "uint256" + } + ], + "name": "LeptonTypeUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "maxAmount", + "type": "uint256" + } + ], + "name": "MaxMintPerTxSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "isPaused", + "type": "bool" + } + ], + "name": "PausedStateSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "tokenUri", + "type": "string" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "supply", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "multiplier", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "bonus", + "type": "uint32" + } + ], + "name": "addLeptonType", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "count", + "type": "uint256" + } + ], + "name": "batchMintLepton", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getBonus", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNextPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNextType", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "oldLeptonContract", + "type": "address" + }, + { + "internalType": "uint256", + "name": "count", + "type": "uint256" + } + ], + "name": "migrateAccounts", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "mintLepton", + "outputs": [ + { + "internalType": "uint256", + "name": "newTokenId", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maxAmount", + "type": "uint256" + } + ], + "name": "setMaxMintPerTx", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "setPausedState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "leptonIndex", + "type": "uint256" + }, + { + "internalType": "string", + "name": "tokenUri", + "type": "string" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "supply", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "multiplier", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "bonus", + "type": "uint32" + } + ], + "name": "updateLeptonType", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x507987d5307809851a722d09229271b8c9f0ae73e10267ab3bcfd48606a26f34", + "receipt": { + "to": null, + "from": "0x6d46b37708dA7Ed4E5C4509495768Fecd3D17C01", + "contractAddress": "0xF771BC29B5CD8d1Fdc82997101f904C3808B4a42", + "transactionIndex": 0, + "gasUsed": "3201460", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000020000000000000002000000000000000000000000008000000000000000000000000000000000000000000000000000000020800001000000000000000100000000000000000000020000000000000000000800000000000000000080000000000000400000000000000010000000000100000000000000040000000400000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100800000020000000000000000080000000000000000000000000000000000000000000100000", + "blockHash": "0x3894c334b0bf9aa941226bb0a2db8df7d0f65fe2f190a1e483db938a80c0768f", + "transactionHash": "0x507987d5307809851a722d09229271b8c9f0ae73e10267ab3bcfd48606a26f34", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 39278920, + "transactionHash": "0x507987d5307809851a722d09229271b8c9f0ae73e10267ab3bcfd48606a26f34", + "address": "0xF771BC29B5CD8d1Fdc82997101f904C3808B4a42", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000006d46b37708da7ed4e5c4509495768fecd3d17c01" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x3894c334b0bf9aa941226bb0a2db8df7d0f65fe2f190a1e483db938a80c0768f" + }, + { + "transactionIndex": 0, + "blockNumber": 39278920, + "transactionHash": "0x507987d5307809851a722d09229271b8c9f0ae73e10267ab3bcfd48606a26f34", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000006d46b37708da7ed4e5c4509495768fecd3d17c01", + "0x0000000000000000000000005082f249cdb2f2c1ee035e4f423c46ea2dab3ab1" + ], + "data": "0x0000000000000000000000000000000000000000000000000071bd1be961db0c000000000000000000000000000000000000000000000000a601543e7aae367700000000000000000000000000000000000000000000004a27af2ba3b0843745000000000000000000000000000000000000000000000000a58f9722914c5b6b00000000000000000000000000000000000000000000004a2820e8bf99e61251", + "logIndex": 1, + "blockHash": "0x3894c334b0bf9aa941226bb0a2db8df7d0f65fe2f190a1e483db938a80c0768f" + } + ], + "blockNumber": 39278920, + "cumulativeGasUsed": "3201460", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "3c4a4867d03c114eb5175ff04b48a99d", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"multiplier\",\"type\":\"uint32\"}],\"name\":\"LeptonBatchMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"multiplier\",\"type\":\"uint32\"}],\"name\":\"LeptonMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"tokenUri\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"supply\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"multiplier\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"bonus\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"upperBounds\",\"type\":\"uint256\"}],\"name\":\"LeptonTypeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"leptonIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"tokenUri\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"supply\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"multiplier\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"bonus\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"upperBounds\",\"type\":\"uint256\"}],\"name\":\"LeptonTypeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxAmount\",\"type\":\"uint256\"}],\"name\":\"MaxMintPerTxSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isPaused\",\"type\":\"bool\"}],\"name\":\"PausedStateSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC1155\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckEther\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"tokenUri\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"supply\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"multiplier\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"bonus\",\"type\":\"uint32\"}],\"name\":\"addLeptonType\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"name\":\"batchMintLepton\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getBonus\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getMultiplier\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNextPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNextType\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"oldLeptonContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"name\":\"migrateAccounts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"mintLepton\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"newTokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxAmount\",\"type\":\"uint256\"}],\"name\":\"setMaxMintPerTx\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"state\",\"type\":\"bool\"}],\"name\":\"setPausedState\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"leptonIndex\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"tokenUri\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"supply\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"multiplier\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"bonus\",\"type\":\"uint32\"}],\"name\":\"updateLeptonType\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawErc20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawEther\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"details\":\"See {IERC721-approve}.\"},\"balanceOf(address)\":{\"details\":\"See {IERC721-balanceOf}.\"},\"getApproved(uint256)\":{\"details\":\"See {IERC721-getApproved}.\"},\"isApprovedForAll(address,address)\":{\"details\":\"See {IERC721-isApprovedForAll}.\"},\"name()\":{\"details\":\"See {IERC721Metadata-name}.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"ownerOf(uint256)\":{\"details\":\"See {IERC721-ownerOf}.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"See {IERC721-setApprovalForAll}.\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}. Time complexity O(1), guaranteed to always use less than 30 000 gas.\"},\"symbol()\":{\"details\":\"See {IERC721Metadata-symbol}.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-transferFrom}.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/v1/tokens/Lepton2.sol\":\"Lepton2\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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 GSN 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 payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xdb26cbf4d028490f49831a7865c2fe1b28db44b535ca8d343785a3b768aae183\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"../GSN/Context.sol\\\";\\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 */\\ncontract 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 () internal {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view 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 emit OwnershipTransferred(_owner, address(0));\\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x4bd6402ca6b3419008c2b482aff54e66836e8cb4eba2680e42ac5884ae6424fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts may inherit from this and call {_registerInterface} to declare\\n * their support of an interface.\\n */\\ncontract ERC165 is IERC165 {\\n /*\\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\\n */\\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\\n\\n /**\\n * @dev Mapping of interface ids to whether or not it's supported.\\n */\\n mapping(bytes4 => bool) private _supportedInterfaces;\\n\\n constructor () internal {\\n // Derived contracts need only register support for their own interfaces,\\n // we register support for ERC165 itself here\\n _registerInterface(_INTERFACE_ID_ERC165);\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n *\\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) public view override returns (bool) {\\n return _supportedInterfaces[interfaceId];\\n }\\n\\n /**\\n * @dev Registers the contract as an implementer of the interface defined by\\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\\n * registering its interface id is not required.\\n *\\n * See {IERC165-supportsInterface}.\\n *\\n * Requirements:\\n *\\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\\n */\\n function _registerInterface(bytes4 interfaceId) internal virtual {\\n require(interfaceId != 0xffffffff, \\\"ERC165: invalid interface id\\\");\\n _supportedInterfaces[interfaceId] = true;\\n }\\n}\\n\",\"keccak256\":\"0xb046d18f9d09683ca1c0ed6d80c61da8a8a7d9b30bad70a17b898538683eff74\",\"license\":\"MIT\"},\"@openzeppelin/contracts/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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\",\"keccak256\":\"0xfa152b6e88a1dc50780e8f1580426dc23ad2e1e2c2f086a088adf206a202f453\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\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 uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\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 sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\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 * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\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 // 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) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts 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 mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9a9cf02622cd7a64261b10534fc3260449da25c98c9e96d1b4ae8110a20e5806\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x31691ad0817f8cb338531b78d2ab2989027d9f27e6f8e62492b754fed9429b10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0x5c26b39d26f7ed489e555d955dcd3e01872972e71fdd1528e93ec164e4f23385\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.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 SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf3b30f8a49631420635a8c35daacfcaa338012755f18a76fdd118730256f9a27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0xaf936da92f3a9a4f98b237323b5eb1d813fb86c4d07a184beba7027cf0509ba3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 /**\\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\",\"keccak256\":\"0x3636662804cd8f474536b2875a9038a4c3fb91879f1bbff48af5c3f140fcd2f0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 /**\\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\",\"keccak256\":\"0xe7f984cedc00a138dc27f263c73c32ba9a4b2fd23b6c34ac46f46c074b943538\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address operator, address from, uint256 tokenId, bytes calldata data)\\n external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x321ee37ef4925020aa818a03ec7fe48e057561f65ab009a84f6c20c86026ade7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 in 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 // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n return _functionCallWithValue(target, data, value, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\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 // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf5fa8cbdffa5ef8be49b246b5628facc30b71707e78a45d80d93b64eff3fe390\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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 */\\ncontract 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 () internal {\\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 make 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\",\"keccak256\":\"0x7ff0067f2d7df4187eaa1cb4800949b929602c9d9cb20fcaee6922a7613ef2fb\",\"license\":\"MIT\"},\"contracts/v1/interfaces/ILepton.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// ILepton.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Charged Particles Lepton Interface\\n * @dev ...\\n */\\ninterface ILepton {\\n\\n struct Classification {\\n string tokenUri;\\n uint256 price;\\n uint128 _upperBounds;\\n uint32 supply;\\n uint32 multiplier;\\n uint32 bonus;\\n }\\n\\n function mintLepton() external payable returns (uint256 newTokenId);\\n function batchMintLepton(uint256 count) external payable;\\n function getNextType() external view returns (uint256);\\n function getNextPrice() external view returns (uint256);\\n function getMultiplier(uint256 tokenId) external view returns (uint256);\\n function getBonus(uint256 tokenId) external view returns (uint256);\\n\\n\\n event MaxMintPerTxSet(uint256 maxAmount);\\n event LeptonTypeAdded(string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\\n event LeptonTypeUpdated(uint256 leptonIndex, string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\\n event LeptonMinted(address indexed receiver, uint256 indexed tokenId, uint256 price, uint32 multiplier);\\n event LeptonBatchMinted(address indexed receiver, uint256 indexed tokenId, uint256 count, uint256 price, uint32 multiplier);\\n event PausedStateSet(bool isPaused);\\n}\\n\",\"keccak256\":\"0x4903085427fa5dbee690fe79854fba60afaf21189957406ade55f6fc12556a01\",\"license\":\"MIT\"},\"contracts/v1/lib/BlackholePrevention.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\\\";\\n\\n/**\\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\\n * the Owner/DAO to pull them out on behalf of a user\\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\\n */\\ncontract BlackholePrevention {\\n using Address for address payable;\\n using SafeERC20 for IERC20;\\n\\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\\n\\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (address(this).balance >= amount) {\\n receiver.sendValue(amount);\\n emit WithdrawStuckEther(receiver, amount);\\n }\\n }\\n\\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\\n IERC20(tokenAddress).safeTransfer(receiver, amount);\\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\\n }\\n }\\n\\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\\n }\\n }\\n\\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \\\"\\\");\\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6a664c8a1c1d7fb32ade2c11f75756b1fdb4c489daa32c1d58e6b867ea2ba8d6\",\"license\":\"MIT\"},\"contracts/v1/lib/ERC721Basic.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/GSN/Context.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/introspection/ERC165.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\n/**\\n * @title ERC721 Non-Fungible Token Standard basic implementation\\n * @dev see https://eips.ethereum.org/EIPS/eip-721\\n */\\ncontract ERC721Basic is Context, ERC165, IERC721, IERC721Metadata {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n // Equals to `bytes4(keccak256(\\\"onERC721Received(address,address,uint256,bytes)\\\"))`\\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\\n bytes4 internal constant _ERC721_RECEIVED = 0x150b7a02;\\n\\n // mapping from token ids to their owners\\n mapping (uint256 => address) internal _tokenOwners;\\n\\n // mapping from owner to token balance\\n mapping (address => uint256) internal _ownerBalance;\\n\\n // Mapping from token ID to approved address\\n mapping (uint256 => address) internal _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping (address => mapping (address => bool)) internal _operatorApprovals;\\n\\n // Token name\\n string internal _name;\\n\\n // Token symbol\\n string internal _symbol;\\n\\n // Token Count\\n uint256 internal _tokenCount;\\n\\n /*\\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\\n *\\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\\n */\\n bytes4 internal constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\\n\\n /*\\n * bytes4(keccak256('name()')) == 0x06fdde03\\n * bytes4(keccak256('symbol()')) == 0x95d89b41\\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\\n *\\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\\n */\\n bytes4 internal constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\\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) public {\\n _name = name;\\n _symbol = symbol;\\n\\n // register the supported interfaces to conform to ERC721 via ERC165\\n _registerInterface(_INTERFACE_ID_ERC721);\\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view override returns (uint256) {\\n require(owner != address(0), \\\"ERC721:E-403\\\");\\n return _ownerBalance[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view override returns (address) {\\n return _tokenOwners[tokenId];\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view 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 return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ownerOf(tokenId);\\n require(to != owner, \\\"ERC721:E-111\\\");\\n\\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \\\"ERC721:E-105\\\");\\n\\n _approve(to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-getApproved}.\\n */\\n function getApproved(uint256 tokenId) public view override returns (address) {\\n require(_exists(tokenId), \\\"ERC721:E-405\\\");\\n return _tokenApprovals[tokenId];\\n }\\n\\n /**\\n * @dev See {IERC721-setApprovalForAll}.\\n */\\n function setApprovalForAll(address operator, bool approved) public virtual override {\\n require(operator != _msgSender(), \\\"ERC721:E-111\\\");\\n\\n _operatorApprovals[_msgSender()][operator] = approved;\\n emit ApprovalForAll(_msgSender(), operator, approved);\\n }\\n\\n /**\\n * @dev See {IERC721-isApprovedForAll}.\\n */\\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\\n return _operatorApprovals[owner][operator];\\n }\\n\\n /**\\n * @dev See {IERC721-transferFrom}.\\n */\\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721:E-105\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721:E-105\\\");\\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\\n _transfer(from, to, tokenId);\\n require(_checkOnERC721Received(from, to, tokenId, _data), \\\"ERC721:E-402\\\");\\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 returns (bool) {\\n return _tokenOwners[tokenId] != address(0x0);\\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 returns (bool) {\\n require(_exists(tokenId), \\\"ERC721:E-405\\\");\\n address owner = ownerOf(tokenId);\\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\\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(address to, bytes memory _data) internal virtual returns (uint256) {\\n uint256 tokenId = _mint(to);\\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \\\"ERC721:E-402\\\");\\n return 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 _safeMintBatch(address to, uint256 count, bytes memory _data) internal virtual {\\n uint256 startTokenId = _mintBatch(to, count);\\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \\\"ERC721:E-402\\\");\\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) internal virtual returns (uint256) {\\n require(to != address(0), \\\"ERC721:E-403\\\");\\n\\n _tokenCount = _tokenCount.add(1);\\n uint256 tokenId = _tokenCount;\\n require(!_exists(tokenId), \\\"ERC721:E-407\\\");\\n\\n _tokenOwners[tokenId] = to;\\n _ownerBalance[to] = _ownerBalance[to].add(1);\\n\\n emit Transfer(address(0), to, tokenId);\\n return tokenId;\\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 _mintBatch(address to, uint256 count) internal virtual returns (uint256) {\\n require(to != address(0), \\\"ERC721:E-403\\\");\\n\\n uint256 startTokenId = _tokenCount.add(1);\\n for (uint i = 1; i <= count; i++) {\\n uint256 tokenId = _tokenCount.add(i);\\n _tokenOwners[tokenId] = to;\\n emit Transfer(address(0), to, tokenId);\\n }\\n\\n _tokenCount = _tokenCount.add(count);\\n _ownerBalance[to] = _ownerBalance[to].add(count);\\n return startTokenId;\\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(address from, address to, uint256 tokenId) internal virtual {\\n require(ownerOf(tokenId) == from, \\\"ERC721:E-102\\\");\\n require(to != address(0), \\\"ERC721:E-403\\\");\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _tokenOwners[tokenId] = to;\\n _ownerBalance[from] = _ownerBalance[from].sub(1);\\n _ownerBalance[to] = _ownerBalance[to].add(1);\\n\\n emit Transfer(from, to, tokenId);\\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(address from, address to, uint256 tokenId, bytes memory _data)\\n internal returns (bool)\\n {\\n if (!to.isContract()) {\\n return true;\\n }\\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\\n IERC721Receiver(to).onERC721Received.selector,\\n _msgSender(),\\n from,\\n tokenId,\\n _data\\n ), \\\"ERC721:E-402\\\");\\n bytes4 retval = abi.decode(returndata, (bytes4));\\n return (retval == _ERC721_RECEIVED);\\n }\\n\\n function _approve(address to, uint256 tokenId) internal {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ownerOf(tokenId), to, tokenId);\\n }\\n}\\n\",\"keccak256\":\"0x4b9f68ff101017027a7d963c7ab888d126c3e5f10fb5dd28daba08d49d9bd291\",\"license\":\"MIT\"},\"contracts/v1/tokens/Lepton2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// Lepton2.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\n\\nimport \\\"../lib/ERC721Basic.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/ReentrancyGuard.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\\\";\\n\\nimport \\\"../interfaces/ILepton.sol\\\";\\nimport \\\"../lib/BlackholePrevention.sol\\\";\\n\\ncontract Lepton2 is ILepton, ERC721Basic, Ownable, ReentrancyGuard, BlackholePrevention {\\n using SafeMath for uint256;\\n using Address for address payable;\\n\\n Classification[] internal _leptonTypes;\\n\\n uint256 internal _typeIndex;\\n uint256 internal _maxSupply;\\n uint256 internal _maxMintPerTx;\\n uint256 internal _migratedCount;\\n\\n bool internal _paused;\\n bool internal _migrationComplete;\\n\\n\\n /***********************************|\\n | Initialization |\\n |__________________________________*/\\n\\n constructor() public ERC721Basic(\\\"Charged Particles - Lepton2\\\", \\\"LEPTON2\\\") {\\n _paused = true;\\n _migrationComplete = false;\\n _migratedCount = 0;\\n }\\n\\n\\n /***********************************|\\n | Public |\\n |__________________________________*/\\n\\n function mintLepton() external payable override nonReentrant whenNotPaused returns (uint256 newTokenId) {\\n newTokenId = _mintLepton(msg.sender);\\n }\\n\\n function batchMintLepton(uint256 count) external payable override nonReentrant whenNotPaused {\\n _batchMintLepton(msg.sender, count);\\n }\\n\\n function totalSupply() public view returns (uint256) {\\n return _tokenCount;\\n }\\n\\n function maxSupply() external view returns (uint256) {\\n return _maxSupply;\\n }\\n\\n function getNextType() external view override returns (uint256) {\\n if (_typeIndex >= _leptonTypes.length) { return 0; }\\n return _typeIndex;\\n }\\n\\n function getNextPrice() external view override returns (uint256) {\\n if (_typeIndex >= _leptonTypes.length) { return 0; }\\n return _leptonTypes[_typeIndex].price;\\n }\\n\\n function getMultiplier(uint256 tokenId) external view override returns (uint256) {\\n require(_exists(tokenId), \\\"LPT:E-405\\\");\\n return _getLepton(tokenId).multiplier;\\n }\\n\\n function getBonus(uint256 tokenId) external view override returns (uint256) {\\n require(_exists(tokenId), \\\"LPT:E-405\\\");\\n return _getLepton(tokenId).bonus;\\n }\\n\\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\\n require(_exists(tokenId), \\\"LPT:E-405\\\");\\n return _getLepton(tokenId).tokenUri;\\n }\\n\\n /***********************************|\\n | Only Admin/DAO |\\n |__________________________________*/\\n\\n function addLeptonType(\\n string calldata tokenUri,\\n uint256 price,\\n uint32 supply,\\n uint32 multiplier,\\n uint32 bonus\\n )\\n external\\n onlyOwner\\n {\\n _maxSupply = _maxSupply.add(uint256(supply));\\n\\n Classification memory lepton = Classification({\\n tokenUri: tokenUri,\\n price: price,\\n supply: supply,\\n multiplier: multiplier,\\n bonus: bonus,\\n _upperBounds: uint128(_maxSupply)\\n });\\n _leptonTypes.push(lepton);\\n\\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\\n }\\n\\n function updateLeptonType(\\n uint256 leptonIndex,\\n string calldata tokenUri,\\n uint256 price,\\n uint32 supply,\\n uint32 multiplier,\\n uint32 bonus\\n )\\n external\\n onlyOwner\\n {\\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\\n _leptonTypes[leptonIndex].price = price;\\n _leptonTypes[leptonIndex].supply = supply;\\n _leptonTypes[leptonIndex].multiplier = multiplier;\\n _leptonTypes[leptonIndex].bonus = bonus;\\n\\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\\n }\\n\\n function setMaxMintPerTx(uint256 maxAmount) external onlyOwner {\\n _maxMintPerTx = maxAmount;\\n emit MaxMintPerTxSet(maxAmount);\\n }\\n\\n function setPausedState(bool state) external onlyOwner {\\n _paused = state;\\n emit PausedStateSet(state);\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n | (blackhole prevention) |\\n |__________________________________*/\\n\\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n function migrateAccounts(address oldLeptonContract, uint256 count) external onlyOwner whenNotMigrated {\\n uint256 oldSupply = IERC721Enumerable(oldLeptonContract).totalSupply();\\n require(oldSupply == 0 || oldSupply > _migratedCount, \\\"LPT:E-004\\\");\\n\\n if (oldSupply > 0) {\\n uint256 endTokenId = _migratedCount.add(count);\\n if (endTokenId > oldSupply) {\\n count = count.sub(endTokenId.sub(oldSupply));\\n }\\n\\n for (uint256 i = 1; i <= count; i++) {\\n uint256 tokenId = _migratedCount.add(i);\\n address tokenOwner = IERC721(oldLeptonContract).ownerOf(tokenId);\\n _mint(tokenOwner);\\n }\\n _migratedCount = _migratedCount.add(count);\\n }\\n\\n if (oldSupply == _migratedCount) {\\n _finalizeMigration();\\n }\\n }\\n\\n /***********************************|\\n | Private Functions |\\n |__________________________________*/\\n\\n function _getLepton(uint256 tokenId) internal view returns (Classification memory) {\\n uint256 types = _leptonTypes.length;\\n for (uint256 i = 0; i < types; i++) {\\n Classification memory lepton = _leptonTypes[i];\\n if (tokenId <= lepton._upperBounds) {\\n return lepton;\\n }\\n }\\n }\\n\\n function _mintLepton(address receiver) internal returns (uint256 newTokenId) {\\n require(_typeIndex < _leptonTypes.length, \\\"LPT:E-408\\\");\\n\\n Classification memory lepton = _leptonTypes[_typeIndex];\\n require(msg.value >= lepton.price, \\\"LPT:E-414\\\");\\n\\n newTokenId = _safeMint(receiver, \\\"\\\");\\n\\n // Determine Next Type\\n if (newTokenId == lepton._upperBounds) {\\n _typeIndex = _typeIndex.add(1);\\n }\\n\\n _refundOverpayment(lepton.price);\\n }\\n\\n function _batchMintLepton(address receiver, uint256 count) internal {\\n require(_typeIndex < _leptonTypes.length, \\\"LPT:E-408\\\");\\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \\\"LPT:E-429\\\");\\n\\n Classification memory lepton = _leptonTypes[_typeIndex];\\n\\n uint256 endTokenId = _tokenCount.add(count);\\n if (endTokenId > lepton._upperBounds) {\\n count = count.sub(endTokenId.sub(lepton._upperBounds));\\n }\\n\\n uint256 salePrice = lepton.price.mul(count);\\n require(msg.value >= salePrice, \\\"LPT:E-414\\\");\\n\\n _safeMintBatch(receiver, count, \\\"\\\");\\n\\n // Determine Next Type\\n if (endTokenId >= lepton._upperBounds) {\\n _typeIndex = _typeIndex.add(1);\\n }\\n\\n _refundOverpayment(salePrice);\\n }\\n\\n function _refundOverpayment(uint256 threshold) internal {\\n uint256 overage = msg.value.sub(threshold);\\n if (overage > 0) {\\n payable(_msgSender()).sendValue(overage);\\n }\\n }\\n\\n function _finalizeMigration() internal {\\n // Determine Next Type\\n _typeIndex = 0;\\n for (uint256 i = 0; i < _leptonTypes.length; i++) {\\n Classification memory lepton = _leptonTypes[i];\\n if (_migratedCount >= lepton._upperBounds) {\\n _typeIndex = i + 1;\\n }\\n }\\n _migrationComplete = true;\\n }\\n\\n\\n /***********************************|\\n | Modifiers |\\n |__________________________________*/\\n\\n modifier whenNotMigrated() {\\n require(!_migrationComplete, \\\"LPT:E-004\\\");\\n _;\\n }\\n\\n modifier whenNotPaused() {\\n require(!_paused, \\\"LPT:E-101\\\");\\n _;\\n }\\n}\",\"keccak256\":\"0x308d33f8e4c5dbc7fa986fd93e3f760f8f81c14e0915af9ba9ab9cd5509fae6d\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50604080518082018252601b81527f43686172676564205061727469636c6573202d204c6570746f6e320000000000602080830191909152825180840190935260078352662622a82a27a71960c91b9083015290620000776301ffc9a760e01b62000148565b81516200008c906005906020850190620001d1565b508051620000a2906006906020840190620001d1565b50620000b56380ac58cd60e01b62000148565b620000c7635b5e139f60e01b62000148565b5060009050620000d6620001cd565b600880546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35060016009819055600f805460ff191690911761ff00191690556000600e556200026d565b6001600160e01b03198082161415620001a8576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b3390565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200021457805160ff191683800117855562000244565b8280016001018555821562000244579182015b828111156200024457825182559160200191906001019062000227565b506200025292915062000256565b5090565b5b8082111562000252576000815560010162000257565b61357b806200027d6000396000f3fe6080604052600436106101e35760003560e01c8063681ce98a11610102578063b88d4fde11610095578063db9f60ff11610064578063db9f60ff146108be578063e6089023146108ea578063e985e9c5146108ff578063f2fde38b1461093a576101e3565b8063b88d4fde14610711578063c87b56dd146107e4578063d5abeb011461080e578063da47bb2614610823576101e3565b806395d89b41116100d157806395d89b41146105f5578063a22cb4651461060a578063adf8252d14610645578063b0fde8cf1461066f576101e3565b8063681ce98a1461058357806370a0823114610598578063715018a6146105cb5780638da5cb5b146105e0576101e3565b806323b872dd1161017a578063522f681511610149578063522f6815146104ee5780635fc194ed14610527578063616cdb1e1461052f5780636352211e14610559576101e3565b806323b872dd146103fb5780634025feb21461043e57806342842e0e146104815780634aa66b28146104c4576101e3565b8063095ea7b3116101b6578063095ea7b31461033b5780630afd902b146103745780631593dee11461039157806318160ddd146103d4576101e3565b806301ffc9a7146101e85780630512487a1461023057806306fdde031461026b578063081812fc146102f5575b600080fd5b3480156101f457600080fd5b5061021c6004803603602081101561020b57600080fd5b50356001600160e01b03191661096d565b604080519115158252519081900360200190f35b34801561023c57600080fd5b506102696004803603604081101561025357600080fd5b506001600160a01b038135169060200135610990565b005b34801561027757600080fd5b50610280610bea565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102ba5781810151838201526020016102a2565b50505050905090810190601f1680156102e75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561030157600080fd5b5061031f6004803603602081101561031857600080fd5b5035610c81565b604080516001600160a01b039092168252519081900360200190f35b34801561034757600080fd5b506102696004803603604081101561035e57600080fd5b506001600160a01b038135169060200135610ce8565b6102696004803603602081101561038a57600080fd5b5035610dc8565b34801561039d57600080fd5b50610269600480360360608110156103b457600080fd5b506001600160a01b03813581169160208101359091169060400135610e7b565b3480156103e057600080fd5b506103e9610ede565b60408051918252519081900360200190f35b34801561040757600080fd5b506102696004803603606081101561041e57600080fd5b506001600160a01b03813581169160208101359091169060400135610ee4565b34801561044a57600080fd5b506102696004803603606081101561046157600080fd5b506001600160a01b03813581169160208101359091169060400135610f40565b34801561048d57600080fd5b50610269600480360360608110156104a457600080fd5b506001600160a01b03813581169160208101359091169060400135610fa3565b3480156104d057600080fd5b506103e9600480360360208110156104e757600080fd5b5035610fbe565b3480156104fa57600080fd5b506102696004803603604081101561051157600080fd5b506001600160a01b03813516906020013561101f565b6103e9611085565b34801561053b57600080fd5b506102696004803603602081101561055257600080fd5b503561113b565b34801561056557600080fd5b5061031f6004803603602081101561057c57600080fd5b50356111ce565b34801561058f57600080fd5b506103e96111e9565b3480156105a457600080fd5b506103e9600480360360208110156105bb57600080fd5b50356001600160a01b0316611225565b3480156105d757600080fd5b5061026961128d565b3480156105ec57600080fd5b5061031f61132f565b34801561060157600080fd5b5061028061133e565b34801561061657600080fd5b506102696004803603604081101561062d57600080fd5b506001600160a01b038135169060200135151561139f565b34801561065157600080fd5b506103e96004803603602081101561066857600080fd5b5035611493565b34801561067b57600080fd5b50610269600480360360c081101561069257600080fd5b813591908101906040810160208201356401000000008111156106b457600080fd5b8201836020820111156106c657600080fd5b803590602001918460018302840111640100000000831117156106e857600080fd5b919350915080359063ffffffff60208201358116916040810135821691606090910135166114f4565b34801561071d57600080fd5b506102696004803603608081101561073457600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561076f57600080fd5b82018360208201111561078157600080fd5b803590602001918460018302840111640100000000831117156107a357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506116fd945050505050565b3480156107f057600080fd5b506102806004803603602081101561080757600080fd5b5035611760565b34801561081a57600080fd5b506103e96117b8565b34801561082f57600080fd5b50610269600480360360a081101561084657600080fd5b81019060208101813564010000000081111561086157600080fd5b82018360208201111561087357600080fd5b8035906020019184600183028401116401000000008311171561089557600080fd5b919350915080359063ffffffff60208201358116916040810135821691606090910135166117be565b3480156108ca57600080fd5b50610269600480360360208110156108e157600080fd5b50351515611a3e565b3480156108f657600080fd5b506103e9611add565b34801561090b57600080fd5b5061021c6004803603604081101561092257600080fd5b506001600160a01b0381358116916020013516611afa565b34801561094657600080fd5b506102696004803603602081101561095d57600080fd5b50356001600160a01b0316611b2a565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b610998611c23565b6008546001600160a01b039081169116146109e8576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b600f54610100900460ff1615610a31576040805162461bcd60e51b81526020600482015260096024820152681314150e914b4c0c0d60ba1b604482015290519081900360640190fd5b6000826001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a6c57600080fd5b505afa158015610a80573d6000803e3d6000fd5b505050506040513d6020811015610a9657600080fd5b50519050801580610aa85750600e5481115b610ae5576040805162461bcd60e51b81526020600482015260096024820152681314150e914b4c0c0d60ba1b604482015290519081900360640190fd5b8015610bd357600e54600090610afb9084611c27565b905081811115610b1c57610b19610b128284611c88565b8490611c88565b92505b60015b838111610bc057600e54600090610b369083611c27565b90506000866001600160a01b0316636352211e836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610b7e57600080fd5b505afa158015610b92573d6000803e3d6000fd5b505050506040513d6020811015610ba857600080fd5b50519050610bb581611cca565b505050600101610b1f565b50600e54610bce9084611c27565b600e55505b600e54811415610be557610be5611e01565b505050565b60058054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610c765780601f10610c4b57610100808354040283529160200191610c76565b820191906000526020600020905b815481529060010190602001808311610c5957829003601f168201915b505050505090505b90565b6000610c8c82611f5e565b610ccc576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303560a01b604482015290519081900360640190fd5b506000908152600360205260409020546001600160a01b031690565b6000610cf3826111ce565b9050806001600160a01b0316836001600160a01b03161415610d4b576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d31313160a01b604482015290519081900360640190fd5b806001600160a01b0316610d5d611c23565b6001600160a01b03161480610d7e5750610d7e81610d79611c23565b611afa565b610dbe576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d31303560a01b604482015290519081900360640190fd5b610be58383611f7b565b60026009541415610e20576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002600955600f5460ff1615610e69576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d31303160b81b604482015290519081900360640190fd5b610e733382611fe9565b506001600955565b610e83611c23565b6008546001600160a01b03908116911614610ed3576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b610be5838383612287565b60075490565b610ef5610eef611c23565b826123b1565b610f35576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d31303560a01b604482015290519081900360640190fd5b610be583838361245a565b610f48611c23565b6008546001600160a01b03908116911614610f98576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b610be58383836125d0565b610be5838383604051806020016040528060008152506116fd565b6000610fc982611f5e565b611006576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d34303560b81b604482015290519081900360640190fd5b61100f82612756565b60a0015163ffffffff1692915050565b611027611c23565b6008546001600160a01b03908116911614611077576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b61108182826128ac565b5050565b6000600260095414156110df576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002600955600f5460ff1615611128576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d31303160b81b604482015290519081900360640190fd5b6111313361294f565b6001600955919050565b611143611c23565b6008546001600160a01b03908116911614611193576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b600d8190556040805182815290517f409ba051a4c57ed282ca3d937444126381926068149b2ceb9dcff792655a9b039181900360200190a150565b6000908152600160205260409020546001600160a01b031690565b600a54600b54600091116111ff57506000610c7e565b600a600b548154811061120e57fe5b906000526020600020906003020160010154905090565b60006001600160a01b038216611271576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303360a01b604482015290519081900360640190fd5b506001600160a01b031660009081526002602052604090205490565b611295611c23565b6008546001600160a01b039081169116146112e5576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b6008546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600880546001600160a01b0319169055565b6008546001600160a01b031690565b60068054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610c765780601f10610c4b57610100808354040283529160200191610c76565b6113a7611c23565b6001600160a01b0316826001600160a01b031614156113fc576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d31313160a01b604482015290519081900360640190fd5b8060046000611409611c23565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff19169215159290921790915561144d611c23565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b600061149e82611f5e565b6114db576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d34303560b81b604482015290519081900360640190fd5b6114e482612756565b6080015163ffffffff1692915050565b6114fc611c23565b6008546001600160a01b0390811691161461154c576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b8585600a898154811061155b57fe5b600091825260209091206115759360039092020191613344565b5083600a888154811061158457fe5b90600052602060002090600302016001018190555082600a88815481106115a757fe5b906000526020600020906003020160020160106101000a81548163ffffffff021916908363ffffffff16021790555081600a88815481106115e457fe5b906000526020600020906003020160020160146101000a81548163ffffffff021916908363ffffffff16021790555080600a888154811061162157fe5b906000526020600020906003020160020160186101000a81548163ffffffff021916908363ffffffff1602179055507fc29eb52b178d59612a9ec3dbfed2e3054ea12f735bff5d06a799a4b06cd47c5287878787878787600c5460405180898152602001806020018781526020018663ffffffff1681526020018563ffffffff1681526020018463ffffffff1681526020018381526020018281038252898982818152602001925080828437600083820152604051601f909101601f19169092018290039b50909950505050505050505050a150505050505050565b61170e611708611c23565b836123b1565b61174e576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d31303560a01b604482015290519081900360640190fd5b61175a84848484612b46565b50505050565b606061176b82611f5e565b6117a8576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d34303560b81b604482015290519081900360640190fd5b6117b182612756565b5192915050565b600c5490565b6117c6611c23565b6008546001600160a01b03908116911614611816576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b600c5461182c9063ffffffff80861690611c2716565b600c556118376133c2565b6040518060c0016040528088888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509385525050506020808301899052600c546001600160801b0316604084015263ffffffff80891660608501528781166080850152861660a090930192909252600a8054600181018255915282518051939450849360039092027fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a801926118ff928492909101906133f7565b5060208281015160018301556040808401516002909301805460608087015160808089015160a0998a01516fffffffffffffffffffffffffffffffff199095166001600160801b039099169890981763ffffffff60801b1916600160801b63ffffffff938416021763ffffffff60a01b1916600160a01b988316989098029790971763ffffffff60c01b1916600160c01b9382169390930292909217909255600c5483519485018c90528a8216938501939093528881169184019190915286169282019290925291820181905260c080835282018890527f03a96a3a809ae0740a794cb4d254030e999b01bb9985f4b0b5f5e524dc8e0667918991899189918991899189918060e08101898980828437600083820152604051601f909101601f19169092018290039a509098505050505050505050a150505050505050565b611a46611c23565b6008546001600160a01b03908116911614611a96576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b600f805482151560ff19909116811790915560408051918252517fa9bfed3d98385b3777389e321dbde773cf7d335fa604fefbae3dca93564f55869181900360200190a150565b600a54600b5460009111611af357506000610c7e565b50600b5490565b6001600160a01b0380831660009081526004602090815260408083209385168352929052205460ff165b92915050565b611b32611c23565b6008546001600160a01b03908116911614611b82576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b6001600160a01b038116611bc75760405162461bcd60e51b815260040180806020018281038252602681526020018061347b6026913960400191505060405180910390fd5b6008546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600880546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b600082820183811015611c81576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000611c8183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612b9d565b60006001600160a01b038216611d16576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303360a01b604482015290519081900360640190fd5b600754611d24906001611c27565b6007819055611d3281611f5e565b15611d73576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303760a01b604482015290519081900360640190fd5b600081815260016020818152604080842080546001600160a01b0319166001600160a01b0389169081179091558452600290915290912054611db491611c27565b6001600160a01b0384166000818152600260205260408082209390935591518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a492915050565b6000600b8190555b600a54811015611f4c57611e1b6133c2565b600a8281548110611e2857fe5b600091825260209182902060408051600393909302909101805460026001821615610100026000190190911604601f8101859004909402830160e090810190925260c0830184815292939092849290918491840182828015611ecb5780601f10611ea057610100808354040283529160200191611ecb565b820191906000526020600020905b815481529060010190602001808311611eae57829003601f168201915b5050509183525050600182015460208201526002909101546001600160801b0380821660408085019190915263ffffffff600160801b840481166060860152600160a01b840481166080860152600160c01b90930490921660a090930192909252820151600e549293501611611f435760018201600b555b50600101611e09565b50600f805461ff001916610100179055565b6000908152600160205260409020546001600160a01b0316151590565b600081815260036020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611fb0826111ce565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600a54600b541061202d576040805162461bcd60e51b8152602060048201526009602482015268098a0a8748a5a6860760bb1b604482015290519081900360640190fd5b600d54158061203e5750600d548111155b61207b576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d34323960b81b604482015290519081900360640190fd5b6120836133c2565b600a600b548154811061209257fe5b600091825260209182902060408051600393909302909101805460026001821615610100026000190190911604601f8101859004909402830160e090810190925260c08301848152929390928492909184918401828280156121355780601f1061210a57610100808354040283529160200191612135565b820191906000526020600020905b81548152906001019060200180831161211857829003601f168201915b5050509183525050600182015460208201526002909101546001600160801b038116604083015263ffffffff600160801b820481166060840152600160a01b820481166080840152600160c01b909104811660a0909201919091526007549192506000916121a5918590611c2716565b905081604001516001600160801b03168111156121e2576121df610b1283604001516001600160801b031683611c8890919063ffffffff16565b92505b60208201516000906121f49085612c34565b905080341015612237576040805162461bcd60e51b81526020600482015260096024820152681314150e914b4d0c4d60ba1b604482015290519081900360640190fd5b612251858560405180602001604052806000815250612c8d565b82604001516001600160801b0316821061227757600b54612273906001611c27565b600b555b61228081612ca8565b5050505050565b6001600160a01b0383166122ce576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b80826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561231c57600080fd5b505afa158015612330573d6000803e3d6000fd5b505050506040513d602081101561234657600080fd5b505110610be5576123616001600160a01b0383168483612cd7565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b836040518082815260200191505060405180910390a3505050565b60006123bc82611f5e565b6123fc576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303560a01b604482015290519081900360640190fd5b6000612407836111ce565b9050806001600160a01b0316846001600160a01b031614806124425750836001600160a01b031661243784610c81565b6001600160a01b0316145b8061245257506124528185611afa565b949350505050565b826001600160a01b031661246d826111ce565b6001600160a01b0316146124b7576040805162461bcd60e51b815260206004820152600c60248201526b22a9219b99189d229698981960a11b604482015290519081900360640190fd5b6001600160a01b038216612501576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303360a01b604482015290519081900360640190fd5b61250c600082611f7b565b600081815260016020818152604080842080546001600160a01b0319166001600160a01b03888116919091179091558716845260029091529091205461255191611c88565b6001600160a01b038085166000908152600260205260408082209390935590841681522054612581906001611c27565b6001600160a01b03808416600081815260026020526040808220949094559251849391928716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b038316612617576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b306001600160a01b0316826001600160a01b0316636352211e836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561266557600080fd5b505afa158015612679573d6000803e3d6000fd5b505050506040513d602081101561268f57600080fd5b50516001600160a01b03161415610be557604080516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018490529151918416916323b872dd9160648082019260009290919082900301818387803b1580156126f857600080fd5b505af115801561270c573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b61275e6133c2565b600a5460005b818110156128a5576127746133c2565b600a828154811061278157fe5b600091825260209182902060408051600393909302909101805460026001821615610100026000190190911604601f8101859004909402830160e090810190925260c08301848152929390928492909184918401828280156128245780601f106127f957610100808354040283529160200191612824565b820191906000526020600020905b81548152906001019060200180831161280757829003601f168201915b5050509183525050600182015460208201526002909101546001600160801b0380821660408085019190915263ffffffff600160801b840481166060860152600160a01b840481166080860152600160c01b90930490921660a09093019290925282015191925016851161289c57925061098b915050565b50600101612764565b5050919050565b6001600160a01b0382166128f3576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b8047106110815761290d6001600160a01b03831682612d29565b6040805182815290516001600160a01b038416917eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd919081900360200190a25050565b600a54600b5460009111612996576040805162461bcd60e51b8152602060048201526009602482015268098a0a8748a5a6860760bb1b604482015290519081900360640190fd5b61299e6133c2565b600a600b54815481106129ad57fe5b600091825260209182902060408051600393909302909101805460026001821615610100026000190190911604601f8101859004909402830160e090810190925260c0830184815292939092849290918491840182828015612a505780601f10612a2557610100808354040283529160200191612a50565b820191906000526020600020905b815481529060010190602001808311612a3357829003601f168201915b505050918352505060018201546020808301919091526002909201546001600160801b038116604083015263ffffffff600160801b820481166060840152600160a01b820481166080840152600160c01b9091041660a090910152810151909150341015612af1576040805162461bcd60e51b81526020600482015260096024820152681314150e914b4d0c4d60ba1b604482015290519081900360640190fd5b612b0a8360405180602001604052806000815250612e0e565b915080604001516001600160801b0316821415612b3357600b54612b2f906001611c27565b600b555b612b408160200151612ca8565b50919050565b612b5184848461245a565b612b5d84848484612e69565b61175a576040805162461bcd60e51b815260206004820152600c60248201526b22a9219b99189d22969a181960a11b604482015290519081900360640190fd5b60008184841115612c2c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612bf1578181015183820152602001612bd9565b50505050905090810190601f168015612c1e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082612c4357506000611b24565b82820282848281612c5057fe5b0414611c815760405162461bcd60e51b81526004018080602001828103825260218152602001806134db6021913960400191505060405180910390fd5b6000612c998484612fe5565b9050612b5d6000858385612e69565b6000612cb43483611c88565b905080156110815761108181612cc8611c23565b6001600160a01b031690612d29565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610be5908490613116565b80471015612d7e576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015290519081900360640190fd5b6040516000906001600160a01b0384169083908381818185875af1925050503d8060008114612dc9576040519150601f19603f3d011682016040523d82523d6000602084013e612dce565b606091505b5050905080610be55760405162461bcd60e51b815260040180806020018281038252603a8152602001806134a1603a913960400191505060405180910390fd5b600080612e1a84611cca565b9050612e296000858386612e69565b611c81576040805162461bcd60e51b815260206004820152600c60248201526b22a9219b99189d22969a181960a11b604482015290519081900360640190fd5b6000612e7d846001600160a01b03166131c7565b612e8957506001612452565b6060612fab630a85bd0160e11b612e9e611c23565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612f05578181015183820152602001612eed565b50505050905090810190601f168015612f325780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b0383818316178352505050506040518060400160405280600c81526020016b22a9219b99189d22969a181960a11b815250876001600160a01b03166131cd9092919063ffffffff16565b90506000818060200190516020811015612fc457600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b60006001600160a01b038316613031576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303360a01b604482015290519081900360640190fd5b600754600090613042906001611c27565b905060015b8381116130c15760075460009061305e9083611c27565b60008181526001602052604080822080546001600160a01b0319166001600160a01b038b16908117909155905192935083929091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a450600101613047565b506007546130cf9084611c27565b6007556001600160a01b0384166000908152600260205260409020546130f59084611c27565b6001600160a01b038516600090815260026020526040902055905092915050565b606061316b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131cd9092919063ffffffff16565b805190915015610be55780806020019051602081101561318a57600080fd5b5051610be55760405162461bcd60e51b815260040180806020018281038252602a81526020018061351c602a913960400191505060405180910390fd5b3b151590565b6060612452848460008560606131e2856131c7565b613233576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106132725780518252601f199092019160209182019101613253565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146132d4576040519150601f19603f3d011682016040523d82523d6000602084013e6132d9565b606091505b509150915081156132ed5791506124529050565b8051156132fd5780518082602001fd5b60405162461bcd60e51b8152602060048201818152865160248401528651879391928392604401919085019080838360008315612bf1578181015183820152602001612bd9565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106133855782800160ff198235161785556133b2565b828001600101855582156133b2579182015b828111156133b2578235825591602001919060010190613397565b506133be929150613465565b5090565b6040805160c081018252606080825260006020830181905292820183905281018290526080810182905260a081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061343857805160ff19168380011785556133b2565b828001600101855582156133b2579182015b828111156133b257825182559160200191906001019061344a565b5b808211156133be576000815560010161346656fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373416464726573733a20756e61626c6520746f2073656e642076616c75652c20726563697069656e74206d61792068617665207265766572746564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220d7e45e90b00ada93bf14e609b381114d3130c10d66c4fda21c728f1176b4ffd264736f6c634300060c0033", + "deployedBytecode": "0x6080604052600436106101e35760003560e01c8063681ce98a11610102578063b88d4fde11610095578063db9f60ff11610064578063db9f60ff146108be578063e6089023146108ea578063e985e9c5146108ff578063f2fde38b1461093a576101e3565b8063b88d4fde14610711578063c87b56dd146107e4578063d5abeb011461080e578063da47bb2614610823576101e3565b806395d89b41116100d157806395d89b41146105f5578063a22cb4651461060a578063adf8252d14610645578063b0fde8cf1461066f576101e3565b8063681ce98a1461058357806370a0823114610598578063715018a6146105cb5780638da5cb5b146105e0576101e3565b806323b872dd1161017a578063522f681511610149578063522f6815146104ee5780635fc194ed14610527578063616cdb1e1461052f5780636352211e14610559576101e3565b806323b872dd146103fb5780634025feb21461043e57806342842e0e146104815780634aa66b28146104c4576101e3565b8063095ea7b3116101b6578063095ea7b31461033b5780630afd902b146103745780631593dee11461039157806318160ddd146103d4576101e3565b806301ffc9a7146101e85780630512487a1461023057806306fdde031461026b578063081812fc146102f5575b600080fd5b3480156101f457600080fd5b5061021c6004803603602081101561020b57600080fd5b50356001600160e01b03191661096d565b604080519115158252519081900360200190f35b34801561023c57600080fd5b506102696004803603604081101561025357600080fd5b506001600160a01b038135169060200135610990565b005b34801561027757600080fd5b50610280610bea565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102ba5781810151838201526020016102a2565b50505050905090810190601f1680156102e75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561030157600080fd5b5061031f6004803603602081101561031857600080fd5b5035610c81565b604080516001600160a01b039092168252519081900360200190f35b34801561034757600080fd5b506102696004803603604081101561035e57600080fd5b506001600160a01b038135169060200135610ce8565b6102696004803603602081101561038a57600080fd5b5035610dc8565b34801561039d57600080fd5b50610269600480360360608110156103b457600080fd5b506001600160a01b03813581169160208101359091169060400135610e7b565b3480156103e057600080fd5b506103e9610ede565b60408051918252519081900360200190f35b34801561040757600080fd5b506102696004803603606081101561041e57600080fd5b506001600160a01b03813581169160208101359091169060400135610ee4565b34801561044a57600080fd5b506102696004803603606081101561046157600080fd5b506001600160a01b03813581169160208101359091169060400135610f40565b34801561048d57600080fd5b50610269600480360360608110156104a457600080fd5b506001600160a01b03813581169160208101359091169060400135610fa3565b3480156104d057600080fd5b506103e9600480360360208110156104e757600080fd5b5035610fbe565b3480156104fa57600080fd5b506102696004803603604081101561051157600080fd5b506001600160a01b03813516906020013561101f565b6103e9611085565b34801561053b57600080fd5b506102696004803603602081101561055257600080fd5b503561113b565b34801561056557600080fd5b5061031f6004803603602081101561057c57600080fd5b50356111ce565b34801561058f57600080fd5b506103e96111e9565b3480156105a457600080fd5b506103e9600480360360208110156105bb57600080fd5b50356001600160a01b0316611225565b3480156105d757600080fd5b5061026961128d565b3480156105ec57600080fd5b5061031f61132f565b34801561060157600080fd5b5061028061133e565b34801561061657600080fd5b506102696004803603604081101561062d57600080fd5b506001600160a01b038135169060200135151561139f565b34801561065157600080fd5b506103e96004803603602081101561066857600080fd5b5035611493565b34801561067b57600080fd5b50610269600480360360c081101561069257600080fd5b813591908101906040810160208201356401000000008111156106b457600080fd5b8201836020820111156106c657600080fd5b803590602001918460018302840111640100000000831117156106e857600080fd5b919350915080359063ffffffff60208201358116916040810135821691606090910135166114f4565b34801561071d57600080fd5b506102696004803603608081101561073457600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561076f57600080fd5b82018360208201111561078157600080fd5b803590602001918460018302840111640100000000831117156107a357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506116fd945050505050565b3480156107f057600080fd5b506102806004803603602081101561080757600080fd5b5035611760565b34801561081a57600080fd5b506103e96117b8565b34801561082f57600080fd5b50610269600480360360a081101561084657600080fd5b81019060208101813564010000000081111561086157600080fd5b82018360208201111561087357600080fd5b8035906020019184600183028401116401000000008311171561089557600080fd5b919350915080359063ffffffff60208201358116916040810135821691606090910135166117be565b3480156108ca57600080fd5b50610269600480360360208110156108e157600080fd5b50351515611a3e565b3480156108f657600080fd5b506103e9611add565b34801561090b57600080fd5b5061021c6004803603604081101561092257600080fd5b506001600160a01b0381358116916020013516611afa565b34801561094657600080fd5b506102696004803603602081101561095d57600080fd5b50356001600160a01b0316611b2a565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b610998611c23565b6008546001600160a01b039081169116146109e8576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b600f54610100900460ff1615610a31576040805162461bcd60e51b81526020600482015260096024820152681314150e914b4c0c0d60ba1b604482015290519081900360640190fd5b6000826001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a6c57600080fd5b505afa158015610a80573d6000803e3d6000fd5b505050506040513d6020811015610a9657600080fd5b50519050801580610aa85750600e5481115b610ae5576040805162461bcd60e51b81526020600482015260096024820152681314150e914b4c0c0d60ba1b604482015290519081900360640190fd5b8015610bd357600e54600090610afb9084611c27565b905081811115610b1c57610b19610b128284611c88565b8490611c88565b92505b60015b838111610bc057600e54600090610b369083611c27565b90506000866001600160a01b0316636352211e836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610b7e57600080fd5b505afa158015610b92573d6000803e3d6000fd5b505050506040513d6020811015610ba857600080fd5b50519050610bb581611cca565b505050600101610b1f565b50600e54610bce9084611c27565b600e55505b600e54811415610be557610be5611e01565b505050565b60058054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610c765780601f10610c4b57610100808354040283529160200191610c76565b820191906000526020600020905b815481529060010190602001808311610c5957829003601f168201915b505050505090505b90565b6000610c8c82611f5e565b610ccc576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303560a01b604482015290519081900360640190fd5b506000908152600360205260409020546001600160a01b031690565b6000610cf3826111ce565b9050806001600160a01b0316836001600160a01b03161415610d4b576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d31313160a01b604482015290519081900360640190fd5b806001600160a01b0316610d5d611c23565b6001600160a01b03161480610d7e5750610d7e81610d79611c23565b611afa565b610dbe576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d31303560a01b604482015290519081900360640190fd5b610be58383611f7b565b60026009541415610e20576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002600955600f5460ff1615610e69576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d31303160b81b604482015290519081900360640190fd5b610e733382611fe9565b506001600955565b610e83611c23565b6008546001600160a01b03908116911614610ed3576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b610be5838383612287565b60075490565b610ef5610eef611c23565b826123b1565b610f35576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d31303560a01b604482015290519081900360640190fd5b610be583838361245a565b610f48611c23565b6008546001600160a01b03908116911614610f98576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b610be58383836125d0565b610be5838383604051806020016040528060008152506116fd565b6000610fc982611f5e565b611006576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d34303560b81b604482015290519081900360640190fd5b61100f82612756565b60a0015163ffffffff1692915050565b611027611c23565b6008546001600160a01b03908116911614611077576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b61108182826128ac565b5050565b6000600260095414156110df576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002600955600f5460ff1615611128576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d31303160b81b604482015290519081900360640190fd5b6111313361294f565b6001600955919050565b611143611c23565b6008546001600160a01b03908116911614611193576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b600d8190556040805182815290517f409ba051a4c57ed282ca3d937444126381926068149b2ceb9dcff792655a9b039181900360200190a150565b6000908152600160205260409020546001600160a01b031690565b600a54600b54600091116111ff57506000610c7e565b600a600b548154811061120e57fe5b906000526020600020906003020160010154905090565b60006001600160a01b038216611271576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303360a01b604482015290519081900360640190fd5b506001600160a01b031660009081526002602052604090205490565b611295611c23565b6008546001600160a01b039081169116146112e5576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b6008546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600880546001600160a01b0319169055565b6008546001600160a01b031690565b60068054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610c765780601f10610c4b57610100808354040283529160200191610c76565b6113a7611c23565b6001600160a01b0316826001600160a01b031614156113fc576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d31313160a01b604482015290519081900360640190fd5b8060046000611409611c23565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff19169215159290921790915561144d611c23565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b600061149e82611f5e565b6114db576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d34303560b81b604482015290519081900360640190fd5b6114e482612756565b6080015163ffffffff1692915050565b6114fc611c23565b6008546001600160a01b0390811691161461154c576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b8585600a898154811061155b57fe5b600091825260209091206115759360039092020191613344565b5083600a888154811061158457fe5b90600052602060002090600302016001018190555082600a88815481106115a757fe5b906000526020600020906003020160020160106101000a81548163ffffffff021916908363ffffffff16021790555081600a88815481106115e457fe5b906000526020600020906003020160020160146101000a81548163ffffffff021916908363ffffffff16021790555080600a888154811061162157fe5b906000526020600020906003020160020160186101000a81548163ffffffff021916908363ffffffff1602179055507fc29eb52b178d59612a9ec3dbfed2e3054ea12f735bff5d06a799a4b06cd47c5287878787878787600c5460405180898152602001806020018781526020018663ffffffff1681526020018563ffffffff1681526020018463ffffffff1681526020018381526020018281038252898982818152602001925080828437600083820152604051601f909101601f19169092018290039b50909950505050505050505050a150505050505050565b61170e611708611c23565b836123b1565b61174e576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d31303560a01b604482015290519081900360640190fd5b61175a84848484612b46565b50505050565b606061176b82611f5e565b6117a8576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d34303560b81b604482015290519081900360640190fd5b6117b182612756565b5192915050565b600c5490565b6117c6611c23565b6008546001600160a01b03908116911614611816576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b600c5461182c9063ffffffff80861690611c2716565b600c556118376133c2565b6040518060c0016040528088888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509385525050506020808301899052600c546001600160801b0316604084015263ffffffff80891660608501528781166080850152861660a090930192909252600a8054600181018255915282518051939450849360039092027fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a801926118ff928492909101906133f7565b5060208281015160018301556040808401516002909301805460608087015160808089015160a0998a01516fffffffffffffffffffffffffffffffff199095166001600160801b039099169890981763ffffffff60801b1916600160801b63ffffffff938416021763ffffffff60a01b1916600160a01b988316989098029790971763ffffffff60c01b1916600160c01b9382169390930292909217909255600c5483519485018c90528a8216938501939093528881169184019190915286169282019290925291820181905260c080835282018890527f03a96a3a809ae0740a794cb4d254030e999b01bb9985f4b0b5f5e524dc8e0667918991899189918991899189918060e08101898980828437600083820152604051601f909101601f19169092018290039a509098505050505050505050a150505050505050565b611a46611c23565b6008546001600160a01b03908116911614611a96576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b600f805482151560ff19909116811790915560408051918252517fa9bfed3d98385b3777389e321dbde773cf7d335fa604fefbae3dca93564f55869181900360200190a150565b600a54600b5460009111611af357506000610c7e565b50600b5490565b6001600160a01b0380831660009081526004602090815260408083209385168352929052205460ff165b92915050565b611b32611c23565b6008546001600160a01b03908116911614611b82576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b6001600160a01b038116611bc75760405162461bcd60e51b815260040180806020018281038252602681526020018061347b6026913960400191505060405180910390fd5b6008546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600880546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b600082820183811015611c81576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000611c8183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612b9d565b60006001600160a01b038216611d16576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303360a01b604482015290519081900360640190fd5b600754611d24906001611c27565b6007819055611d3281611f5e565b15611d73576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303760a01b604482015290519081900360640190fd5b600081815260016020818152604080842080546001600160a01b0319166001600160a01b0389169081179091558452600290915290912054611db491611c27565b6001600160a01b0384166000818152600260205260408082209390935591518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a492915050565b6000600b8190555b600a54811015611f4c57611e1b6133c2565b600a8281548110611e2857fe5b600091825260209182902060408051600393909302909101805460026001821615610100026000190190911604601f8101859004909402830160e090810190925260c0830184815292939092849290918491840182828015611ecb5780601f10611ea057610100808354040283529160200191611ecb565b820191906000526020600020905b815481529060010190602001808311611eae57829003601f168201915b5050509183525050600182015460208201526002909101546001600160801b0380821660408085019190915263ffffffff600160801b840481166060860152600160a01b840481166080860152600160c01b90930490921660a090930192909252820151600e549293501611611f435760018201600b555b50600101611e09565b50600f805461ff001916610100179055565b6000908152600160205260409020546001600160a01b0316151590565b600081815260036020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611fb0826111ce565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600a54600b541061202d576040805162461bcd60e51b8152602060048201526009602482015268098a0a8748a5a6860760bb1b604482015290519081900360640190fd5b600d54158061203e5750600d548111155b61207b576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d34323960b81b604482015290519081900360640190fd5b6120836133c2565b600a600b548154811061209257fe5b600091825260209182902060408051600393909302909101805460026001821615610100026000190190911604601f8101859004909402830160e090810190925260c08301848152929390928492909184918401828280156121355780601f1061210a57610100808354040283529160200191612135565b820191906000526020600020905b81548152906001019060200180831161211857829003601f168201915b5050509183525050600182015460208201526002909101546001600160801b038116604083015263ffffffff600160801b820481166060840152600160a01b820481166080840152600160c01b909104811660a0909201919091526007549192506000916121a5918590611c2716565b905081604001516001600160801b03168111156121e2576121df610b1283604001516001600160801b031683611c8890919063ffffffff16565b92505b60208201516000906121f49085612c34565b905080341015612237576040805162461bcd60e51b81526020600482015260096024820152681314150e914b4d0c4d60ba1b604482015290519081900360640190fd5b612251858560405180602001604052806000815250612c8d565b82604001516001600160801b0316821061227757600b54612273906001611c27565b600b555b61228081612ca8565b5050505050565b6001600160a01b0383166122ce576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b80826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561231c57600080fd5b505afa158015612330573d6000803e3d6000fd5b505050506040513d602081101561234657600080fd5b505110610be5576123616001600160a01b0383168483612cd7565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b836040518082815260200191505060405180910390a3505050565b60006123bc82611f5e565b6123fc576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303560a01b604482015290519081900360640190fd5b6000612407836111ce565b9050806001600160a01b0316846001600160a01b031614806124425750836001600160a01b031661243784610c81565b6001600160a01b0316145b8061245257506124528185611afa565b949350505050565b826001600160a01b031661246d826111ce565b6001600160a01b0316146124b7576040805162461bcd60e51b815260206004820152600c60248201526b22a9219b99189d229698981960a11b604482015290519081900360640190fd5b6001600160a01b038216612501576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303360a01b604482015290519081900360640190fd5b61250c600082611f7b565b600081815260016020818152604080842080546001600160a01b0319166001600160a01b03888116919091179091558716845260029091529091205461255191611c88565b6001600160a01b038085166000908152600260205260408082209390935590841681522054612581906001611c27565b6001600160a01b03808416600081815260026020526040808220949094559251849391928716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b038316612617576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b306001600160a01b0316826001600160a01b0316636352211e836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561266557600080fd5b505afa158015612679573d6000803e3d6000fd5b505050506040513d602081101561268f57600080fd5b50516001600160a01b03161415610be557604080516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018490529151918416916323b872dd9160648082019260009290919082900301818387803b1580156126f857600080fd5b505af115801561270c573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b61275e6133c2565b600a5460005b818110156128a5576127746133c2565b600a828154811061278157fe5b600091825260209182902060408051600393909302909101805460026001821615610100026000190190911604601f8101859004909402830160e090810190925260c08301848152929390928492909184918401828280156128245780601f106127f957610100808354040283529160200191612824565b820191906000526020600020905b81548152906001019060200180831161280757829003601f168201915b5050509183525050600182015460208201526002909101546001600160801b0380821660408085019190915263ffffffff600160801b840481166060860152600160a01b840481166080860152600160c01b90930490921660a09093019290925282015191925016851161289c57925061098b915050565b50600101612764565b5050919050565b6001600160a01b0382166128f3576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b8047106110815761290d6001600160a01b03831682612d29565b6040805182815290516001600160a01b038416917eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd919081900360200190a25050565b600a54600b5460009111612996576040805162461bcd60e51b8152602060048201526009602482015268098a0a8748a5a6860760bb1b604482015290519081900360640190fd5b61299e6133c2565b600a600b54815481106129ad57fe5b600091825260209182902060408051600393909302909101805460026001821615610100026000190190911604601f8101859004909402830160e090810190925260c0830184815292939092849290918491840182828015612a505780601f10612a2557610100808354040283529160200191612a50565b820191906000526020600020905b815481529060010190602001808311612a3357829003601f168201915b505050918352505060018201546020808301919091526002909201546001600160801b038116604083015263ffffffff600160801b820481166060840152600160a01b820481166080840152600160c01b9091041660a090910152810151909150341015612af1576040805162461bcd60e51b81526020600482015260096024820152681314150e914b4d0c4d60ba1b604482015290519081900360640190fd5b612b0a8360405180602001604052806000815250612e0e565b915080604001516001600160801b0316821415612b3357600b54612b2f906001611c27565b600b555b612b408160200151612ca8565b50919050565b612b5184848461245a565b612b5d84848484612e69565b61175a576040805162461bcd60e51b815260206004820152600c60248201526b22a9219b99189d22969a181960a11b604482015290519081900360640190fd5b60008184841115612c2c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612bf1578181015183820152602001612bd9565b50505050905090810190601f168015612c1e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082612c4357506000611b24565b82820282848281612c5057fe5b0414611c815760405162461bcd60e51b81526004018080602001828103825260218152602001806134db6021913960400191505060405180910390fd5b6000612c998484612fe5565b9050612b5d6000858385612e69565b6000612cb43483611c88565b905080156110815761108181612cc8611c23565b6001600160a01b031690612d29565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610be5908490613116565b80471015612d7e576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015290519081900360640190fd5b6040516000906001600160a01b0384169083908381818185875af1925050503d8060008114612dc9576040519150601f19603f3d011682016040523d82523d6000602084013e612dce565b606091505b5050905080610be55760405162461bcd60e51b815260040180806020018281038252603a8152602001806134a1603a913960400191505060405180910390fd5b600080612e1a84611cca565b9050612e296000858386612e69565b611c81576040805162461bcd60e51b815260206004820152600c60248201526b22a9219b99189d22969a181960a11b604482015290519081900360640190fd5b6000612e7d846001600160a01b03166131c7565b612e8957506001612452565b6060612fab630a85bd0160e11b612e9e611c23565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612f05578181015183820152602001612eed565b50505050905090810190601f168015612f325780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b0383818316178352505050506040518060400160405280600c81526020016b22a9219b99189d22969a181960a11b815250876001600160a01b03166131cd9092919063ffffffff16565b90506000818060200190516020811015612fc457600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b60006001600160a01b038316613031576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303360a01b604482015290519081900360640190fd5b600754600090613042906001611c27565b905060015b8381116130c15760075460009061305e9083611c27565b60008181526001602052604080822080546001600160a01b0319166001600160a01b038b16908117909155905192935083929091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a450600101613047565b506007546130cf9084611c27565b6007556001600160a01b0384166000908152600260205260409020546130f59084611c27565b6001600160a01b038516600090815260026020526040902055905092915050565b606061316b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131cd9092919063ffffffff16565b805190915015610be55780806020019051602081101561318a57600080fd5b5051610be55760405162461bcd60e51b815260040180806020018281038252602a81526020018061351c602a913960400191505060405180910390fd5b3b151590565b6060612452848460008560606131e2856131c7565b613233576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106132725780518252601f199092019160209182019101613253565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146132d4576040519150601f19603f3d011682016040523d82523d6000602084013e6132d9565b606091505b509150915081156132ed5791506124529050565b8051156132fd5780518082602001fd5b60405162461bcd60e51b8152602060048201818152865160248401528651879391928392604401919085019080838360008315612bf1578181015183820152602001612bd9565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106133855782800160ff198235161785556133b2565b828001600101855582156133b2579182015b828111156133b2578235825591602001919060010190613397565b506133be929150613465565b5090565b6040805160c081018252606080825260006020830181905292820183905281018290526080810182905260a081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061343857805160ff19168380011785556133b2565b828001600101855582156133b2579182015b828111156133b257825182559160200191906001019061344a565b5b808211156133be576000815560010161346656fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373416464726573733a20756e61626c6520746f2073656e642076616c75652c20726563697069656e74206d61792068617665207265766572746564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220d7e45e90b00ada93bf14e609b381114d3130c10d66c4fda21c728f1176b4ffd264736f6c634300060c0033", + "devdoc": { + "kind": "dev", + "methods": { + "approve(address,uint256)": { + "details": "See {IERC721-approve}." + }, + "balanceOf(address)": { + "details": "See {IERC721-balanceOf}." + }, + "getApproved(uint256)": { + "details": "See {IERC721-getApproved}." + }, + "isApprovedForAll(address,address)": { + "details": "See {IERC721-isApprovedForAll}." + }, + "name()": { + "details": "See {IERC721Metadata-name}." + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "ownerOf(uint256)": { + "details": "See {IERC721-ownerOf}." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "safeTransferFrom(address,address,uint256)": { + "details": "See {IERC721-safeTransferFrom}." + }, + "safeTransferFrom(address,address,uint256,bytes)": { + "details": "See {IERC721-safeTransferFrom}." + }, + "setApprovalForAll(address,bool)": { + "details": "See {IERC721-setApprovalForAll}." + }, + "supportsInterface(bytes4)": { + "details": "See {IERC165-supportsInterface}. Time complexity O(1), guaranteed to always use less than 30 000 gas." + }, + "symbol()": { + "details": "See {IERC721Metadata-symbol}." + }, + "transferFrom(address,address,uint256)": { + "details": "See {IERC721-transferFrom}." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 4592, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_supportedInterfaces", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_bytes4,t_bool)" + }, + { + "astId": 32156, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_tokenOwners", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_uint256,t_address)" + }, + { + "astId": 32160, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_ownerBalance", + "offset": 0, + "slot": "2", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 32164, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_tokenApprovals", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_address)" + }, + { + "astId": 32170, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_operatorApprovals", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" + }, + { + "astId": 32172, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_name", + "offset": 0, + "slot": "5", + "type": "t_string_storage" + }, + { + "astId": 32174, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_symbol", + "offset": 0, + "slot": "6", + "type": "t_string_storage" + }, + { + "astId": 32176, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_tokenCount", + "offset": 0, + "slot": "7", + "type": "t_uint256" + }, + { + "astId": 4406, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_owner", + "offset": 0, + "slot": "8", + "type": "t_address" + }, + { + "astId": 9097, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_status", + "offset": 0, + "slot": "9", + "type": "t_uint256" + }, + { + "astId": 36360, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_leptonTypes", + "offset": 0, + "slot": "10", + "type": "t_array(t_struct(Classification)27847_storage)dyn_storage" + }, + { + "astId": 36362, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_typeIndex", + "offset": 0, + "slot": "11", + "type": "t_uint256" + }, + { + "astId": 36364, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_maxSupply", + "offset": 0, + "slot": "12", + "type": "t_uint256" + }, + { + "astId": 36366, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_maxMintPerTx", + "offset": 0, + "slot": "13", + "type": "t_uint256" + }, + { + "astId": 36368, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_migratedCount", + "offset": 0, + "slot": "14", + "type": "t_uint256" + }, + { + "astId": 36370, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_paused", + "offset": 0, + "slot": "15", + "type": "t_bool" + }, + { + "astId": 36372, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_migrationComplete", + "offset": 1, + "slot": "15", + "type": "t_bool" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_struct(Classification)27847_storage)dyn_storage": { + "base": "t_struct(Classification)27847_storage", + "encoding": "dynamic_array", + "label": "struct ILepton.Classification[]", + "numberOfBytes": "32" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_mapping(t_address,t_bool))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => bool))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_bool)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes4,t_bool)": { + "encoding": "mapping", + "key": "t_bytes4", + "label": "mapping(bytes4 => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_uint256,t_address)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(Classification)27847_storage": { + "encoding": "inplace", + "label": "struct ILepton.Classification", + "members": [ + { + "astId": 27836, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "tokenUri", + "offset": 0, + "slot": "0", + "type": "t_string_storage" + }, + { + "astId": 27838, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "price", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 27840, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_upperBounds", + "offset": 0, + "slot": "2", + "type": "t_uint128" + }, + { + "astId": 27842, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "supply", + "offset": 16, + "slot": "2", + "type": "t_uint32" + }, + { + "astId": 27844, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "multiplier", + "offset": 20, + "slot": "2", + "type": "t_uint32" + }, + { + "astId": 27846, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "bonus", + "offset": 24, + "slot": "2", + "type": "t_uint32" + } + ], + "numberOfBytes": "96" + }, + "t_uint128": { + "encoding": "inplace", + "label": "uint128", + "numberOfBytes": "16" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint32": { + "encoding": "inplace", + "label": "uint32", + "numberOfBytes": "4" + } + } + } +} \ No newline at end of file diff --git a/deployments/mumbai/RewardProgramDAI.json b/deployments/mumbai/RewardProgramDAI.json new file mode 100644 index 0000000..88c2ca2 --- /dev/null +++ b/deployments/mumbai/RewardProgramDAI.json @@ -0,0 +1,814 @@ +{ + "address": "0x4addF917AaFdff3D8BcD40eC01b34646173927b4", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "AssetDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "AssetRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "AssetRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardProgramFunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "RewardProgramOutOfFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewarded", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remaining", + "type": "uint256" + } + ], + "name": "RewardsClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "parentNftUuid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "calculateRewardsEarned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "fundProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "parentNftUuid", + "type": "uint256" + } + ], + "name": "getAssetStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimableRewards", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + } + ], + "internalType": "struct IRewardProgram.AssetStake", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getClaimableRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFundBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProgramData", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + } + ], + "internalType": "struct IRewardProgram.ProgramRewardData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + }, + { + "internalType": "address", + "name": "chargedManagers", + "type": "address" + }, + { + "internalType": "address", + "name": "universe", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "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": "nonpayable", + "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": "nonpayable", + "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": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "registerAssetDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "registerAssetRelease", + "outputs": [ + { + "internalType": "uint256", + "name": "rewards", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + } + ], + "name": "registerExistingDeposits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newMultiplier", + "type": "uint256" + } + ], + "name": "setBaseMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "setChargedManagers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newRewardToken", + "type": "address" + } + ], + "name": "setRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newStakingToken", + "type": "address" + } + ], + "name": "setStakingToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "universe", + "type": "address" + } + ], + "name": "setUniverse", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x7c30a9fe21389c90045feef1b07ed584963957a96c4c998f70a3b1f4d86618d7", + "numDeployments": 1 +} \ No newline at end of file diff --git a/deployments/mumbai/RewardProgramFactory.json b/deployments/mumbai/RewardProgramFactory.json new file mode 100644 index 0000000..3a2fed7 --- /dev/null +++ b/deployments/mumbai/RewardProgramFactory.json @@ -0,0 +1,418 @@ +{ + "address": "0x43f89148F17e10eD9A871FD6b410C066D968c80F", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "rewardProgram", + "type": "address" + } + ], + "name": "RewardProgramCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [], + "name": "_template", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + }, + { + "internalType": "address", + "name": "chargedManagers", + "type": "address" + }, + { + "internalType": "address", + "name": "universe", + "type": "address" + } + ], + "name": "createRewardProgram", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xa7941b86e1864506b389ab9641c3a71b5f5a68592002d55a377b8ac66309cd96", + "receipt": { + "to": null, + "from": "0x6d46b37708dA7Ed4E5C4509495768Fecd3D17C01", + "contractAddress": "0x43f89148F17e10eD9A871FD6b410C066D968c80F", + "transactionIndex": 0, + "gasUsed": "3259530", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000008000000080000000000000000000000000000400000000200000000020800001000000000000000100000000000000000000020000000000000000000800000000000000000080000000000000400000000000000000000000000000000000000000040000000400000000001000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100000000020000008000000000000000000000000000000000000000000000000000000100000", + "blockHash": "0x9e355198c5b69f3d16e30ae0a26ffc557c7a5db3a716b840cb616bd4b4eb98d4", + "transactionHash": "0xa7941b86e1864506b389ab9641c3a71b5f5a68592002d55a377b8ac66309cd96", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 39278950, + "transactionHash": "0xa7941b86e1864506b389ab9641c3a71b5f5a68592002d55a377b8ac66309cd96", + "address": "0x43f89148F17e10eD9A871FD6b410C066D968c80F", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000006d46b37708da7ed4e5c4509495768fecd3d17c01" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x9e355198c5b69f3d16e30ae0a26ffc557c7a5db3a716b840cb616bd4b4eb98d4" + }, + { + "transactionIndex": 0, + "blockNumber": 39278950, + "transactionHash": "0xa7941b86e1864506b389ab9641c3a71b5f5a68592002d55a377b8ac66309cd96", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000006d46b37708da7ed4e5c4509495768fecd3d17c01", + "0x000000000000000000000000e7f13f6bc1e7f5ca4a6c9a255124ce22c46f8ef0" + ], + "data": "0x0000000000000000000000000000000000000000000000000073cd40aa59a64c000000000000000000000000000000000000000000000000a49ed39ffa74e67700000000000000000000000000000000000000000000002f490fe38a061af196000000000000000000000000000000000000000000000000a42b065f501b402b00000000000000000000000000000000000000000000002f4983b0cab07497e2", + "logIndex": 1, + "blockHash": "0x9e355198c5b69f3d16e30ae0a26ffc557c7a5db3a716b840cb616bd4b4eb98d4" + } + ], + "blockNumber": 39278950, + "cumulativeGasUsed": "3259530", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "3c4a4867d03c114eb5175ff04b48a99d", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"rewardProgram\",\"type\":\"address\"}],\"name\":\"RewardProgramCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC1155\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckEther\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"_template\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"stakingToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rewardToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"baseMultiplier\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"chargedManagers\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"universe\",\"type\":\"address\"}],\"name\":\"createRewardProgram\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC1155\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawErc20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawEther\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/v1/incentives/RewardProgramFactory.sol\":\"RewardProgramFactory\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <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\",\"keccak256\":\"0x4784c3f8a520a739dd25d76f514833a653990902d0e21601aed45bda44c87524\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0xa1931c47a617014f858580db625aa0dcf343796f39acd4b5b51effc092a1f0a9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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 GSN 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 payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xdb26cbf4d028490f49831a7865c2fe1b28db44b535ca8d343785a3b768aae183\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"../GSN/Context.sol\\\";\\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 */\\ncontract 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 () internal {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view 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 emit OwnershipTransferred(_owner, address(0));\\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x4bd6402ca6b3419008c2b482aff54e66836e8cb4eba2680e42ac5884ae6424fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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\",\"keccak256\":\"0xfa152b6e88a1dc50780e8f1580426dc23ad2e1e2c2f086a088adf206a202f453\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\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 uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\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 sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\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 * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\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 // 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) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts 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 mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9a9cf02622cd7a64261b10534fc3260449da25c98c9e96d1b4ae8110a20e5806\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x31691ad0817f8cb338531b78d2ab2989027d9f27e6f8e62492b754fed9429b10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"../../introspection/IERC165.sol\\\";\\n\\n/**\\n * _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n\\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 )\\n external\\n 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 )\\n external\\n returns(bytes4);\\n}\\n\",\"keccak256\":\"0x0bc1d0b8fa3b262a6fb98b88dceab8b3348903b95dcc5909b9074fb19a3d2da5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0x5c26b39d26f7ed489e555d955dcd3e01872972e71fdd1528e93ec164e4f23385\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.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 SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf3b30f8a49631420635a8c35daacfcaa338012755f18a76fdd118730256f9a27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0xaf936da92f3a9a4f98b237323b5eb1d813fb86c4d07a184beba7027cf0509ba3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 /**\\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\",\"keccak256\":\"0x3636662804cd8f474536b2875a9038a4c3fb91879f1bbff48af5c3f140fcd2f0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address operator, address from, uint256 tokenId, bytes calldata data)\\n external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x321ee37ef4925020aa818a03ec7fe48e057561f65ab009a84f6c20c86026ade7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 in 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 // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n return _functionCallWithValue(target, data, value, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\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 // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf5fa8cbdffa5ef8be49b246b5628facc30b71707e78a45d80d93b64eff3fe390\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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.0.0, only sets of type `address` (`AddressSet`) and `uint256`\\n * (`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\\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\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] = toDeleteIndex + 1; // All indexes are 1-based\\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 require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\n return set._values[index];\\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(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(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(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(uint256(_at(set._inner, index)));\\n }\\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\",\"keccak256\":\"0xb2a11b236f073662f5a196995863f51c11d006bf7c3de158b316dfa1506c4b79\",\"license\":\"MIT\"},\"contracts/v1/incentives/RewardProgram.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// RewardProgram.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../interfaces/IRewardProgram.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/introspection/IERC165.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/EnumerableSet.sol\\\";\\n\\nimport \\\"../interfaces/IUniverseRP.sol\\\";\\nimport \\\"../interfaces/IChargedManagers.sol\\\";\\nimport \\\"../interfaces/IWalletManager.sol\\\";\\nimport \\\"../lib/TokenInfo.sol\\\";\\nimport \\\"../lib/ReentrancyGuard.sol\\\";\\nimport \\\"../lib/BlackholePrevention.sol\\\";\\nimport \\\"../interfaces/IERC20Detailed.sol\\\";\\n\\ncontract RewardProgram is\\n IRewardProgram,\\n BlackholePrevention,\\n IERC165,\\n ReentrancyGuard,\\n IERC721Receiver,\\n IERC1155Receiver\\n{\\n using SafeMath for uint256;\\n using TokenInfo for address;\\n using SafeERC20 for IERC20;\\n using EnumerableSet for EnumerableSet.UintSet;\\n\\n uint256 constant private PERCENTAGE_SCALE = 1e4; // 10000 (100%)\\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\\n\\n address private _owner;\\n IUniverseRP private _universe;\\n IChargedManagers private _chargedManagers;\\n ProgramRewardData private _programData;\\n mapping(uint256 => AssetStake) private _assetStake;\\n\\n\\n /***********************************|\\n | Initialization |\\n |__________________________________*/\\n\\n constructor() public {}\\n\\n function initialize(\\n address stakingToken,\\n address rewardToken,\\n uint256 baseMultiplier,\\n address chargedManagers,\\n address universe,\\n address owner\\n ) external override {\\n require(_owner == address(0x0), \\\"Already initialized\\\");\\n _owner = owner;\\n\\n // Prepare Reward Program\\n _programData.stakingToken = stakingToken;\\n _programData.rewardToken = rewardToken;\\n _programData.baseMultiplier = baseMultiplier; // Basis Points\\n\\n // Connect to Charged Particles\\n _chargedManagers = IChargedManagers(chargedManagers);\\n _universe = IUniverseRP(universe);\\n }\\n\\n\\n /***********************************|\\n | Public Functions |\\n |__________________________________*/\\n\\n function getProgramData() external view override returns (ProgramRewardData memory) {\\n return _programData;\\n }\\n\\n function getAssetStake(uint256 parentNftUuid) external view override returns (AssetStake memory) {\\n return _assetStake[parentNftUuid];\\n }\\n\\n function getFundBalance() external view override returns (uint256) {\\n return _getFundBalance();\\n }\\n\\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) public view override returns (uint256) {\\n return _calculateRewardsEarned(parentNftUuid, interestAmount);\\n }\\n\\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view override returns (uint256) {\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n return _assetStake[parentNftUuid].claimableRewards;\\n }\\n\\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\\n return IERC721Receiver.onERC721Received.selector;\\n }\\n\\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\\n return IERC1155Receiver.onERC1155BatchReceived.selector;\\n }\\n\\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\\n return \\\"\\\";\\n }\\n\\n function supportsInterface(bytes4 interfaceId)\\n public\\n view\\n virtual\\n override(IERC165)\\n returns (bool)\\n {\\n // default interface support\\n if (\\n interfaceId == type(IERC721Receiver).interfaceId ||\\n interfaceId == type(IERC1155Receiver).interfaceId ||\\n interfaceId == type(IERC165).interfaceId\\n ) {\\n return true;\\n }\\n }\\n\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n\\n /***********************************|\\n | Only Universe |\\n |__________________________________*/\\n\\n function registerAssetDeposit(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n uint256 principalAmount\\n )\\n external\\n override\\n onlyUniverse\\n {\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n AssetStake storage assetStake = _assetStake[parentNftUuid];\\n\\n if (assetStake.start == 0) {\\n assetStake.start = block.number;\\n assetStake.walletManagerId = walletManagerId;\\n }\\n emit AssetDeposit(contractAddress, tokenId, walletManagerId, principalAmount);\\n }\\n\\n function registerAssetRelease(\\n address contractAddress,\\n uint256 tokenId,\\n uint256 interestAmount\\n )\\n external\\n override\\n onlyUniverse\\n nonReentrant\\n returns (uint256 rewards)\\n {\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n AssetStake storage assetStake = _assetStake[parentNftUuid];\\n\\n // Update Claimable Rewards\\n uint256 newRewards = _calculateRewardsEarned(parentNftUuid, interestAmount);\\n assetStake.claimableRewards = assetStake.claimableRewards.add(newRewards);\\n\\n // Reset Stake if Principal Balance falls to Zero\\n IWalletManager walletMgr = _chargedManagers.getWalletManager(assetStake.walletManagerId);\\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\\n if (principal == 0) {\\n assetStake.start = 0;\\n }\\n\\n // Issue Rewards to NFT Owner\\n rewards = _claimRewards(contractAddress, tokenId);\\n\\n emit AssetRelease(contractAddress, tokenId, interestAmount);\\n }\\n\\n\\n /***********************************|\\n | Reward Calculation |\\n |__________________________________*/\\n\\n function _calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) internal view returns (uint256 totalReward) {\\n uint256 baseReward = _calculateBaseReward(interestAmount);\\n uint256 leptonMultipliedReward = _calculateMultipliedReward(parentNftUuid, baseReward);\\n totalReward = _convertDecimals(leptonMultipliedReward);\\n }\\n\\n function _calculateBaseReward(uint256 amount) internal view returns(uint256 baseReward) {\\n baseReward = amount.mul(_programData.baseMultiplier).div(PERCENTAGE_SCALE);\\n }\\n\\n function _calculateMultipliedReward(uint256 parentNftUuid, uint256 baseReward) internal view returns(uint256) {\\n AssetStake storage assetStake = _assetStake[parentNftUuid];\\n if (assetStake.start == 0) { return baseReward; }\\n\\n IUniverseRP.NftStake memory nftStake = _universe.getNftStake(parentNftUuid);\\n uint256 multiplierBP = nftStake.multiplier;\\n\\n uint256 assetDepositLength = block.number.sub(assetStake.start);\\n uint256 nftDepositLength = 0;\\n if (nftStake.releaseBlockNumber > 0) {\\n nftDepositLength = nftStake.releaseBlockNumber.sub(nftStake.depositBlockNumber);\\n } else {\\n nftDepositLength = block.number.sub(nftStake.depositBlockNumber);\\n }\\n\\n if (multiplierBP == 0 || nftDepositLength == 0 || assetDepositLength == 0) {\\n return baseReward;\\n }\\n\\n if (nftDepositLength > assetDepositLength) {\\n nftDepositLength = assetDepositLength;\\n }\\n\\n // Percentage of the total program that the Multiplier Nft was deposited for\\n uint256 nftRewardRatioBP = nftDepositLength.mul(PERCENTAGE_SCALE).div(assetDepositLength);\\n\\n // Amount of reward that the Multiplier Nft is responsible for\\n uint256 amountGeneratedDuringNftDeposit = baseReward.mul(nftRewardRatioBP).div(PERCENTAGE_SCALE);\\n\\n // Amount of Multiplied Reward from NFT\\n uint256 multipliedReward = amountGeneratedDuringNftDeposit.mul(multiplierBP.mul(LEPTON_MULTIPLIER_SCALE)).div(PERCENTAGE_SCALE);\\n\\n // Amount of Base Reward without Multiplied NFT Rewards\\n uint256 amountGeneratedWithoutNftDeposit = baseReward.sub(amountGeneratedDuringNftDeposit);\\n\\n // Amount of Base Rewards + Multiplied NFT Rewards\\n return amountGeneratedWithoutNftDeposit.add(multipliedReward);\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n |__________________________________*/\\n\\n function fundProgram(uint256 amount) external onlyOwner {\\n require(_programData.rewardToken != address(0), \\\"RP:E-405\\\");\\n IERC20(_programData.rewardToken).safeTransferFrom(msg.sender, address(this), amount);\\n emit RewardProgramFunded(amount);\\n }\\n\\n function setStakingToken(address newStakingToken) external onlyOwner {\\n _programData.stakingToken = newStakingToken;\\n }\\n\\n function setRewardToken(address newRewardToken) external onlyOwner {\\n _programData.rewardToken = newRewardToken;\\n }\\n\\n function setBaseMultiplier(uint256 newMultiplier) external onlyOwner {\\n _programData.baseMultiplier = newMultiplier; // Basis Points\\n }\\n\\n function setChargedManagers(address manager) external onlyOwner {\\n _chargedManagers = IChargedManagers(manager);\\n }\\n\\n function setUniverse(address universe) external onlyOwner {\\n _universe = IUniverseRP(universe);\\n }\\n\\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external override onlyOwner {\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n\\n // Initiate Asset Stake\\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\\n if (principal > 0) {\\n _assetStake[parentNftUuid] = AssetStake(block.number, 0, walletManagerId);\\n emit AssetRegistered(contractAddress, tokenId, walletManagerId, principal);\\n }\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n | (blackhole prevention) |\\n |__________________________________*/\\n\\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n\\n\\n /***********************************|\\n | Private Functions |\\n |__________________________________*/\\n\\n function _claimRewards(\\n address contractAddress,\\n uint256 tokenId\\n )\\n internal\\n returns (uint256 totalReward)\\n {\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n AssetStake storage assetStake = _assetStake[parentNftUuid];\\n\\n // Rewards Receiver\\n address receiver = IERC721(contractAddress).ownerOf(tokenId);\\n\\n // Ensure Reward Pool has Sufficient Balance\\n totalReward = assetStake.claimableRewards;\\n uint256 fundBalance = _getFundBalance();\\n uint256 unavailReward = totalReward > fundBalance ? totalReward.sub(fundBalance) : 0;\\n\\n // Determine amount of Rewards to Transfer\\n if (unavailReward > 0) {\\n totalReward = totalReward.sub(unavailReward);\\n emit RewardProgramOutOfFunds();\\n }\\n\\n // Update Asset Stake\\n assetStake.claimableRewards = unavailReward;\\n\\n if (totalReward > 0) {\\n // Transfer Available Rewards to Receiver\\n IERC20(_programData.rewardToken).safeTransfer(receiver, totalReward);\\n }\\n\\n emit RewardsClaimed(contractAddress, tokenId, receiver, totalReward, unavailReward);\\n }\\n\\n function _convertDecimals(uint256 reward) internal view returns (uint256) {\\n uint8 stakingTokenDecimals = IERC20Detailed(_programData.stakingToken).decimals();\\n return reward.mul(10**(18 - uint256(stakingTokenDecimals)));\\n }\\n\\n function _getFundBalance() internal view returns (uint256) {\\n return IERC20Detailed(_programData.rewardToken).balanceOf(address(this));\\n }\\n\\n\\n modifier onlyOwner() {\\n require(_owner == msg.sender, \\\"Caller is not the owner\\\");\\n _;\\n }\\n\\n modifier onlyUniverse() {\\n require(msg.sender == address(_universe), \\\"RP:E-108\\\");\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x2c6b66490dda8cea12387706aa49742f7d8c90ff3b699abd3c84dae227277e3f\",\"license\":\"MIT\"},\"contracts/v1/incentives/RewardProgramFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// RewardProgramFactory.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\nimport \\\"./RewardProgram.sol\\\";\\nimport \\\"../lib/BlackholePrevention.sol\\\";\\n\\ncontract RewardProgramFactory is BlackholePrevention, Ownable {\\n event RewardProgramCreated(address indexed rewardProgram);\\n\\n address public _template;\\n\\n constructor () public {\\n _template = address(new RewardProgram());\\n }\\n\\n // function _msgSender() internal view override returns (address payable) {\\n // return msg.sender;\\n // }\\n\\n function createRewardProgram(\\n address stakingToken,\\n address rewardToken,\\n uint256 baseMultiplier,\\n address chargedManagers,\\n address universe\\n )\\n external\\n onlyOwner\\n returns (address)\\n {\\n address newRewardProgram = _createClone(_template);\\n RewardProgram rewardProgram = RewardProgram(newRewardProgram);\\n rewardProgram.initialize(stakingToken, rewardToken, baseMultiplier, chargedManagers, universe, _msgSender());\\n emit RewardProgramCreated(newRewardProgram);\\n return newRewardProgram;\\n }\\n\\n /**\\n * @dev Creates Contracts from a Template via Cloning\\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\\n */\\n function _createClone(address target) internal returns (address result) {\\n bytes20 targetBytes = bytes20(target);\\n assembly {\\n let clone := mload(0x40)\\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\\n mstore(add(clone, 0x14), targetBytes)\\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\\n result := create(0, clone, 0x37)\\n }\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n | (blackhole prevention) |\\n |__________________________________*/\\n\\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n}\\n\",\"keccak256\":\"0x5a3692f0c9dee582d05013bc2f808cca4e7257756ed8125d81586d674c166559\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IBasketManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IBasketManager.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Particle Basket Manager interface\\n * @dev The basket-manager for underlying assets attached to Charged Particles\\n * @dev Manages the link between NFTs and their respective Smart-Baskets\\n */\\ninterface IBasketManager {\\n\\n event ControllerSet(address indexed controller);\\n event ExecutorSet(address indexed executor);\\n event PausedStateSet(bool isPaused);\\n event NewSmartBasket(address indexed contractAddress, uint256 indexed tokenId, address indexed smartBasket);\\n event BasketAdd(address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\\n event BasketRemove(address indexed receiver, address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\\n event BasketRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\\n event RewardProgramSet(address indexed rewardProgram);\\n\\n function isPaused() external view returns (bool);\\n\\n function getTokenTotalCount(address contractAddress, uint256 tokenId) external view returns (uint256);\\n function getTokenCountByType(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (uint256);\\n\\n function prepareTransferAmount(uint256 nftTokenAmount) external;\\n function addToBasket(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\\n function getBasketAddressById(address contractAddress, uint256 tokenId) external returns (address);\\n\\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount) external;\\n}\\n\",\"keccak256\":\"0x20367a08a95c30ed283f46877bef9c5f1ccd0f07409fe632f4f82a5d33b6a0c3\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IChargedManagers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"./IWalletManager.sol\\\";\\nimport \\\"./IBasketManager.sol\\\";\\n\\n/**\\n * @notice Interface for Charged Wallet-Managers\\n */\\ninterface IChargedManagers {\\n\\n /***********************************|\\n | Public API |\\n |__________________________________*/\\n\\n function isContractOwner(address contractAddress, address account) external view returns (bool);\\n\\n // ERC20\\n function isWalletManagerEnabled(string calldata walletManagerId) external view returns (bool);\\n function getWalletManager(string calldata walletManagerId) external view returns (IWalletManager);\\n\\n // ERC721\\n function isNftBasketEnabled(string calldata basketId) external view returns (bool);\\n function getBasketManager(string calldata basketId) external view returns (IBasketManager);\\n\\n // Validation\\n function validateDeposit(\\n address sender,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external;\\n function validateNftDeposit(\\n address sender,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external;\\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external;\\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external;\\n\\n /***********************************|\\n | Particle Events |\\n |__________________________________*/\\n\\n event Initialized(address indexed initiator);\\n event ControllerSet(address indexed controllerAddress, string controllerId);\\n event WalletManagerRegistered(string indexed walletManagerId, address indexed walletManager);\\n event BasketManagerRegistered(string indexed basketId, address indexed basketManager);\\n}\\n\",\"keccak256\":\"0x98103c0832064c1e446dcfebfdeeec1a9189675e9cf630f568c65c16c94d5478\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IERC20Detailed.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Detailed {\\n function decimals() external view returns (uint8);\\n function symbol() external view returns (string memory);\\n function name() external view returns (string memory);\\n\\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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0x96b8e4b6723a052ec16a1a729854532c953fb2eb758a0e01f75a3eafe242ccd8\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IERC721Chargeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IERC721Chargeable.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\\\";\\n\\ninterface IERC721Chargeable is IERC165Upgradeable {\\n function owner() external view returns (address);\\n function creatorOf(uint256 tokenId) external view returns (address);\\n function balanceOf(address tokenOwner) external view returns (uint256 balance);\\n function ownerOf(uint256 tokenId) external view returns (address tokenOwner);\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n function transferFrom(address from, address to, uint256 tokenId) external;\\n function approve(address to, uint256 tokenId) external;\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n function setApprovalForAll(address operator, bool _approved) external;\\n function isApprovedForAll(address tokenOwner, address operator) external view returns (bool);\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x459e57b2d35c7cd78e6c3d47eb9f3e981529a18c89e2c318b10fe369c479c737\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IRewardProgram.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IRewardProgram.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\npragma experimental ABIEncoderV2;\\n\\ninterface IRewardProgram {\\n /* admin events */\\n event RewardProgramFunded(uint256 amount);\\n event RewardProgramOutOfFunds();\\n\\n /* user events */\\n event RewardsClaimed(address indexed contractAddress, uint256 tokenId, address indexed receiver, uint256 rewarded, uint256 remaining);\\n\\n event AssetRegistered(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\\n event AssetDeposit(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\\n event AssetRelease(address indexed contractAddress, uint256 tokenId, uint256 interestAmount);\\n\\n /* data types */\\n struct ProgramRewardData {\\n address stakingToken;\\n address rewardToken;\\n uint256 baseMultiplier; // Basis Points\\n }\\n\\n struct AssetStake {\\n uint256 start;\\n uint256 claimableRewards;\\n string walletManagerId;\\n }\\n\\n function initialize(address stakingToken, address rewardToken, uint256 baseMultiplier, address chargedManagers, address universe, address owner) external;\\n\\n /* user functions */\\n function getProgramData() external view returns (ProgramRewardData memory programData);\\n function getAssetStake(uint256 uuid) external view returns (AssetStake memory);\\n function getFundBalance() external view returns (uint256);\\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) external view returns (uint256);\\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view returns (uint256);\\n\\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external;\\n function registerAssetDeposit(address contractAddress, uint256 tokenId, string calldata walletManagerId, uint256 principalAmount) external;\\n function registerAssetRelease(address contractAddress, uint256 tokenId, uint256 interestAmount) external returns (uint256 rewards);\\n}\",\"keccak256\":\"0xe0f4076a4b001856c54cb8a63decedc81ca34c71708f8cbe9b3a26603dc9c050\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IUniverse.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IUniverse.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Universal Controller interface\\n * @dev ...\\n */\\ninterface IUniverse {\\n\\n event ChargedParticlesSet(address indexed chargedParticles);\\n event PhotonSet(address indexed photonToken, uint256 maxSupply);\\n event ProtonTokenSet(address indexed protonToken);\\n event LeptonTokenSet(address indexed leptonToken);\\n event QuarkTokenSet(address indexed quarkToken);\\n event BosonTokenSet(address indexed bosonToken);\\n event EsaMultiplierSet(address indexed assetToken, uint256 multiplier);\\n event ElectrostaticAttraction(address indexed account, address photonSource, uint256 energy, uint256 multiplier);\\n event ElectrostaticDischarge(address indexed account, address photonSource, uint256 energy);\\n\\n function onEnergize(\\n address sender,\\n address referrer,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 assetEnergy\\n ) external;\\n\\n function onDischarge(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onDischargeForCreator(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address creator,\\n address assetToken,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onRelease(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 principalEnergy,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onCovalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n\\n function onCovalentBreak(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n\\n function onProtonSale(\\n address contractAddress,\\n uint256 tokenId,\\n address oldOwner,\\n address newOwner,\\n uint256 salePrice,\\n address creator,\\n uint256 creatorRoyalties\\n ) external;\\n}\\n\",\"keccak256\":\"0x6cebb97ce4d32c61afc746e4a6538eb605bb01276dfa66fa4bd6f63362bdc9ef\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IUniverseRP.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IUniverseRP.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"./IUniverse.sol\\\";\\n\\n/**\\n * @title Universal Controller interface for Rewards Program\\n * @dev ...\\n */\\ninterface IUniverseRP is IUniverse {\\n event RewardProgramSet(address indexed assetToken, address indexed rewardProgram);\\n event RewardProgramRemoved(address indexed assetToken);\\n event NftDeposit(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\\n event NftRelease(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\\n\\n struct NftStake {\\n uint256 multiplier; // in Basis Points\\n uint256 depositBlockNumber;\\n uint256 releaseBlockNumber;\\n }\\n\\n function getRewardProgram(address asset) external view returns (address);\\n function getNftStake(uint256 uuid) external view returns (NftStake memory);\\n}\\n\",\"keccak256\":\"0xd9c5a996bbb7f2a27bb85dde52587f7368c7b6512fc1064821a3975acdf4b7db\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IWalletManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IWalletManager.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Particle Wallet Manager interface\\n * @dev The wallet-manager for underlying assets attached to Charged Particles\\n * @dev Manages the link between NFTs and their respective Smart-Wallets\\n */\\ninterface IWalletManager {\\n\\n event ControllerSet(address indexed controller);\\n event ExecutorSet(address indexed executor);\\n event PausedStateSet(bool isPaused);\\n event NewSmartWallet(address indexed contractAddress, uint256 indexed tokenId, address indexed smartWallet, address creator, uint256 annuityPct);\\n event WalletEnergized(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 assetAmount, uint256 yieldTokensAmount);\\n event WalletDischarged(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 creatorAmount, uint256 receiverAmount);\\n event WalletDischargedForCreator(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, address creator, uint256 receiverAmount);\\n event WalletReleased(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address assetToken, uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\\n event WalletRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\\n\\n function isPaused() external view returns (bool);\\n\\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view returns (bool);\\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view returns (address);\\n\\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\\n function getInterest(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken) external returns (uint256);\\n\\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount) external returns (uint256 yieldTokensAmount);\\n function discharge(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n function dischargeAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n function dischargeAmountForCreator(address receiver, address contractAddress, uint256 tokenId, address creator, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\\n function release(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\\n function releaseAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken) external;\\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct) external returns (address);\\n\\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\\n}\\n\",\"keccak256\":\"0xb03ee0e216d7444e72af388814d219ad9aa87006ec96d660b45dcad0875ef0d7\",\"license\":\"MIT\"},\"contracts/v1/lib/BlackholePrevention.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\\\";\\n\\n/**\\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\\n * the Owner/DAO to pull them out on behalf of a user\\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\\n */\\ncontract BlackholePrevention {\\n using Address for address payable;\\n using SafeERC20 for IERC20;\\n\\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\\n\\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (address(this).balance >= amount) {\\n receiver.sendValue(amount);\\n emit WithdrawStuckEther(receiver, amount);\\n }\\n }\\n\\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\\n IERC20(tokenAddress).safeTransfer(receiver, amount);\\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\\n }\\n }\\n\\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\\n }\\n }\\n\\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \\\"\\\");\\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6a664c8a1c1d7fb32ade2c11f75756b1fdb4c489daa32c1d58e6b867ea2ba8d6\",\"license\":\"MIT\"},\"contracts/v1/lib/ReentrancyGuard.sol\":{\"content\":\"pragma solidity 0.6.12;\\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 () public {\\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 _nonReentrantBefore();\\n _;\\n _nonReentrantAfter();\\n }\\n\\n function _nonReentrantBefore() private {\\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n }\\n\\n function _nonReentrantAfter() private {\\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 /**\\n * @dev Returns true if the reentrancy guard is currently set to \\\"entered\\\", which indicates there is a\\n * `nonReentrant` function in the call stack.\\n */\\n function _reentrancyGuardEntered() internal view returns (bool) {\\n return _status == _ENTERED;\\n }\\n}\",\"keccak256\":\"0x4897c6fee5e1601d203efa54d29b2cef20825cab134b8e63b0b13ee9603642ad\"},\"contracts/v1/lib/TokenInfo.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// TokenInfo.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport \\\"../interfaces/IERC721Chargeable.sol\\\";\\n\\nlibrary TokenInfo {\\n function getTokenUUID(address contractAddress, uint256 tokenId) internal pure virtual returns (uint256) {\\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n function getTokenOwner(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n return tokenInterface.ownerOf(tokenId);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n function getTokenCreator(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n return tokenInterface.creatorOf(tokenId);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Owner of an External NFT contract\\n /// @param contractAddress The Address to the Contract of the NFT to check\\n /// @param account The Address of the Account to check\\n /// @return True if the account owns the contract\\n function isContractOwner(address contractAddress, address account) internal view virtual returns (bool) {\\n address contractOwner = IERC721Chargeable(contractAddress).owner();\\n return contractOwner != address(0x0) && contractOwner == account;\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Creator of a Proton-based NFT\\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\\n /// @param tokenId The Token ID of the Proton-based NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the creator of the Proton-based NFT\\n function isTokenCreator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenCreator = tokenInterface.creatorOf(tokenId);\\n return (sender == tokenCreator);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\\n /// @param tokenId The Token ID of the Proton-based NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the creator of the Proton-based NFT or the Contract itself\\n function isTokenContractOrCreator(address contractAddress, uint256 tokenId, address creator, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenCreator = tokenInterface.creatorOf(tokenId);\\n if (sender == contractAddress && creator == tokenCreator) { return true; }\\n return (sender == tokenCreator);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Owner or Operator of an External NFT\\n /// @param contractAddress The Address to the Contract of the External NFT to check\\n /// @param tokenId The Token ID of the External NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the Owner or Operator of the External NFT\\n function isErc721OwnerOrOperator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenOwner = tokenInterface.ownerOf(tokenId);\\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\\n }\\n\\n /**\\n * @dev Returns true if `account` is a contract.\\n * @dev Taken from OpenZeppelin library\\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { codehash := extcodehash(account) }\\n return (codehash != accountHash && codehash != 0x0);\\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 * @dev Taken from OpenZeppelin library\\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, uint256 gasLimit) internal {\\n require(address(this).balance >= amount, \\\"TokenInfo: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = (gasLimit > 0)\\n ? recipient.call{ value: amount, gas: gasLimit }(\\\"\\\")\\n : recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"TokenInfo: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0xbc78c6173db068d95084288246642402d0f4af399e1eb754182cae2d9173af5e\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50600061001b6100b3565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350604051610071906100b7565b604051809103906000f08015801561008d573d6000803e3d6000fd5b50600180546001600160a01b0319166001600160a01b03929092169190911790556100c4565b3390565b6127bd8061115483390190565b611081806100d36000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c80636fe6fabb116100665780636fe6fabb146100fc578063715018a6146101045780638da5cb5b1461010c578063a0edb48b14610114578063f2fde38b1461012757610093565b80631593dee1146100985780634025feb2146100ad578063522f6815146100c05780636f9d5f78146100d3575b600080fd5b6100ab6100a6366004610be7565b61013a565b005b6100ab6100bb366004610be7565b610188565b6100ab6100ce366004610c6c565b6101c8565b6100e66100e1366004610c97565b61020b565b6040516100f39190610d55565b60405180910390f35b6100e661030b565b6100ab61031a565b6100e6610399565b6100ab610122366004610c27565b6103a8565b6100ab610135366004610ba8565b6103ef565b6101426104a5565b6000546001600160a01b039081169116146101785760405162461bcd60e51b815260040161016f90610f48565b60405180910390fd5b6101838383836104a9565b505050565b6101906104a5565b6000546001600160a01b039081169116146101bd5760405162461bcd60e51b815260040161016f90610f48565b6101838383836105b6565b6101d06104a5565b6000546001600160a01b039081169116146101fd5760405162461bcd60e51b815260040161016f90610f48565b6102078282610711565b5050565b60006102156104a5565b6000546001600160a01b039081169116146102425760405162461bcd60e51b815260040161016f90610f48565b60015460009061025a906001600160a01b0316610795565b9050806001600160a01b03811663ff9935cb89898989896102796104a5565b6040518763ffffffff1660e01b815260040161029a96959493929190610dc5565b600060405180830381600087803b1580156102b457600080fd5b505af11580156102c8573d6000803e3d6000fd5b50506040516001600160a01b03851692507f6ecb2838bef4560681475e8bb5e7feccefe33df915df2d6757024bc6fe4c616a9150600090a2509695505050505050565b6001546001600160a01b031681565b6103226104a5565b6000546001600160a01b0390811691161461034f5760405162461bcd60e51b815260040161016f90610f48565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b6103b06104a5565b6000546001600160a01b039081169116146103dd5760405162461bcd60e51b815260040161016f90610f48565b6103e9848484846107e7565b50505050565b6103f76104a5565b6000546001600160a01b039081169116146104245760405162461bcd60e51b815260040161016f90610f48565b6001600160a01b03811661044a5760405162461bcd60e51b815260040161016f90610e4b565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b0383166104cf5760405162461bcd60e51b815260040161016f90610e91565b6040516370a0823160e01b815281906001600160a01b038416906370a08231906104fd903090600401610d55565b60206040518083038186803b15801561051557600080fd5b505afa158015610529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061054d9190610d1e565b10610183576105666001600160a01b0383168483610946565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b836040516105a99190610ffe565b60405180910390a3505050565b6001600160a01b0383166105dc5760405162461bcd60e51b815260040161016f90610e91565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e9061060a908590600401610ffe565b60206040518083038186803b15801561062257600080fd5b505afa158015610636573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065a9190610bcb565b6001600160a01b03161415610183576040516323b872dd60e01b81526001600160a01b038316906323b872dd9061069990309087908690600401610d69565b600060405180830381600087803b1580156106b357600080fd5b505af11580156106c7573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b0382166107375760405162461bcd60e51b815260040161016f90610e91565b804710610207576107516001600160a01b0383168261099c565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd826040516107899190610ffe565b60405180910390a25050565b6000808260601b9050604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528160148201526e5af43d82803e903d91602b57fd5bf360881b60288201526037816000f0949350505050565b6001600160a01b03841661080d5760405162461bcd60e51b815260040161016f90610e91565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e9061083b9030908790600401610dff565b60206040518083038186803b15801561085357600080fd5b505afa158015610867573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088b9190610d1e565b106103e957604051637921219560e11b81526001600160a01b0384169063f242432a906108c2903090889087908790600401610d8d565b600060405180830381600087803b1580156108dc57600080fd5b505af11580156108f0573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b846040516109389190610ffe565b60405180910390a450505050565b6101838363a9059cbb60e01b8484604051602401610965929190610dff565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610a38565b804710156109bc5760405162461bcd60e51b815260040161016f90610f11565b6000826001600160a01b0316826040516109d590610d52565b60006040518083038185875af1925050503d8060008114610a12576040519150601f19603f3d011682016040523d82523d6000602084013e610a17565b606091505b50509050806101835760405162461bcd60e51b815260040161016f90610eb4565b6060610a8d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610ac79092919063ffffffff16565b8051909150156101835780806020019051810190610aab9190610cfe565b6101835760405162461bcd60e51b815260040161016f90610fb4565b6060610ad68484600085610ade565b949350505050565b6060610ae985610ba2565b610b055760405162461bcd60e51b815260040161016f90610f7d565b60006060866001600160a01b03168587604051610b229190610d36565b60006040518083038185875af1925050503d8060008114610b5f576040519150601f19603f3d011682016040523d82523d6000602084013e610b64565b606091505b50915091508115610b78579150610ad69050565b805115610b885780518082602001fd5b8360405162461bcd60e51b815260040161016f9190610e18565b3b151590565b600060208284031215610bb9578081fd5b8135610bc481611033565b9392505050565b600060208284031215610bdc578081fd5b8151610bc481611033565b600080600060608486031215610bfb578182fd5b8335610c0681611033565b92506020840135610c1681611033565b929592945050506040919091013590565b60008060008060808587031215610c3c578081fd5b8435610c4781611033565b93506020850135610c5781611033565b93969395505050506040820135916060013590565b60008060408385031215610c7e578182fd5b8235610c8981611033565b946020939093013593505050565b600080600080600060a08688031215610cae578081fd5b8535610cb981611033565b94506020860135610cc981611033565b9350604086013592506060860135610ce081611033565b91506080860135610cf081611033565b809150509295509295909350565b600060208284031215610d0f578081fd5b81518015158114610bc4578182fd5b600060208284031215610d2f578081fd5b5051919050565b60008251610d48818460208701611007565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b0396871681529486166020860152604085019390935290841660608401528316608083015290911660a082015260c00190565b6001600160a01b03929092168252602082015260400190565b6000602082528251806020840152610e37816040850160208701611007565b601f01601f19169190910160400192915050565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b90815260200190565b60005b8381101561102257818101518382015260200161100a565b838111156103e95750506000910152565b6001600160a01b038116811461104857600080fd5b5056fea2646970667358221220260383f23709db660967a522664682b39439430262c686f1ff999462e44f3aff64736f6c634300060c0033608060405234801561001057600080fd5b506001600055612798806100256000396000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c8063533f852e116100c3578063ae9704cd1161007c578063ae9704cd146102f6578063bc197c8114610309578063dae9e3791461031c578063e3043ee814610324578063f23a6e6114610337578063ff9935cb1461034a57610158565b8063533f852e1461027557806370d2e5cd14610288578063784483491461029b5780638aee8127146102bb5780638da5cb5b146102ce578063a0edb48b146102e357610158565b8063352685bc11610115578063352685bc146101f65780634025feb21461020957806346c65f621461021c578063494b01001461022f57806350d0c63c14610242578063522f68151461026257610158565b806301ffc9a71461015d57806314e5f66814610186578063150b7a021461019b5780631593dee1146101bb5780631e9b12ef146101d05780631f5b149f146101e3575b600080fd5b61017061016b3660046120c8565b61035d565b60405161017d91906122fc565b60405180910390f35b61018e6103b7565b60405161017d919061268b565b6101ae6101a9366004611ecd565b6103f0565b60405161017d9190612307565b6101ce6101c9366004611cea565b610401565b005b6101ce6101de366004611cb2565b610444565b6101ce6101f1366004611cb2565b610490565b6101ce610204366004612147565b6104dc565b6101ce610217366004611cea565b610580565b6101ce61022a366004612012565b6105b5565b6101ce61023d366004611fb8565b61066f565b610255610250366004612074565b61089f565b60405161017d91906126ba565b6101ce610270366004611d6f565b610a9a565b610255610283366004611d6f565b610ad2565b6101ce610296366004612147565b610b04565b6102ae6102a9366004612147565b610b33565b60405161017d919061265c565b6101ce6102c9366004611cb2565b610c16565b6102d6610c62565b60405161017d9190612250565b6101ce6102f1366004611d2a565b610c71565b6101ce610304366004611cb2565b610cad565b6101ae610317366004611d9a565b610cf9565b610255610d07565b610255610332366004612177565b610d16565b6101ae610345366004611f3e565b610d22565b6101ce610358366004611e55565b610d34565b60006001600160e01b03198216630a85bd0160e11b148061038e57506001600160e01b03198216630271189760e51b145b806103a957506001600160e01b031982166301ffc9a760e01b145b156103b2575060015b919050565b6103bf611ac6565b50604080516060810182526004546001600160a01b0390811682526005541660208201526006549181019190915290565b630a85bd0160e11b95945050505050565b6001546001600160a01b031633146104345760405162461bcd60e51b815260040161042b906123cd565b60405180910390fd5b61043f838383610dbf565b505050565b6001546001600160a01b0316331461046e5760405162461bcd60e51b815260040161042b906123cd565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633146104ba5760405162461bcd60e51b815260040161042b906123cd565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633146105065760405162461bcd60e51b815260040161042b906123cd565b6005546001600160a01b031661052e5760405162461bcd60e51b815260040161042b90612514565b600554610546906001600160a01b0316333084610ecc565b7fcbd64454da4b3587b11b8f8170d7656cbe58e29ee18fd715b0e79ad85edb6e5d8160405161057591906126ba565b60405180910390a150565b6001546001600160a01b031633146105aa5760405162461bcd60e51b815260040161042b906123cd565b61043f838383610f24565b6002546001600160a01b031633146105df5760405162461bcd60e51b815260040161042b906124f2565b60006105f46001600160a01b0387168661107f565b600081815260076020526040902080549192509061061f5743815561061d600282018686611ae6565b505b866001600160a01b03167f30d53e48465c48642e346a636a4eef45c72095b65bef5825308376e2f59f09e28787878760405161065e94939291906126c3565b60405180910390a250505050505050565b6001546001600160a01b031633146106995760405162461bcd60e51b815260040161042b906123cd565b60006106ae6001600160a01b0386168561107f565b6003546040516334b7328d60e01b81529192506000916001600160a01b03909116906334b7328d906106e6908790879060040161231c565b60206040518083038186803b1580156106fe57600080fd5b505afa158015610712573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107369190611cce565b60048054604051632da9ef8160e01b81529293506000926001600160a01b0380861693632da9ef8193610770938d938d93921691016122d9565b602060405180830381600087803b15801561078a57600080fd5b505af115801561079e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c2919061215f565b905080156108965760405180606001604052804381526020016000815260200186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093909452505085815260076020908152604091829020845181558482015160018201559184015180519293506108539260028501929190910190611b64565b50905050866001600160a01b03167fdd1b8616b3983aa94529955a2f7d0dd75e5a93e53875372ea41a9eab5e3ef3268787878560405161065e94939291906126c3565b50505050505050565b6002546000906001600160a01b031633146108cc5760405162461bcd60e51b815260040161042b906124f2565b6108d46110b3565b60006108e96001600160a01b0386168561107f565b600081815260076020526040812091925061090483866110dd565b6001830154909150610916908261110b565b60018301556003546040516334b7328d60e01b81526000916001600160a01b0316906334b7328d9061094f906002870190600401612343565b60206040518083038186803b15801561096757600080fd5b505afa15801561097b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099f9190611cce565b60048054604051632da9ef8160e01b81529293506000926001600160a01b0380861693632da9ef81936109d9938f938f93921691016122d9565b602060405180830381600087803b1580156109f357600080fd5b505af1158015610a07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2b919061215f565b905080610a3757600084555b610a418989611130565b9550886001600160a01b03167f8abeaea5da22bf1966530d4f970ac7c71ae0999eb1d2181afaeff8b56c394f3f8989604051610a7e9291906126ee565b60405180910390a25050505050610a936112c0565b9392505050565b6001546001600160a01b03163314610ac45760405162461bcd60e51b815260040161042b906123cd565b610ace82826112c7565b5050565b600080610ae86001600160a01b0385168461107f565b6000908152600760205260409020600101549150505b92915050565b6001546001600160a01b03163314610b2e5760405162461bcd60e51b815260040161042b906123cd565b600655565b610b3b611bd2565b600760008381526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610c065780601f10610bdb57610100808354040283529160200191610c06565b820191906000526020600020905b815481529060010190602001808311610be957829003601f168201915b5050505050815250509050919050565b6001546001600160a01b03163314610c405760405162461bcd60e51b815260040161042b906123cd565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031690565b6001546001600160a01b03163314610c9b5760405162461bcd60e51b815260040161042b906123cd565b610ca78484848461134b565b50505050565b6001546001600160a01b03163314610cd75760405162461bcd60e51b815260040161042b906123cd565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b600098975050505050505050565b6000610d116114aa565b905090565b6000610a9383836110dd565b63bc197c8160e01b9695505050505050565b6001546001600160a01b031615610d5d5760405162461bcd60e51b815260040161042b906125ae565b600180546001600160a01b03199081166001600160a01b03938416179091556004805482169783169790971790965560058054871695821695909517909455600692909255600380548516918416919091179055600280549093169116179055565b6001600160a01b038316610de55760405162461bcd60e51b815260040161042b90612404565b6040516370a0823160e01b815281906001600160a01b038416906370a0823190610e13903090600401612250565b60206040518083038186803b158015610e2b57600080fd5b505afa158015610e3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e63919061215f565b1061043f57610e7c6001600160a01b038316848361152b565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b83604051610ebf91906126ba565b60405180910390a3505050565b610ca7846323b872dd60e01b858585604051602401610eed93929190612264565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261154a565b6001600160a01b038316610f4a5760405162461bcd60e51b815260040161042b90612404565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e90610f789085906004016126ba565b60206040518083038186803b158015610f9057600080fd5b505afa158015610fa4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc89190611cce565b6001600160a01b0316141561043f576040516323b872dd60e01b81526001600160a01b038316906323b872dd9061100790309087908690600401612264565b600060405180830381600087803b15801561102157600080fd5b505af1158015611035573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6000828260405160200161109492919061220f565b60408051601f1981840301815291905280516020909101209392505050565b600260005414156110d65760405162461bcd60e51b815260040161042b90612625565b6002600055565b6000806110e9836115d9565b905060006110f785836115ff565b905061110281611797565b95945050505050565b600082820183811015610a935760405162461bcd60e51b815260040161042b90612427565b6000806111466001600160a01b0385168461107f565b60008181526007602052604080822090516331a9108f60e11b8152929350916001600160a01b03871690636352211e906111849088906004016126ba565b60206040518083038186803b15801561119c57600080fd5b505afa1580156111b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d49190611cce565b90508160010154935060006111e76114aa565b905060008186116111f9576000611203565b6112038683611828565b90508015611242576112158682611828565b6040519096507f9fc735fd421d3eb45362ea6d0d94945975bce33842b1bc94840719e66d937e4790600090a15b60018401819055851561126657600554611266906001600160a01b0316848861152b565b826001600160a01b0316886001600160a01b03167fb918e5bcd5ce5aadd59ae96fe4c568669afc7af190dbf16061540816cb407c738989856040516112ad939291906126fc565b60405180910390a3505050505092915050565b6001600055565b6001600160a01b0382166112ed5760405162461bcd60e51b815260040161042b90612404565b804710610ace576113076001600160a01b0383168261186a565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd8260405161133f91906126ba565b60405180910390a25050565b6001600160a01b0384166113715760405162461bcd60e51b815260040161042b90612404565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e9061139f90309087906004016122c0565b60206040518083038186803b1580156113b757600080fd5b505afa1580156113cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ef919061215f565b10610ca757604051637921219560e11b81526001600160a01b0384169063f242432a90611426903090889087908790600401612288565b600060405180830381600087803b15801561144057600080fd5b505af1158015611454573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b8460405161149c91906126ba565b60405180910390a450505050565b6005546040516370a0823160e01b81526000916001600160a01b0316906370a08231906114db903090600401612250565b60206040518083038186803b1580156114f357600080fd5b505afa158015611507573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d11919061215f565b61043f8363a9059cbb60e01b8484604051602401610eed9291906122c0565b606061159f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166119069092919063ffffffff16565b80519091501561043f57808060200190518101906115bd91906120a8565b61043f5760405162461bcd60e51b815260040161042b906125db565b6000610afe6127106115f96004600201548561191d90919063ffffffff16565b90611957565b6000828152600760205260408120805461161c5782915050610afe565b611624611bf3565b60025460405163836c478d60e01b81526001600160a01b039091169063836c478d906116549088906004016126ba565b60606040518083038186803b15801561166c57600080fd5b505afa158015611680573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a491906120f0565b80518354919250906000906116ba904390611828565b9050600080846040015111156116e457602084015160408501516116dd91611828565b90506116f7565b60208401516116f4904390611828565b90505b821580611702575080155b8061170b575081155b1561171d578695505050505050610afe565b818111156117285750805b600061173a836115f98461271061191d565b9050600061174e6127106115f98b8561191d565b9050600061176d6127106115f961176689606461191d565b859061191d565b9050600061177b8b84611828565b9050611787818361110b565b9c9b505050505050505050505050565b600480546040805163313ce56760e01b8152905160009384936001600160a01b03169263313ce5679281830192602092829003018186803b1580156117db57600080fd5b505afa1580156117ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118139190612198565b9050610a938360ff8316601203600a0a61191d565b6000610a9383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611999565b8047101561188a5760405162461bcd60e51b815260040161042b906124bb565b6000826001600160a01b0316826040516118a39061224d565b60006040518083038185875af1925050503d80600081146118e0576040519150601f19603f3d011682016040523d82523d6000602084013e6118e5565b606091505b505090508061043f5760405162461bcd60e51b815260040161042b9061245e565b606061191584846000856119c5565b949350505050565b60008261192c57506000610afe565b8282028284828161193957fe5b0414610a935760405162461bcd60e51b815260040161042b90612536565b6000610a9383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611a89565b600081848411156119bd5760405162461bcd60e51b815260040161042b9190612330565b505050900390565b60606119d085611ac0565b6119ec5760405162461bcd60e51b815260040161042b90612577565b60006060866001600160a01b03168587604051611a099190612231565b60006040518083038185875af1925050503d8060008114611a46576040519150601f19603f3d011682016040523d82523d6000602084013e611a4b565b606091505b50915091508115611a5f5791506119159050565b805115611a6f5780518082602001fd5b8360405162461bcd60e51b815260040161042b9190612330565b60008183611aaa5760405162461bcd60e51b815260040161042b9190612330565b506000838581611ab657fe5b0495945050505050565b3b151590565b604080516060810182526000808252602082018190529181019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611b275782800160ff19823516178555611b54565b82800160010185558215611b54579182015b82811115611b54578235825591602001919060010190611b39565b50611b60929150611c14565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611ba557805160ff1916838001178555611b54565b82800160010185558215611b54579182015b82811115611b54578251825591602001919060010190611bb7565b60405180606001604052806000815260200160008152602001606081525090565b60405180606001604052806000815260200160008152602001600081525090565b5b80821115611b605760008155600101611c15565b60008083601f840112611c3a578182fd5b50813567ffffffffffffffff811115611c51578182fd5b6020830191508360208083028501011115611c6b57600080fd5b9250929050565b60008083601f840112611c83578182fd5b50813567ffffffffffffffff811115611c9a578182fd5b602083019150836020828501011115611c6b57600080fd5b600060208284031215611cc3578081fd5b8135610a938161274a565b600060208284031215611cdf578081fd5b8151610a938161274a565b600080600060608486031215611cfe578182fd5b8335611d098161274a565b92506020840135611d198161274a565b929592945050506040919091013590565b60008060008060808587031215611d3f578081fd5b8435611d4a8161274a565b93506020850135611d5a8161274a565b93969395505050506040820135916060013590565b60008060408385031215611d81578182fd5b8235611d8c8161274a565b946020939093013593505050565b60008060008060008060008060a0898b031215611db5578384fd5b8835611dc08161274a565b97506020890135611dd08161274a565b9650604089013567ffffffffffffffff80821115611dec578586fd5b611df88c838d01611c29565b909850965060608b0135915080821115611e10578586fd5b611e1c8c838d01611c29565b909650945060808b0135915080821115611e34578384fd5b50611e418b828c01611c72565b999c989b5096995094979396929594505050565b60008060008060008060c08789031215611e6d578182fd5b8635611e788161274a565b95506020870135611e888161274a565b9450604087013593506060870135611e9f8161274a565b92506080870135611eaf8161274a565b915060a0870135611ebf8161274a565b809150509295509295509295565b600080600080600060808688031215611ee4578081fd5b8535611eef8161274a565b94506020860135611eff8161274a565b935060408601359250606086013567ffffffffffffffff811115611f21578182fd5b611f2d88828901611c72565b969995985093965092949392505050565b60008060008060008060a08789031215611f56578384fd5b8635611f618161274a565b95506020870135611f718161274a565b94506040870135935060608701359250608087013567ffffffffffffffff811115611f9a578283fd5b611fa689828a01611c72565b979a9699509497509295939492505050565b60008060008060608587031215611fcd578182fd5b8435611fd88161274a565b935060208501359250604085013567ffffffffffffffff811115611ffa578283fd5b61200687828801611c72565b95989497509550505050565b600080600080600060808688031215612029578283fd5b85356120348161274a565b945060208601359350604086013567ffffffffffffffff811115612056578384fd5b61206288828901611c72565b96999598509660600135949350505050565b600080600060608486031215612088578081fd5b83356120938161274a565b95602085013595506040909401359392505050565b6000602082840312156120b9578081fd5b81518015158114610a93578182fd5b6000602082840312156120d9578081fd5b81356001600160e01b031981168114610a93578182fd5b600060608284031215612101578081fd5b6040516060810181811067ffffffffffffffff82111715612120578283fd5b80604052508251815260208301516020820152604083015160408201528091505092915050565b600060208284031215612158578081fd5b5035919050565b600060208284031215612170578081fd5b5051919050565b60008060408385031215612189578182fd5b50508035926020909101359150565b6000602082840312156121a9578081fd5b815160ff81168114610a93578182fd5b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526121fb81602086016020860161271e565b601f01601f19169290920160200192915050565b60609290921b6bffffffffffffffffffffffff19168252601482015260340190565b6000825161224381846020870161271e565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b901515815260200190565b6001600160e01b031991909116815260200190565b6000602082526119156020830184866121b9565b600060208252610a9360208301846121e3565b6000602080830181845282855460018082166000811461236a5760018114612388576123c0565b60028304607f16855260ff19831660408901526060880193506123c0565b600283048086526123988a612712565b885b828110156123b65781548b82016040015290840190880161239a565b8a01604001955050505b5091979650505050505050565b60208082526017908201527f43616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252600890820152670a4a0748a5a6260760c31b604082015260600190565b60208082526008908201526752503a452d34303560c01b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b602080825260139082015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6000602082528251602083015260208301516040830152604083015160608084015261191560808401826121e3565b81516001600160a01b039081168252602080840151909116908201526040918201519181019190915260600190565b90815260200190565b6000858252606060208301526126dd6060830185876121b9565b905082604083015295945050505050565b918252602082015260400190565b9283526020830191909152604082015260600190565b60009081526020902090565b60005b83811015612739578181015183820152602001612721565b83811115610ca75750506000910152565b6001600160a01b038116811461275f57600080fd5b5056fea264697066735822122089923bf05c0e88235caef82d9eb9c338dbdb5c9a300cc0b182773089e351721e64736f6c634300060c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100935760003560e01c80636fe6fabb116100665780636fe6fabb146100fc578063715018a6146101045780638da5cb5b1461010c578063a0edb48b14610114578063f2fde38b1461012757610093565b80631593dee1146100985780634025feb2146100ad578063522f6815146100c05780636f9d5f78146100d3575b600080fd5b6100ab6100a6366004610be7565b61013a565b005b6100ab6100bb366004610be7565b610188565b6100ab6100ce366004610c6c565b6101c8565b6100e66100e1366004610c97565b61020b565b6040516100f39190610d55565b60405180910390f35b6100e661030b565b6100ab61031a565b6100e6610399565b6100ab610122366004610c27565b6103a8565b6100ab610135366004610ba8565b6103ef565b6101426104a5565b6000546001600160a01b039081169116146101785760405162461bcd60e51b815260040161016f90610f48565b60405180910390fd5b6101838383836104a9565b505050565b6101906104a5565b6000546001600160a01b039081169116146101bd5760405162461bcd60e51b815260040161016f90610f48565b6101838383836105b6565b6101d06104a5565b6000546001600160a01b039081169116146101fd5760405162461bcd60e51b815260040161016f90610f48565b6102078282610711565b5050565b60006102156104a5565b6000546001600160a01b039081169116146102425760405162461bcd60e51b815260040161016f90610f48565b60015460009061025a906001600160a01b0316610795565b9050806001600160a01b03811663ff9935cb89898989896102796104a5565b6040518763ffffffff1660e01b815260040161029a96959493929190610dc5565b600060405180830381600087803b1580156102b457600080fd5b505af11580156102c8573d6000803e3d6000fd5b50506040516001600160a01b03851692507f6ecb2838bef4560681475e8bb5e7feccefe33df915df2d6757024bc6fe4c616a9150600090a2509695505050505050565b6001546001600160a01b031681565b6103226104a5565b6000546001600160a01b0390811691161461034f5760405162461bcd60e51b815260040161016f90610f48565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b6103b06104a5565b6000546001600160a01b039081169116146103dd5760405162461bcd60e51b815260040161016f90610f48565b6103e9848484846107e7565b50505050565b6103f76104a5565b6000546001600160a01b039081169116146104245760405162461bcd60e51b815260040161016f90610f48565b6001600160a01b03811661044a5760405162461bcd60e51b815260040161016f90610e4b565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b0383166104cf5760405162461bcd60e51b815260040161016f90610e91565b6040516370a0823160e01b815281906001600160a01b038416906370a08231906104fd903090600401610d55565b60206040518083038186803b15801561051557600080fd5b505afa158015610529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061054d9190610d1e565b10610183576105666001600160a01b0383168483610946565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b836040516105a99190610ffe565b60405180910390a3505050565b6001600160a01b0383166105dc5760405162461bcd60e51b815260040161016f90610e91565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e9061060a908590600401610ffe565b60206040518083038186803b15801561062257600080fd5b505afa158015610636573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065a9190610bcb565b6001600160a01b03161415610183576040516323b872dd60e01b81526001600160a01b038316906323b872dd9061069990309087908690600401610d69565b600060405180830381600087803b1580156106b357600080fd5b505af11580156106c7573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b0382166107375760405162461bcd60e51b815260040161016f90610e91565b804710610207576107516001600160a01b0383168261099c565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd826040516107899190610ffe565b60405180910390a25050565b6000808260601b9050604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528160148201526e5af43d82803e903d91602b57fd5bf360881b60288201526037816000f0949350505050565b6001600160a01b03841661080d5760405162461bcd60e51b815260040161016f90610e91565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e9061083b9030908790600401610dff565b60206040518083038186803b15801561085357600080fd5b505afa158015610867573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088b9190610d1e565b106103e957604051637921219560e11b81526001600160a01b0384169063f242432a906108c2903090889087908790600401610d8d565b600060405180830381600087803b1580156108dc57600080fd5b505af11580156108f0573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b846040516109389190610ffe565b60405180910390a450505050565b6101838363a9059cbb60e01b8484604051602401610965929190610dff565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610a38565b804710156109bc5760405162461bcd60e51b815260040161016f90610f11565b6000826001600160a01b0316826040516109d590610d52565b60006040518083038185875af1925050503d8060008114610a12576040519150601f19603f3d011682016040523d82523d6000602084013e610a17565b606091505b50509050806101835760405162461bcd60e51b815260040161016f90610eb4565b6060610a8d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610ac79092919063ffffffff16565b8051909150156101835780806020019051810190610aab9190610cfe565b6101835760405162461bcd60e51b815260040161016f90610fb4565b6060610ad68484600085610ade565b949350505050565b6060610ae985610ba2565b610b055760405162461bcd60e51b815260040161016f90610f7d565b60006060866001600160a01b03168587604051610b229190610d36565b60006040518083038185875af1925050503d8060008114610b5f576040519150601f19603f3d011682016040523d82523d6000602084013e610b64565b606091505b50915091508115610b78579150610ad69050565b805115610b885780518082602001fd5b8360405162461bcd60e51b815260040161016f9190610e18565b3b151590565b600060208284031215610bb9578081fd5b8135610bc481611033565b9392505050565b600060208284031215610bdc578081fd5b8151610bc481611033565b600080600060608486031215610bfb578182fd5b8335610c0681611033565b92506020840135610c1681611033565b929592945050506040919091013590565b60008060008060808587031215610c3c578081fd5b8435610c4781611033565b93506020850135610c5781611033565b93969395505050506040820135916060013590565b60008060408385031215610c7e578182fd5b8235610c8981611033565b946020939093013593505050565b600080600080600060a08688031215610cae578081fd5b8535610cb981611033565b94506020860135610cc981611033565b9350604086013592506060860135610ce081611033565b91506080860135610cf081611033565b809150509295509295909350565b600060208284031215610d0f578081fd5b81518015158114610bc4578182fd5b600060208284031215610d2f578081fd5b5051919050565b60008251610d48818460208701611007565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b0396871681529486166020860152604085019390935290841660608401528316608083015290911660a082015260c00190565b6001600160a01b03929092168252602082015260400190565b6000602082528251806020840152610e37816040850160208701611007565b601f01601f19169190910160400192915050565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b90815260200190565b60005b8381101561102257818101518382015260200161100a565b838111156103e95750506000910152565b6001600160a01b038116811461104857600080fd5b5056fea2646970667358221220260383f23709db660967a522664682b39439430262c686f1ff999462e44f3aff64736f6c634300060c0033", + "devdoc": { + "kind": "dev", + "methods": { + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 4406, + "contract": "contracts/v1/incentives/RewardProgramFactory.sol:RewardProgramFactory", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 19460, + "contract": "contracts/v1/incentives/RewardProgramFactory.sol:RewardProgramFactory", + "label": "_template", + "offset": 0, + "slot": "1", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + } + } + } +} \ No newline at end of file diff --git a/deployments/mumbai/RewardProgramUSDC.json b/deployments/mumbai/RewardProgramUSDC.json new file mode 100644 index 0000000..9f82955 --- /dev/null +++ b/deployments/mumbai/RewardProgramUSDC.json @@ -0,0 +1,814 @@ +{ + "address": "0x458B6d09cb188E1ed6DbC8A34149E503FCb697D6", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "AssetDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "AssetRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "AssetRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardProgramFunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "RewardProgramOutOfFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewarded", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remaining", + "type": "uint256" + } + ], + "name": "RewardsClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "parentNftUuid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "calculateRewardsEarned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "fundProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "parentNftUuid", + "type": "uint256" + } + ], + "name": "getAssetStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimableRewards", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + } + ], + "internalType": "struct IRewardProgram.AssetStake", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getClaimableRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFundBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProgramData", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + } + ], + "internalType": "struct IRewardProgram.ProgramRewardData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + }, + { + "internalType": "address", + "name": "chargedManagers", + "type": "address" + }, + { + "internalType": "address", + "name": "universe", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "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": "nonpayable", + "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": "nonpayable", + "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": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "registerAssetDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "registerAssetRelease", + "outputs": [ + { + "internalType": "uint256", + "name": "rewards", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + } + ], + "name": "registerExistingDeposits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newMultiplier", + "type": "uint256" + } + ], + "name": "setBaseMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "setChargedManagers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newRewardToken", + "type": "address" + } + ], + "name": "setRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newStakingToken", + "type": "address" + } + ], + "name": "setStakingToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "universe", + "type": "address" + } + ], + "name": "setUniverse", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x6d364ccb72bce22a6d0dbe851bc6cbd992fd646a65d8c1b63e16a9e9952376a9", + "numDeployments": 1 +} \ No newline at end of file diff --git a/deployments/mumbai/UniverseRP.json b/deployments/mumbai/UniverseRP.json new file mode 100644 index 0000000..b20227e --- /dev/null +++ b/deployments/mumbai/UniverseRP.json @@ -0,0 +1,1192 @@ +{ + "address": "0x4402daCEb7889dB63158701A07f9562F1e0642Fa", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bosonToken", + "type": "address" + } + ], + "name": "BosonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "chargedParticles", + "type": "address" + } + ], + "name": "ChargedParticlesSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "photonSource", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "energy", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "ElectrostaticAttraction", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "photonSource", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "energy", + "type": "uint256" + } + ], + "name": "ElectrostaticDischarge", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "EsaMultiplierSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "leptonToken", + "type": "address" + } + ], + "name": "LeptonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + } + ], + "name": "NftDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + } + ], + "name": "NftRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "photonToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxSupply", + "type": "uint256" + } + ], + "name": "PhotonSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "protonToken", + "type": "address" + } + ], + "name": "ProtonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "quarkToken", + "type": "address" + } + ], + "name": "QuarkTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "RewardProgramRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardProgram", + "type": "address" + } + ], + "name": "RewardProgramSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [], + "name": "_chargedParticles", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_multiplierNft", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "uuid", + "type": "uint256" + } + ], + "name": "getNftStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositBlockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "releaseBlockNumber", + "type": "uint256" + } + ], + "internalType": "struct IUniverseRP.NftStake", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getRewardProgram", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nftTokenAmount", + "type": "uint256" + } + ], + "name": "onCovalentBond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nftTokenAmount", + "type": "uint256" + } + ], + "name": "onCovalentBreak", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creatorEnergy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onDischarge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onDischargeForCreator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assetAmount", + "type": "uint256" + } + ], + "name": "onEnergize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "newOwner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "salePrice", + "type": "uint256" + }, + { + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creatorRoyalties", + "type": "uint256" + } + ], + "name": "onProtonSale", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "creatorEnergy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onRelease", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "removeRewardProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "controller", + "type": "address" + } + ], + "name": "setChargedParticles", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + } + ], + "name": "setMultiplierNft", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "rewardProgam", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "setRewardProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0xe6086d798d0793c92d2c761b265e513458a6469c7647b8e22dd67d8de994c342", + "receipt": { + "to": null, + "from": "0x6d46b37708dA7Ed4E5C4509495768Fecd3D17C01", + "contractAddress": "0x4402daCEb7889dB63158701A07f9562F1e0642Fa", + "transactionIndex": 2, + "gasUsed": "769434", + "logsBloom": "0x00000000000000000000000000000000400000000000000000800000000000000000000000000000000000000000000000008000000080000000000000000000000000000000000000000000000022800001000000000000000100000000000000000000020000000000000000080800000000800000000080000000000000400000000000000000000000000000000004000000040000000400200000801000200000000000000000000000000000000000000000000000000000000000004000000020000000000001000000000000000000000400000000100000000020240008000000000004000000000000000000000000000000000000000000100000", + "blockHash": "0xa0b30a763c50b92eaa26606630602be15ae850d798a15134518e02f0c04aaa6e", + "transactionHash": "0xe6086d798d0793c92d2c761b265e513458a6469c7647b8e22dd67d8de994c342", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 39278947, + "transactionHash": "0xe6086d798d0793c92d2c761b265e513458a6469c7647b8e22dd67d8de994c342", + "address": "0x4402daCEb7889dB63158701A07f9562F1e0642Fa", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000003759b63c5879d1c130fe6c368ee8c3f8068826a3" + ], + "data": "0x", + "logIndex": 9, + "blockHash": "0xa0b30a763c50b92eaa26606630602be15ae850d798a15134518e02f0c04aaa6e" + }, + { + "transactionIndex": 2, + "blockNumber": 39278947, + "transactionHash": "0xe6086d798d0793c92d2c761b265e513458a6469c7647b8e22dd67d8de994c342", + "address": "0x4402daCEb7889dB63158701A07f9562F1e0642Fa", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000006d46b37708da7ed4e5c4509495768fecd3d17c01" + ], + "data": "0x", + "logIndex": 10, + "blockHash": "0xa0b30a763c50b92eaa26606630602be15ae850d798a15134518e02f0c04aaa6e" + }, + { + "transactionIndex": 2, + "blockNumber": 39278947, + "transactionHash": "0xe6086d798d0793c92d2c761b265e513458a6469c7647b8e22dd67d8de994c342", + "address": "0x4402daCEb7889dB63158701A07f9562F1e0642Fa", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f23a65878cd6a71b87b7f72c4f2870090f711b0", + "logIndex": 11, + "blockHash": "0xa0b30a763c50b92eaa26606630602be15ae850d798a15134518e02f0c04aaa6e" + }, + { + "transactionIndex": 2, + "blockNumber": 39278947, + "transactionHash": "0xe6086d798d0793c92d2c761b265e513458a6469c7647b8e22dd67d8de994c342", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000006d46b37708da7ed4e5c4509495768fecd3d17c01", + "0x000000000000000000000000e7f13f6bc1e7f5ca4a6c9a255124ce22c46f8ef0" + ], + "data": "0x000000000000000000000000000000000000000000000000001b55f621a7d32c000000000000000000000000000000000000000000000000a4ba29961cf00e7700000000000000000000000000000000000000000000002f4889e7d0c96760d0000000000000000000000000000000000000000000000000a49ed39ffb483b4b00000000000000000000000000000000000000000000002f48a53dc6eb0f33fc", + "logIndex": 12, + "blockHash": "0xa0b30a763c50b92eaa26606630602be15ae850d798a15134518e02f0c04aaa6e" + } + ], + "blockNumber": 39278947, + "cumulativeGasUsed": "948859", + "status": 1, + "byzantium": true + }, + "args": [ + "0x3759B63c5879D1c130FE6C368ee8C3F8068826A3", + "0x6f23A65878cd6A71b87B7F72C4F2870090F711b0", + "0x8129fc1c" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev 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\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "execute": { + "methodName": "initialize", + "args": [] + }, + "implementation": "0x3759B63c5879D1c130FE6C368ee8C3F8068826A3", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/mumbai/UniverseRP_Implementation.json b/deployments/mumbai/UniverseRP_Implementation.json new file mode 100644 index 0000000..763fdf2 --- /dev/null +++ b/deployments/mumbai/UniverseRP_Implementation.json @@ -0,0 +1,1209 @@ +{ + "address": "0x3759B63c5879D1c130FE6C368ee8C3F8068826A3", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bosonToken", + "type": "address" + } + ], + "name": "BosonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "chargedParticles", + "type": "address" + } + ], + "name": "ChargedParticlesSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "photonSource", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "energy", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "ElectrostaticAttraction", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "photonSource", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "energy", + "type": "uint256" + } + ], + "name": "ElectrostaticDischarge", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "EsaMultiplierSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "leptonToken", + "type": "address" + } + ], + "name": "LeptonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + } + ], + "name": "NftDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + } + ], + "name": "NftRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "photonToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxSupply", + "type": "uint256" + } + ], + "name": "PhotonSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "protonToken", + "type": "address" + } + ], + "name": "ProtonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "quarkToken", + "type": "address" + } + ], + "name": "QuarkTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "RewardProgramRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardProgram", + "type": "address" + } + ], + "name": "RewardProgramSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [], + "name": "_chargedParticles", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_multiplierNft", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "uuid", + "type": "uint256" + } + ], + "name": "getNftStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositBlockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "releaseBlockNumber", + "type": "uint256" + } + ], + "internalType": "struct IUniverseRP.NftStake", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getRewardProgram", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nftTokenAmount", + "type": "uint256" + } + ], + "name": "onCovalentBond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nftTokenAmount", + "type": "uint256" + } + ], + "name": "onCovalentBreak", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creatorEnergy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onDischarge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onDischargeForCreator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assetAmount", + "type": "uint256" + } + ], + "name": "onEnergize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "newOwner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "salePrice", + "type": "uint256" + }, + { + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creatorRoyalties", + "type": "uint256" + } + ], + "name": "onProtonSale", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "creatorEnergy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onRelease", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "removeRewardProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "controller", + "type": "address" + } + ], + "name": "setChargedParticles", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + } + ], + "name": "setMultiplierNft", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "rewardProgam", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "setRewardProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x9f720db893f9804233891ee006e0b3d99dfd2d85389edef47545ea95ae4f31c0", + "receipt": { + "to": null, + "from": "0x6d46b37708dA7Ed4E5C4509495768Fecd3D17C01", + "contractAddress": "0x3759B63c5879D1c130FE6C368ee8C3F8068826A3", + "transactionIndex": 1, + "gasUsed": "2219167", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000080000000000000000000000000000000000000000000000020800000000000000000000100000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000040000000400000000001000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100000000000000008000000000000000000000000000000000000000000000000000000100000", + "blockHash": "0xd68f1ea11f4607040289eb444f21c81564fa582d92fa51e95486f4a2fdf271b9", + "transactionHash": "0x9f720db893f9804233891ee006e0b3d99dfd2d85389edef47545ea95ae4f31c0", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 39278944, + "transactionHash": "0x9f720db893f9804233891ee006e0b3d99dfd2d85389edef47545ea95ae4f31c0", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000006d46b37708da7ed4e5c4509495768fecd3d17c01", + "0x000000000000000000000000e7f13f6bc1e7f5ca4a6c9a255124ce22c46f8ef0" + ], + "data": "0x000000000000000000000000000000000000000000000000004ed734ccf118d2000000000000000000000000000000000000000000000000a50900caec42aa7700000000000000000000000000000000000000000000002f47cbf803574ca5e4000000000000000000000000000000000000000000000000a4ba29961f5191a500000000000000000000000000000000000000000000002f481acf38243dbeb6", + "logIndex": 2, + "blockHash": "0xd68f1ea11f4607040289eb444f21c81564fa582d92fa51e95486f4a2fdf271b9" + } + ], + "blockNumber": 39278944, + "cumulativeGasUsed": "2279988", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "3c4a4867d03c114eb5175ff04b48a99d", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bosonToken\",\"type\":\"address\"}],\"name\":\"BosonTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"chargedParticles\",\"type\":\"address\"}],\"name\":\"ChargedParticlesSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"photonSource\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"energy\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"multiplier\",\"type\":\"uint256\"}],\"name\":\"ElectrostaticAttraction\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"photonSource\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"energy\",\"type\":\"uint256\"}],\"name\":\"ElectrostaticDischarge\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"multiplier\",\"type\":\"uint256\"}],\"name\":\"EsaMultiplierSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"leptonToken\",\"type\":\"address\"}],\"name\":\"LeptonTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"}],\"name\":\"NftDeposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"}],\"name\":\"NftRelease\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"photonToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxSupply\",\"type\":\"uint256\"}],\"name\":\"PhotonSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"protonToken\",\"type\":\"address\"}],\"name\":\"ProtonTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"quarkToken\",\"type\":\"address\"}],\"name\":\"QuarkTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"RewardProgramRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"rewardProgram\",\"type\":\"address\"}],\"name\":\"RewardProgramSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC1155\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckEther\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"_chargedParticles\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"_multiplierNft\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"uuid\",\"type\":\"uint256\"}],\"name\":\"getNftStake\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"multiplier\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"depositBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"releaseBlockNumber\",\"type\":\"uint256\"}],\"internalType\":\"struct IUniverseRP.NftStake\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"getRewardProgram\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"onCovalentBond\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"onCovalentBreak\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"creatorEnergy\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverEnergy\",\"type\":\"uint256\"}],\"name\":\"onDischarge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"receiverEnergy\",\"type\":\"uint256\"}],\"name\":\"onDischargeForCreator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"}],\"name\":\"onEnergize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"salePrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"creatorRoyalties\",\"type\":\"uint256\"}],\"name\":\"onProtonSale\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"principalAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creatorEnergy\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverEnergy\",\"type\":\"uint256\"}],\"name\":\"onRelease\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"removeRewardProgram\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"controller\",\"type\":\"address\"}],\"name\":\"setChargedParticles\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"}],\"name\":\"setMultiplierNft\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rewardProgam\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"setRewardProgram\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC1155\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawErc20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawEther\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Upgradeable Contract\",\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Charged Particles Universe Contract with Rewards Program\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/v1/UniverseRP.sol\":\"UniverseRP\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/Initializable.sol\\\";\\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 initializer {\\n __Context_init_unchained();\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal initializer {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), 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 emit OwnershipTransferred(_owner, address(0));\\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xb419e68addcb82ecda3ad3974b0d2db76435ce9b08435a04d5b119a0c5d45ea5\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <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\",\"keccak256\":\"0x4784c3f8a520a739dd25d76f514833a653990902d0e21601aed45bda44c87524\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMathUpgradeable {\\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 uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\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 if (b > a) return (false, 0);\\n return (true, a - b);\\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 // 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 * @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 if (b == 0) return (false, 0);\\n return (true, a / b);\\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 if (b == 0) return (false, 0);\\n return (true, a % b);\\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 uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\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 require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\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 if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\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. 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(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\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 require(b > 0, \\\"SafeMath: modulo by zero\\\");\\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x0dd1e9b19801e3e7d900fbf4182d81e1afd23ad7be39504e33df6bbcba91d724\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// solhint-disable-next-line compiler-version\\npragma solidity >=0.4.24 <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 {UpgradeableProxy-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 */\\nabstract contract Initializable {\\n\\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 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 /// @dev Returns true if and only if the function is running in the constructor\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0xd8e4eb08dcc1d1860fb347ba5ffd595242b9a1b66d49a47f2b4cb51c3f35017e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0xa1931c47a617014f858580db625aa0dcf343796f39acd4b5b51effc092a1f0a9\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"../../math/SafeMathUpgradeable.sol\\\";\\nimport \\\"../../utils/AddressUpgradeable.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 SafeERC20Upgradeable {\\n using SafeMathUpgradeable for uint256;\\n using AddressUpgradeable for address;\\n\\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) 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(IERC20Upgradeable token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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(IERC20Upgradeable 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) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x8457e15aa90badabe0d6ef6f572f1ebd47bebf156921c825ae6e009dda15b706\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.2 <0.8.0;\\n\\nimport \\\"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x3dab19bb4a63bcbda1ee153ca291694f92f9009fad28626126b15a8503b0e5ff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.2 <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 // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) 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 // solhint-disable-next-line avoid-low-level-calls\\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(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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 // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfc5ea91fa9ceb1961023b2a6c978b902888c52b90847ac7813fe3b79524165f6\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\nimport \\\"../proxy/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 GSN 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 initializer {\\n __Context_init_unchained();\\n }\\n\\n function __Context_init_unchained() internal initializer {\\n }\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xbbf8a21b9a66c48d45ff771b8563c6df19ba451d63dfb8380a865c1e1f29d1a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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\",\"keccak256\":\"0xfa152b6e88a1dc50780e8f1580426dc23ad2e1e2c2f086a088adf206a202f453\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\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 uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\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 sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\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 * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\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 // 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) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts 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 mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9a9cf02622cd7a64261b10534fc3260449da25c98c9e96d1b4ae8110a20e5806\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x31691ad0817f8cb338531b78d2ab2989027d9f27e6f8e62492b754fed9429b10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0x5c26b39d26f7ed489e555d955dcd3e01872972e71fdd1528e93ec164e4f23385\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.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 SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf3b30f8a49631420635a8c35daacfcaa338012755f18a76fdd118730256f9a27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0xaf936da92f3a9a4f98b237323b5eb1d813fb86c4d07a184beba7027cf0509ba3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 in 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 // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n return _functionCallWithValue(target, data, value, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\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 // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf5fa8cbdffa5ef8be49b246b5628facc30b71707e78a45d80d93b64eff3fe390\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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.0.0, only sets of type `address` (`AddressSet`) and `uint256`\\n * (`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\\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\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] = toDeleteIndex + 1; // All indexes are 1-based\\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 require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\n return set._values[index];\\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(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(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(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(uint256(_at(set._inner, index)));\\n }\\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\",\"keccak256\":\"0xb2a11b236f073662f5a196995863f51c11d006bf7c3de158b316dfa1506c4b79\",\"license\":\"MIT\"},\"contracts/v1/UniverseRP.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// Universe.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/EnumerableSet.sol\\\";\\n\\nimport \\\"./interfaces/IUniverseRP.sol\\\";\\nimport \\\"./interfaces/IChargedParticles.sol\\\";\\nimport \\\"./interfaces/ILepton.sol\\\";\\nimport \\\"./interfaces/IRewardNft.sol\\\";\\nimport \\\"./lib/TokenInfo.sol\\\";\\nimport \\\"./lib/BlackholePrevention.sol\\\";\\nimport \\\"./interfaces/IRewardProgram.sol\\\";\\n\\n/**\\n * @notice Charged Particles Universe Contract with Rewards Program\\n * @dev Upgradeable Contract\\n */\\ncontract UniverseRP is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\\n using SafeMathUpgradeable for uint256;\\n using TokenInfo for address;\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n using EnumerableSet for EnumerableSet.UintSet;\\n\\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\\n\\n // The ChargedParticles Contract Address\\n address public _chargedParticles;\\n\\n // The Lepton NFT Contract Address\\n address public _multiplierNft;\\n\\n // Asset Token => Reward Program\\n mapping (address => address) internal _assetRewardPrograms;\\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\\n\\n // Token UUID => NFT Staking Data\\n mapping (uint256 => NftStake) private _nftStake;\\n\\n\\n /***********************************|\\n | Initialization |\\n |__________________________________*/\\n\\n function initialize() public initializer {\\n __Ownable_init();\\n }\\n\\n function getRewardProgram(address asset) external view override returns (address) {\\n return _getRewardProgram(asset);\\n }\\n\\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\\n return _nftStake[uuid];\\n }\\n\\n /***********************************|\\n | Only Charged Particles |\\n |__________________________________*/\\n\\n function onEnergize(\\n address /* sender */,\\n address /* referrer */,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n address rewardProgram = _getRewardProgram(assetToken);\\n if (rewardProgram != address(0)) {\\n IRewardProgram(rewardProgram).registerAssetDeposit(\\n contractAddress,\\n tokenId,\\n walletManagerId,\\n assetAmount\\n );\\n }\\n }\\n\\n function onDischarge(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* walletManagerId */,\\n address assetToken,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n address rewardProgram = _getRewardProgram(assetToken);\\n if (rewardProgram != address(0)) {\\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\\n }\\n }\\n\\n function onDischargeForCreator(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* walletManagerId */,\\n address /* creator */,\\n address assetToken,\\n uint256 receiverEnergy\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n address rewardProgram = _getRewardProgram(assetToken);\\n if (rewardProgram != address(0)) {\\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\\n }\\n }\\n\\n function onRelease(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* walletManagerId */,\\n address assetToken,\\n uint256 principalAmount,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n address rewardProgram = _getRewardProgram(assetToken);\\n if (rewardProgram != address(0)) {\\n // \\\"receiverEnergy\\\" includes the \\\"principalAmount\\\"\\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\\n }\\n }\\n\\n function onCovalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* managerId */,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\\n }\\n\\n function onCovalentBreak(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* managerId */,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\\n }\\n\\n function onProtonSale(\\n address contractAddress,\\n uint256 tokenId,\\n address oldOwner,\\n address newOwner,\\n uint256 salePrice,\\n address creator,\\n uint256 creatorRoyalties\\n )\\n external\\n virtual\\n override\\n {\\n // no-op\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n |__________________________________*/\\n\\n function setChargedParticles(\\n address controller\\n )\\n external\\n onlyOwner\\n onlyValidContractAddress(controller)\\n {\\n _chargedParticles = controller;\\n emit ChargedParticlesSet(controller);\\n }\\n\\n function setMultiplierNft(address nftTokenAddress)\\n external\\n onlyOwner\\n onlyValidContractAddress(nftTokenAddress)\\n {\\n _multiplierNft = nftTokenAddress;\\n }\\n\\n function setRewardProgram(\\n address rewardProgam,\\n address assetToken\\n )\\n external\\n onlyOwner\\n onlyValidContractAddress(rewardProgam)\\n {\\n require(assetToken != address(0x0), \\\"UNI:E-403\\\");\\n _assetRewardPrograms[assetToken] = rewardProgam;\\n emit RewardProgramSet(assetToken, rewardProgam);\\n }\\n\\n function removeRewardProgram(address assetToken) external onlyOwner {\\n delete _assetRewardPrograms[assetToken];\\n emit RewardProgramRemoved(assetToken);\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n | (blackhole prevention) |\\n |__________________________________*/\\n\\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n\\n\\n /***********************************|\\n | Private Functions |\\n |__________________________________*/\\n\\n function _getRewardProgram(address assetToken) internal view returns (address) {\\n return _assetRewardPrograms[assetToken];\\n }\\n\\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\\n internal\\n {\\n // We only care about the Multiplier NFT\\n if (_multiplierNft != depositNftAddress) { return; }\\n\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n uint256 multiplier = _getNftMultiplier(depositNftAddress, depositNftTokenId);\\n\\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\\n // Add to Multipliers Set\\n _multiplierNftsSet[parentNftUuid].add(multiplier);\\n\\n // Update NFT Stake\\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\\n } else {\\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\\n }\\n }\\n\\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\\n }\\n\\n function _registerNftRelease(\\n address contractAddress,\\n uint256 tokenId,\\n address releaseNftAddress,\\n uint256 releaseNftTokenId,\\n uint256 /* nftTokenAmount */\\n )\\n internal\\n {\\n // We only care about the Multiplier NFT\\n if (_multiplierNft != releaseNftAddress) { return; }\\n\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n NftStake storage nftStake = _nftStake[parentNftUuid];\\n\\n // Remove from Multipliers Set\\n uint256 multiplier = _getNftMultiplier(releaseNftAddress, releaseNftTokenId);\\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\\n\\n // Determine New Multiplier or Mark as Released\\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\\n } else {\\n nftStake.releaseBlockNumber = block.number;\\n }\\n\\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\\n }\\n\\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\\n uint256 i = 0;\\n uint256 multiplier = _multiplierNftsSet[parentNftUuid].at(i);\\n\\n // If holding all 6, Max Multiplier of 10X\\n if (len == 6) {\\n return LEPTON_MULTIPLIER_SCALE.mul(10);\\n }\\n\\n // If holding multiple; Multiplier = Half of the Sum of all\\n if (len > 1) {\\n for (; i < len; i++) {\\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\\n }\\n return multiplier.div(2); // Half of the Sum\\n }\\n\\n // Holding single or none\\n return multiplier;\\n }\\n\\n function _getNftMultiplier(address contractAddress, uint256 tokenId) internal returns (uint256) {\\n bytes4 fnSig = IRewardNft.getMultiplier.selector;\\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\\n\\n if (success) {\\n return abi.decode(returnData, (uint256));\\n } else {\\n return 0;\\n }\\n }\\n\\n\\n /***********************************|\\n | Modifiers |\\n |__________________________________*/\\n\\n /// @dev Throws if called by any non-account\\n modifier onlyValidContractAddress(address account) {\\n require(account != address(0x0) && account.isContract(), \\\"UNI:E-417\\\");\\n _;\\n }\\n\\n /// @dev Throws if called by any account other than the Charged Particles contract\\n modifier onlyChargedParticles() {\\n require(_chargedParticles == msg.sender, \\\"UNI:E-108\\\");\\n _;\\n }\\n}\\n\",\"keccak256\":\"0xfd56ab7e2210ad17442929ac373763abfbda10339b04a14030d3053737ef6ed8\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IChargedParticles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @notice Interface for Charged Particles\\n */\\ninterface IChargedParticles {\\n\\n /***********************************|\\n | Public API |\\n |__________________________________*/\\n\\n function getStateAddress() external view returns (address stateAddress);\\n function getSettingsAddress() external view returns (address settingsAddress);\\n function getManagersAddress() external view returns (address managersAddress);\\n\\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\\n\\n /***********************************|\\n | Particle Mechanics |\\n |__________________________________*/\\n\\n function energizeParticle(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount,\\n address referrer\\n ) external returns (uint256 yieldTokensAmount);\\n\\n function dischargeParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function dischargeParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function dischargeParticleForCreator(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 receiverAmount);\\n\\n function releaseParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function releaseParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function covalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success);\\n\\n function breakCovalentBond(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success);\\n\\n /***********************************|\\n | Particle Events |\\n |__________________________________*/\\n\\n event Initialized(address indexed initiator);\\n event ControllerSet(address indexed controllerAddress, string controllerId);\\n event DepositFeeSet(uint256 depositFee);\\n event ProtocolFeesCollected(address indexed assetToken, uint256 depositAmount, uint256 feesCollected);\\n}\\n\",\"keccak256\":\"0x37104c629e40193ddc8677af8a632adf53754e7915f055a5a14861cd9b417729\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IERC721Chargeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IERC721Chargeable.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\\\";\\n\\ninterface IERC721Chargeable is IERC165Upgradeable {\\n function owner() external view returns (address);\\n function creatorOf(uint256 tokenId) external view returns (address);\\n function balanceOf(address tokenOwner) external view returns (uint256 balance);\\n function ownerOf(uint256 tokenId) external view returns (address tokenOwner);\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n function transferFrom(address from, address to, uint256 tokenId) external;\\n function approve(address to, uint256 tokenId) external;\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n function setApprovalForAll(address operator, bool _approved) external;\\n function isApprovedForAll(address tokenOwner, address operator) external view returns (bool);\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x459e57b2d35c7cd78e6c3d47eb9f3e981529a18c89e2c318b10fe369c479c737\",\"license\":\"MIT\"},\"contracts/v1/interfaces/ILepton.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// ILepton.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Charged Particles Lepton Interface\\n * @dev ...\\n */\\ninterface ILepton {\\n\\n struct Classification {\\n string tokenUri;\\n uint256 price;\\n uint128 _upperBounds;\\n uint32 supply;\\n uint32 multiplier;\\n uint32 bonus;\\n }\\n\\n function mintLepton() external payable returns (uint256 newTokenId);\\n function batchMintLepton(uint256 count) external payable;\\n function getNextType() external view returns (uint256);\\n function getNextPrice() external view returns (uint256);\\n function getMultiplier(uint256 tokenId) external view returns (uint256);\\n function getBonus(uint256 tokenId) external view returns (uint256);\\n\\n\\n event MaxMintPerTxSet(uint256 maxAmount);\\n event LeptonTypeAdded(string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\\n event LeptonTypeUpdated(uint256 leptonIndex, string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\\n event LeptonMinted(address indexed receiver, uint256 indexed tokenId, uint256 price, uint32 multiplier);\\n event LeptonBatchMinted(address indexed receiver, uint256 indexed tokenId, uint256 count, uint256 price, uint32 multiplier);\\n event PausedStateSet(bool isPaused);\\n}\\n\",\"keccak256\":\"0x4903085427fa5dbee690fe79854fba60afaf21189957406ade55f6fc12556a01\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IRewardNft.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IRewardNft.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Charged Particles Reward-NFT Interface\\n * @dev ...\\n */\\ninterface IRewardNft {\\n function getMultiplier(uint256 tokenId) external view returns (uint256);\\n function getBonus(uint256 tokenId) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x51a5666003af460a55356974a286dde959c5f166104c75b4d563e8294a90b07a\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IRewardProgram.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IRewardProgram.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\npragma experimental ABIEncoderV2;\\n\\ninterface IRewardProgram {\\n /* admin events */\\n event RewardProgramFunded(uint256 amount);\\n event RewardProgramOutOfFunds();\\n\\n /* user events */\\n event RewardsClaimed(address indexed contractAddress, uint256 tokenId, address indexed receiver, uint256 rewarded, uint256 remaining);\\n\\n event AssetRegistered(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\\n event AssetDeposit(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\\n event AssetRelease(address indexed contractAddress, uint256 tokenId, uint256 interestAmount);\\n\\n /* data types */\\n struct ProgramRewardData {\\n address stakingToken;\\n address rewardToken;\\n uint256 baseMultiplier; // Basis Points\\n }\\n\\n struct AssetStake {\\n uint256 start;\\n uint256 claimableRewards;\\n string walletManagerId;\\n }\\n\\n function initialize(address stakingToken, address rewardToken, uint256 baseMultiplier, address chargedManagers, address universe, address owner) external;\\n\\n /* user functions */\\n function getProgramData() external view returns (ProgramRewardData memory programData);\\n function getAssetStake(uint256 uuid) external view returns (AssetStake memory);\\n function getFundBalance() external view returns (uint256);\\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) external view returns (uint256);\\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view returns (uint256);\\n\\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external;\\n function registerAssetDeposit(address contractAddress, uint256 tokenId, string calldata walletManagerId, uint256 principalAmount) external;\\n function registerAssetRelease(address contractAddress, uint256 tokenId, uint256 interestAmount) external returns (uint256 rewards);\\n}\",\"keccak256\":\"0xe0f4076a4b001856c54cb8a63decedc81ca34c71708f8cbe9b3a26603dc9c050\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IUniverse.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IUniverse.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Universal Controller interface\\n * @dev ...\\n */\\ninterface IUniverse {\\n\\n event ChargedParticlesSet(address indexed chargedParticles);\\n event PhotonSet(address indexed photonToken, uint256 maxSupply);\\n event ProtonTokenSet(address indexed protonToken);\\n event LeptonTokenSet(address indexed leptonToken);\\n event QuarkTokenSet(address indexed quarkToken);\\n event BosonTokenSet(address indexed bosonToken);\\n event EsaMultiplierSet(address indexed assetToken, uint256 multiplier);\\n event ElectrostaticAttraction(address indexed account, address photonSource, uint256 energy, uint256 multiplier);\\n event ElectrostaticDischarge(address indexed account, address photonSource, uint256 energy);\\n\\n function onEnergize(\\n address sender,\\n address referrer,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 assetEnergy\\n ) external;\\n\\n function onDischarge(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onDischargeForCreator(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address creator,\\n address assetToken,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onRelease(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 principalEnergy,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onCovalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n\\n function onCovalentBreak(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n\\n function onProtonSale(\\n address contractAddress,\\n uint256 tokenId,\\n address oldOwner,\\n address newOwner,\\n uint256 salePrice,\\n address creator,\\n uint256 creatorRoyalties\\n ) external;\\n}\\n\",\"keccak256\":\"0x6cebb97ce4d32c61afc746e4a6538eb605bb01276dfa66fa4bd6f63362bdc9ef\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IUniverseRP.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IUniverseRP.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"./IUniverse.sol\\\";\\n\\n/**\\n * @title Universal Controller interface for Rewards Program\\n * @dev ...\\n */\\ninterface IUniverseRP is IUniverse {\\n event RewardProgramSet(address indexed assetToken, address indexed rewardProgram);\\n event RewardProgramRemoved(address indexed assetToken);\\n event NftDeposit(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\\n event NftRelease(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\\n\\n struct NftStake {\\n uint256 multiplier; // in Basis Points\\n uint256 depositBlockNumber;\\n uint256 releaseBlockNumber;\\n }\\n\\n function getRewardProgram(address asset) external view returns (address);\\n function getNftStake(uint256 uuid) external view returns (NftStake memory);\\n}\\n\",\"keccak256\":\"0xd9c5a996bbb7f2a27bb85dde52587f7368c7b6512fc1064821a3975acdf4b7db\",\"license\":\"MIT\"},\"contracts/v1/lib/BlackholePrevention.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\\\";\\n\\n/**\\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\\n * the Owner/DAO to pull them out on behalf of a user\\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\\n */\\ncontract BlackholePrevention {\\n using Address for address payable;\\n using SafeERC20 for IERC20;\\n\\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\\n\\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (address(this).balance >= amount) {\\n receiver.sendValue(amount);\\n emit WithdrawStuckEther(receiver, amount);\\n }\\n }\\n\\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\\n IERC20(tokenAddress).safeTransfer(receiver, amount);\\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\\n }\\n }\\n\\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\\n }\\n }\\n\\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \\\"\\\");\\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6a664c8a1c1d7fb32ade2c11f75756b1fdb4c489daa32c1d58e6b867ea2ba8d6\",\"license\":\"MIT\"},\"contracts/v1/lib/TokenInfo.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// TokenInfo.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport \\\"../interfaces/IERC721Chargeable.sol\\\";\\n\\nlibrary TokenInfo {\\n function getTokenUUID(address contractAddress, uint256 tokenId) internal pure virtual returns (uint256) {\\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n function getTokenOwner(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n return tokenInterface.ownerOf(tokenId);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n function getTokenCreator(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n return tokenInterface.creatorOf(tokenId);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Owner of an External NFT contract\\n /// @param contractAddress The Address to the Contract of the NFT to check\\n /// @param account The Address of the Account to check\\n /// @return True if the account owns the contract\\n function isContractOwner(address contractAddress, address account) internal view virtual returns (bool) {\\n address contractOwner = IERC721Chargeable(contractAddress).owner();\\n return contractOwner != address(0x0) && contractOwner == account;\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Creator of a Proton-based NFT\\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\\n /// @param tokenId The Token ID of the Proton-based NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the creator of the Proton-based NFT\\n function isTokenCreator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenCreator = tokenInterface.creatorOf(tokenId);\\n return (sender == tokenCreator);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\\n /// @param tokenId The Token ID of the Proton-based NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the creator of the Proton-based NFT or the Contract itself\\n function isTokenContractOrCreator(address contractAddress, uint256 tokenId, address creator, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenCreator = tokenInterface.creatorOf(tokenId);\\n if (sender == contractAddress && creator == tokenCreator) { return true; }\\n return (sender == tokenCreator);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Owner or Operator of an External NFT\\n /// @param contractAddress The Address to the Contract of the External NFT to check\\n /// @param tokenId The Token ID of the External NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the Owner or Operator of the External NFT\\n function isErc721OwnerOrOperator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenOwner = tokenInterface.ownerOf(tokenId);\\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\\n }\\n\\n /**\\n * @dev Returns true if `account` is a contract.\\n * @dev Taken from OpenZeppelin library\\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { codehash := extcodehash(account) }\\n return (codehash != accountHash && codehash != 0x0);\\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 * @dev Taken from OpenZeppelin library\\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, uint256 gasLimit) internal {\\n require(address(this).balance >= amount, \\\"TokenInfo: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = (gasLimit > 0)\\n ? recipient.call{ value: amount, gas: gasLimit }(\\\"\\\")\\n : recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"TokenInfo: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0xbc78c6173db068d95084288246642402d0f4af399e1eb754182cae2d9173af5e\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061272e806100206000396000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c80638da5cb5b116100c3578063b9e09b4b1161007c578063b9e09b4b1461028e578063bbf1da84146102a1578063bea38be0146102a9578063c5d1d706146102bc578063f2fde38b146102cf578063fbf5ca14146102e25761014d565b80638da5cb5b14610227578063945233e21461022f57806395469dfc146102425780639a87c0de14610255578063a0edb48b14610268578063aa29542d1461027b5761014d565b8063522f681511610115578063522f6815146101be5780636e5559fd146101d1578063715018a6146101e45780638129fc1c146101ec578063836c478d146101f45780638b9309b2146102145761014d565b80631593dee1146101525780632bdbb77f1461016757806330219ef41461017a5780634025feb21461019857806341db85d6146101ab575b600080fd5b610165610160366004611d90565b6102f5565b005b610165610175366004612020565b61034d565b61018261038d565b60405161018f91906121bf565b60405180910390f35b6101656101a6366004611d90565b61039c565b6101656101b9366004612020565b6103e6565b6101656101cc366004611e15565b6104ca565b6101656101df366004611d58565b610517565b6101656105e3565b61016561066c565b61020761020236600461214e565b6106f7565b60405161018f919061267f565b610165610222366004611f18565b610384565b61018261073b565b61016561023d366004611d58565b61074a565b610165610250366004611e40565b6107d8565b610165610263366004611d58565b6108d7565b610165610276366004611dd0565b61097b565b610165610289366004611f92565b6109cc565b61016561029c366004611e78565b610a9f565b610182610b56565b6101656102b7366004612020565b610b65565b6101826102ca366004611d58565b610b9c565b6101656102dd366004611d58565b610bad565b6101656102f03660046120a4565b610c6e565b6102fd610d5c565b6001600160a01b031661030e61073b565b6001600160a01b03161461033d5760405162461bcd60e51b8152600401610334906125a6565b60405180910390fd5b610348838383610d60565b505050565b6065546001600160a01b031633146103775760405162461bcd60e51b8152600401610334906125db565b6103848787858585610e6d565b50505050505050565b6065546001600160a01b031681565b6103a4610d5c565b6001600160a01b03166103b561073b565b6001600160a01b0316146103db5760405162461bcd60e51b8152600401610334906125a6565b610348838383611000565b6065546001600160a01b031633146104105760405162461bcd60e51b8152600401610334906125db565b600061041b8461115b565b90506001600160a01b038116156104c05760006104388385611179565b604051631434318f60e21b81529091506001600160a01b038316906350d0c63c9061046b908c908c908690600401612299565b602060405180830381600087803b15801561048557600080fd5b505af1158015610499573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bd9190612166565b50505b5050505050505050565b6104d2610d5c565b6001600160a01b03166104e361073b565b6001600160a01b0316146105095760405162461bcd60e51b8152600401610334906125a6565b61051382826111a5565b5050565b61051f610d5c565b6001600160a01b031661053061073b565b6001600160a01b0316146105565760405162461bcd60e51b8152600401610334906125a6565b806001600160a01b0381161580159061057c575061057c816001600160a01b0316611229565b6105985760405162461bcd60e51b8152600401610334906123bb565b606580546001600160a01b0319166001600160a01b0384169081179091556040517f5ce0e6b7fd36339ee97339831b6c72694ecee88c62aab49919d9cabe0a732e4190600090a25050565b6105eb610d5c565b6001600160a01b03166105fc61073b565b6001600160a01b0316146106225760405162461bcd60e51b8152600401610334906125a6565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b600054610100900460ff16806106855750610685611265565b80610693575060005460ff16155b6106af5760405162461bcd60e51b815260040161033490612517565b600054610100900460ff161580156106da576000805460ff1961ff0019909116610100171660011790555b6106e2611276565b80156106f4576000805461ff00191690555b50565b6106ff611cf0565b5060008181526069602090815260409182902082516060810184528154815260018201549281019290925260020154918101919091525b919050565b6033546001600160a01b031690565b610752610d5c565b6001600160a01b031661076361073b565b6001600160a01b0316146107895760405162461bcd60e51b8152600401610334906125a6565b6001600160a01b03811660008181526067602052604080822080546001600160a01b0319169055517f87e1027e3dc61d1977f39f0dfe911b66a943946b4ceb39210dee01495621de529190a250565b6107e0610d5c565b6001600160a01b03166107f161073b565b6001600160a01b0316146108175760405162461bcd60e51b8152600401610334906125a6565b816001600160a01b0381161580159061083d575061083d816001600160a01b0316611229565b6108595760405162461bcd60e51b8152600401610334906123bb565b6001600160a01b03821661087f5760405162461bcd60e51b81526004016103349061232f565b6001600160a01b0382811660008181526067602052604080822080546001600160a01b0319169488169485179055517f3b76c6366ef8a1f8d2dbb75e4be27be1e0749716fff3e6bc327da9c6158deada9190a3505050565b6108df610d5c565b6001600160a01b03166108f061073b565b6001600160a01b0316146109165760405162461bcd60e51b8152600401610334906125a6565b806001600160a01b0381161580159061093c575061093c816001600160a01b0316611229565b6109585760405162461bcd60e51b8152600401610334906123bb565b50606680546001600160a01b0319166001600160a01b0392909216919091179055565b610983610d5c565b6001600160a01b031661099461073b565b6001600160a01b0316146109ba5760405162461bcd60e51b8152600401610334906125a6565b6109c6848484846112f4565b50505050565b6065546001600160a01b031633146109f65760405162461bcd60e51b8152600401610334906125db565b6000610a018361115b565b90506001600160a01b038116156104c057604051631434318f60e21b81526001600160a01b038216906350d0c63c90610a42908b908b908790600401612299565b602060405180830381600087803b158015610a5c57600080fd5b505af1158015610a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a949190612166565b505050505050505050565b6065546001600160a01b03163314610ac95760405162461bcd60e51b8152600401610334906125db565b6000610ad48361115b565b90506001600160a01b03811615610a94576040516323632fb160e11b81526001600160a01b038216906346c65f6290610b19908a908a908a908a908990600401612248565b600060405180830381600087803b158015610b3357600080fd5b505af1158015610b47573d6000803e3d6000fd5b50505050505050505050505050565b6066546001600160a01b031681565b6065546001600160a01b03163314610b8f5760405162461bcd60e51b8152600401610334906125db565b6103848787858585611453565b6000610ba78261115b565b92915050565b610bb5610d5c565b6001600160a01b0316610bc661073b565b6001600160a01b031614610bec5760405162461bcd60e51b8152600401610334906125a6565b6001600160a01b038116610c125760405162461bcd60e51b815260040161033490612352565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6065546001600160a01b03163314610c985760405162461bcd60e51b8152600401610334906125db565b6000610ca38561115b565b90506001600160a01b03811615610a94576000610cca84610cc48588611544565b90611179565b604051631434318f60e21b81529091506001600160a01b038316906350d0c63c90610cfd908d908d908690600401612299565b602060405180830381600087803b158015610d1757600080fd5b505af1158015610d2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4f9190612166565b5050505050505050505050565b3390565b6001600160a01b038316610d865760405162461bcd60e51b815260040161033490612398565b6040516370a0823160e01b815281906001600160a01b038416906370a0823190610db49030906004016121bf565b60206040518083038186803b158015610dcc57600080fd5b505afa158015610de0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e049190612166565b1061034857610e1d6001600160a01b038316848361156c565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b83604051610e6091906126a0565b60405180910390a3505050565b6066546001600160a01b03848116911614610e8757610ff9565b6000610e9c6001600160a01b038716866115c2565b90506000610eaa85856115f6565b9050600081118015610ed157506000828152606860205260409020610ecf90826116d8565b155b15610fa9576000828152606860205260409020610eee90826116e4565b506000610efa836116f0565b600084815260696020526040902060010154909150610f5457604080516060810182528281524360208083019182526000838501818152888252606990925293909320915182555160018201559051600290910155610fa7565b60008381526069602052604090206001810154908290554303610f93610f7b826002611791565b60008681526069602052604090206001015490611179565b600085815260696020526040902060010155505b505b846001600160a01b0316876001600160a01b03167f186ebbe503be539e070ca73b33a78f4266d96003e62b888dc31f88a39ddc9c878887604051610fee9291906126a9565b60405180910390a350505b5050505050565b6001600160a01b0383166110265760405162461bcd60e51b815260040161033490612398565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e906110549085906004016126a0565b60206040518083038186803b15801561106c57600080fd5b505afa158015611080573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a49190611d74565b6001600160a01b03161415610348576040516323b872dd60e01b81526001600160a01b038316906323b872dd906110e3903090879086906004016121d3565b600060405180830381600087803b1580156110fd57600080fd5b505af1158015611111573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b039081166000908152606760205260409020541690565b60008282018381101561119e5760405162461bcd60e51b8152600401610334906123de565b9392505050565b6001600160a01b0382166111cb5760405162461bcd60e51b815260040161033490612398565b804710610513576111e56001600160a01b038316826117c3565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd8260405161121d91906126a0565b60405180910390a25050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061125d57508115155b949350505050565b60006112703061185f565b15905090565b600054610100900460ff168061128f575061128f611265565b8061129d575060005460ff16155b6112b95760405162461bcd60e51b815260040161033490612517565b600054610100900460ff161580156112e4576000805460ff1961ff0019909116610100171660011790555b6112ec611865565b6106e26118e6565b6001600160a01b03841661131a5760405162461bcd60e51b815260040161033490612398565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e90611348903090879060040161222f565b60206040518083038186803b15801561136057600080fd5b505afa158015611374573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113989190612166565b106109c657604051637921219560e11b81526001600160a01b0384169063f242432a906113cf9030908890879087906004016121f7565b600060405180830381600087803b1580156113e957600080fd5b505af11580156113fd573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b8460405161144591906126a0565b60405180910390a450505050565b6066546001600160a01b0384811691161461146d57610ff9565b60006114826001600160a01b038716866115c2565b600081815260696020526040812091925061149d86866115f6565b60008481526068602052604090209091506114b890826119c0565b5060008381526068602052604081206114d0906119cc565b11156114e6576114df836116f0565b82556114ed565b4360028301555b856001600160a01b0316886001600160a01b03167ff3cfcfc091fdd683cf6c013de9806af93f3af27b256a57cb776331291cef408589886040516115329291906126a9565b60405180910390a35050505050505050565b6000828211156115665760405162461bcd60e51b815260040161033490612415565b50900390565b6103488363a9059cbb60e01b848460405160240161158b92919061222f565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526119d7565b600082826040516020016115d792919061217e565b60408051601f1981840301815291905280516020909101209392505050565b60008063adf8252d60e01b905060006060856001600160a01b0316838660405160240161162391906126a0565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161166191906121a0565b6000604051808303816000865af19150503d806000811461169e576040519150601f19603f3d011682016040523d82523d6000602084013e6116a3565b606091505b509150915081156116cc57808060200190518101906116c29190612166565b9350505050610ba7565b60009350505050610ba7565b600061119e8383611a66565b600061119e8383611a7e565b60008181526068602052604081208190611709906119cc565b60008481526068602052604081209192509081906117279082611ac8565b905082600614156117485761173e6064600a611ad4565b9350505050610736565b600183111561125d575b8282101561178a57600085815260686020526040902061177d906117769084611ac8565b8290611179565b6001909201919050611752565b61173e8160025b60008082116117b25760405162461bcd60e51b8152600401610334906124e0565b8183816117bb57fe5b049392505050565b804710156117e35760405162461bcd60e51b8152600401610334906124a9565b6000826001600160a01b0316826040516117fc906121bc565b60006040518083038185875af1925050503d8060008114611839576040519150601f19603f3d011682016040523d82523d6000602084013e61183e565b606091505b50509050806103485760405162461bcd60e51b81526004016103349061244c565b3b151590565b600054610100900460ff168061187e575061187e611265565b8061188c575060005460ff16155b6118a85760405162461bcd60e51b815260040161033490612517565b600054610100900460ff161580156106e2576000805460ff1961ff00199091166101001716600117905580156106f4576000805461ff001916905550565b600054610100900460ff16806118ff57506118ff611265565b8061190d575060005460ff16155b6119295760405162461bcd60e51b815260040161033490612517565b600054610100900460ff16158015611954576000805460ff1961ff0019909116610100171660011790555b600061195e610d5c565b603380546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35080156106f4576000805461ff001916905550565b600061119e8383611b0e565b6000610ba782611bd4565b6060611a2c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611bd89092919063ffffffff16565b8051909150156103485780806020019051810190611a4a919061212e565b6103485760405162461bcd60e51b815260040161033490612635565b60009081526001919091016020526040902054151590565b6000611a8a8383611a66565b611ac057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ba7565b506000610ba7565b600061119e8383611be7565b600082611ae357506000610ba7565b82820282848281611af057fe5b041461119e5760405162461bcd60e51b815260040161033490612565565b60008181526001830160205260408120548015611bca5783546000198083019190810190600090879083908110611b4157fe5b9060005260206000200154905080876000018481548110611b5e57fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080611b8e57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610ba7565b6000915050610ba7565b5490565b606061125d8484600085611c2c565b81546000908210611c0a5760405162461bcd60e51b8152600401610334906122ed565b826000018281548110611c1957fe5b9060005260206000200154905092915050565b6060611c378561185f565b611c535760405162461bcd60e51b8152600401610334906125fe565b60006060866001600160a01b03168587604051611c7091906121a0565b60006040518083038185875af1925050503d8060008114611cad576040519150601f19603f3d011682016040523d82523d6000602084013e611cb2565b606091505b50915091508115611cc657915061125d9050565b805115611cd65780518082602001fd5b8360405162461bcd60e51b815260040161033491906122ba565b60405180606001604052806000815260200160008152602001600081525090565b60008083601f840112611d22578182fd5b50813567ffffffffffffffff811115611d39578182fd5b602083019150836020828501011115611d5157600080fd5b9250929050565b600060208284031215611d69578081fd5b813561119e816126e3565b600060208284031215611d85578081fd5b815161119e816126e3565b600080600060608486031215611da4578182fd5b8335611daf816126e3565b92506020840135611dbf816126e3565b929592945050506040919091013590565b60008060008060808587031215611de5578081fd5b8435611df0816126e3565b93506020850135611e00816126e3565b93969395505050506040820135916060013590565b60008060408385031215611e27578182fd5b8235611e32816126e3565b946020939093013593505050565b60008060408385031215611e52578182fd5b8235611e5d816126e3565b91506020830135611e6d816126e3565b809150509250929050565b60008060008060008060008060e0898b031215611e93578384fd5b8835611e9e816126e3565b97506020890135611eae816126e3565b96506040890135611ebe816126e3565b955060608901359450608089013567ffffffffffffffff811115611ee0578485fd5b611eec8b828c01611d11565b90955093505060a0890135611f00816126e3565b8092505060c089013590509295985092959890939650565b600080600080600080600060e0888a031215611f32578283fd5b8735611f3d816126e3565b9650602088013595506040880135611f54816126e3565b94506060880135611f64816126e3565b93506080880135925060a0880135611f7b816126e3565b8092505060c0880135905092959891949750929550565b600080600080600080600060c0888a031215611fac578283fd5b8735611fb7816126e3565b965060208801359550604088013567ffffffffffffffff811115611fd9578384fd5b611fe58a828b01611d11565b9096509450506060880135611ff9816126e3565b92506080880135612009816126e3565b8092505060a0880135905092959891949750929550565b600080600080600080600060c0888a03121561203a578081fd5b8735612045816126e3565b965060208801359550604088013567ffffffffffffffff811115612067578182fd5b6120738a828b01611d11565b9096509450506060880135612087816126e3565b969995985093969295946080840135945060a09093013592915050565b60008060008060008060008060e0898b0312156120bf578182fd5b88356120ca816126e3565b975060208901359650604089013567ffffffffffffffff8111156120ec578283fd5b6120f88b828c01611d11565b909750955050606089013561210c816126e3565b979a96995094979396956080850135955060a08501359460c001359350915050565b60006020828403121561213f578081fd5b8151801515811461119e578182fd5b60006020828403121561215f578081fd5b5035919050565b600060208284031215612177578081fd5b5051919050565b60609290921b6bffffffffffffffffffffffff19168252601482015260340190565b600082516121b28184602087016126b7565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03861681526020810185905260806040820181905281018390526000838560a08401378060a0858401015260a0601f19601f86011683010190508260608301529695505050505050565b6001600160a01b039390931683526020830191909152604082015260600190565b60006020825282518060208401526122d98160408501602087016126b7565b601f01601f19169190910160400192915050565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b602080825260099082015268554e493a452d34303360b81b604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b602080825260099082015268554e493a452d34313760b81b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252600990820152680aa9c92748a5a6260760bb1b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b81518152602080830151908201526040918201519181019190915260600190565b90815260200190565b918252602082015260400190565b60005b838110156126d25781810151838201526020016126ba565b838111156109c65750506000910152565b6001600160a01b03811681146106f457600080fdfea2646970667358221220af698ef9bcf763676411f19a12660b048964e2e24f44f31e99726fe0b5cb8b0864736f6c634300060c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061014d5760003560e01c80638da5cb5b116100c3578063b9e09b4b1161007c578063b9e09b4b1461028e578063bbf1da84146102a1578063bea38be0146102a9578063c5d1d706146102bc578063f2fde38b146102cf578063fbf5ca14146102e25761014d565b80638da5cb5b14610227578063945233e21461022f57806395469dfc146102425780639a87c0de14610255578063a0edb48b14610268578063aa29542d1461027b5761014d565b8063522f681511610115578063522f6815146101be5780636e5559fd146101d1578063715018a6146101e45780638129fc1c146101ec578063836c478d146101f45780638b9309b2146102145761014d565b80631593dee1146101525780632bdbb77f1461016757806330219ef41461017a5780634025feb21461019857806341db85d6146101ab575b600080fd5b610165610160366004611d90565b6102f5565b005b610165610175366004612020565b61034d565b61018261038d565b60405161018f91906121bf565b60405180910390f35b6101656101a6366004611d90565b61039c565b6101656101b9366004612020565b6103e6565b6101656101cc366004611e15565b6104ca565b6101656101df366004611d58565b610517565b6101656105e3565b61016561066c565b61020761020236600461214e565b6106f7565b60405161018f919061267f565b610165610222366004611f18565b610384565b61018261073b565b61016561023d366004611d58565b61074a565b610165610250366004611e40565b6107d8565b610165610263366004611d58565b6108d7565b610165610276366004611dd0565b61097b565b610165610289366004611f92565b6109cc565b61016561029c366004611e78565b610a9f565b610182610b56565b6101656102b7366004612020565b610b65565b6101826102ca366004611d58565b610b9c565b6101656102dd366004611d58565b610bad565b6101656102f03660046120a4565b610c6e565b6102fd610d5c565b6001600160a01b031661030e61073b565b6001600160a01b03161461033d5760405162461bcd60e51b8152600401610334906125a6565b60405180910390fd5b610348838383610d60565b505050565b6065546001600160a01b031633146103775760405162461bcd60e51b8152600401610334906125db565b6103848787858585610e6d565b50505050505050565b6065546001600160a01b031681565b6103a4610d5c565b6001600160a01b03166103b561073b565b6001600160a01b0316146103db5760405162461bcd60e51b8152600401610334906125a6565b610348838383611000565b6065546001600160a01b031633146104105760405162461bcd60e51b8152600401610334906125db565b600061041b8461115b565b90506001600160a01b038116156104c05760006104388385611179565b604051631434318f60e21b81529091506001600160a01b038316906350d0c63c9061046b908c908c908690600401612299565b602060405180830381600087803b15801561048557600080fd5b505af1158015610499573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bd9190612166565b50505b5050505050505050565b6104d2610d5c565b6001600160a01b03166104e361073b565b6001600160a01b0316146105095760405162461bcd60e51b8152600401610334906125a6565b61051382826111a5565b5050565b61051f610d5c565b6001600160a01b031661053061073b565b6001600160a01b0316146105565760405162461bcd60e51b8152600401610334906125a6565b806001600160a01b0381161580159061057c575061057c816001600160a01b0316611229565b6105985760405162461bcd60e51b8152600401610334906123bb565b606580546001600160a01b0319166001600160a01b0384169081179091556040517f5ce0e6b7fd36339ee97339831b6c72694ecee88c62aab49919d9cabe0a732e4190600090a25050565b6105eb610d5c565b6001600160a01b03166105fc61073b565b6001600160a01b0316146106225760405162461bcd60e51b8152600401610334906125a6565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b600054610100900460ff16806106855750610685611265565b80610693575060005460ff16155b6106af5760405162461bcd60e51b815260040161033490612517565b600054610100900460ff161580156106da576000805460ff1961ff0019909116610100171660011790555b6106e2611276565b80156106f4576000805461ff00191690555b50565b6106ff611cf0565b5060008181526069602090815260409182902082516060810184528154815260018201549281019290925260020154918101919091525b919050565b6033546001600160a01b031690565b610752610d5c565b6001600160a01b031661076361073b565b6001600160a01b0316146107895760405162461bcd60e51b8152600401610334906125a6565b6001600160a01b03811660008181526067602052604080822080546001600160a01b0319169055517f87e1027e3dc61d1977f39f0dfe911b66a943946b4ceb39210dee01495621de529190a250565b6107e0610d5c565b6001600160a01b03166107f161073b565b6001600160a01b0316146108175760405162461bcd60e51b8152600401610334906125a6565b816001600160a01b0381161580159061083d575061083d816001600160a01b0316611229565b6108595760405162461bcd60e51b8152600401610334906123bb565b6001600160a01b03821661087f5760405162461bcd60e51b81526004016103349061232f565b6001600160a01b0382811660008181526067602052604080822080546001600160a01b0319169488169485179055517f3b76c6366ef8a1f8d2dbb75e4be27be1e0749716fff3e6bc327da9c6158deada9190a3505050565b6108df610d5c565b6001600160a01b03166108f061073b565b6001600160a01b0316146109165760405162461bcd60e51b8152600401610334906125a6565b806001600160a01b0381161580159061093c575061093c816001600160a01b0316611229565b6109585760405162461bcd60e51b8152600401610334906123bb565b50606680546001600160a01b0319166001600160a01b0392909216919091179055565b610983610d5c565b6001600160a01b031661099461073b565b6001600160a01b0316146109ba5760405162461bcd60e51b8152600401610334906125a6565b6109c6848484846112f4565b50505050565b6065546001600160a01b031633146109f65760405162461bcd60e51b8152600401610334906125db565b6000610a018361115b565b90506001600160a01b038116156104c057604051631434318f60e21b81526001600160a01b038216906350d0c63c90610a42908b908b908790600401612299565b602060405180830381600087803b158015610a5c57600080fd5b505af1158015610a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a949190612166565b505050505050505050565b6065546001600160a01b03163314610ac95760405162461bcd60e51b8152600401610334906125db565b6000610ad48361115b565b90506001600160a01b03811615610a94576040516323632fb160e11b81526001600160a01b038216906346c65f6290610b19908a908a908a908a908990600401612248565b600060405180830381600087803b158015610b3357600080fd5b505af1158015610b47573d6000803e3d6000fd5b50505050505050505050505050565b6066546001600160a01b031681565b6065546001600160a01b03163314610b8f5760405162461bcd60e51b8152600401610334906125db565b6103848787858585611453565b6000610ba78261115b565b92915050565b610bb5610d5c565b6001600160a01b0316610bc661073b565b6001600160a01b031614610bec5760405162461bcd60e51b8152600401610334906125a6565b6001600160a01b038116610c125760405162461bcd60e51b815260040161033490612352565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6065546001600160a01b03163314610c985760405162461bcd60e51b8152600401610334906125db565b6000610ca38561115b565b90506001600160a01b03811615610a94576000610cca84610cc48588611544565b90611179565b604051631434318f60e21b81529091506001600160a01b038316906350d0c63c90610cfd908d908d908690600401612299565b602060405180830381600087803b158015610d1757600080fd5b505af1158015610d2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4f9190612166565b5050505050505050505050565b3390565b6001600160a01b038316610d865760405162461bcd60e51b815260040161033490612398565b6040516370a0823160e01b815281906001600160a01b038416906370a0823190610db49030906004016121bf565b60206040518083038186803b158015610dcc57600080fd5b505afa158015610de0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e049190612166565b1061034857610e1d6001600160a01b038316848361156c565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b83604051610e6091906126a0565b60405180910390a3505050565b6066546001600160a01b03848116911614610e8757610ff9565b6000610e9c6001600160a01b038716866115c2565b90506000610eaa85856115f6565b9050600081118015610ed157506000828152606860205260409020610ecf90826116d8565b155b15610fa9576000828152606860205260409020610eee90826116e4565b506000610efa836116f0565b600084815260696020526040902060010154909150610f5457604080516060810182528281524360208083019182526000838501818152888252606990925293909320915182555160018201559051600290910155610fa7565b60008381526069602052604090206001810154908290554303610f93610f7b826002611791565b60008681526069602052604090206001015490611179565b600085815260696020526040902060010155505b505b846001600160a01b0316876001600160a01b03167f186ebbe503be539e070ca73b33a78f4266d96003e62b888dc31f88a39ddc9c878887604051610fee9291906126a9565b60405180910390a350505b5050505050565b6001600160a01b0383166110265760405162461bcd60e51b815260040161033490612398565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e906110549085906004016126a0565b60206040518083038186803b15801561106c57600080fd5b505afa158015611080573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a49190611d74565b6001600160a01b03161415610348576040516323b872dd60e01b81526001600160a01b038316906323b872dd906110e3903090879086906004016121d3565b600060405180830381600087803b1580156110fd57600080fd5b505af1158015611111573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b039081166000908152606760205260409020541690565b60008282018381101561119e5760405162461bcd60e51b8152600401610334906123de565b9392505050565b6001600160a01b0382166111cb5760405162461bcd60e51b815260040161033490612398565b804710610513576111e56001600160a01b038316826117c3565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd8260405161121d91906126a0565b60405180910390a25050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061125d57508115155b949350505050565b60006112703061185f565b15905090565b600054610100900460ff168061128f575061128f611265565b8061129d575060005460ff16155b6112b95760405162461bcd60e51b815260040161033490612517565b600054610100900460ff161580156112e4576000805460ff1961ff0019909116610100171660011790555b6112ec611865565b6106e26118e6565b6001600160a01b03841661131a5760405162461bcd60e51b815260040161033490612398565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e90611348903090879060040161222f565b60206040518083038186803b15801561136057600080fd5b505afa158015611374573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113989190612166565b106109c657604051637921219560e11b81526001600160a01b0384169063f242432a906113cf9030908890879087906004016121f7565b600060405180830381600087803b1580156113e957600080fd5b505af11580156113fd573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b8460405161144591906126a0565b60405180910390a450505050565b6066546001600160a01b0384811691161461146d57610ff9565b60006114826001600160a01b038716866115c2565b600081815260696020526040812091925061149d86866115f6565b60008481526068602052604090209091506114b890826119c0565b5060008381526068602052604081206114d0906119cc565b11156114e6576114df836116f0565b82556114ed565b4360028301555b856001600160a01b0316886001600160a01b03167ff3cfcfc091fdd683cf6c013de9806af93f3af27b256a57cb776331291cef408589886040516115329291906126a9565b60405180910390a35050505050505050565b6000828211156115665760405162461bcd60e51b815260040161033490612415565b50900390565b6103488363a9059cbb60e01b848460405160240161158b92919061222f565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526119d7565b600082826040516020016115d792919061217e565b60408051601f1981840301815291905280516020909101209392505050565b60008063adf8252d60e01b905060006060856001600160a01b0316838660405160240161162391906126a0565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161166191906121a0565b6000604051808303816000865af19150503d806000811461169e576040519150601f19603f3d011682016040523d82523d6000602084013e6116a3565b606091505b509150915081156116cc57808060200190518101906116c29190612166565b9350505050610ba7565b60009350505050610ba7565b600061119e8383611a66565b600061119e8383611a7e565b60008181526068602052604081208190611709906119cc565b60008481526068602052604081209192509081906117279082611ac8565b905082600614156117485761173e6064600a611ad4565b9350505050610736565b600183111561125d575b8282101561178a57600085815260686020526040902061177d906117769084611ac8565b8290611179565b6001909201919050611752565b61173e8160025b60008082116117b25760405162461bcd60e51b8152600401610334906124e0565b8183816117bb57fe5b049392505050565b804710156117e35760405162461bcd60e51b8152600401610334906124a9565b6000826001600160a01b0316826040516117fc906121bc565b60006040518083038185875af1925050503d8060008114611839576040519150601f19603f3d011682016040523d82523d6000602084013e61183e565b606091505b50509050806103485760405162461bcd60e51b81526004016103349061244c565b3b151590565b600054610100900460ff168061187e575061187e611265565b8061188c575060005460ff16155b6118a85760405162461bcd60e51b815260040161033490612517565b600054610100900460ff161580156106e2576000805460ff1961ff00199091166101001716600117905580156106f4576000805461ff001916905550565b600054610100900460ff16806118ff57506118ff611265565b8061190d575060005460ff16155b6119295760405162461bcd60e51b815260040161033490612517565b600054610100900460ff16158015611954576000805460ff1961ff0019909116610100171660011790555b600061195e610d5c565b603380546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35080156106f4576000805461ff001916905550565b600061119e8383611b0e565b6000610ba782611bd4565b6060611a2c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611bd89092919063ffffffff16565b8051909150156103485780806020019051810190611a4a919061212e565b6103485760405162461bcd60e51b815260040161033490612635565b60009081526001919091016020526040902054151590565b6000611a8a8383611a66565b611ac057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ba7565b506000610ba7565b600061119e8383611be7565b600082611ae357506000610ba7565b82820282848281611af057fe5b041461119e5760405162461bcd60e51b815260040161033490612565565b60008181526001830160205260408120548015611bca5783546000198083019190810190600090879083908110611b4157fe5b9060005260206000200154905080876000018481548110611b5e57fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080611b8e57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610ba7565b6000915050610ba7565b5490565b606061125d8484600085611c2c565b81546000908210611c0a5760405162461bcd60e51b8152600401610334906122ed565b826000018281548110611c1957fe5b9060005260206000200154905092915050565b6060611c378561185f565b611c535760405162461bcd60e51b8152600401610334906125fe565b60006060866001600160a01b03168587604051611c7091906121a0565b60006040518083038185875af1925050503d8060008114611cad576040519150601f19603f3d011682016040523d82523d6000602084013e611cb2565b606091505b50915091508115611cc657915061125d9050565b805115611cd65780518082602001fd5b8360405162461bcd60e51b815260040161033491906122ba565b60405180606001604052806000815260200160008152602001600081525090565b60008083601f840112611d22578182fd5b50813567ffffffffffffffff811115611d39578182fd5b602083019150836020828501011115611d5157600080fd5b9250929050565b600060208284031215611d69578081fd5b813561119e816126e3565b600060208284031215611d85578081fd5b815161119e816126e3565b600080600060608486031215611da4578182fd5b8335611daf816126e3565b92506020840135611dbf816126e3565b929592945050506040919091013590565b60008060008060808587031215611de5578081fd5b8435611df0816126e3565b93506020850135611e00816126e3565b93969395505050506040820135916060013590565b60008060408385031215611e27578182fd5b8235611e32816126e3565b946020939093013593505050565b60008060408385031215611e52578182fd5b8235611e5d816126e3565b91506020830135611e6d816126e3565b809150509250929050565b60008060008060008060008060e0898b031215611e93578384fd5b8835611e9e816126e3565b97506020890135611eae816126e3565b96506040890135611ebe816126e3565b955060608901359450608089013567ffffffffffffffff811115611ee0578485fd5b611eec8b828c01611d11565b90955093505060a0890135611f00816126e3565b8092505060c089013590509295985092959890939650565b600080600080600080600060e0888a031215611f32578283fd5b8735611f3d816126e3565b9650602088013595506040880135611f54816126e3565b94506060880135611f64816126e3565b93506080880135925060a0880135611f7b816126e3565b8092505060c0880135905092959891949750929550565b600080600080600080600060c0888a031215611fac578283fd5b8735611fb7816126e3565b965060208801359550604088013567ffffffffffffffff811115611fd9578384fd5b611fe58a828b01611d11565b9096509450506060880135611ff9816126e3565b92506080880135612009816126e3565b8092505060a0880135905092959891949750929550565b600080600080600080600060c0888a03121561203a578081fd5b8735612045816126e3565b965060208801359550604088013567ffffffffffffffff811115612067578182fd5b6120738a828b01611d11565b9096509450506060880135612087816126e3565b969995985093969295946080840135945060a09093013592915050565b60008060008060008060008060e0898b0312156120bf578182fd5b88356120ca816126e3565b975060208901359650604089013567ffffffffffffffff8111156120ec578283fd5b6120f88b828c01611d11565b909750955050606089013561210c816126e3565b979a96995094979396956080850135955060a08501359460c001359350915050565b60006020828403121561213f578081fd5b8151801515811461119e578182fd5b60006020828403121561215f578081fd5b5035919050565b600060208284031215612177578081fd5b5051919050565b60609290921b6bffffffffffffffffffffffff19168252601482015260340190565b600082516121b28184602087016126b7565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03861681526020810185905260806040820181905281018390526000838560a08401378060a0858401015260a0601f19601f86011683010190508260608301529695505050505050565b6001600160a01b039390931683526020830191909152604082015260600190565b60006020825282518060208401526122d98160408501602087016126b7565b601f01601f19169190910160400192915050565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b602080825260099082015268554e493a452d34303360b81b604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b602080825260099082015268554e493a452d34313760b81b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252600990820152680aa9c92748a5a6260760bb1b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b81518152602080830151908201526040918201519181019190915260600190565b90815260200190565b918252602082015260400190565b60005b838110156126d25781810151838201526020016126ba565b838111156109c65750506000910152565b6001600160a01b03811681146106f457600080fdfea2646970667358221220af698ef9bcf763676411f19a12660b048964e2e24f44f31e99726fe0b5cb8b0864736f6c634300060c0033", + "devdoc": { + "details": "Upgradeable Contract", + "kind": "dev", + "methods": { + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Charged Particles Universe Contract with Rewards Program", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 680, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 683, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 3177, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 111, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "t_address" + }, + { + "astId": 230, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 16752, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_chargedParticles", + "offset": 0, + "slot": "101", + "type": "t_address" + }, + { + "astId": 16754, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_multiplierNft", + "offset": 0, + "slot": "102", + "type": "t_address" + }, + { + "astId": 16758, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_assetRewardPrograms", + "offset": 0, + "slot": "103", + "type": "t_mapping(t_address,t_address)" + }, + { + "astId": 16762, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_multiplierNftsSet", + "offset": 0, + "slot": "104", + "type": "t_mapping(t_uint256,t_struct(UintSet)8991_storage)" + }, + { + "astId": 16766, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_nftStake", + "offset": 0, + "slot": "105", + "type": "t_mapping(t_uint256,t_struct(NftStake)29448_storage)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_address)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_uint256,t_struct(NftStake)29448_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct IUniverseRP.NftStake)", + "numberOfBytes": "32", + "value": "t_struct(NftStake)29448_storage" + }, + "t_mapping(t_uint256,t_struct(UintSet)8991_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct EnumerableSet.UintSet)", + "numberOfBytes": "32", + "value": "t_struct(UintSet)8991_storage" + }, + "t_struct(NftStake)29448_storage": { + "encoding": "inplace", + "label": "struct IUniverseRP.NftStake", + "members": [ + { + "astId": 29443, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "multiplier", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 29445, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "depositBlockNumber", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 29447, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "releaseBlockNumber", + "offset": 0, + "slot": "2", + "type": "t_uint256" + } + ], + "numberOfBytes": "96" + }, + "t_struct(Set)8702_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 8697, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 8701, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_struct(UintSet)8991_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.UintSet", + "members": [ + { + "astId": 8990, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)8702_storage" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/deployments/mumbai/UniverseRP_Proxy.json b/deployments/mumbai/UniverseRP_Proxy.json new file mode 100644 index 0000000..9189fb9 --- /dev/null +++ b/deployments/mumbai/UniverseRP_Proxy.json @@ -0,0 +1,264 @@ +{ + "address": "0x4402daCEb7889dB63158701A07f9562F1e0642Fa", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xe6086d798d0793c92d2c761b265e513458a6469c7647b8e22dd67d8de994c342", + "receipt": { + "to": null, + "from": "0x6d46b37708dA7Ed4E5C4509495768Fecd3D17C01", + "contractAddress": "0x4402daCEb7889dB63158701A07f9562F1e0642Fa", + "transactionIndex": 2, + "gasUsed": "769434", + "logsBloom": "0x00000000000000000000000000000000400000000000000000800000000000000000000000000000000000000000000000008000000080000000000000000000000000000000000000000000000022800001000000000000000100000000000000000000020000000000000000080800000000800000000080000000000000400000000000000000000000000000000004000000040000000400200000801000200000000000000000000000000000000000000000000000000000000000004000000020000000000001000000000000000000000400000000100000000020240008000000000004000000000000000000000000000000000000000000100000", + "blockHash": "0xa0b30a763c50b92eaa26606630602be15ae850d798a15134518e02f0c04aaa6e", + "transactionHash": "0xe6086d798d0793c92d2c761b265e513458a6469c7647b8e22dd67d8de994c342", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 39278947, + "transactionHash": "0xe6086d798d0793c92d2c761b265e513458a6469c7647b8e22dd67d8de994c342", + "address": "0x4402daCEb7889dB63158701A07f9562F1e0642Fa", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000003759b63c5879d1c130fe6c368ee8c3f8068826a3" + ], + "data": "0x", + "logIndex": 9, + "blockHash": "0xa0b30a763c50b92eaa26606630602be15ae850d798a15134518e02f0c04aaa6e" + }, + { + "transactionIndex": 2, + "blockNumber": 39278947, + "transactionHash": "0xe6086d798d0793c92d2c761b265e513458a6469c7647b8e22dd67d8de994c342", + "address": "0x4402daCEb7889dB63158701A07f9562F1e0642Fa", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000006d46b37708da7ed4e5c4509495768fecd3d17c01" + ], + "data": "0x", + "logIndex": 10, + "blockHash": "0xa0b30a763c50b92eaa26606630602be15ae850d798a15134518e02f0c04aaa6e" + }, + { + "transactionIndex": 2, + "blockNumber": 39278947, + "transactionHash": "0xe6086d798d0793c92d2c761b265e513458a6469c7647b8e22dd67d8de994c342", + "address": "0x4402daCEb7889dB63158701A07f9562F1e0642Fa", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f23a65878cd6a71b87b7f72c4f2870090f711b0", + "logIndex": 11, + "blockHash": "0xa0b30a763c50b92eaa26606630602be15ae850d798a15134518e02f0c04aaa6e" + }, + { + "transactionIndex": 2, + "blockNumber": 39278947, + "transactionHash": "0xe6086d798d0793c92d2c761b265e513458a6469c7647b8e22dd67d8de994c342", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x0000000000000000000000006d46b37708da7ed4e5c4509495768fecd3d17c01", + "0x000000000000000000000000e7f13f6bc1e7f5ca4a6c9a255124ce22c46f8ef0" + ], + "data": "0x000000000000000000000000000000000000000000000000001b55f621a7d32c000000000000000000000000000000000000000000000000a4ba29961cf00e7700000000000000000000000000000000000000000000002f4889e7d0c96760d0000000000000000000000000000000000000000000000000a49ed39ffb483b4b00000000000000000000000000000000000000000000002f48a53dc6eb0f33fc", + "logIndex": 12, + "blockHash": "0xa0b30a763c50b92eaa26606630602be15ae850d798a15134518e02f0c04aaa6e" + } + ], + "blockNumber": 39278947, + "cumulativeGasUsed": "948859", + "status": 1, + "byzantium": true + }, + "args": [ + "0x3759B63c5879D1c130FE6C368ee8C3F8068826A3", + "0x6f23A65878cd6A71b87B7F72C4F2870090F711b0", + "0x8129fc1c" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev 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\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/mumbai/solcInputs/0e89febeebc7444140de8e67c9067d2c.json b/deployments/mumbai/solcInputs/0e89febeebc7444140de8e67c9067d2c.json new file mode 100644 index 0000000..6eb5ed9 --- /dev/null +++ b/deployments/mumbai/solcInputs/0e89febeebc7444140de8e67c9067d2c.json @@ -0,0 +1,80 @@ +{ + "language": "Solidity", + "sources": { + "solc_0.8/openzeppelin/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 (address initialOwner) {\n _transferOwnership(initialOwner);\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" + }, + "solc_0.8/openzeppelin/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" + }, + "solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"../../access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n\n constructor (address initialOwner) Ownable(initialOwner) {}\n\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(\n TransparentUpgradeableProxy proxy,\n address implementation,\n bytes memory data\n ) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(\n address _logic,\n address admin_,\n bytes memory _data\n ) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _changeAdmin(admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n _changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overriden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n" + }, + "solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view virtual returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(Address.isContract(IBeacon(newBeacon).implementation()), \"ERC1967: beacon implementation is not a contract\");\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "solc_0.8/openzeppelin/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\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 * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev 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" + }, + "solc_0.8/openzeppelin/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n assembly {\n r.slot := slot\n }\n }\n}\n" + }, + "solc_0.8/proxy/OptimizedTransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract OptimizedTransparentUpgradeableProxy is ERC1967Proxy {\n address internal immutable _ADMIN;\n\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(\n address _logic,\n address admin_,\n bytes memory _data\n ) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _ADMIN = admin_;\n\n // still store it to work with EIP-1967\n bytes32 slot = _ADMIN_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, admin_)\n }\n emit AdminChanged(address(0), admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n\n function _getAdmin() internal view virtual override returns (address) {\n return _ADMIN;\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/utils/UUPSUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../ERC1967/ERC1967Upgrade.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n *\n * _Available since v4.1._\n */\nabstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade {\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\n address private immutable __self = address(this);\n\n /**\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n * fail.\n */\n modifier onlyProxy() {\n require(address(this) != __self, \"Function must be called through delegatecall\");\n require(_getImplementation() == __self, \"Function must be called through active proxy\");\n _;\n }\n\n /**\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\n * callable on the implementing contract but not through proxies.\n */\n modifier notDelegated() {\n require(address(this) == __self, \"UUPSUpgradeable: must not be called through delegatecall\");\n _;\n }\n\n /**\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\n * implementation. It is used to validate that the this implementation remains valid after an upgrade.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\n */\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\n return _IMPLEMENTATION_SLOT;\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n */\n function upgradeTo(address newImplementation) external virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n * encoded in `data`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n */\n function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, data, true);\n }\n\n /**\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n * {upgradeTo} and {upgradeToAndCall}.\n *\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\n *\n * ```solidity\n * function _authorizeUpgrade(address) internal override onlyOwner {}\n * ```\n */\n function _authorizeUpgrade(address newImplementation) internal virtual;\n}\n" + }, + "solc_0.8/openzeppelin/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * 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 !Address.isContract(address(this));\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/beacon/UpgradeableBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/UpgradeableBeacon.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IBeacon.sol\";\nimport \"../../access/Ownable.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their\n * implementation contract, which is where they will delegate all function calls.\n *\n * An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon.\n */\ncontract UpgradeableBeacon is IBeacon, Ownable {\n address private _implementation;\n\n /**\n * @dev Emitted when the implementation returned by the beacon is changed.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Sets the address of the initial implementation, and the deployer account as the owner who can upgrade the\n * beacon.\n */\n\n constructor(address implementation_, address initialOwner) Ownable(initialOwner) {\n _setImplementation(implementation_);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function implementation() public view virtual override returns (address) {\n return _implementation;\n }\n\n /**\n * @dev Upgrades the beacon to a new implementation.\n *\n * Emits an {Upgraded} event.\n *\n * Requirements:\n *\n * - msg.sender must be the owner of the contract.\n * - `newImplementation` must be a contract.\n */\n function upgradeTo(address newImplementation) public virtual onlyOwner {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Sets the implementation contract address for this beacon\n *\n * Requirements:\n *\n * - `newImplementation` must be a contract.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableBeacon: implementation is not a contract\");\n _implementation = newImplementation;\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/beacon/BeaconProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/BeaconProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IBeacon.sol\";\nimport \"../Proxy.sol\";\nimport \"../ERC1967/ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements a proxy that gets the implementation address for each call from a {UpgradeableBeacon}.\n *\n * The beacon address is stored in storage slot `uint256(keccak256('eip1967.proxy.beacon')) - 1`, so that it doesn't\n * conflict with the storage layout of the implementation behind the proxy.\n *\n * _Available since v3.4._\n */\ncontract BeaconProxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the proxy with `beacon`.\n *\n * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This\n * will typically be an encoded function call, and allows initializating the storage of the proxy like a Solidity\n * constructor.\n *\n * Requirements:\n *\n * - `beacon` must be a contract with the interface {IBeacon}.\n */\n constructor(address beacon, bytes memory data) payable {\n assert(_BEACON_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.beacon\")) - 1));\n _upgradeBeaconToAndCall(beacon, data, false);\n }\n\n /**\n * @dev Returns the current beacon address.\n */\n function _beacon() internal view virtual returns (address) {\n return _getBeacon();\n }\n\n /**\n * @dev Returns the current implementation address of the associated beacon.\n */\n function _implementation() internal view virtual override returns (address) {\n return IBeacon(_getBeacon()).implementation();\n }\n\n /**\n * @dev Changes the proxy to use a new beacon. Deprecated: see {_upgradeBeaconToAndCall}.\n *\n * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon.\n *\n * Requirements:\n *\n * - `beacon` must be a contract.\n * - The implementation returned by `beacon` must be a contract.\n */\n function _setBeacon(address beacon, bytes memory data) internal virtual {\n _upgradeBeaconToAndCall(beacon, data, false);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "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/deployments/mumbai/solcInputs/3c4a4867d03c114eb5175ff04b48a99d.json b/deployments/mumbai/solcInputs/3c4a4867d03c114eb5175ff04b48a99d.json new file mode 100644 index 0000000..40b9947 --- /dev/null +++ b/deployments/mumbai/solcInputs/3c4a4867d03c114eb5175ff04b48a99d.json @@ -0,0 +1,452 @@ +{ + "language": "Solidity", + "sources": { + "@opengsn/gsn/contracts/BaseRelayRecipient.sol": { + "content": "// SPDX-License-Identifier:MIT\n// solhint-disable no-inline-assembly\npragma solidity ^0.6.2;\n\nimport \"./interfaces/IRelayRecipient.sol\";\n\n/**\n * A base contract to be inherited by any contract that want to receive relayed transactions\n * A subclass must use \"_msgSender()\" instead of \"msg.sender\"\n */\nabstract contract BaseRelayRecipient is IRelayRecipient {\n\n /*\n * Forwarder singleton we accept calls from\n */\n address public trustedForwarder;\n\n function isTrustedForwarder(address forwarder) public override view returns(bool) {\n return forwarder == trustedForwarder;\n }\n\n /**\n * return the sender of this call.\n * if the call came through our trusted forwarder, return the original sender.\n * otherwise, return `msg.sender`.\n * should be used in the contract anywhere instead of msg.sender\n */\n function _msgSender() internal override virtual view returns (address payable ret) {\n if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // so we trust that the last bytes of msg.data are the verified sender address.\n // extract sender address from the end of msg.data\n assembly {\n ret := shr(96,calldataload(sub(calldatasize(),20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n /**\n * return the msg.data of this call.\n * if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes\n * of the msg.data - so this method will strip those 20 bytes off.\n * otherwise, return `msg.data`\n * should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly\n * signing or hashing the\n */\n function _msgData() internal override virtual view returns (bytes memory ret) {\n if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // we copy the msg.data , except the last 20 bytes (and update the total length)\n assembly {\n let ptr := mload(0x40)\n // copy only size-20 bytes\n let size := sub(calldatasize(),20)\n // structure RLP data as \n mstore(ptr, 0x20)\n mstore(add(ptr,32), size)\n calldatacopy(add(ptr,64), 0, size)\n return(ptr, add(size,64))\n }\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "@opengsn/gsn/contracts/interfaces/IRelayRecipient.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.6.2;\n\n/**\n * a contract must implement this interface in order to support relayed transaction.\n * It is better to inherit the BaseRelayRecipient as its implementation.\n */\nabstract contract IRelayRecipient {\n\n /**\n * return if the forwarder is trusted to forward relayed transactions to us.\n * the forwarder is required to verify the sender's signature, and verify\n * the call is not a replay.\n */\n function isTrustedForwarder(address forwarder) public virtual view returns(bool);\n\n /**\n * return the sender of this call.\n * if the call came through our trusted forwarder, then the real sender is appended as the last 20 bytes\n * of the msg.data.\n * otherwise, return `msg.sender`\n * should be used in the contract anywhere instead of msg.sender\n */\n function _msgSender() internal virtual view returns (address payable);\n\n /**\n * return the msg.data of this call.\n * if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes\n * of the msg.data - so this method will strip those 20 bytes off.\n * otherwise, return `msg.data`\n * should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly\n * signing or hashing the\n */\n function _msgData() internal virtual view returns (bytes memory);\n\n function versionRecipient() external virtual view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\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 initializer {\n __Context_init_unchained();\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal initializer {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), 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 emit OwnershipTransferred(_owner, address(0));\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n function __ERC165_init() internal initializer {\n __ERC165_init_unchained();\n }\n\n function __ERC165_init_unchained() internal initializer {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMathUpgradeable {\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 uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\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 if (b > a) return (false, 0);\n return (true, a - b);\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 // 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 * @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 if (b == 0) return (false, 0);\n return (true, a / b);\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 if (b == 0) return (false, 0);\n return (true, a % b);\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 uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n return c;\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 require(b <= a, \"SafeMath: subtraction overflow\");\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 if (a == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n return c;\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. 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(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: division by zero\");\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 require(b > 0, \"SafeMath: modulo by zero\");\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n return a - b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a / b;\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.4.24 <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 {UpgradeableProxy-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 */\nabstract contract Initializable {\n\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 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 /// @dev Returns true if and only if the function is running in the constructor\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\n\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 )\n external\n 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 )\n external\n returns(bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC20Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../proxy/Initializable.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 guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable {\n using SafeMathUpgradeable for uint256;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal initializer {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer {\n _name = name_;\n _symbol = symbol_;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal virtual {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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(address sender, address recipient, uint256 amount) 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/ERC20/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.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 SafeERC20Upgradeable {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) 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(IERC20Upgradeable token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\n require((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(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\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(IERC20Upgradeable 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) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721MetadataUpgradeable.sol\";\nimport \"./IERC721EnumerableUpgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"../../introspection/ERC165Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/EnumerableSetUpgradeable.sol\";\nimport \"../../utils/EnumerableMapUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../proxy/Initializable.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable, IERC721EnumerableUpgradeable {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet;\n using EnumerableMapUpgradeable for EnumerableMapUpgradeable.UintToAddressMap;\n using StringsUpgradeable for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSetUpgradeable.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMapUpgradeable.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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 initializer {\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 initializer {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\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 _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\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 _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\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(_msgSender() == owner || ERC721Upgradeable.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 require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) 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(address from, address to, uint256 tokenId, bytes memory _data) 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 _tokenOwners.contains(tokenId);\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 || ERC721Upgradeable.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\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 _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(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); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(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(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721ReceiverUpgradeable(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); // internal owner\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(address from, address to, uint256 tokenId) internal virtual { }\n uint256[41] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721EnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 /**\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/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 /**\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\npragma solidity >=0.6.0 <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(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) 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 // solhint-disable-next-line avoid-low-level-calls\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(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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 // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/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 GSN 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 initializer {\n __Context_init_unchained();\n }\n\n function __Context_init_unchained() internal initializer {\n }\n function _msgSender() internal view virtual returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/EnumerableMapUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMapUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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 EnumerableSetUpgradeable {\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\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\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] = toDeleteIndex + 1; // All indexes are 1-based\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 require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\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 // 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 // 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" + }, + "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/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 initializer {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal initializer {\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 make 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/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n /**\n * @dev Converts a `uint256` to its ASCII `string` 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 uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = bytes1(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../GSN/Context.sol\";\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 */\ncontract 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 () internal {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), msgSender);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view 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 emit OwnershipTransferred(_owner, address(0));\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n" + }, + "@openzeppelin/contracts/cryptography/MerkleProof.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev These functions deal with verification of Merkle trees (hash trees),\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(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {\n bytes32 computedHash = leaf;\n\n for (uint256 i = 0; i < proof.length; i++) {\n bytes32 proofElement = proof[i];\n\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\n // Check if the computed hash (root) is equal to the provided root\n return computedHash == root;\n }\n}\n" + }, + "@openzeppelin/contracts/GSN/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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 GSN 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 payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\ncontract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () internal {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n" + }, + "@openzeppelin/contracts/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\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 uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\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 sub(a, b, \"SafeMath: subtraction overflow\");\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 * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\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 // 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) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts 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 mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\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 SafeMath for uint256;\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 * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri) public {\n _setURI(uri);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\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) external view 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 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(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\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 require(accounts[i] != address(0), \"ERC1155: batch balance query for the zero address\");\n batchBalances[i] = _balances[ids[i]][accounts[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 require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view 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 )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, 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 )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\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 _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(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 `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` 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(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, 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(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) 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 (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\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 `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, 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(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != 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, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\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 )\n internal virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).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 )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).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/token/ERC1155/ERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() public {\n _registerInterface(\n ERC1155Receiver(0).onERC1155Received.selector ^\n ERC1155Receiver(0).onERC1155BatchReceived.selector\n );\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\nimport \"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\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 )\n external\n 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 )\n external\n returns(bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.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 guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 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 {\n using SafeMath for uint256;\n using Address for address;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name, string memory symbol) public {\n _name = name;\n _symbol = symbol;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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/token/ERC20/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.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 SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\n require((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(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\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) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n\n // If there is no base URI, return the token URI.\n if (bytes(_baseURI).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(_baseURI, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(_baseURI, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_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 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 require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) 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(address from, address to, uint256 tokenId, bytes memory _data) 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 returns (bool) {\n return _tokenOwners.contains(tokenId);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = 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 d*\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\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 _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(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 = ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(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(address from, address to, uint256 tokenId) internal virtual {\n require(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 _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\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(address from, address to, uint256 tokenId) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\nimport \"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 /**\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/token/ERC721/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 /**\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/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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(address operator, address from, uint256 tokenId, bytes calldata data)\n external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 in 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 // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n return _functionCallWithValue(target, data, value, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\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 // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../math/SafeMath.sol\";\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented or decremented by one. 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 * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}\n * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never\n * directly accessed.\n */\nlibrary Counters {\n using SafeMath for uint256;\n\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 // The {SafeMath} overflow check can be skipped here, see the comment at the top\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableMap.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n return _get(map, key, \"EnumerableMap: nonexistent key\");\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(value)));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint256(value)));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint256(_get(map._inner, bytes32(key))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint256(_get(map._inner, bytes32(key), errorMessage)));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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.0.0, only sets of type `address` (`AddressSet`) and `uint256`\n * (`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\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\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] = toDeleteIndex + 1; // All indexes are 1-based\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 require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\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(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(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(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(uint256(_at(set._inner, index)));\n }\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" + }, + "@openzeppelin/contracts/utils/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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 */\ncontract 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 () internal {\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 make 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/utils/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value < 2**128, \"SafeCast: value doesn\\'t fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value < 2**64, \"SafeCast: value doesn\\'t fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value < 2**32, \"SafeCast: value doesn\\'t fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value < 2**16, \"SafeCast: value doesn\\'t fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value < 2**8, \"SafeCast: value doesn\\'t fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= -2**127 && value < 2**127, \"SafeCast: value doesn\\'t fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= -2**63 && value < 2**63, \"SafeCast: value doesn\\'t fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= -2**31 && value < 2**31, \"SafeCast: value doesn\\'t fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= -2**15 && value < 2**15, \"SafeCast: value doesn\\'t fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= -2**7 && value < 2**7, \"SafeCast: value doesn\\'t fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n require(value < 2**255, \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` 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 uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = byte(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n" + }, + "contracts/v1/ChargedManagers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Wallet-Managers Contract\n */\ncontract ChargedManagers is\n IChargedManagers,\n Initializable,\n OwnableUpgradeable,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n\n IChargedSettings internal _chargedSettings;\n IChargedState internal _chargedState;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // Wallet/Basket Managers (by Unique Manager ID)\n mapping (string => IWalletManager) internal _ftWalletManager;\n mapping (string => IBasketManager) internal _nftBasketManager;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n /// @notice Checks if an Account is the Owner of an NFT Contract\n /// When Custom Contracts are registered, only the \"owner\" or operator of the Contract\n /// is allowed to register them and define custom rules for how their tokens are \"Charged\".\n /// Otherwise, any token can be \"Charged\" according to the default rules of Charged Particles.\n /// @param contractAddress The Address to the External NFT Contract to check\n /// @param account The Account to check if it is the Owner of the specified Contract\n /// @return True if the account is the Owner of the _contract\n function isContractOwner(address contractAddress, address account) external view override virtual returns (bool) {\n return contractAddress.isContractOwner(account);\n }\n\n function isWalletManagerEnabled(string calldata walletManagerId) external virtual override view returns (bool) {\n return _isWalletManagerEnabled(walletManagerId);\n }\n\n function getWalletManager(string calldata walletManagerId) external virtual override view returns (IWalletManager) {\n return _ftWalletManager[walletManagerId];\n }\n\n function isNftBasketEnabled(string calldata basketId) external virtual override view returns (bool) {\n return _isNftBasketEnabled(basketId);\n }\n\n function getBasketManager(string calldata basketId) external virtual override view returns (IBasketManager) {\n return _nftBasketManager[basketId];\n }\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param sender The sender address to validate against\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external virtual override {\n _validateDeposit(sender, contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param sender The sender address to validate against\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external virtual override {\n _validateNftDeposit(sender, contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateDischarge(sender, contractAddress, tokenId);\n }\n\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateRelease(sender, contractAddress, tokenId);\n }\n\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateBreakBond(sender, contractAddress, tokenId);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"state\"))) {\n _chargedState = IChargedState(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n /// @dev Register Contracts as wallet managers with a unique liquidity provider ID\n function registerWalletManager(string calldata walletManagerId, address walletManager) external virtual onlyOwner {\n // Validate wallet manager\n IWalletManager newWalletMgr = IWalletManager(walletManager);\n require(newWalletMgr.isPaused() != true, \"CP:E-418\");\n\n // Register LP ID\n _ftWalletManager[walletManagerId] = newWalletMgr;\n emit WalletManagerRegistered(walletManagerId, walletManager);\n }\n\n /// @dev Register Contracts as basket managers with a unique basket ID\n function registerBasketManager(string calldata basketId, address basketManager) external virtual onlyOwner {\n // Validate basket manager\n IBasketManager newBasketMgr = IBasketManager(basketManager);\n require(newBasketMgr.isPaused() != true, \"CP:E-418\");\n\n // Register Basket ID\n _nftBasketManager[basketId] = newBasketMgr;\n emit BasketManagerRegistered(basketId, basketManager);\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev See {ChargedParticles-isWalletManagerEnabled}.\n function _isWalletManagerEnabled(string calldata walletManagerId) internal view virtual returns (bool) {\n return (address(_ftWalletManager[walletManagerId]) != address(0x0) && !_ftWalletManager[walletManagerId].isPaused());\n }\n\n /// @dev See {ChargedParticles-isNftBasketEnabled}.\n function _isNftBasketEnabled(string calldata basketId) internal view virtual returns (bool) {\n return (address(_nftBasketManager[basketId]) != address(0x0) && !_nftBasketManager[basketId].isPaused());\n }\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n internal\n virtual\n {\n if (_chargedState.isEnergizeRestricted(contractAddress, tokenId)) {\n bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender);\n require(isNFTOwnerOrOperator, \"CP:E-105\");\n }\n\n ( string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n ) = _chargedSettings.getAssetRequirements(contractAddress, assetToken);\n\n require(energizeEnabled, \"CP:E-417\");\n\n require(!invalidAsset, \"CP:E-424\");\n\n // Valid Wallet Manager?\n if (bytes(requiredWalletManager).length > 0) {\n require(keccak256(abi.encodePacked(requiredWalletManager)) == keccak256(abi.encodePacked(walletManagerId)), \"CP:E-419\");\n }\n\n // Valid Asset?\n if (restrictedAssets) {\n require(validAsset, \"CP:E-424\");\n }\n\n _validateDepositAmount(\n contractAddress,\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n depositCap,\n depositMin,\n depositMax\n );\n }\n\n /// @dev Validates a Deposit-Amount according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDepositAmount(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax\n )\n internal\n virtual\n {\n uint256 existingBalance = _ftWalletManager[walletManagerId].getPrincipal(contractAddress, tokenId, assetToken);\n uint256 newBalance = assetAmount.add(existingBalance);\n\n // Validate Deposit Cap\n if (depositCap > 0) {\n require(newBalance <= depositCap, \"CP:E-408\");\n }\n\n // Valid Amount for Deposit?\n if (depositMin > 0) {\n require(newBalance >= depositMin, \"CP:E-410\");\n }\n if (depositMax > 0) {\n require(newBalance <= depositMax, \"CP:E-410\");\n }\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n {\n // Prevent Ouroboros NFTs\n require(contractAddress.getTokenUUID(tokenId) != nftTokenAddress.getTokenUUID(nftTokenId), \"CP:E-433\");\n\n if (_chargedState.isCovalentBondRestricted(contractAddress, tokenId)) {\n bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender);\n require(isNFTOwnerOrOperator, \"CP:E-105\");\n }\n\n ( string memory requiredBasketManager,\n bool basketEnabled,\n uint256 maxNfts\n ) = _chargedSettings.getNftAssetRequirements(contractAddress, nftTokenAddress);\n\n require(basketEnabled, \"CP:E-417\");\n\n // Valid Basket Manager?\n if (bytes(requiredBasketManager).length > 0) {\n require(keccak256(abi.encodePacked(requiredBasketManager)) == keccak256(abi.encodePacked(basketManagerId)), \"CP:E-419\");\n }\n\n if (maxNfts > 0) {\n uint256 tokenCount = _nftBasketManager[basketManagerId].getTokenTotalCount(contractAddress, tokenId);\n require(maxNfts >= (tokenCount + nftTokenAmount), \"CP:E-427\");\n }\n }\n\n function _validateDischarge(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getDischargeState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateRelease(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getReleaseState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateBreakBond(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getBreakBondState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateState(\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n internal\n view\n virtual\n {\n if (!allowFromAll) {\n require(isApproved, \"CP:E-105\");\n }\n if (timelock > 0) {\n require(block.number >= timelock, \"CP:E-302\");\n }\n if (tempLockExpiry > 0) {\n require(block.number >= tempLockExpiry, \"CP:E-303\");\n }\n }\n}\n" + }, + "contracts/v1/ChargedParticles.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\n\nimport \"./interfaces/IUniverse.sol\";\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/IWalletManager.sol\";\nimport \"./interfaces/IBasketManager.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/RelayRecipient.sol\";\n\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles V2 Contract\n * @dev Upgradeable Contract\n */\ncontract ChargedParticles is\n IChargedParticles,\n Initializable,\n OwnableUpgradeable,\n ReentrancyGuardUpgradeable,\n RelayRecipient,\n IERC721ReceiverUpgradeable,\n BlackholePrevention,\n IERC1155ReceiverUpgradeable\n{\n using SafeMathUpgradeable for uint256;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using Bitwise for uint32;\n using AddressUpgradeable for address;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n //\n // Particle Terminology\n //\n // Particle - Non-fungible Token (NFT)\n // Mass - Underlying Asset of a Token (ex; DAI)\n // Charge - Accrued Interest on the Underlying Asset of a Token\n // Charged Particle - Any NFT that has a Mass and a Positive Charge\n // Neutral Particle - Any NFT that has a Mass and No Charge\n // Energize / Recharge - Deposit of an Underlying Asset into an NFT\n // Discharge - Withdraw the Accrued Interest of an NFT leaving the Particle with its initial Mass\n // Release - Withdraw the Underlying Asset & Accrued Interest of an NFT leaving the Particle with No Mass or Charge\n //\n // Proton - NFTs minted from the Charged Particle Accelerator\n // - A proton is a subatomic particle, symbol p or p⁺, with a positive electric charge of +1e elementary\n // charge and a mass slightly less than that of a neutron.\n // Ion - Platform Governance Token\n // - A charged subatomic particle. An atom or group of atoms that carries a positive or negative electric charge\n // as a result of having lost or gained one or more electrons.\n //\n\n // Linked Contracts\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n address internal _lepton;\n uint256 internal depositFee;\n ITokenInfoProxy internal _tokenInfoProxy;\n IChargedManagers internal _chargedManagers;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n __ReentrancyGuard_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getStateAddress() external view virtual override returns (address stateAddress) {\n return address(_chargedState);\n }\n\n function getSettingsAddress() external view virtual override returns (address settingsAddress) {\n return address(_chargedSettings);\n }\n\n function getManagersAddress() external view virtual override returns (address managersAddress) {\n return address(_chargedManagers);\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external virtual override returns (bytes4) {\n return IERC721ReceiverUpgradeable(0).onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external virtual override returns (bytes4) {\n return IERC1155ReceiverUpgradeable(0).onERC1155Received.selector;\n }\n\n // Unimplemented\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external virtual override returns (bytes4) {\n return \"\"; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector;\n }\n\n function supportsInterface(bytes4 /* interfaceId */) external view virtual override returns (bool) {\n return false;\n }\n\n /// @notice Calculates the amount of Fees to be paid for a specific deposit amount\n /// @param assetAmount The Amount of Assets to calculate Fees on\n /// @return protocolFee The amount of deposit fees for the protocol\n function getFeesForDeposit(\n uint256 assetAmount\n )\n external\n override\n view\n returns (uint256 protocolFee)\n {\n protocolFee = _getFeesForDeposit(assetAmount);\n }\n\n /// @notice Gets the Amount of Asset Tokens that have been Deposited into the Particle\n /// representing the Mass of the Particle.\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Asset balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The Amount of underlying Assets held within the Token\n function baseParticleMass(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _baseParticleMass(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the amount of Interest that the Particle has generated representing\n /// the Charge of the Particle\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Interest balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The amount of interest the Token has generated (in Asset Token)\n function currentParticleCharge(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _currentParticleCharge(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the amount of LP Tokens that the Particle has generated representing\n /// the Kinetics of the Particle\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Kinetics balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The amount of LP tokens that have been generated\n function currentParticleKinetics(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _currentParticleKinetics(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the total amount of ERC721 Tokens that the Particle holds\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param basketManagerId The ID of the BasketManager to check the token balance of\n /// @return The total amount of ERC721 tokens that are held within the Particle\n function currentParticleCovalentBonds(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId\n )\n external\n view\n virtual\n override\n basketEnabled(basketManagerId)\n returns (uint256)\n {\n return _currentParticleCovalentBonds(contractAddress, tokenId, basketManagerId);\n }\n\n\n /***********************************|\n | Energize Particles |\n |__________________________________*/\n\n /// @notice Fund Particle with Asset Token\n /// Must be called by the account providing the Asset\n /// Account must Approve THIS contract as Operator of Asset\n ///\n /// NOTE: DO NOT Energize an ERC20 Token, as anyone who holds any amount\n /// of the same ERC20 token could discharge or release the funds.\n /// All holders of the ERC20 token would essentially be owners of the Charged Particle.\n ///\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param walletManagerId The Asset-Pair to Energize the Token with\n /// @param assetToken The Address of the Asset Token being used\n /// @param assetAmount The Amount of Asset Token to Energize the Token with\n /// @return yieldTokensAmount The amount of Yield-bearing Tokens added to the escrow for the Token\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 yieldTokensAmount)\n {\n _validateDeposit(contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n\n // Transfer ERC20 Token from Caller to Contract (reverts on fail)\n uint256 feeAmount = _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n yieldTokensAmount = _depositIntoWalletManager(contractAddress, tokenId, walletManagerId, assetToken, assetAmount, feeAmount);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onEnergize(_msgSender(), referrer, contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n }\n\n\n /***********************************|\n | Discharge Particles |\n |__________________________________*/\n\n /// @notice Allows the owner or operator of the Token to collect or transfer the interest generated\n /// from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @return creatorAmount Amount of Asset Token discharged to the Creator\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateDischarge(contractAddress, tokenId);\n\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).discharge(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount);\n }\n }\n\n /// @notice Allows the owner or operator of the Token to collect or transfer a specific amount of the interest\n /// generated from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @param assetAmount The specific amount of Asset Token to Discharge from the Token\n /// @return creatorAmount Amount of Asset Token discharged to the Creator\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateDischarge(contractAddress, tokenId);\n\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).dischargeAmount(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n assetAmount,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount);\n }\n }\n\n /// @notice Allows the Creator of the Token to collect or transfer a their portion of the interest (if any)\n /// generated from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @param assetAmount The specific amount of Asset Token to Discharge from the Particle\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 receiverAmount)\n {\n address sender = _msgSender();\n address tokenCreator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId);\n require(sender == tokenCreator, \"CP:E-104\");\n\n receiverAmount = _chargedManagers.getWalletManager(walletManagerId).dischargeAmountForCreator(\n receiver,\n contractAddress,\n tokenId,\n sender,\n assetToken,\n assetAmount\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischargeForCreator(contractAddress, tokenId, walletManagerId, sender, assetToken, receiverAmount);\n }\n }\n\n\n /***********************************|\n | Release Particles |\n |__________________________________*/\n\n /// @notice Releases the Full amount of Asset + Interest held within the Particle by LP of the Assets\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Release\n /// @param tokenId The ID of the Token to Release\n /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token\n /// @param assetToken The Address of the Asset Token being released\n /// @return creatorAmount Amount of Asset Token released to the Creator\n /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount)\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateRelease(contractAddress, tokenId);\n\n // Release Particle to Receiver\n uint256 principalAmount;\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).release(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n }\n\n\n /// @notice Releases a partial amount of Asset + Interest held within the Particle by LP of the Assets\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Release\n /// @param tokenId The ID of the Token to Release\n /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token\n /// @param assetToken The Address of the Asset Token being released\n /// @param assetAmount The specific amount of Asset Token to Release from the Particle\n /// @return creatorAmount Amount of Asset Token released to the Creator\n /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount)\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateRelease(contractAddress, tokenId);\n\n // Release Particle to Receiver\n uint256 principalAmount;\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).releaseAmount(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n assetAmount,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n }\n\n\n /***********************************|\n | Covalent Bonding |\n |__________________________________*/\n\n /// @notice Deposit other NFT Assets into the Particle\n /// Must be called by the account providing the Asset\n /// Account must Approve THIS contract as Operator of Asset\n ///\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n basketEnabled(basketManagerId)\n nonReentrant\n returns (bool success)\n {\n _validateNftDeposit(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Transfer ERC721 Token from Caller to Contract (reverts on fail)\n _collectNftToken(_msgSender(), nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n success = _depositIntoBasketManager(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onCovalentBond(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n }\n\n /// @notice Release NFT Assets from the Particle\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Withdraw (ERC1155-specific)\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n basketEnabled(basketManagerId)\n nonReentrant\n returns (bool success)\n {\n _validateBreakBond(contractAddress, tokenId);\n\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked(\"generic\"))) {\n basketMgr.prepareTransferAmount(nftTokenAmount);\n }\n\n // Release Particle to Receiver\n success = basketMgr.removeFromBasket(\n receiver,\n contractAddress,\n tokenId,\n nftTokenAddress,\n nftTokenId\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onCovalentBreak(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"universe\"))) {\n _universe = IUniverse(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"state\"))) {\n _chargedState = IChargedState(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"managers\"))) {\n _chargedManagers = IChargedManagers(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"leptons\"))) {\n _lepton = controller;\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"forwarder\"))) {\n trustedForwarder = controller;\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n\n /***********************************|\n | Protocol Fees |\n |__________________________________*/\n\n /// @dev Setup the Base Deposit Fee for the Protocol\n function setDepositFee(uint256 fee) external onlyOwner {\n require(fee < PERCENTAGE_SCALE, \"CP:E-421\");\n depositFee = fee;\n emit DepositFeeSet(fee);\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n internal\n virtual\n {\n _chargedManagers.validateDeposit(_msgSender(), contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _validateNftDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n {\n _chargedManagers.validateNftDeposit(_msgSender(), contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function _validateDischarge(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateDischarge(_msgSender(), contractAddress, tokenId);\n }\n\n function _validateRelease(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateRelease(_msgSender(), contractAddress, tokenId);\n }\n\n function _validateBreakBond(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateBreakBond(_msgSender(), contractAddress, tokenId);\n }\n\n /// @dev Deposit Asset Tokens into an NFT via the Wallet Manager\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n /// @param feeAmount The Amount of Protocol Fees charged\n function _depositIntoWalletManager(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 feeAmount\n )\n internal\n virtual\n returns (uint256)\n {\n // Get Wallet-Manager for LP\n IWalletManager lpWalletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n address wallet = lpWalletMgr.getWalletAddressById(contractAddress, tokenId, creator, annuityPct);\n IERC20Upgradeable(assetToken).transfer(wallet, assetAmount);\n\n emit ProtocolFeesCollected(assetToken, assetAmount, feeAmount);\n\n return lpWalletMgr.energize(contractAddress, tokenId, assetToken, assetAmount);\n }\n\n /// @dev Deposit NFT Tokens into the Basket Manager\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @param basketManagerId The Wallet Manager of the Assets to Deposit\n /// @param nftTokenAddress The Address of the Asset Token to Deposit\n /// @param nftTokenId The specific amount of Asset Token to Deposit\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _depositIntoBasketManager(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n returns (bool)\n {\n // Deposit NFT Token directly into Smart Wallet (reverts on fail) and Update BasketManager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId);\n\n if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked(\"generic\"))) {\n basketMgr.prepareTransferAmount(nftTokenAmount);\n }\n\n if (_isERC1155(nftTokenAddress)) {\n if (nftTokenAmount == 0) { nftTokenAmount = 1; }\n IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(address(this), wallet, nftTokenId, nftTokenAmount, \"\");\n } else {\n IERC721Upgradeable(nftTokenAddress).transferFrom(address(this), wallet, nftTokenId);\n }\n return basketMgr.addToBasket(contractAddress, tokenId, nftTokenAddress, nftTokenId);\n }\n\n /**\n * @dev Calculates the amount of Fees to be paid for a specific deposit amount\n * Fees are calculated in Interest-Token as they are the type collected for Fees\n * @param assetAmount The Amount of Assets to calculate Fees on\n * @return protocolFee The amount of fees reserved for the protocol\n */\n function _getFeesForDeposit(\n uint256 assetAmount\n )\n internal\n view\n returns (uint256 protocolFee)\n {\n if (depositFee > 0) {\n protocolFee = assetAmount.mul(depositFee).div(PERCENTAGE_SCALE);\n }\n }\n\n /// @dev Collects the Required ERC20 Token(s) from the users wallet\n /// Be sure to Approve this Contract to transfer your Token(s)\n /// @param from The owner address to collect the tokens from\n /// @param tokenAddress The addres of the token to transfer\n /// @param tokenAmount The amount of tokens to collect\n function _collectAssetToken(address from, address tokenAddress, uint256 tokenAmount) internal virtual returns (uint256 protocolFee) {\n protocolFee = _getFeesForDeposit(tokenAmount);\n IERC20Upgradeable(tokenAddress).safeTransferFrom(from, address(this), tokenAmount.add(protocolFee));\n }\n\n /// @dev Collects the Required ERC721 Token(s) from the users wallet\n /// Be sure to Approve this Contract to transfer your Token(s)\n /// @param from The owner address to collect the tokens from\n /// @param nftTokenAddress The address of the NFT token to transfer\n /// @param nftTokenId The ID of the NFT token to transfer\n /// @param nftTokenAmount The amount of Tokens to Transfer (ERC1155-specific)\n function _collectNftToken(address from, address nftTokenAddress, uint256 nftTokenId, uint256 nftTokenAmount) internal virtual {\n if (_isERC1155(nftTokenAddress)) {\n IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId, nftTokenAmount, \"\");\n } else {\n IERC721Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId);\n }\n }\n\n /// @dev Checks if an NFT token contract supports the ERC1155 standard interface\n function _isERC1155(address nftTokenAddress) internal view virtual returns (bool) {\n bytes4 _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n return IERC165Upgradeable(nftTokenAddress).supportsInterface(_INTERFACE_ID_ERC1155);\n }\n\n /// @dev See {ChargedParticles-baseParticleMass}.\n function _baseParticleMass(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n return _chargedManagers.getWalletManager(walletManagerId).getPrincipal(contractAddress, tokenId, assetToken);\n }\n\n /// @dev See {ChargedParticles-currentParticleCharge}.\n function _currentParticleCharge(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n (, uint256 ownerInterest) = _chargedManagers.getWalletManager(walletManagerId).getInterest(contractAddress, tokenId, assetToken);\n return ownerInterest;\n }\n\n /// @dev See {ChargedParticles-currentParticleKinetics}.\n function _currentParticleKinetics(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n return _chargedManagers.getWalletManager(walletManagerId).getRewards(contractAddress, tokenId, assetToken);\n }\n\n /// @dev See {ChargedParticles-currentParticleCovalentBonds}.\n function _currentParticleCovalentBonds(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId\n )\n internal\n view\n virtual\n returns (uint256)\n {\n return _chargedManagers.getBasketManager(basketManagerId).getTokenTotalCount(contractAddress, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier managerEnabled(string calldata walletManagerId) {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"CP:E-419\");\n _;\n }\n\n modifier basketEnabled(string calldata basketManagerId) {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"CP:E-419\");\n _;\n }\n}\n" + }, + "contracts/v1/ChargedSettings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/RelayRecipient.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\nimport \"./lib/TokenInfoProxy.sol\";\n\n/**\n * @notice Charged Particles Settings Contract\n */\ncontract ChargedSettings is\n IChargedSettings,\n Initializable,\n OwnableUpgradeable,\n RelayRecipient,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using Bitwise for uint32;\n\n uint256 constant internal MAX_ANNUITIES = 1e4; // 10000 (100%)\n\n // NftSettings - actionPerms\n uint32 constant internal PERM_CHARGE_NFT = 1; // NFT Contracts that can have assets Deposited into them (Charged)\n uint32 constant internal PERM_BASKET_NFT = 2; // NFT Contracts that can have other NFTs Deposited into them\n uint32 constant internal PERM_TIMELOCK_ANY_NFT = 4; // NFT Contracts that can timelock any NFT on behalf of users (primarily used for Front-run Protection)\n uint32 constant internal PERM_TIMELOCK_OWN_NFT = 8; // NFT Contracts that can timelock their own NFTs on behalf of their users\n uint32 constant internal PERM_RESTRICTED_ASSETS = 16; // NFT Contracts that have restricted deposits to specific assets\n\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // Current Settings for External NFT Token Contracts;\n // - Any user can add any ERC721 or ERC1155 token as a Charged Particle without Limits,\n // unless the Owner of the ERC721 or ERC1155 token contract registers the token\n // and sets the Custom Settings for their token(s)\n mapping (address => uint32) internal _nftActionPerms;\n\n mapping (address => string) internal _nftRequiredWalletManager;\n mapping (address => string) internal _nftRequiredBasketManager;\n\n // ERC20\n mapping (address => mapping(address => bool)) internal _nftAllowedAssetTokens;\n mapping (address => mapping (address => uint256)) internal _nftDepositMin;\n mapping (address => mapping (address => uint256)) internal _nftDepositMax;\n\n // ERC721 / ERC1155\n mapping (address => mapping (address => uint256)) internal _nftMaxNfts; // NFT Token Address => Max\n\n // Optional Configs for individual NFTs set by NFT Creator (by Token UUID)\n mapping (uint256 => uint256) internal _creatorAnnuityPercent;\n mapping (uint256 => address) internal _creatorAnnuityRedirect;\n\n mapping (address => uint256) internal _depositCap;\n uint256 internal _tempLockExpiryBlocks;\n\n // Blacklist for non-compliant tokens\n mapping (address => bool) internal _invalidAssets;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n /// @dev Gets the amount of creator annuities reserved for the creator for the specified NFT\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @return creator The address of the creator\n /// @return annuityPct The percentage amount of annuities reserved for the creator\n function getCreatorAnnuities(\n address contractAddress,\n uint256 tokenId\n )\n external\n override\n virtual\n returns (address creator, uint256 annuityPct)\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n creator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId);\n annuityPct = _creatorAnnuityPercent[tokenUuid];\n }\n\n function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId)\n external\n view\n override\n virtual\n returns (address)\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _creatorAnnuityRedirect[tokenUuid];\n }\n\n function getTempLockExpiryBlocks() external view override virtual returns (uint256) {\n return _tempLockExpiryBlocks;\n }\n\n function getTimelockApprovals(address operator)\n external\n view\n override\n virtual\n returns (bool timelockAny, bool timelockOwn)\n {\n timelockAny = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_ANY_NFT);\n timelockOwn = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_OWN_NFT);\n }\n\n function getAssetRequirements(address contractAddress, address assetToken)\n external\n view\n override\n virtual\n returns (\n string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n )\n {\n requiredWalletManager = _nftRequiredWalletManager[contractAddress];\n energizeEnabled = _nftActionPerms[contractAddress].hasBit(PERM_CHARGE_NFT);\n restrictedAssets = _nftActionPerms[contractAddress].hasBit(PERM_RESTRICTED_ASSETS);\n validAsset = _nftAllowedAssetTokens[contractAddress][assetToken];\n depositCap = _depositCap[assetToken];\n depositMin = _nftDepositMin[contractAddress][assetToken];\n depositMax = _nftDepositMax[contractAddress][assetToken];\n invalidAsset = _invalidAssets[assetToken];\n }\n\n function getNftAssetRequirements(address contractAddress, address nftTokenAddress)\n external\n view\n override\n virtual\n returns (string memory requiredBasketManager, bool basketEnabled, uint256 maxNfts)\n {\n requiredBasketManager = _nftRequiredBasketManager[contractAddress];\n basketEnabled = _nftActionPerms[contractAddress].hasBit(PERM_BASKET_NFT);\n maxNfts = _nftMaxNfts[contractAddress][nftTokenAddress];\n }\n\n\n /***********************************|\n | Only NFT Creator |\n |__________________________________*/\n\n /// @notice Sets the Custom Configuration for Creators of Proton-based NFTs\n /// @param contractAddress The Address to the Proton-based NFT to configure\n /// @param tokenId The token ID of the Proton-based NFT to configure\n /// @param creator The creator of the Proton-based NFT\n /// @param annuityPercent The percentage of interest-annuities to reserve for the creator\n function setCreatorAnnuities(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent\n )\n external\n virtual\n override\n {\n require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), \"CP:E-104\");\n _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent);\n }\n\n /// @notice Sets a Custom Receiver Address for the Creator Annuities\n /// @param contractAddress The Address to the Proton-based NFT to configure\n /// @param tokenId The token ID of the Proton-based NFT to configure\n /// @param receiver The receiver of the Creator interest-annuities\n function setCreatorAnnuitiesRedirect(\n address contractAddress,\n uint256 tokenId,\n address receiver\n )\n external\n virtual\n override\n {\n require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), \"CP:E-104\");\n _setCreatorAnnuitiesRedirect(contractAddress, tokenId, receiver);\n }\n\n\n /***********************************|\n | Register Contract Settings |\n |(For External Contract Integration)|\n |__________________________________*/\n\n /// @notice Sets a Required Wallet-Manager for External NFT Contracts (otherwise set to \"none\" to allow any Wallet-Manager)\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param walletManager If set, will only allow deposits from this specific Wallet-Manager\n function setRequiredWalletManager(\n address contractAddress,\n string calldata walletManager\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (keccak256(bytes(walletManager)) == keccak256(bytes(\"none\"))) {\n _nftRequiredWalletManager[contractAddress] = \"\";\n } else {\n _nftRequiredWalletManager[contractAddress] = walletManager;\n }\n\n emit RequiredWalletManagerSet(\n contractAddress,\n walletManager\n );\n }\n\n /// @notice Sets a Required Basket-Manager for External NFT Contracts (otherwise set to \"none\" to allow any Basket-Manager)\n /// @param contractAddress The Address to the External Contract to configure\n /// @param basketManager If set, will only allow deposits from this specific Basket-Manager\n function setRequiredBasketManager(\n address contractAddress,\n string calldata basketManager\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (keccak256(bytes(basketManager)) == keccak256(bytes(\"none\"))) {\n _nftRequiredBasketManager[contractAddress] = \"\";\n } else {\n _nftRequiredBasketManager[contractAddress] = basketManager;\n }\n\n emit RequiredBasketManagerSet(\n contractAddress,\n basketManager\n );\n }\n\n /// @notice Enables or Disables Asset-Token Restrictions for External NFT Contracts\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param restrictionsEnabled If set, will only allow deposits from Allowed Asset Tokens\n function setAssetTokenRestrictions(\n address contractAddress,\n bool restrictionsEnabled\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (restrictionsEnabled) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_RESTRICTED_ASSETS);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_RESTRICTED_ASSETS);\n }\n\n emit AssetTokenRestrictionsSet(\n contractAddress,\n restrictionsEnabled\n );\n }\n\n /// @notice Enables or Disables Allowed Asset Tokens for External NFT Contracts\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param assetToken The Address of the Asset Token to Allow or Disallow\n /// @param isAllowed True if the Asset Token is allowed\n function setAllowedAssetToken(\n address contractAddress,\n address assetToken,\n bool isAllowed\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftAllowedAssetTokens[contractAddress][assetToken] = isAllowed;\n\n emit AllowedAssetTokenSet(\n contractAddress,\n assetToken,\n isAllowed\n );\n }\n\n /// @notice Sets the Custom Configuration for External Contracts\n /// @param contractAddress The Address to the External Contract to configure\n /// @param assetToken The address of the Asset Token to set Limits for\n /// @param depositMin If set, will define the minimum amount of Asset tokens the NFT may hold, otherwise any amount\n /// @param depositMax If set, will define the maximum amount of Asset tokens the NFT may hold, otherwise any amount\n function setAssetTokenLimits(\n address contractAddress,\n address assetToken,\n uint256 depositMin,\n uint256 depositMax\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftDepositMin[contractAddress][assetToken] = depositMin;\n _nftDepositMax[contractAddress][assetToken] = depositMax;\n\n emit AssetTokenLimitsSet(\n contractAddress,\n assetToken,\n depositMin,\n depositMax\n );\n }\n\n /// @notice Sets the Max Number of NFTs that can be held by a Charged Particle NFT\n /// @param contractAddress The Address to the External Contract to configure\n /// @param nftTokenAddress The address of the NFT Token to set a Max for\n /// @param maxNfts The maximum numbers of NFTs that can be held by a given NFT (0 = unlimited)\n function setMaxNfts(\n address contractAddress,\n address nftTokenAddress,\n uint256 maxNfts\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftMaxNfts[contractAddress][nftTokenAddress] = maxNfts;\n\n emit MaxNftsSet(\n contractAddress,\n nftTokenAddress,\n maxNfts\n );\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n function setAssetInvalidity(address assetToken, bool invalidity) external virtual override onlyOwner {\n _invalidAssets[assetToken] = invalidity;\n emit AssetInvaliditySet(assetToken, invalidity);\n }\n\n function setDepositCap(address assetToken, uint256 cap) external virtual onlyOwner {\n _depositCap[assetToken] = cap;\n emit DepositCapSet(assetToken, cap);\n }\n\n function setTempLockExpiryBlocks(uint256 numBlocks) external virtual onlyOwner {\n _tempLockExpiryBlocks = numBlocks;\n emit TempLockExpirySet(numBlocks);\n }\n\n function enableNftContracts(address[] calldata contracts) external override virtual onlyOwner {\n uint count = contracts.length;\n for (uint i = 0; i < count; i++) {\n address tokenContract = contracts[i];\n _setPermsForCharge(tokenContract, true);\n _setPermsForBasket(tokenContract, true);\n _setPermsForTimelockSelf(tokenContract, true);\n }\n }\n\n function migrateToken(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent,\n address annuityReceiver\n )\n external\n onlyOwner\n {\n _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent);\n if (annuityReceiver != address(0)) {\n _setCreatorAnnuitiesRedirect(contractAddress, tokenId, annuityReceiver);\n }\n }\n\n /// @dev Update the list of NFT contracts that can be Charged\n function setPermsForCharge(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForCharge(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can hold other NFTs\n function setPermsForBasket(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForBasket(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection\n function setPermsForTimelockAny(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForTimelockAny(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock their own tokens\n function setPermsForTimelockSelf(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForTimelockSelf(contractAddress, state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Update the list of NFT contracts that can be Charged\n function _setPermsForCharge(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_CHARGE_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_CHARGE_NFT);\n }\n emit PermsSetForCharge(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can hold other NFTs\n function _setPermsForBasket(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_BASKET_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_BASKET_NFT);\n }\n emit PermsSetForBasket(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection\n function _setPermsForTimelockAny(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_ANY_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_ANY_NFT);\n }\n emit PermsSetForTimelockAny(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock their own tokens\n function _setPermsForTimelockSelf(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_OWN_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_OWN_NFT);\n }\n emit PermsSetForTimelockSelf(contractAddress, state);\n }\n\n /// @dev see setCreatorAnnuities()\n function _setCreatorAnnuities(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent\n )\n internal\n virtual\n {\n require(annuityPercent <= MAX_ANNUITIES, \"CP:E-421\");\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Update Configs for External Token Creator\n _creatorAnnuityPercent[tokenUuid] = annuityPercent;\n\n emit TokenCreatorConfigsSet(\n contractAddress,\n tokenId,\n creator,\n annuityPercent\n );\n }\n\n /// @dev see setCreatorAnnuitiesRedirect()\n function _setCreatorAnnuitiesRedirect(\n address contractAddress,\n uint256 tokenId,\n address receiver\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _creatorAnnuityRedirect[tokenUuid] = receiver;\n emit TokenCreatorAnnuitiesRedirected(contractAddress, tokenId, receiver);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyValidExternalContract(address contractAddress) {\n require(contractAddress.isContract(), \"CP:E-420\");\n _;\n }\n\n modifier onlyContractOwnerOrAdmin(address contractAddress, address sender) {\n require(sender == owner() || contractAddress.isContractOwner(sender), \"CP:E-103\");\n _;\n }\n}\n" + }, + "contracts/v1/ChargedState.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedState.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/RelayRecipient.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Settings Contract\n */\ncontract ChargedState is\n IChargedState,\n Initializable,\n OwnableUpgradeable,\n RelayRecipient,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using Bitwise for uint32;\n\n // NftState - actionPerms\n uint32 constant internal PERM_RESTRICT_ENERGIZE_FROM_ALL = 1; // NFTs that have Restrictions on Energize\n uint32 constant internal PERM_ALLOW_DISCHARGE_FROM_ALL = 2; // NFTs that allow Discharge by anyone\n uint32 constant internal PERM_ALLOW_RELEASE_FROM_ALL = 4; // NFTs that allow Release by anyone\n uint32 constant internal PERM_RESTRICT_BOND_FROM_ALL = 8; // NFTs that have Restrictions on Covalent Bonds\n uint32 constant internal PERM_ALLOW_BREAK_BOND_FROM_ALL = 16; // NFTs that allow Breaking Covalent Bonds by anyone\n\n IChargedSettings internal _chargedSettings;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // NftTimelocks\n /// @dev discharge unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftDischargeTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftDischargeTimelockLockedBy;\n\n /// @dev release unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftReleaseTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftReleaseTimelockLockedBy;\n\n /// @dev release unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftBreakBondTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftBreakBondTimelockLockedBy;\n\n // NftState\n /// @dev maps nft by tokenId to actionPermissions uint32 which is a composite of all possible NftState - actionPerms\n mapping (uint256 => uint32) internal _nftActionPerms;\n\n /// @dev maps nft by tokenId to its tempLockExpiry\n mapping (uint256 => uint256) internal _nftTempLockExpiry;\n\n /// @dev maps tokenId to user address to operator address for approving various actions\n mapping (uint256 => mapping(address => address)) internal _nftDischargeApproval;\n mapping (uint256 => mapping(address => address)) internal _nftReleaseApproval;\n mapping (uint256 => mapping(address => address)) internal _nftBreakBondApproval;\n mapping (uint256 => mapping(address => address)) internal _nftTimelockApproval;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftDischargeTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftDischargeTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftReleaseTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftReleaseTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftBreakBondTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftBreakBondTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n\n /// @notice Checks if an operator is allowed to Discharge a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForDischarge(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Release a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForRelease(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Break Covalent Bonds on a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForBreakBond(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Timelock a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForTimelock(contractAddress, tokenId, operator);\n }\n\n\n function isEnergizeRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n }\n\n\n function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_BOND_FROM_ALL);\n }\n\n\n function getDischargeState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n isApproved = _isApprovedForDischarge(contractAddress, tokenId, sender);\n timelock = _nftDischargeTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n function getReleaseState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_RELEASE_FROM_ALL);\n isApproved = _isApprovedForRelease(contractAddress, tokenId, sender);\n timelock = _nftReleaseTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n function getBreakBondState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n isApproved = _isApprovedForBreakBond(contractAddress, tokenId, sender);\n timelock = _nftBreakBondTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n\n /***********************************|\n | Only NFT Owner/Operator |\n |__________________________________*/\n\n /// @notice Sets an Operator as Approved to Discharge a specific Token\n /// This allows an operator to withdraw the interest-portion only\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setDischargeApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Release a specific Token\n /// This allows an operator to withdraw the principal + interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setReleaseApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token\n /// This allows an operator to withdraw Basket NFTs\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setBreakBondApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Timelock a specific Token\n /// This allows an operator to timelock the principal or interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setTimelockApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Discharge/Release/Timelock a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setApprovalForAll(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @dev Updates Restrictions on Energizing an NFT\n function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForRestrictCharge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowDischarge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowRelease(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Restrictions on Covalent Bonds on an NFT\n function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForRestrictBond(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone\n function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowBreakBond(contractAddress, tokenId, state);\n }\n\n /// @notice Sets a Timelock on the ability to Discharge the Interest of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setDischargeTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftDischargeTimelockLockedBy[tokenUuid] == sender) {\n delete _nftDischargeTimelockUnlockBlock[tokenUuid];\n delete _nftDischargeTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftDischargeTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftDischargeTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftDischargeTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenDischargeTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n /// @notice Sets a Timelock on the ability to Release the Assets of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setReleaseTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftReleaseTimelockLockedBy[tokenUuid] == sender) {\n delete _nftReleaseTimelockUnlockBlock[tokenUuid];\n delete _nftReleaseTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftReleaseTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftReleaseTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftReleaseTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenReleaseTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n /// @notice Sets a Timelock on the ability to Break the Covalent Bond of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setBreakBondTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftBreakBondTimelockLockedBy[tokenUuid] == sender) {\n delete _nftBreakBondTimelockUnlockBlock[tokenUuid];\n delete _nftBreakBondTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftBreakBondTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftBreakBondTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftBreakBondTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenBreakBondTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n\n /***********************************|\n | Only NFT Contract |\n |__________________________________*/\n\n /// @notice Sets a Temporary-Lock on the ability to Release/Discharge the Assets of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param isLocked The locked state; contracts are expected to disable this lock before expiry\n function setTemporaryLock(\n address contractAddress,\n uint256 tokenId,\n bool isLocked\n )\n external\n override\n virtual\n {\n require(msg.sender == contractAddress, \"CP:E-112\");\n\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n uint256 unlockBlock;\n if (isLocked && _nftTempLockExpiry[tokenUuid] == 0) {\n unlockBlock = block.number.add(_chargedSettings.getTempLockExpiryBlocks());\n _nftTempLockExpiry[tokenUuid] = unlockBlock;\n }\n if (!isLocked) {\n _nftTempLockExpiry[tokenUuid] = 0;\n }\n\n emit TokenTempLock(contractAddress, tokenId, unlockBlock);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n function migrateToken(\n address contractAddress,\n uint256 tokenId,\n uint256 releaseTimelockExpiry,\n address releaseTimelockLockedBy,\n uint256 tempLockExpiry\n )\n external\n onlyOwner\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (releaseTimelockExpiry > block.number && releaseTimelockLockedBy != address(0)) {\n _nftReleaseTimelockUnlockBlock[tokenUuid] = releaseTimelockExpiry;\n _nftReleaseTimelockLockedBy[tokenUuid] = releaseTimelockLockedBy;\n emit TokenReleaseTimelock(contractAddress, tokenId, releaseTimelockLockedBy, releaseTimelockExpiry);\n }\n\n if (tempLockExpiry > 0) {\n _nftTempLockExpiry[tokenUuid] = tempLockExpiry;\n emit TokenTempLock(contractAddress, tokenId, tempLockExpiry);\n }\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev See {ChargedParticles-isApprovedForDischarge}.\n function _isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftDischargeApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForRelease}.\n function _isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftReleaseApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForBreakBond}.\n function _isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftBreakBondApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForTimelock}.\n function _isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n (bool timelockAny, bool timelockOwn) = _chargedSettings.getTimelockApprovals(operator);\n if (timelockAny || (timelockOwn && contractAddress == operator)) { return true; }\n\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return tokenOwner == operator || _nftTimelockApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @notice Sets an Operator as Approved to Discharge a specific Token\n /// This allows an operator to withdraw the interest-portion only\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setDischargeApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftDischargeApproval[tokenUuid][tokenOwner] = operator;\n emit DischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Release a specific Token\n /// This allows an operator to withdraw the principal + interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setReleaseApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftReleaseApproval[tokenUuid][tokenOwner] = operator;\n emit ReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token\n /// This allows an operator to withdraw Basket NFTs\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setBreakBondApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftBreakBondApproval[tokenUuid][tokenOwner] = operator;\n emit BreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Timelock a specific Token\n /// This allows an operator to timelock the principal or interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setTimelockApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftTimelockApproval[tokenUuid][tokenOwner] = operator;\n emit TimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @dev Updates Restrictions on Energizing an NFT\n function _setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n }\n emit PermsSetForRestrictCharge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function _setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n }\n emit PermsSetForAllowDischarge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function _setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_RELEASE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_RELEASE_FROM_ALL);\n }\n emit PermsSetForAllowRelease(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Restrictions on Covalent Bonds on an NFT\n function _setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_BOND_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_BOND_FROM_ALL);\n }\n emit PermsSetForRestrictBond(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone\n function _setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n }\n emit PermsSetForAllowBreakBond(contractAddress, tokenId, state);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) {\n require(_tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender), \"CP:E-105\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/CommunityVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract CommunityVault is Ownable, BlackholePrevention {\n\n IERC20 private immutable _ionx;\n\n constructor (address ionx) public {\n _ionx = IERC20(ionx);\n }\n\n event SetAllowance(address indexed caller, address indexed spender, uint256 amount);\n\n function setAllowance(address spender, uint amount) public onlyOwner {\n _ionx.approve(spender, amount);\n\n emit SetAllowance(msg.sender, spender, amount);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens other than IONX, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n require(tokenAddress != address(_ionx), \"CommunityVault: cannot withdraw IONX\");\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n}" + }, + "contracts/v1/incentives/MerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_) public {\n token = token_;\n merkleRoot = merkleRoot_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), 'MerkleDistributor: Drop already claimed.');\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), 'MerkleDistributor: Invalid proof.');\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), 'MerkleDistributor: Transfer failed.');\n\n emit Claimed(index, account, amount);\n }\n}\n" + }, + "contracts/v1/incentives/MerkleDistributor2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor2 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"MerkleDistributor2: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"MerkleDistributor2: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor2: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"MerkleDistributor2: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"MerkleDistributor2: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"MerkleDistributor2: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/MerkleDistributor3.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor3 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"MerkleDistributor3: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"MerkleDistributor3: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor3: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"MerkleDistributor3: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"MerkleDistributor3: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"MerkleDistributor3: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/RewardProgram.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// RewardProgram.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/IRewardProgram.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/introspection/IERC165.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"../interfaces/IUniverseRP.sol\";\nimport \"../interfaces/IChargedManagers.sol\";\nimport \"../interfaces/IWalletManager.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IERC20Detailed.sol\";\n\ncontract RewardProgram is\n IRewardProgram,\n BlackholePrevention,\n IERC165,\n ReentrancyGuard,\n IERC721Receiver,\n IERC1155Receiver\n{\n using SafeMath for uint256;\n using TokenInfo for address;\n using SafeERC20 for IERC20;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n\n address private _owner;\n IUniverseRP private _universe;\n IChargedManagers private _chargedManagers;\n ProgramRewardData private _programData;\n mapping(uint256 => AssetStake) private _assetStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public {}\n\n function initialize(\n address stakingToken,\n address rewardToken,\n uint256 baseMultiplier,\n address chargedManagers,\n address universe,\n address owner\n ) external override {\n require(_owner == address(0x0), \"Already initialized\");\n _owner = owner;\n\n // Prepare Reward Program\n _programData.stakingToken = stakingToken;\n _programData.rewardToken = rewardToken;\n _programData.baseMultiplier = baseMultiplier; // Basis Points\n\n // Connect to Charged Particles\n _chargedManagers = IChargedManagers(chargedManagers);\n _universe = IUniverseRP(universe);\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getProgramData() external view override returns (ProgramRewardData memory) {\n return _programData;\n }\n\n function getAssetStake(uint256 parentNftUuid) external view override returns (AssetStake memory) {\n return _assetStake[parentNftUuid];\n }\n\n function getFundBalance() external view override returns (uint256) {\n return _getFundBalance();\n }\n\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) public view override returns (uint256) {\n return _calculateRewardsEarned(parentNftUuid, interestAmount);\n }\n\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n return _assetStake[parentNftUuid].claimableRewards;\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\n return \"\";\n }\n\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(IERC165)\n returns (bool)\n {\n // default interface support\n if (\n interfaceId == type(IERC721Receiver).interfaceId ||\n interfaceId == type(IERC1155Receiver).interfaceId ||\n interfaceId == type(IERC165).interfaceId\n ) {\n return true;\n }\n }\n\n function owner() public view returns (address) {\n return _owner;\n }\n\n\n /***********************************|\n | Only Universe |\n |__________________________________*/\n\n function registerAssetDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n uint256 principalAmount\n )\n external\n override\n onlyUniverse\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n if (assetStake.start == 0) {\n assetStake.start = block.number;\n assetStake.walletManagerId = walletManagerId;\n }\n emit AssetDeposit(contractAddress, tokenId, walletManagerId, principalAmount);\n }\n\n function registerAssetRelease(\n address contractAddress,\n uint256 tokenId,\n uint256 interestAmount\n )\n external\n override\n onlyUniverse\n nonReentrant\n returns (uint256 rewards)\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n // Update Claimable Rewards\n uint256 newRewards = _calculateRewardsEarned(parentNftUuid, interestAmount);\n assetStake.claimableRewards = assetStake.claimableRewards.add(newRewards);\n\n // Reset Stake if Principal Balance falls to Zero\n IWalletManager walletMgr = _chargedManagers.getWalletManager(assetStake.walletManagerId);\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\n if (principal == 0) {\n assetStake.start = 0;\n }\n\n // Issue Rewards to NFT Owner\n rewards = _claimRewards(contractAddress, tokenId);\n\n emit AssetRelease(contractAddress, tokenId, interestAmount);\n }\n\n\n /***********************************|\n | Reward Calculation |\n |__________________________________*/\n\n function _calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) internal view returns (uint256 totalReward) {\n uint256 baseReward = _calculateBaseReward(interestAmount);\n uint256 leptonMultipliedReward = _calculateMultipliedReward(parentNftUuid, baseReward);\n totalReward = _convertDecimals(leptonMultipliedReward);\n }\n\n function _calculateBaseReward(uint256 amount) internal view returns(uint256 baseReward) {\n baseReward = amount.mul(_programData.baseMultiplier).div(PERCENTAGE_SCALE);\n }\n\n function _calculateMultipliedReward(uint256 parentNftUuid, uint256 baseReward) internal view returns(uint256) {\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n if (assetStake.start == 0) { return baseReward; }\n\n IUniverseRP.NftStake memory nftStake = _universe.getNftStake(parentNftUuid);\n uint256 multiplierBP = nftStake.multiplier;\n\n uint256 assetDepositLength = block.number.sub(assetStake.start);\n uint256 nftDepositLength = 0;\n if (nftStake.releaseBlockNumber > 0) {\n nftDepositLength = nftStake.releaseBlockNumber.sub(nftStake.depositBlockNumber);\n } else {\n nftDepositLength = block.number.sub(nftStake.depositBlockNumber);\n }\n\n if (multiplierBP == 0 || nftDepositLength == 0 || assetDepositLength == 0) {\n return baseReward;\n }\n\n if (nftDepositLength > assetDepositLength) {\n nftDepositLength = assetDepositLength;\n }\n\n // Percentage of the total program that the Multiplier Nft was deposited for\n uint256 nftRewardRatioBP = nftDepositLength.mul(PERCENTAGE_SCALE).div(assetDepositLength);\n\n // Amount of reward that the Multiplier Nft is responsible for\n uint256 amountGeneratedDuringNftDeposit = baseReward.mul(nftRewardRatioBP).div(PERCENTAGE_SCALE);\n\n // Amount of Multiplied Reward from NFT\n uint256 multipliedReward = amountGeneratedDuringNftDeposit.mul(multiplierBP.mul(LEPTON_MULTIPLIER_SCALE)).div(PERCENTAGE_SCALE);\n\n // Amount of Base Reward without Multiplied NFT Rewards\n uint256 amountGeneratedWithoutNftDeposit = baseReward.sub(amountGeneratedDuringNftDeposit);\n\n // Amount of Base Rewards + Multiplied NFT Rewards\n return amountGeneratedWithoutNftDeposit.add(multipliedReward);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function fundProgram(uint256 amount) external onlyOwner {\n require(_programData.rewardToken != address(0), \"RP:E-405\");\n IERC20(_programData.rewardToken).safeTransferFrom(msg.sender, address(this), amount);\n emit RewardProgramFunded(amount);\n }\n\n function setStakingToken(address newStakingToken) external onlyOwner {\n _programData.stakingToken = newStakingToken;\n }\n\n function setRewardToken(address newRewardToken) external onlyOwner {\n _programData.rewardToken = newRewardToken;\n }\n\n function setBaseMultiplier(uint256 newMultiplier) external onlyOwner {\n _programData.baseMultiplier = newMultiplier; // Basis Points\n }\n\n function setChargedManagers(address manager) external onlyOwner {\n _chargedManagers = IChargedManagers(manager);\n }\n\n function setUniverse(address universe) external onlyOwner {\n _universe = IUniverseRP(universe);\n }\n\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external override onlyOwner {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n\n // Initiate Asset Stake\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\n if (principal > 0) {\n _assetStake[parentNftUuid] = AssetStake(block.number, 0, walletManagerId);\n emit AssetRegistered(contractAddress, tokenId, walletManagerId, principal);\n }\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _claimRewards(\n address contractAddress,\n uint256 tokenId\n )\n internal\n returns (uint256 totalReward)\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n // Rewards Receiver\n address receiver = IERC721(contractAddress).ownerOf(tokenId);\n\n // Ensure Reward Pool has Sufficient Balance\n totalReward = assetStake.claimableRewards;\n uint256 fundBalance = _getFundBalance();\n uint256 unavailReward = totalReward > fundBalance ? totalReward.sub(fundBalance) : 0;\n\n // Determine amount of Rewards to Transfer\n if (unavailReward > 0) {\n totalReward = totalReward.sub(unavailReward);\n emit RewardProgramOutOfFunds();\n }\n\n // Update Asset Stake\n assetStake.claimableRewards = unavailReward;\n\n if (totalReward > 0) {\n // Transfer Available Rewards to Receiver\n IERC20(_programData.rewardToken).safeTransfer(receiver, totalReward);\n }\n\n emit RewardsClaimed(contractAddress, tokenId, receiver, totalReward, unavailReward);\n }\n\n function _convertDecimals(uint256 reward) internal view returns (uint256) {\n uint8 stakingTokenDecimals = IERC20Detailed(_programData.stakingToken).decimals();\n return reward.mul(10**(18 - uint256(stakingTokenDecimals)));\n }\n\n function _getFundBalance() internal view returns (uint256) {\n return IERC20Detailed(_programData.rewardToken).balanceOf(address(this));\n }\n\n\n modifier onlyOwner() {\n require(_owner == msg.sender, \"Caller is not the owner\");\n _;\n }\n\n modifier onlyUniverse() {\n require(msg.sender == address(_universe), \"RP:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/RewardProgramFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// RewardProgramFactory.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport \"./RewardProgram.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract RewardProgramFactory is BlackholePrevention, Ownable {\n event RewardProgramCreated(address indexed rewardProgram);\n\n address public _template;\n\n constructor () public {\n _template = address(new RewardProgram());\n }\n\n // function _msgSender() internal view override returns (address payable) {\n // return msg.sender;\n // }\n\n function createRewardProgram(\n address stakingToken,\n address rewardToken,\n uint256 baseMultiplier,\n address chargedManagers,\n address universe\n )\n external\n onlyOwner\n returns (address)\n {\n address newRewardProgram = _createClone(_template);\n RewardProgram rewardProgram = RewardProgram(newRewardProgram);\n rewardProgram.initialize(stakingToken, rewardToken, baseMultiplier, chargedManagers, universe, _msgSender());\n emit RewardProgramCreated(newRewardProgram);\n return newRewardProgram;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n}\n" + }, + "contracts/v1/incentives/Staking.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/Staking2.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking2 is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/Staking3.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking3 is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/YieldFarm.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/incentives/YieldFarm2.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm2 is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/incentives/YieldFarm3.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm3 is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/interfaces/IAaveBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IAaveBridge.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n\ninterface IAaveBridge {\n function getReserveInterestToken(address assetToken) external view returns (address aTokenAddress);\n function isReserveActive(address assetToken) external view returns (bool);\n\n function getTotalBalance(address account, address assetToken) external view returns (uint256);\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(address receiver, address assetToken, uint256 assetAmount) external;\n}\n" + }, + "contracts/v1/interfaces/IBaseProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IBaseProton is IERC721 {\n event PausedStateSet(bool isPaused);\n event SalePriceSet(uint256 indexed tokenId, uint256 salePrice);\n event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct);\n event FeesWithdrawn(address indexed receiver, uint256 amount);\n event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties);\n event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view returns (address);\n function getSalePrice(uint256 tokenId) external view returns (uint256);\n function getLastSellPrice(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyalties(address account) external view returns (uint256);\n function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address);\n\n function buyProton(uint256 tokenId, uint256 gasLimit) external payable returns (bool);\n function claimCreatorRoyalties() external returns (uint256);\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n ) external returns (uint256 newTokenId);\n\n function createProtons(\n address creator,\n address receiver,\n string[] calldata tokenMetaUris\n ) external returns (bool);\n\n function createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n ) external returns (bool);\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice) external;\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external;\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external;\n}" + }, + "contracts/v1/interfaces/IBasketManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Particle Basket Manager interface\n * @dev The basket-manager for underlying assets attached to Charged Particles\n * @dev Manages the link between NFTs and their respective Smart-Baskets\n */\ninterface IBasketManager {\n\n event ControllerSet(address indexed controller);\n event ExecutorSet(address indexed executor);\n event PausedStateSet(bool isPaused);\n event NewSmartBasket(address indexed contractAddress, uint256 indexed tokenId, address indexed smartBasket);\n event BasketAdd(address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\n event BasketRemove(address indexed receiver, address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\n event BasketRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\n event RewardProgramSet(address indexed rewardProgram);\n\n function isPaused() external view returns (bool);\n\n function getTokenTotalCount(address contractAddress, uint256 tokenId) external view returns (uint256);\n function getTokenCountByType(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (uint256);\n\n function prepareTransferAmount(uint256 nftTokenAmount) external;\n function addToBasket(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function getBasketAddressById(address contractAddress, uint256 tokenId) external returns (address);\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/IChargedManagers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IWalletManager.sol\";\nimport \"./IBasketManager.sol\";\n\n/**\n * @notice Interface for Charged Wallet-Managers\n */\ninterface IChargedManagers {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function isContractOwner(address contractAddress, address account) external view returns (bool);\n\n // ERC20\n function isWalletManagerEnabled(string calldata walletManagerId) external view returns (bool);\n function getWalletManager(string calldata walletManagerId) external view returns (IWalletManager);\n\n // ERC721\n function isNftBasketEnabled(string calldata basketId) external view returns (bool);\n function getBasketManager(string calldata basketId) external view returns (IBasketManager);\n\n // Validation\n function validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external;\n function validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external;\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external;\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event WalletManagerRegistered(string indexed walletManagerId, address indexed walletManager);\n event BasketManagerRegistered(string indexed basketId, address indexed basketManager);\n}\n" + }, + "contracts/v1/interfaces/IChargedParticles.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Charged Particles\n */\ninterface IChargedParticles {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getStateAddress() external view returns (address stateAddress);\n function getSettingsAddress() external view returns (address settingsAddress);\n function getManagersAddress() external view returns (address managersAddress);\n\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\n\n /***********************************|\n | Particle Mechanics |\n |__________________________________*/\n\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n ) external returns (uint256 yieldTokensAmount);\n\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 receiverAmount);\n\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositFeeSet(uint256 depositFee);\n event ProtocolFeesCollected(address indexed assetToken, uint256 depositAmount, uint256 feesCollected);\n}\n" + }, + "contracts/v1/interfaces/IChargedSettings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IWalletManager.sol\";\nimport \"./IBasketManager.sol\";\n\n/**\n * @notice Interface for Charged Settings\n */\ninterface IChargedSettings {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n // function isContractOwner(address contractAddress, address account) external view returns (bool);\n function getCreatorAnnuities(address contractAddress, uint256 tokenId) external returns (address creator, uint256 annuityPct);\n function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId) external view returns (address);\n function getTempLockExpiryBlocks() external view returns (uint256);\n function getTimelockApprovals(address operator) external view returns (bool timelockAny, bool timelockOwn);\n function getAssetRequirements(\n address contractAddress,\n address assetToken\n ) external view returns (\n string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n );\n function getNftAssetRequirements(\n address contractAddress,\n address nftTokenAddress\n ) external view returns (\n string memory requiredBasketManager,\n bool basketEnabled,\n uint256 maxNfts\n );\n\n /***********************************|\n | Only NFT Creator |\n |__________________________________*/\n\n function setCreatorAnnuities(address contractAddress, uint256 tokenId, address creator, uint256 annuityPercent) external;\n function setCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId, address receiver) external;\n\n\n /***********************************|\n | Only NFT Contract Owner |\n |__________________________________*/\n\n function setRequiredWalletManager(address contractAddress, string calldata walletManager) external;\n function setRequiredBasketManager(address contractAddress, string calldata basketManager) external;\n function setAssetTokenRestrictions(address contractAddress, bool restrictionsEnabled) external;\n function setAllowedAssetToken(address contractAddress, address assetToken, bool isAllowed) external;\n function setAssetTokenLimits(address contractAddress, address assetToken, uint256 depositMin, uint256 depositMax) external;\n function setMaxNfts(address contractAddress, address nftTokenAddress, uint256 maxNfts) external;\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAssetInvalidity(address assetToken, bool invalidity) external;\n function enableNftContracts(address[] calldata contracts) external;\n function setPermsForCharge(address contractAddress, bool state) external;\n function setPermsForBasket(address contractAddress, bool state) external;\n function setPermsForTimelockAny(address contractAddress, bool state) external;\n function setPermsForTimelockSelf(address contractAddress, bool state) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositCapSet(address assetToken, uint256 depositCap);\n event TempLockExpirySet(uint256 expiryBlocks);\n\n event RequiredWalletManagerSet(address indexed contractAddress, string walletManager);\n event RequiredBasketManagerSet(address indexed contractAddress, string basketManager);\n event AssetTokenRestrictionsSet(address indexed contractAddress, bool restrictionsEnabled);\n event AllowedAssetTokenSet(address indexed contractAddress, address assetToken, bool isAllowed);\n event AssetTokenLimitsSet(address indexed contractAddress, address assetToken, uint256 assetDepositMin, uint256 assetDepositMax);\n event MaxNftsSet(address indexed contractAddress, address indexed nftTokenAddress, uint256 maxNfts);\n event AssetInvaliditySet(address indexed assetToken, bool invalidity);\n\n event TokenCreatorConfigsSet(address indexed contractAddress, uint256 indexed tokenId, address indexed creatorAddress, uint256 annuityPercent);\n event TokenCreatorAnnuitiesRedirected(address indexed contractAddress, uint256 indexed tokenId, address indexed redirectAddress);\n\n event PermsSetForCharge(address indexed contractAddress, bool state);\n event PermsSetForBasket(address indexed contractAddress, bool state);\n event PermsSetForTimelockAny(address indexed contractAddress, bool state);\n event PermsSetForTimelockSelf(address indexed contractAddress, bool state);\n}\n" + }, + "contracts/v1/interfaces/IChargedState.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IChargedSettings.sol\";\n\n/**\n * @notice Interface for Charged State\n */\ninterface IChargedState {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n\n function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n\n function isEnergizeRestricted(address contractAddress, uint256 tokenId) external view returns (bool);\n function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external view returns (bool);\n\n function getDischargeState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n function getReleaseState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n function getBreakBondState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n\n /***********************************|\n | Only NFT Owner/Operator |\n |__________________________________*/\n\n function setDischargeApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setReleaseApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setBreakBondApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setTimelockApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setApprovalForAll(address contractAddress, uint256 tokenId, address operator) external;\n\n function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) external;\n\n function setDischargeTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n function setReleaseTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n function setBreakBondTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n /***********************************|\n | Only NFT Contract |\n |__________________________________*/\n\n function setTemporaryLock(\n address contractAddress,\n uint256 tokenId,\n bool isLocked\n ) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n\n event DischargeApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event ReleaseApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event BreakBondApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event TimelockApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n\n event TokenDischargeTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenReleaseTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenBreakBondTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenTempLock(address indexed contractAddress, uint256 indexed tokenId, uint256 unlockBlock);\n\n event PermsSetForRestrictCharge(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowDischarge(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowRelease(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForRestrictBond(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowBreakBond(address indexed contractAddress, uint256 indexed tokenId, bool state);\n}\n" + }, + "contracts/v1/interfaces/IDai.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\ninterface IDai is IERC20Upgradeable {\n // --- Approve by signature ---\n function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external;\n function transferFrom(address src, address dst, uint wad) external override returns (bool);\n}" + }, + "contracts/v1/interfaces/IERC20Detailed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Detailed {\n function decimals() external view returns (uint8);\n function symbol() external view returns (string memory);\n function name() external view returns (string memory);\n\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(address sender, address recipient, uint256 amount) 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" + }, + "contracts/v1/interfaces/IERC721Chargeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IERC721Chargeable.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\n\ninterface IERC721Chargeable is IERC165Upgradeable {\n function owner() external view returns (address);\n function creatorOf(uint256 tokenId) external view returns (address);\n function balanceOf(address tokenOwner) external view returns (uint256 balance);\n function ownerOf(uint256 tokenId) external view returns (address tokenOwner);\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n function transferFrom(address from, address to, uint256 tokenId) external;\n function approve(address to, uint256 tokenId) external;\n function getApproved(uint256 tokenId) external view returns (address operator);\n function setApprovalForAll(address operator, bool _approved) external;\n function isApprovedForAll(address tokenOwner, address operator) external view returns (bool);\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "contracts/v1/interfaces/ILepton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ILepton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Lepton Interface\n * @dev ...\n */\ninterface ILepton {\n\n struct Classification {\n string tokenUri;\n uint256 price;\n uint128 _upperBounds;\n uint32 supply;\n uint32 multiplier;\n uint32 bonus;\n }\n\n function mintLepton() external payable returns (uint256 newTokenId);\n function batchMintLepton(uint256 count) external payable;\n function getNextType() external view returns (uint256);\n function getNextPrice() external view returns (uint256);\n function getMultiplier(uint256 tokenId) external view returns (uint256);\n function getBonus(uint256 tokenId) external view returns (uint256);\n\n\n event MaxMintPerTxSet(uint256 maxAmount);\n event LeptonTypeAdded(string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\n event LeptonTypeUpdated(uint256 leptonIndex, string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\n event LeptonMinted(address indexed receiver, uint256 indexed tokenId, uint256 price, uint32 multiplier);\n event LeptonBatchMinted(address indexed receiver, uint256 indexed tokenId, uint256 count, uint256 price, uint32 multiplier);\n event PausedStateSet(bool isPaused);\n}\n" + }, + "contracts/v1/interfaces/IMerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.6.0;\n\n// Allows anyone to claim a token if they exist in a merkle root.\ninterface IMerkleDistributor {\n // Returns the address of the token distributed by this contract.\n function token() external view returns (address);\n // Returns the merkle root of the merkle tree containing account balances available to claim.\n function merkleRoot() external view returns (bytes32);\n // Returns true if the index has been marked claimed.\n function isClaimed(uint256 index) external view returns (bool);\n // Claim the given amount of the token to the given address. Reverts if the inputs are invalid.\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external;\n\n // This event is triggered whenever a call to #claim succeeds.\n event Claimed(uint256 index, address account, uint256 amount);\n}" + }, + "contracts/v1/interfaces/IParticleSplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IParticleSplitter.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Particle Splitter\n */\ninterface IParticleSplitter {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function executeForWallet(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address externalAddress,\n bytes memory encodedParams\n ) external payable returns (bytes memory);\n\n function executeForBasket(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address externalAddress,\n bytes memory encodedParams\n ) external payable returns (bytes memory);\n\n function withdrawWalletRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n ) external returns (uint256 amountWithdrawn);\n\n function withdrawBasketRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n ) external returns (uint256 amountWithdrawn);\n\n function refreshWalletPrincipal(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external;\n\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event ChargedManagersSet(address indexed chargedManagers);\n event TokenInfoProxySet(address indexed tokenInfoProxy);\n\n event ExecuteForWallet(\n address indexed contractAddress,\n uint256 tokenId,\n string walletManagerId,\n address indexed externalAddress,\n bytes encodedParams,\n uint256 ethValue\n );\n event ExecuteForBasket(\n address indexed contractAddress,\n uint256 tokenId,\n string basketManagerId,\n address indexed externalAddress,\n bytes encodedParams,\n uint256 ethValue\n );\n event PrincipalRefreshed(\n address contractAddress,\n uint256 tokenId,\n string walletManagerId,\n address assetToken\n );\n event PermsSetForExternal(\n address indexed contractAddress,\n bool state\n );\n}\n" + }, + "contracts/v1/interfaces/IProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IProton is IERC721 {\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n event PausedStateSet(bool isPaused);\n event SalePriceSet(uint256 indexed tokenId, uint256 salePrice);\n event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct);\n event FeesWithdrawn(address indexed receiver, uint256 amount);\n event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties);\n event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view returns (address);\n function getSalePrice(uint256 tokenId) external view returns (uint256);\n function getLastSellPrice(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyalties(address account) external view returns (uint256);\n function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address);\n\n function buyProton(uint256 tokenId) external payable returns (bool);\n function claimCreatorRoyalties() external returns (uint256);\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n ) external returns (uint256 newTokenId);\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n ) external returns (uint256 newTokenId);\n\n function batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n ) external;\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice) external;\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external;\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external;\n}" + }, + "contracts/v1/interfaces/IProtonB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IProtonB is IERC721 {\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n ) external returns (uint256 newTokenId);\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n}" + }, + "contracts/v1/interfaces/IRewardNft.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IRewardNft.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Reward-NFT Interface\n * @dev ...\n */\ninterface IRewardNft {\n function getMultiplier(uint256 tokenId) external view returns (uint256);\n function getBonus(uint256 tokenId) external view returns (uint256);\n}\n" + }, + "contracts/v1/interfaces/IRewardProgram.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IRewardProgram.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\ninterface IRewardProgram {\n /* admin events */\n event RewardProgramFunded(uint256 amount);\n event RewardProgramOutOfFunds();\n\n /* user events */\n event RewardsClaimed(address indexed contractAddress, uint256 tokenId, address indexed receiver, uint256 rewarded, uint256 remaining);\n\n event AssetRegistered(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\n event AssetDeposit(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\n event AssetRelease(address indexed contractAddress, uint256 tokenId, uint256 interestAmount);\n\n /* data types */\n struct ProgramRewardData {\n address stakingToken;\n address rewardToken;\n uint256 baseMultiplier; // Basis Points\n }\n\n struct AssetStake {\n uint256 start;\n uint256 claimableRewards;\n string walletManagerId;\n }\n\n function initialize(address stakingToken, address rewardToken, uint256 baseMultiplier, address chargedManagers, address universe, address owner) external;\n\n /* user functions */\n function getProgramData() external view returns (ProgramRewardData memory programData);\n function getAssetStake(uint256 uuid) external view returns (AssetStake memory);\n function getFundBalance() external view returns (uint256);\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) external view returns (uint256);\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external;\n function registerAssetDeposit(address contractAddress, uint256 tokenId, string calldata walletManagerId, uint256 principalAmount) external;\n function registerAssetRelease(address contractAddress, uint256 tokenId, uint256 interestAmount) external returns (uint256 rewards);\n}" + }, + "contracts/v1/interfaces/ISmartBasket.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartBasket.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Basket\n * @dev Manages holding and transferring NFTs within an NFT (if any),\n */\ninterface ISmartBasket {\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function addToBasket(address contractAddress, uint256 tokenId) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId) external returns (bool);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartBasketB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartBasketB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Basket \"B\"\n * @dev Manages holding and transferring NFTs within an NFT (if any),\n */\ninterface ISmartBasketB {\n function getNestedNftCount() external view returns (uint256);\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool);\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Wallet\n * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any),\n */\ninterface ISmartWallet {\n function getAssetTokenCount() external view returns (uint256);\n function getAssetTokenByIndex(uint256 index) external view returns (address);\n\n function setNftCreator(address creator, uint256 annuityPct) external;\n\n function isReserveActive(address assetToken) external view returns (bool);\n function getReserveInterestToken(address assetToken) external view returns (address);\n\n function getPrincipal(address assetToken) external returns (uint256);\n function getInterest(address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getTotal(address assetToken) external returns (uint256);\n function getRewards(address assetToken) external returns (uint256);\n\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(address receiver, address creatorRedirect, address assetToken) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function withdrawAmount(address receiver, address creatorRedirect, address assetToken, uint256 assetAmount) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function withdrawAmountForCreator(address receiver, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address assetToken) external;\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Wallet\n * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any),\n */\ninterface ISmartWalletB {\n function getAssetTokenCount() external view returns (uint256);\n function getAssetTokenByIndex(uint256 index) external view returns (address);\n\n function isReserveActive(address assetToken) external view returns (bool);\n function getReserveInterestToken(address assetToken) external view returns (address);\n\n function getPrincipal(address assetToken) external returns (uint256);\n function getInterest(address assetToken, uint256 creatorPct) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getTotal(address assetToken) external returns (uint256);\n function getRewards(address assetToken) external returns (uint256);\n\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken\n ) external returns (\n uint256 creatorAmount,\n uint256 receiverAmount\n );\n function withdrawAmount(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n ) external returns (\n uint256 creatorAmount,\n uint256 receiverAmount\n );\n function withdrawAmountForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n ) external returns (\n uint256 receiverAmount\n );\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address assetToken) external;\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/IStaking.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\ninterface IStaking {\n function manualEpochInit(address[] memory tokens, uint128 epochId) external;\n function getCurrentEpoch() external view returns (uint128);\n function getEpochId(uint timestamp) external view returns (uint); // get epoch id\n function getEpochUserBalance(address user, address token, uint128 epoch) external view returns(uint);\n function getEpochPoolSize(address token, uint128 epoch) external view returns (uint);\n function epoch1Start() external view returns (uint);\n function epochDuration() external view returns (uint);\n}" + }, + "contracts/v1/interfaces/ITokenInfoProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfoProxy.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\n\ninterface ITokenInfoProxy {\n\n event ContractFunctionSignatureSet(address indexed contractAddress, string fnName, bytes4 fnSig);\n\n struct FnSignatures {\n bytes4 ownerOf;\n bytes4 creatorOf;\n }\n\n function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external;\n function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external;\n\n function getTokenUUID(address contractAddress, uint256 tokenId) external pure returns (uint256);\n function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external returns (bool);\n function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external returns (bool);\n function getTokenOwner(address contractAddress, uint256 tokenId) external returns (address);\n function getTokenCreator(address contractAddress, uint256 tokenId) external returns (address);\n}\n" + }, + "contracts/v1/interfaces/IUniverse.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IUniverse.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Universal Controller interface\n * @dev ...\n */\ninterface IUniverse {\n\n event ChargedParticlesSet(address indexed chargedParticles);\n event PhotonSet(address indexed photonToken, uint256 maxSupply);\n event ProtonTokenSet(address indexed protonToken);\n event LeptonTokenSet(address indexed leptonToken);\n event QuarkTokenSet(address indexed quarkToken);\n event BosonTokenSet(address indexed bosonToken);\n event EsaMultiplierSet(address indexed assetToken, uint256 multiplier);\n event ElectrostaticAttraction(address indexed account, address photonSource, uint256 energy, uint256 multiplier);\n event ElectrostaticDischarge(address indexed account, address photonSource, uint256 energy);\n\n function onEnergize(\n address sender,\n address referrer,\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 assetEnergy\n ) external;\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n ) external;\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address creator,\n address assetToken,\n uint256 receiverEnergy\n ) external;\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 principalEnergy,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n ) external;\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n ) external;\n}\n" + }, + "contracts/v1/interfaces/IUniverseRP.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IUniverseRP.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport \"./IUniverse.sol\";\n\n/**\n * @title Universal Controller interface for Rewards Program\n * @dev ...\n */\ninterface IUniverseRP is IUniverse {\n event RewardProgramSet(address indexed assetToken, address indexed rewardProgram);\n event RewardProgramRemoved(address indexed assetToken);\n event NftDeposit(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\n event NftRelease(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\n\n struct NftStake {\n uint256 multiplier; // in Basis Points\n uint256 depositBlockNumber;\n uint256 releaseBlockNumber;\n }\n\n function getRewardProgram(address asset) external view returns (address);\n function getNftStake(uint256 uuid) external view returns (NftStake memory);\n}\n" + }, + "contracts/v1/interfaces/IWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Particle Wallet Manager interface\n * @dev The wallet-manager for underlying assets attached to Charged Particles\n * @dev Manages the link between NFTs and their respective Smart-Wallets\n */\ninterface IWalletManager {\n\n event ControllerSet(address indexed controller);\n event ExecutorSet(address indexed executor);\n event PausedStateSet(bool isPaused);\n event NewSmartWallet(address indexed contractAddress, uint256 indexed tokenId, address indexed smartWallet, address creator, uint256 annuityPct);\n event WalletEnergized(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 assetAmount, uint256 yieldTokensAmount);\n event WalletDischarged(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 creatorAmount, uint256 receiverAmount);\n event WalletDischargedForCreator(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, address creator, uint256 receiverAmount);\n event WalletReleased(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address assetToken, uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n event WalletRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\n\n function isPaused() external view returns (bool);\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view returns (bool);\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view returns (address);\n\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\n function getInterest(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken) external returns (uint256);\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount) external returns (uint256 yieldTokensAmount);\n function discharge(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function dischargeAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function dischargeAmountForCreator(address receiver, address contractAddress, uint256 tokenId, address creator, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\n function release(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n function releaseAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken) external;\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct) external returns (address);\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\n}\n" + }, + "contracts/v1/lib/BaseProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IBaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n/// @title Base Proton Contract for Charged Particles compatible ERC721 NFTs\n/// @dev MUST NOT be Upgradeable, as Upgradeable NFTs are incompatible with Charged Particles.\ncontract BaseProton is \n IBaseProton, \n ERC721, \n Ownable, \n RelayRecipient, \n ReentrancyGuard, \n BlackholePrevention \n{\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n event Received(address, uint);\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n /// @dev Sequential Token IDs storage\n Counters.Counter internal _tokenIds;\n\n /// @dev NFT Token Creator settings\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct;\n mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect;\n mapping (address => uint256) internal _tokenCreatorClaimableRoyalties;\n\n /// @dev NFT Token Sale settings\n mapping (uint256 => uint256) internal _tokenSalePrice;\n mapping (uint256 => uint256) internal _tokenLastSellPrice;\n\n /// @dev Whether of not the Contract is Paused\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n /// @dev Inherit from ERC721 standard\n constructor(string memory _name, string memory _symbol) public ERC721(_name, _symbol) {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n receive() external payable virtual {\n emit Received(msg.sender, msg.value);\n }\n\n /// Returns the Creator address of an NFT by Token ID\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The address of the Creator account\n function creatorOf(uint256 tokenId) external view virtual override returns (address) {\n return _tokenCreator[tokenId];\n }\n\n /// Returns the Sale Price of an NFT by Token ID\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The sale price of the NFT\n function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenSalePrice[tokenId];\n }\n\n /// Returns the Last Sale Price of an NFT by Token ID\n /// @notice This is used to determine any increase in sale price used in royalties calculations\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The last sale price of the NFT\n function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenLastSellPrice[tokenId];\n }\n\n /// Returns the Claimable Royalties for the NFT Creator\n /// @param account The address of the Creator account to lookup\n /// @return The amount of earned royalties for the creator account\n function getCreatorRoyalties(address account) external view virtual override returns (uint256) {\n return _tokenCreatorClaimableRoyalties[account];\n }\n\n /// Returns the Percentage of Royalties reserved for the NFT Creator\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The percentage of royalties reserved for the creator\n function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenCreatorRoyaltiesPct[tokenId];\n }\n\n /// Returns the Receiving address of the Creator Royalties (or Creator if not set)\n /// @dev Returns the creator address if a receiving address has not been configured\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The Receiving address of the Creator Royalties\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) {\n return _creatorRoyaltiesReceiver(tokenId);\n }\n\n /// Allows an NFT Creator to Claim any Royalties that have been earned from NFT sales\n /// @dev Must be called by the royalties receiver account (not neccessarily the creator)\n /// @return The amout of creator royalties claimed\n function claimCreatorRoyalties()\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256)\n {\n return _claimCreatorRoyalties(_msgSender());\n }\n\n\n /***********************************|\n | Create Single Protons |\n |__________________________________*/\n\n /// Creates a Basic NFT with no Royalties and no initial Sale Price\n /// @dev Royalties and Sale Price can be configured later\n /// @param creator The address of the NFT Creator (can be different from the caller)\n /// @param receiver The receiving address of the NFT (can be different from the caller)\n /// @param tokenMetaUri The unique metadata URI for the NFT\n /// @return newTokenId The newly minted NFT Token ID\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n\n /***********************************|\n | Create Multiple Protons |\n |__________________________________*/\n\n function createProtons(\n address creator,\n address receiver,\n string[] calldata tokenMetaUris\n )\n external\n virtual\n override\n whenNotPaused\n returns (bool)\n {\n _createProtons(\n creator,\n receiver,\n 0, // royaltiesPercent\n tokenMetaUris\n );\n return true;\n }\n\n function createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n external\n virtual\n override\n whenNotPaused\n returns (bool)\n {\n _createProtonsForSale(\n creator,\n receiver,\n royaltiesPercent,\n tokenMetaUris,\n salePrices\n );\n return true;\n }\n\n\n /***********************************|\n | Buy Protons |\n |__________________________________*/\n\n function buyProton(uint256 tokenId, uint256 gasLimit)\n external\n payable\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (bool)\n {\n _buyProton(tokenId, gasLimit);\n return true;\n }\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice)\n external\n virtual\n override\n whenNotPaused\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setSalePrice(tokenId, salePrice);\n }\n\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setRoyaltiesPct(tokenId, royaltiesPct);\n }\n\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n {\n _tokenCreatorRoyaltiesRedirect[tokenId] = receiver;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual {\n _tokenSalePrice[tokenId] = salePrice;\n emit SalePriceSet(tokenId, salePrice);\n }\n\n function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual {\n require(royaltiesPct <= PERCENTAGE_SCALE, \"PRT:E-421\");\n _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct;\n emit CreatorRoyaltiesSet(tokenId, royaltiesPct);\n }\n\n function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) {\n address receiver = _tokenCreatorRoyaltiesRedirect[tokenId];\n if (receiver == address(0x0)) {\n receiver = _tokenCreator[tokenId];\n }\n return receiver;\n }\n\n function _createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n _tokenIds.increment();\n\n newTokenId = _tokenIds.current();\n _safeMint(receiver, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUri);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n }\n\n function _createProtons(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris\n )\n internal\n virtual\n {\n uint256 count = tokenMetaUris.length;\n for (uint256 i; i < count; i++) {\n _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, 0);\n }\n }\n\n function _createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n internal\n virtual\n {\n require(tokenMetaUris.length == salePrices.length, \"PRT:E-202\");\n\n uint256 count = tokenMetaUris.length;\n for (uint256 i; i < count; i++) {\n _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, salePrices[i]);\n }\n }\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n contractAddress = address(this);\n tokenId = _tokenId;\n salePrice = _tokenSalePrice[_tokenId];\n require(salePrice > 0, \"PRT:E-416\");\n require(msg.value >= salePrice, \"PRT:E-414\");\n\n uint256 ownerAmount = salePrice;\n creatorAmount;\n oldOwner = ownerOf(_tokenId);\n newOwner = _msgSender();\n\n // Creator Royalties\n royaltiesReceiver = _creatorRoyaltiesReceiver(_tokenId);\n uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[_tokenId];\n uint256 lastSellPrice = _tokenLastSellPrice[_tokenId];\n if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) {\n creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE);\n ownerAmount = ownerAmount.sub(creatorAmount);\n }\n _tokenLastSellPrice[_tokenId] = salePrice;\n\n // Reserve Royalties for Creator\n if (creatorAmount > 0) {\n _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount);\n }\n\n // Transfer Token\n _transfer(oldOwner, newOwner, _tokenId);\n\n // Transfer Payment\n if (ownerAmount > 0) {\n payable(oldOwner).sendValue(ownerAmount, _gasLimit);\n }\n\n emit ProtonSold(_tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n\n _refundOverpayment(salePrice, _gasLimit);\n }\n\n /**\n * @dev Pays out the Creator Royalties of the calling account\n * @param receiver The receiver of the claimable royalties\n * @return The amount of Creator Royalties claimed\n */\n function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) {\n uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver];\n require(claimableAmount > 0, \"PRT:E-411\");\n\n delete _tokenCreatorClaimableRoyalties[receiver];\n payable(receiver).sendValue(claimableAmount, 0);\n\n emit RoyaltiesClaimed(receiver, claimableAmount);\n }\n\n /**\n * @dev Collects the Required Asset Token from the users wallet\n * @param from The owner address to collect the Assets from\n * @param assetAmount The Amount of Asset Tokens to Collect\n */\n function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual {\n uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from);\n require(assetAmount <= _userAssetBalance, \"PRT:E-411\");\n // Be sure to Approve this Contract to transfer your Asset Token\n require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), \"PRT:E-401\");\n }\n\n function _refundOverpayment(uint256 threshold, uint256 gasLimit) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage, gasLimit);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n _tokenSalePrice[tokenId] = 0;\n super._transfer(from, to, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"PRT:E-101\");\n _;\n }\n\n modifier onlyTokenOwnerOrApproved(uint256 tokenId) {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"PRT:E-105\");\n _;\n }\n\n modifier onlyTokenCreator(uint256 tokenId) {\n require(_tokenCreator[tokenId] == _msgSender(), \"PRT:E-104\");\n _;\n }\n}" + }, + "contracts/v1/lib/Bitwise.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Bitwise.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nlibrary Bitwise {\n function negate(uint32 a) internal pure returns (uint32) {\n return a ^ maxInt();\n }\n\n function shiftLeft(uint32 a, uint32 n) internal pure returns (uint32) {\n return a * uint32(2) ** n;\n }\n\n function shiftRight(uint32 a, uint32 n) internal pure returns (uint32) {\n return a / uint32(2) ** n;\n }\n\n function maxInt() internal pure returns (uint32) {\n return uint32(-1);\n }\n\n // Get bit value at position\n function hasBit(uint32 a, uint32 n) internal pure returns (bool) {\n return a & shiftLeft(0x01, n) != 0;\n }\n\n // Set bit value at position\n function setBit(uint32 a, uint32 n) internal pure returns (uint32) {\n return a | shiftLeft(0x01, n);\n }\n\n // Set the bit into state \"false\"\n function clearBit(uint32 a, uint32 n) internal pure returns (uint32) {\n uint32 mask = negate(shiftLeft(0x01, n));\n return a & mask;\n }\n}\n" + }, + "contracts/v1/lib/BlackholePrevention.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\n\n/**\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\n * the Owner/DAO to pull them out on behalf of a user\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\n */\ncontract BlackholePrevention {\n using Address for address payable;\n using SafeERC20 for IERC20;\n\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\n\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (address(this).balance >= amount) {\n receiver.sendValue(amount);\n emit WithdrawStuckEther(receiver, amount);\n }\n }\n\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\n IERC20(tokenAddress).safeTransfer(receiver, amount);\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\n }\n }\n\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\n }\n }\n\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \"\");\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\n }\n }\n}\n" + }, + "contracts/v1/lib/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/GSN/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableMap.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n /**\n * @dev Emitted when `tokenId` token is transfered from `from` to `to`.\n */\n event TransferBatch(address indexed from, address indexed to, uint256 startTokenId, uint256 count);\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721:E-403\");\n\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721:E-405\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"ERC721:E-405\");\n return _tokenURIs[tokenId];\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721:E-111\");\n\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \"ERC721:E-105\");\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view override returns (address) {\n require(_exists(tokenId), \"ERC721:E-405\");\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 require(operator != _msgSender(), \"ERC721:E-111\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721:E-402\");\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 returns (bool) {\n return _tokenOwners.contains(tokenId);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721:E-405\");\n address owner = ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721:E-402\");\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 _safeMintBatch(address to, uint256 startTokenId, uint256 count, bytes memory _data) internal virtual {\n _mintBatch(to, startTokenId, count);\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \"ERC721:E-402\");\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:E-403\");\n require(!_exists(tokenId), \"ERC721:E-407\");\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\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 _mintBatch(address to, uint256 startTokenId, uint256 count) internal virtual {\n require(to != address(0), \"ERC721:E-403\");\n require(!_exists(startTokenId), \"ERC721:E-407\");\n\n for (uint i = 0; i < count; i++) {\n uint256 tokenId = startTokenId.add(i);\n _holderTokens[to].add(tokenId);\n _tokenOwners.set(tokenId, to);\n }\n\n emit TransferBatch(address(0), to, startTokenId, count);\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(address from, address to, uint256 tokenId) internal virtual {\n require(ownerOf(tokenId) == from, \"ERC721:E-102\");\n require(to != address(0), \"ERC721:E-403\");\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721:E-405\");\n _tokenURIs[tokenId] = _tokenURI;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721:E-402\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\n }\n}\n" + }, + "contracts/v1/lib/ERC721Basic.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/GSN/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Basic is Context, ERC165, IERC721, IERC721Metadata {\n using SafeMath for uint256;\n using Address for address;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 internal constant _ERC721_RECEIVED = 0x150b7a02;\n\n // mapping from token ids to their owners\n mapping (uint256 => address) internal _tokenOwners;\n\n // mapping from owner to token balance\n mapping (address => uint256) internal _ownerBalance;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) internal _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) internal _operatorApprovals;\n\n // Token name\n string internal _name;\n\n // Token symbol\n string internal _symbol;\n\n // Token Count\n uint256 internal _tokenCount;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 internal constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 internal constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721:E-403\");\n return _ownerBalance[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners[tokenId];\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view 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 return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721:E-111\");\n\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \"ERC721:E-105\");\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view override returns (address) {\n require(_exists(tokenId), \"ERC721:E-405\");\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721:E-111\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721:E-402\");\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 returns (bool) {\n return _tokenOwners[tokenId] != address(0x0);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721:E-405\");\n address owner = ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\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(address to, bytes memory _data) internal virtual returns (uint256) {\n uint256 tokenId = _mint(to);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721:E-402\");\n return 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 _safeMintBatch(address to, uint256 count, bytes memory _data) internal virtual {\n uint256 startTokenId = _mintBatch(to, count);\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \"ERC721:E-402\");\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) internal virtual returns (uint256) {\n require(to != address(0), \"ERC721:E-403\");\n\n _tokenCount = _tokenCount.add(1);\n uint256 tokenId = _tokenCount;\n require(!_exists(tokenId), \"ERC721:E-407\");\n\n _tokenOwners[tokenId] = to;\n _ownerBalance[to] = _ownerBalance[to].add(1);\n\n emit Transfer(address(0), to, tokenId);\n return tokenId;\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 _mintBatch(address to, uint256 count) internal virtual returns (uint256) {\n require(to != address(0), \"ERC721:E-403\");\n\n uint256 startTokenId = _tokenCount.add(1);\n for (uint i = 1; i <= count; i++) {\n uint256 tokenId = _tokenCount.add(i);\n _tokenOwners[tokenId] = to;\n emit Transfer(address(0), to, tokenId);\n }\n\n _tokenCount = _tokenCount.add(count);\n _ownerBalance[to] = _ownerBalance[to].add(count);\n return startTokenId;\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(address from, address to, uint256 tokenId) internal virtual {\n require(ownerOf(tokenId) == from, \"ERC721:E-102\");\n require(to != address(0), \"ERC721:E-403\");\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _tokenOwners[tokenId] = to;\n _ownerBalance[from] = _ownerBalance[from].sub(1);\n _ownerBalance[to] = _ownerBalance[to].add(1);\n\n emit Transfer(from, to, tokenId);\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(address from, address to, uint256 tokenId, bytes memory _data)\n internal returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721:E-402\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) internal {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\n }\n}\n" + }, + "contracts/v1/lib/IERC5192.sol": { + "content": "// SPDX-License-Identifier: CC0-1.0\npragma solidity ^0.6.0;\n\ninterface IERC5192 {\n /// @notice Emitted when the locking status is changed to locked.\n /// @dev If a token is minted and the status is locked, this event should be emitted.\n /// @param tokenId The identifier for a token.\n event Locked(uint256 tokenId);\n\n /// @notice Emitted when the locking status is changed to unlocked.\n /// @dev If a token is minted and the status is unlocked, this event should be emitted.\n /// @param tokenId The identifier for a token.\n event Unlocked(uint256 tokenId);\n\n /// @notice Returns the locking status of an Soulbound Token\n /// @dev SBTs assigned to zero address are considered invalid, and queries\n /// about them do throw.\n /// @param tokenId The identifier for an SBT.\n function locked(uint256 tokenId) external view returns (bool);\n}\n" + }, + "contracts/v1/lib/NftTokenType.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// NftTokenType.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/introspection/IERC165.sol\";\n\nlibrary NftTokenType {\n bytes4 constant internal INTERFACE_SIGNATURE_ERC721 = 0x80ac58cd;\n bytes4 constant internal INTERFACE_SIGNATURE_ERC1155 = 0xd9b67a26;\n\n uint256 constant internal TYPE_MASK = uint256(uint128(~0)) << 128;\n uint256 constant internal TYPE_NFT_BIT = 1 << 255;\n\n function isERC721(address contractAddress) internal view returns (bool) {\n return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC721);\n }\n\n function isERC1155(address contractAddress) internal view returns (bool) {\n return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC1155);\n }\n\n function getTokenType(address contractAddress, uint256 tokenId) internal view returns (uint256) {\n IERC165 tokenInterface = IERC165(contractAddress);\n bool is1155 = tokenInterface.supportsInterface(INTERFACE_SIGNATURE_ERC1155);\n\n if (!is1155 || (tokenId & TYPE_NFT_BIT != TYPE_NFT_BIT)) { return 0; }\n\n return tokenId & TYPE_MASK;\n }\n}\n" + }, + "contracts/v1/lib/ReentrancyGuard.sol": { + "content": "pragma solidity 0.6.12;\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 () public {\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 _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\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 /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}" + }, + "contracts/v1/lib/RelayRecipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0;\n\nimport \"@opengsn/gsn/contracts/BaseRelayRecipient.sol\";\n\ncontract RelayRecipient is BaseRelayRecipient {\n function versionRecipient() external override view returns (string memory) {\n return \"1.0.0-beta.1/charged-particles.relay.recipient\";\n }\n}\n" + }, + "contracts/v1/lib/SmartWalletBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// SmartWalletBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../interfaces/ISmartWallet.sol\";\nimport \"./BlackholePrevention.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract SmartWalletBase is ISmartWallet, BlackholePrevention {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n address internal _walletManager;\n\n address internal nftCreator;\n uint256 internal nftCreatorAnnuityPct;\n uint256 internal nftCreatorAmountDischarged;\n\n EnumerableSet.AddressSet internal _assetTokens;\n\n // Asset Token => Principal Balance\n mapping (address => uint256) internal _assetPrincipalBalance;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initializeBase() public {\n require(_walletManager == address(0x0), \"SWB:E-002\");\n _walletManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getAssetTokenCount() external view virtual override returns (uint256) {\n return _assetTokens.length();\n }\n\n function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) {\n if (index >= _assetTokens.length()) {\n return address(0);\n }\n return _assetTokens.at(index);\n }\n\n function setNftCreator(address creator, uint256 annuityPct) external virtual override onlyWalletManager {\n nftCreator = creator;\n nftCreatorAnnuityPct = annuityPct;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyWalletManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n function refreshPrincipal(address assetToken)\n external\n virtual\n override\n onlyWalletManager\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getPrincipal(address assetToken) internal view virtual returns (uint256) {\n return _assetPrincipalBalance[assetToken];\n }\n\n function _trackAssetToken(address assetToken) internal virtual {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n }\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the wallet manager\n modifier onlyWalletManager() {\n require(_walletManager == msg.sender, \"SWB:E-109\");\n _;\n }\n}" + }, + "contracts/v1/lib/SmartWalletBaseB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// SmartWalletBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../interfaces/ISmartWalletB.sol\";\nimport \"./BlackholePrevention.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract SmartWalletBaseB is ISmartWalletB, BlackholePrevention {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n address internal _walletManager;\n\n EnumerableSet.AddressSet internal _assetTokens;\n\n // Asset Token => Principal Balance\n mapping (address => uint256) internal _assetPrincipalBalance;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initializeBase() public {\n require(_walletManager == address(0x0), \"SWB:E-002\");\n _walletManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getAssetTokenCount() external view virtual override returns (uint256) {\n return _assetTokens.length();\n }\n\n function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) {\n if (index >= _assetTokens.length()) {\n return address(0);\n }\n return _assetTokens.at(index);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyWalletManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getPrincipal(address assetToken) internal view virtual returns (uint256) {\n return _assetPrincipalBalance[assetToken];\n }\n\n function _trackAssetToken(address assetToken) internal virtual {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n }\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the wallet manager\n modifier onlyWalletManager() {\n require(_walletManager == msg.sender, \"SWB:E-109\");\n _;\n }\n}" + }, + "contracts/v1/lib/Soul.sol": { + "content": "// SPDX-License-Identifier: CC0-1.0\npragma solidity ^0.6.12;\n\nimport \"./IERC5192.sol\";\n\ncontract Soul is IERC5192 {\n \n mapping (uint256 => bool) public lockedTokens;\n\n function _lockToken(uint256 tokenId) internal {\n lockedTokens[tokenId] = true;\n emit Locked(tokenId);\n }\n\n function _unlockToken(uint256 tokenId) internal {\n lockedTokens[tokenId] = false;\n emit Unlocked(tokenId);\n }\n\n function locked(uint256 tokenId)\n external\n view\n override(IERC5192)\n returns (bool)\n {\n return lockedTokens[tokenId];\n }\n}\n" + }, + "contracts/v1/lib/TokenInfo.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfo.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"../interfaces/IERC721Chargeable.sol\";\n\nlibrary TokenInfo {\n function getTokenUUID(address contractAddress, uint256 tokenId) internal pure virtual returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n function getTokenOwner(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n return tokenInterface.ownerOf(tokenId);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n function getTokenCreator(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n return tokenInterface.creatorOf(tokenId);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Owner of an External NFT contract\n /// @param contractAddress The Address to the Contract of the NFT to check\n /// @param account The Address of the Account to check\n /// @return True if the account owns the contract\n function isContractOwner(address contractAddress, address account) internal view virtual returns (bool) {\n address contractOwner = IERC721Chargeable(contractAddress).owner();\n return contractOwner != address(0x0) && contractOwner == account;\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Creator of a Proton-based NFT\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the Proton-based NFT\n function isTokenCreator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenCreator = tokenInterface.creatorOf(tokenId);\n return (sender == tokenCreator);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the Proton-based NFT or the Contract itself\n function isTokenContractOrCreator(address contractAddress, uint256 tokenId, address creator, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenCreator = tokenInterface.creatorOf(tokenId);\n if (sender == contractAddress && creator == tokenCreator) { return true; }\n return (sender == tokenCreator);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Owner or Operator of an External NFT\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the Owner or Operator of the External NFT\n function isErc721OwnerOrOperator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenOwner = tokenInterface.ownerOf(tokenId);\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\n }\n\n /**\n * @dev Returns true if `account` is a contract.\n * @dev Taken from OpenZeppelin library\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\n // for accounts without code, i.e. `keccak256('')`\n bytes32 codehash;\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n // solhint-disable-next-line no-inline-assembly\n assembly { codehash := extcodehash(account) }\n return (codehash != accountHash && codehash != 0x0);\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 * @dev Taken from OpenZeppelin library\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, uint256 gasLimit) internal {\n require(address(this).balance >= amount, \"TokenInfo: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = (gasLimit > 0)\n ? recipient.call{ value: amount, gas: gasLimit }(\"\")\n : recipient.call{ value: amount }(\"\");\n require(success, \"TokenInfo: unable to send value, recipient may have reverted\");\n }\n}\n" + }, + "contracts/v1/lib/TokenInfoProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfoProxy.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../interfaces/ITokenInfoProxy.sol\";\nimport \"../interfaces/IERC721Chargeable.sol\";\n\n\ncontract TokenInfoProxy is ITokenInfoProxy, Ownable {\n using Address for address;\n\n mapping (address => FnSignatures) internal _remappedFnSigs;\n\n function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner {\n _remappedFnSigs[contractAddress].ownerOf = fnSig;\n emit ContractFunctionSignatureSet(contractAddress, \"ownerOf\", fnSig);\n }\n\n function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner {\n _remappedFnSigs[contractAddress].creatorOf = fnSig;\n emit ContractFunctionSignatureSet(contractAddress, \"creatorOf\", fnSig);\n }\n\n\n function getTokenUUID(address contractAddress, uint256 tokenId) external pure virtual override returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n function getTokenOwner(address contractAddress, uint256 tokenId) external virtual override returns (address) {\n return _getTokenOwner(contractAddress, tokenId);\n }\n\n function getTokenCreator(address contractAddress, uint256 tokenId) external virtual override returns (address) {\n return _getTokenCreator(contractAddress, tokenId);\n }\n\n function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenOwner = _getTokenOwner(contractAddress, tokenId);\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\n }\n\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the NFT or the Contract itself\n function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) {\n address tokenCreator = _getTokenCreator(contractAddress, tokenId);\n return (sender == tokenCreator || sender == contractAddress);\n }\n\n\n\n function _getTokenCreator(address contractAddress, uint256 tokenId) internal returns (address) {\n bytes4 fnSig = IERC721Chargeable.creatorOf.selector;\n if (_remappedFnSigs[contractAddress].creatorOf != bytes4(0)) {\n fnSig = _remappedFnSigs[contractAddress].creatorOf;\n }\n\n // solhint-disable-next-line\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n if (success) {\n return abi.decode(returnData, (address));\n } else {\n return address(0x0);\n }\n }\n\n function _getTokenOwner(address contractAddress, uint256 tokenId) internal returns (address) {\n bytes4 fnSig = IERC721Chargeable.ownerOf.selector;\n if (_remappedFnSigs[contractAddress].ownerOf != bytes4(0)) {\n fnSig = _remappedFnSigs[contractAddress].ownerOf;\n }\n\n // solhint-disable-next-line\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n if (success) {\n return abi.decode(returnData, (address));\n } else {\n return address(0x0);\n }\n }\n}\n" + }, + "contracts/v1/lib/WalletManagerBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// WalletManagerBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IWalletManager.sol\";\nimport \"../interfaces/ISmartWallet.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"./BlackholePrevention.sol\";\n\n\n/**\n * @notice Wallet-Manager Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract WalletManagerBase is Ownable, BlackholePrevention, IWalletManager {\n using TokenInfo for address;\n\n // The Controller Contract Address\n address internal _controller;\n\n // The Executor Contract Address\n address internal _executor;\n\n // Template Contract for creating Token Smart-Wallet Bridges\n address internal _walletTemplate;\n\n // TokenID => Token Smart-Wallet Address\n mapping (uint256 => address) internal _wallets;\n\n // State of Wallet Manager\n bool internal _paused;\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Wallet Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n /**\n * @dev Connects to the ExecForAccount Controller\n */\n function setExecutor(address executor) external onlyOwner {\n _executor = executor;\n emit ExecutorSet(executor);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartWallet(wallet).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartWallet(wallet).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartWallet(wallet).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Executor contract\n modifier onlyExecutor() {\n require(_executor == msg.sender, \"WMB:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Controller or Executor contract\n modifier onlyControllerOrExecutor() {\n require(_executor == msg.sender || _controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"WMB:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/ParticleSplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ParticleSplitter.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"./interfaces/IParticleSplitter.sol\";\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IWalletManager.sol\";\nimport \"./interfaces/IBasketManager.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Contract\n * @dev Upgradeable Contract\n */\ncontract ParticleSplitter is IParticleSplitter, Ownable, ReentrancyGuard, BlackholePrevention\n{\n IChargedManagers internal _chargedManagers;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n mapping (address => bool) internal _externalAddressesAllowed;\n\n\n /***********************************|\n | Execute for Account |\n |__________________________________*/\n\n /// @notice Executes an arbitrary command on an NFT Wallet\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Wallet Manager controlling the NFT Wallet to execute on\n /// @param externalAddress The Address of the External Contract to execute on\n /// @param encodedParams The encoded function call to execute\n function executeForWallet(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address externalAddress,\n bytes memory encodedParams\n )\n external\n payable\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (bytes memory)\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n require(_externalAddressesAllowed[externalAddress], \"PS:E-117\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Wallet Manager\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n // Get Address of Wallet to send any ETH into\n if (msg.value > 0) {\n address wallet = walletMgr.getWalletAddressById(contractAddress, tokenId, address(0), 0);\n payable(wallet).sendValue(msg.value);\n }\n\n emit ExecuteForWallet(contractAddress, tokenId, walletManagerId, externalAddress, encodedParams, msg.value);\n\n // Execute command for NFT Wallet\n return walletMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams);\n }\n\n /// @notice Executes an arbitrary command on an NFT Basket\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param basketManagerId The Basket Manager controlling the NFT Wallet to execute on\n /// @param externalAddress The Address of the External Contract to execute on\n /// @param encodedParams The encoded function call to execute\n function executeForBasket(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address externalAddress,\n bytes memory encodedParams\n )\n external\n payable\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (bytes memory)\n {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"PS:E-419\");\n require(_externalAddressesAllowed[externalAddress], \"PS:E-117\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Basket Manager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n\n // Get Address of Wallet to send any ETH into\n if (msg.value > 0) {\n address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId);\n payable(wallet).sendValue(msg.value);\n }\n\n emit ExecuteForBasket(contractAddress, tokenId, basketManagerId, externalAddress, encodedParams, msg.value);\n\n // Execute command for NFT Wallet\n return basketMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams);\n }\n\n function withdrawWalletRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (uint256 amountWithdrawn)\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Wallet Manager\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n // Withdraw Rewards for NFT Wallet\n return walletMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount);\n }\n\n function withdrawBasketRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (uint256 amountWithdrawn)\n {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"PS:E-419\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Basket Manager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n\n // Withdraw Rewards for NFT Basket\n return basketMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount);\n }\n\n function refreshWalletPrincipal(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n walletMgr.refreshPrincipal(contractAddress, tokenId, assetToken);\n\n emit PrincipalRefreshed(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedManagers Interface\n */\n function setChargedManagers(address chargedManagers) external virtual onlyOwner {\n _chargedManagers = IChargedManagers(chargedManagers);\n emit ChargedManagersSet(chargedManagers);\n }\n\n /**\n * @dev Setup the ChargedManagers Interface\n */\n function setTokenInfoProxy(address tokenInfoProxy) external virtual onlyOwner {\n _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy);\n emit TokenInfoProxySet(tokenInfoProxy);\n }\n\n /**\n * @dev Allows/Disallows execute from on specific contracts\n */\n function setExternalContracts(address[] calldata contracts, bool state) external onlyOwner {\n uint count = contracts.length;\n for (uint i; i < count; i++) {\n address externalContract = contracts[i];\n _externalAddressesAllowed[externalContract] = state;\n emit PermsSetForExternal(externalContract, state);\n }\n }\n\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyTokenOwner(address contractAddress, uint256 tokenId) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(msg.sender == tokenOwner, \"PS:E-102\");\n _;\n }\n}\n" + }, + "contracts/v1/test/Dai.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"../interfaces/IDai.sol\";\n\ncontract Dai is IDai {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (uint256 chainId_) public {\n string memory version = \"1\";\n\n _name = \"Dai Stablecoin\";\n _symbol = \"DAI\";\n _decimals = 18;\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(_name)),\n keccak256(bytes(version)),\n chainId_,\n address(this)\n )\n );\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view 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(msg.sender, 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(msg.sender, 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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(msg.sender, spender, _allowances[msg.sender][spender].add(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 _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20:E-403\");\n require(recipient != address(0), \"ERC20:E-403\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20:E-403\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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:E-403\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20:E-403\");\n require(spender != address(0), \"ERC20:E-403\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n\n mapping (address => uint) public nonces;\n\n // --- EIP712 niceties ---\n bytes32 public DOMAIN_SEPARATOR;\n // bytes32 public constant PERMIT_TYPEHASH = keccak256(\"Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)\");\n bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;\n\n // --- Approve by signature ---\n function permit(\n address holder, address spender, uint256 nonce, uint256 expiry,\n bool allowed, uint8 v, bytes32 r, bytes32 s) external override\n {\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n holder,\n spender,\n nonce,\n expiry,\n allowed\n )\n )\n )\n );\n\n require(holder != address(0), \"Dai/invalid-address-0\");\n require(holder == ecrecover(digest, v, r, s), \"Dai/invalid-permit\");\n require(expiry == 0 || now <= expiry, \"Dai/permit-expired\");\n require(nonce == nonces[holder]++, \"Dai/invalid-nonce\");\n uint wad = allowed ? uint(-1) : 0;\n _allowances[holder][spender] = wad;\n emit Approval(holder, spender, wad);\n }\n\n function mint(address to, uint256 amount) external {\n _mint(to, amount);\n }\n}" + }, + "contracts/v1/test/ERC20Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.7.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/**\n * @dev Extension of {ERC20} that adds a set of accounts with the {MinterRole},\n * which have permission to mint (create) new tokens as they see fit.\n *\n * At construction, the deployer of the contract is the only minter.\n */\ncontract ERC20Mintable is ERC20Upgradeable {\n\n constructor(string memory _name, string memory _symbol) public {\n __ERC20_init(_name, _symbol);\n }\n\n /**\n * @dev See {ERC20-_mint}.\n *\n * Requirements:\n *\n * - the caller must have the {MinterRole}.\n */\n function mint(address account, uint256 amount) public returns (bool) {\n _mint(account, amount);\n return true;\n }\n\n function burn(address account, uint256 amount) public returns (bool) {\n _burn(account, amount);\n return true;\n }\n}" + }, + "contracts/v1/test/ERC721Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.7.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\n\n/**\n * @dev Extension of {ERC721} for Minting/Burning\n */\ncontract ERC721Mintable is ERC721Upgradeable {\n\n constructor () public {\n __ERC721_init(\"ERC 721\", \"NFT\");\n }\n\n /**\n * @dev See {ERC721-_mint}.\n */\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n\n /**\n * @dev See {ERC721-_burn}.\n */\n function burn(uint256 tokenId) public {\n _burn(tokenId);\n }\n}\n" + }, + "contracts/v1/tokens/ExternalERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ExternalERC721.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\n\ncontract ExternalERC721 is ERC721 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n\n constructor() public ERC721(\"Charged Particles - ExternalERC721\", \"ExNFT\") {}\n\n function mintNft(address receiver, string memory tokenUri) external returns (uint256 newTokenId) {\n return _mintNft(receiver, tokenUri);\n }\n\n function _mintNft(address receiver, string memory tokenUri) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n\n _safeMint(receiver, newTokenId, \"\");\n\n _setTokenURI(newTokenId, tokenUri);\n }\n}\n" + }, + "contracts/v1/tokens/FungibleERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// FungibleERC1155.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract FungibleERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n\n constructor() public ERC1155(\"https://staging.app.charged.fi/erc1155/metadata.json\") {}\n\n function mintNft(address receiver, uint256 amount) external returns (uint256 newTokenId) {\n return _mintNft(receiver, amount);\n }\n\n function _mintNft(address receiver, uint256 amount) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n _mint(receiver, newTokenId, amount, \"\");\n }\n}\n" + }, + "contracts/v1/tokens/Ionx.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Ionx.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"erc20permit/contracts/ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\n\ncontract Ionx is ERC20Permit, Ownable, BlackholePrevention {\n using SafeMath for uint256;\n\n /// @notice An event thats emitted when the minter address is changed\n event MinterChanged(address minter, address newMinter);\n\n /// @notice Total number of tokens in circulation\n uint256 constant public INITIAL_SUPPLY = 1e8 ether;\n\n /// @notice Minimum time between mints\n uint32 public constant INFLATION_EPOCH = 1 days * 365;\n\n /// @notice Cap on the percentage of totalSupply that can be minted at each mint\n uint8 public constant INFLATION_CAP = 2;\n\n /// @notice Address which may mint new tokens\n address public minter;\n\n /// @notice The timestamp after which minting may occur\n uint256 public mintingAllowedAfter;\n\n\n constructor() public ERC20Permit(\"Charged Particles - IONX\", \"IONX\") {}\n\n\n /**\n * @notice Change the minter address\n * @param newMinter The address of the new minter\n */\n function setMinter(address newMinter) external onlyOwner {\n emit MinterChanged(minter, newMinter);\n minter = newMinter;\n }\n\n /**\n * @notice Mint new tokens\n * @param receiver The address of the destination account\n * @param amount The number of tokens to be minted\n */\n function mint(address receiver, uint256 amount) external onlyMinter {\n require(block.timestamp >= mintingAllowedAfter, \"Ionx:E-114\");\n require(receiver != address(0), \"Ionx:E-403\");\n\n uint256 amountToMint = amount;\n uint256 _totalSupply = totalSupply();\n\n // From Inflationary Supply\n if (_totalSupply >= INITIAL_SUPPLY) {\n mintingAllowedAfter = mintingAllowedAfter.add(INFLATION_EPOCH);\n amountToMint = _totalSupply.mul(INFLATION_CAP).div(100);\n }\n\n // From Initial Supply\n else {\n if (_totalSupply.add(amountToMint) > INITIAL_SUPPLY) {\n amountToMint = INITIAL_SUPPLY.sub(_totalSupply);\n }\n if (_totalSupply.add(amountToMint) == INITIAL_SUPPLY) {\n mintingAllowedAfter = block.timestamp.add(INFLATION_EPOCH);\n }\n }\n\n // transfer the amount to the recipient\n _mint(receiver, amountToMint);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n modifier onlyMinter() {\n require(msg.sender == minter, \"Ionx:E-113\");\n _;\n }\n}\n" + }, + "contracts/v1/tokens/Lepton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Lepton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/ILepton.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\n\ncontract Lepton is ILepton, ERC721, Ownable, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenIds;\n Classification[] internal _leptonTypes;\n mapping (uint256 => Classification) internal _leptonData;\n\n uint256 internal _typeIndex;\n uint256 internal _maxSupply;\n uint256 internal _maxMintPerTx;\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721(\"Charged Particles - Lepton\", \"LEPTON\") {\n _paused = true;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function mintLepton() external payable virtual override nonReentrant whenNotPaused returns (uint256 newTokenId) {\n newTokenId = _mintLepton(msg.sender);\n }\n\n function batchMintLepton(uint256 count) external payable virtual override nonReentrant whenNotPaused {\n _batchMintLepton(msg.sender, count);\n }\n\n function getNextType() external view virtual override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _typeIndex;\n }\n\n function getNextPrice() external view virtual override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _leptonTypes[_typeIndex].price;\n }\n\n function getMultiplier(uint256 tokenId) external view virtual override returns (uint256) {\n return _leptonData[tokenId].multiplier;\n }\n\n function getBonus(uint256 tokenId) external view virtual override returns (uint256) {\n return _leptonData[tokenId].bonus;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function addLeptonType(\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n virtual\n onlyOwner\n {\n _maxSupply = _maxSupply.add(uint256(supply));\n\n Classification memory lepton = Classification({\n tokenUri: tokenUri,\n price: price,\n supply: supply,\n multiplier: multiplier,\n bonus: bonus,\n _upperBounds: uint128(_maxSupply)\n });\n _leptonTypes.push(lepton);\n\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function updateLeptonType(\n uint256 leptonIndex,\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n virtual\n onlyOwner\n {\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\n _leptonTypes[leptonIndex].price = price;\n _leptonTypes[leptonIndex].supply = supply;\n _leptonTypes[leptonIndex].multiplier = multiplier;\n _leptonTypes[leptonIndex].bonus = bonus;\n\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function setMaxMintPerTx(uint256 maxAmount) external virtual onlyOwner {\n _maxMintPerTx = maxAmount;\n emit MaxMintPerTxSet(maxAmount);\n }\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _mintLepton(address receiver) internal virtual returns (uint256 newTokenId) {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n require(msg.value >= lepton.price, \"LPT:E-414\");\n\n _tokenIds.increment();\n newTokenId = _tokenIds.current();\n\n _leptonData[newTokenId] = lepton;\n _safeMint(receiver, newTokenId, \"\");\n _setTokenURI(newTokenId, lepton.tokenUri);\n\n // Distribute Next Type\n if (newTokenId == lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n emit LeptonMinted(receiver, newTokenId, lepton.price, lepton.multiplier);\n\n _refundOverpayment(lepton.price);\n }\n\n\n function _batchMintLepton(address receiver, uint256 count) internal virtual {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \"LPT:E-429\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n\n uint256 startTokenId = _tokenIds.current();\n uint256 endTokenId = startTokenId.add(count);\n if (endTokenId > lepton._upperBounds) {\n count = count.sub(endTokenId.sub(lepton._upperBounds));\n }\n\n uint256 salePrice = lepton.price.mul(count);\n require(msg.value >= salePrice, \"LPT:E-414\");\n\n _safeMintBatch(receiver, startTokenId.add(1), count, \"\");\n\n for (uint i = 0; i < count; i++) {\n _tokenIds.increment();\n startTokenId = _tokenIds.current();\n\n _leptonData[startTokenId] = lepton;\n _setTokenURI(startTokenId, lepton.tokenUri);\n }\n\n // Distribute Next Type\n if (startTokenId >= lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n emit LeptonBatchMinted(receiver, startTokenId, count, lepton.price, lepton.multiplier);\n\n _refundOverpayment(salePrice);\n }\n\n function _refundOverpayment(uint256 threshold) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"LPT:E-101\");\n _;\n }\n}" + }, + "contracts/v1/tokens/Lepton2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Lepton2.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"../lib/ERC721Basic.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\n\nimport \"../interfaces/ILepton.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Lepton2 is ILepton, ERC721Basic, Ownable, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n\n Classification[] internal _leptonTypes;\n\n uint256 internal _typeIndex;\n uint256 internal _maxSupply;\n uint256 internal _maxMintPerTx;\n uint256 internal _migratedCount;\n\n bool internal _paused;\n bool internal _migrationComplete;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721Basic(\"Charged Particles - Lepton2\", \"LEPTON2\") {\n _paused = true;\n _migrationComplete = false;\n _migratedCount = 0;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function mintLepton() external payable override nonReentrant whenNotPaused returns (uint256 newTokenId) {\n newTokenId = _mintLepton(msg.sender);\n }\n\n function batchMintLepton(uint256 count) external payable override nonReentrant whenNotPaused {\n _batchMintLepton(msg.sender, count);\n }\n\n function totalSupply() public view returns (uint256) {\n return _tokenCount;\n }\n\n function maxSupply() external view returns (uint256) {\n return _maxSupply;\n }\n\n function getNextType() external view override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _typeIndex;\n }\n\n function getNextPrice() external view override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _leptonTypes[_typeIndex].price;\n }\n\n function getMultiplier(uint256 tokenId) external view override returns (uint256) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).multiplier;\n }\n\n function getBonus(uint256 tokenId) external view override returns (uint256) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).bonus;\n }\n\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).tokenUri;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function addLeptonType(\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n onlyOwner\n {\n _maxSupply = _maxSupply.add(uint256(supply));\n\n Classification memory lepton = Classification({\n tokenUri: tokenUri,\n price: price,\n supply: supply,\n multiplier: multiplier,\n bonus: bonus,\n _upperBounds: uint128(_maxSupply)\n });\n _leptonTypes.push(lepton);\n\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function updateLeptonType(\n uint256 leptonIndex,\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n onlyOwner\n {\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\n _leptonTypes[leptonIndex].price = price;\n _leptonTypes[leptonIndex].supply = supply;\n _leptonTypes[leptonIndex].multiplier = multiplier;\n _leptonTypes[leptonIndex].bonus = bonus;\n\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function setMaxMintPerTx(uint256 maxAmount) external onlyOwner {\n _maxMintPerTx = maxAmount;\n emit MaxMintPerTxSet(maxAmount);\n }\n\n function setPausedState(bool state) external onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function migrateAccounts(address oldLeptonContract, uint256 count) external onlyOwner whenNotMigrated {\n uint256 oldSupply = IERC721Enumerable(oldLeptonContract).totalSupply();\n require(oldSupply == 0 || oldSupply > _migratedCount, \"LPT:E-004\");\n\n if (oldSupply > 0) {\n uint256 endTokenId = _migratedCount.add(count);\n if (endTokenId > oldSupply) {\n count = count.sub(endTokenId.sub(oldSupply));\n }\n\n for (uint256 i = 1; i <= count; i++) {\n uint256 tokenId = _migratedCount.add(i);\n address tokenOwner = IERC721(oldLeptonContract).ownerOf(tokenId);\n _mint(tokenOwner);\n }\n _migratedCount = _migratedCount.add(count);\n }\n\n if (oldSupply == _migratedCount) {\n _finalizeMigration();\n }\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getLepton(uint256 tokenId) internal view returns (Classification memory) {\n uint256 types = _leptonTypes.length;\n for (uint256 i = 0; i < types; i++) {\n Classification memory lepton = _leptonTypes[i];\n if (tokenId <= lepton._upperBounds) {\n return lepton;\n }\n }\n }\n\n function _mintLepton(address receiver) internal returns (uint256 newTokenId) {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n require(msg.value >= lepton.price, \"LPT:E-414\");\n\n newTokenId = _safeMint(receiver, \"\");\n\n // Determine Next Type\n if (newTokenId == lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n _refundOverpayment(lepton.price);\n }\n\n function _batchMintLepton(address receiver, uint256 count) internal {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \"LPT:E-429\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n\n uint256 endTokenId = _tokenCount.add(count);\n if (endTokenId > lepton._upperBounds) {\n count = count.sub(endTokenId.sub(lepton._upperBounds));\n }\n\n uint256 salePrice = lepton.price.mul(count);\n require(msg.value >= salePrice, \"LPT:E-414\");\n\n _safeMintBatch(receiver, count, \"\");\n\n // Determine Next Type\n if (endTokenId >= lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n _refundOverpayment(salePrice);\n }\n\n function _refundOverpayment(uint256 threshold) internal {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n function _finalizeMigration() internal {\n // Determine Next Type\n _typeIndex = 0;\n for (uint256 i = 0; i < _leptonTypes.length; i++) {\n Classification memory lepton = _leptonTypes[i];\n if (_migratedCount >= lepton._upperBounds) {\n _typeIndex = i + 1;\n }\n }\n _migrationComplete = true;\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotMigrated() {\n require(!_migrationComplete, \"LPT:E-004\");\n _;\n }\n\n modifier whenNotPaused() {\n require(!_paused, \"LPT:E-101\");\n _;\n }\n}" + }, + "contracts/v1/tokens/NonFungibleERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// NonFungibleERC1155.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract NonFungibleERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => address) internal _tokenOwner;\n\n constructor() public ERC1155(\"https://staging.app.charged.fi/erc1155/metadata.json\") {}\n\n function creatorOf(uint256 tokenId) external view returns (address) {\n return _tokenCreator[tokenId];\n }\n\n function ownerOf(uint256 tokenId) external view returns (address) {\n return _tokenOwner[tokenId];\n }\n\n function mintNft(address receiver) external returns (uint256 newTokenId) {\n return _mintNft(msg.sender, receiver);\n }\n\n function _mintNft(address creator, address receiver) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n\n _mint(receiver, newTokenId, 1, \"\");\n _tokenCreator[newTokenId] = creator;\n _tokenOwner[newTokenId] = receiver;\n }\n}\n" + }, + "contracts/v1/tokens/Proton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IProton.sol\";\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ncontract Proton is IProton, ERC721, Ownable, RelayRecipient, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n using Counters for Counters.Counter;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n uint256 constant internal MAX_ROYALTIES = 8e3; // 8000 (80%)\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n Counters.Counter internal _tokenIds;\n\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct;\n mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect;\n mapping (address => uint256) internal _tokenCreatorClaimableRoyalties;\n\n mapping (uint256 => uint256) internal _tokenSalePrice;\n mapping (uint256 => uint256) internal _tokenLastSellPrice;\n\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721(\"Charged Particles - Proton\", \"PROTON\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view virtual override returns (address) {\n return _tokenCreator[tokenId];\n }\n\n function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenSalePrice[tokenId];\n }\n\n function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenLastSellPrice[tokenId];\n }\n\n function getCreatorRoyalties(address account) external view virtual override returns (uint256) {\n return _tokenCreatorClaimableRoyalties[account];\n }\n\n function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenCreatorRoyaltiesPct[tokenId];\n }\n\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) {\n return _creatorRoyaltiesReceiver(tokenId);\n }\n\n function claimCreatorRoyalties()\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256)\n {\n return _claimCreatorRoyalties(_msgSender());\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // annuityPercent,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n royaltiesPercent,\n salePrice\n );\n }\n\n function batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n external\n virtual\n override\n whenNotPaused\n {\n _batchProtonsForSale(\n creator,\n annuityPercent,\n royaltiesPercent,\n tokenMetaUris,\n salePrices\n );\n }\n\n function buyProton(uint256 tokenId)\n external\n payable\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (bool)\n {\n return _buyProton(tokenId);\n }\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice)\n external\n virtual\n override\n whenNotPaused\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setSalePrice(tokenId, salePrice);\n }\n\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setRoyaltiesPct(tokenId, royaltiesPct);\n }\n\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n {\n _tokenCreatorRoyaltiesRedirect[tokenId] = receiver;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual {\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n\n _tokenSalePrice[tokenId] = salePrice;\n emit SalePriceSet(tokenId, salePrice);\n }\n\n function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual {\n require(royaltiesPct <= MAX_ROYALTIES, \"PRT:E-421\");\n _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct;\n emit CreatorRoyaltiesSet(tokenId, royaltiesPct);\n }\n\n function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) {\n address receiver = _tokenCreatorRoyaltiesRedirect[tokenId];\n if (receiver == address(0x0)) {\n receiver = _tokenCreator[tokenId];\n }\n return receiver;\n }\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, annuityPercent, 0, 0);\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n _tokenIds.increment();\n\n newTokenId = _tokenIds.current();\n _safeMint(receiver, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUri);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function _batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n internal\n virtual\n {\n require(tokenMetaUris.length == salePrices.length, \"PRT:E-202\");\n address self = address(this);\n\n uint256 count = tokenMetaUris.length;\n for (uint256 i = 0; i < count; i++) {\n _tokenIds.increment();\n uint256 newTokenId = _tokenIds.current();\n\n _safeMint(creator, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUris[i]);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n uint256 salePrice = salePrices[i];\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n self,\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n function _buyProton(uint256 tokenId)\n internal\n virtual\n returns (bool)\n {\n uint256 salePrice = _tokenSalePrice[tokenId];\n require(salePrice > 0, \"PRT:E-416\");\n require(msg.value >= salePrice, \"PRT:E-414\");\n\n uint256 ownerAmount = salePrice;\n uint256 creatorAmount;\n address oldOwner = ownerOf(tokenId);\n address newOwner = _msgSender();\n\n // Creator Royalties\n address royaltiesReceiver = _creatorRoyaltiesReceiver(tokenId);\n uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[tokenId];\n uint256 lastSellPrice = _tokenLastSellPrice[tokenId];\n if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) {\n creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE);\n ownerAmount = ownerAmount.sub(creatorAmount);\n }\n _tokenLastSellPrice[tokenId] = salePrice;\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(address(this), tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n\n // Reserve Royalties for Creator\n if (creatorAmount > 0) {\n _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount);\n }\n\n // Transfer Token\n _transfer(oldOwner, newOwner, tokenId);\n\n // Transfer Payment\n payable(oldOwner).sendValue(ownerAmount);\n\n emit ProtonSold(tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n\n _refundOverpayment(salePrice);\n return true;\n }\n\n /**\n * @dev Pays out the Creator Royalties of the calling account\n * @param receiver The receiver of the claimable royalties\n * @return The amount of Creator Royalties claimed\n */\n function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) {\n uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver];\n require(claimableAmount > 0, \"PRT:E-411\");\n\n delete _tokenCreatorClaimableRoyalties[receiver];\n payable(receiver).sendValue(claimableAmount);\n\n emit RoyaltiesClaimed(receiver, claimableAmount);\n }\n\n /**\n * @dev Collects the Required Asset Token from the users wallet\n * @param from The owner address to collect the Assets from\n * @param assetAmount The Amount of Asset Tokens to Collect\n */\n function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual {\n uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from);\n require(assetAmount <= _userAssetBalance, \"PRT:E-411\");\n // Be sure to Approve this Contract to transfer your Asset Token\n require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), \"PRT:E-401\");\n }\n\n function _refundOverpayment(uint256 threshold) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n _tokenSalePrice[tokenId] = 0;\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n super._transfer(from, to, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"PRT:E-101\");\n _;\n }\n\n modifier onlyTokenOwnerOrApproved(uint256 tokenId) {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"PRT:E-105\");\n _;\n }\n\n modifier onlyTokenCreator(uint256 tokenId) {\n require(_tokenCreator[tokenId] == _msgSender(), \"PRT:E-104\");\n _;\n }\n}" + }, + "contracts/v1/tokens/ProtonB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\nimport \"../interfaces/IProtonB.sol\";\n\nimport \"../lib/BaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ncontract ProtonB is BaseProton, IProtonB {\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public BaseProton(\"Charged Particles - ProtonB\", \"PROTON.B\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n external\n virtual\n override\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n royaltiesPercent,\n salePrice\n );\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n /// @dev for backwards compatibility with v1\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0);\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n\n /***********************************|\n | Function Overrides |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override {\n super._setSalePrice(tokenId, salePrice);\n\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n }\n\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n override\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n }\n\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n // Unlock NFT\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n\n super._transfer(from, to, tokenId);\n }\n}" + }, + "contracts/v1/tokens/ProtonC.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\nimport \"../lib/Soul.sol\";\n\n\ncontract ProtonC is BaseProton, Soul {\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public BaseProton(\"Charged Particles - ProtonC\", \"PROTON.C\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createBondedToken(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent\n )\n external\n virtual\n payable\n returns (uint256 newTokenId)\n {\n uint256 tokenId = createProtonForSale(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n royaltiesPercent,\n 0\n );\n lockToken(tokenId);\n\n return tokenId;\n }\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n public \n virtual\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n royaltiesPercent,\n salePrice\n );\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n nonReentrant\n whenNotPaused\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n /// @dev for backwards compatibility with v1\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n whenNotPaused\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function burn(uint256 tokenId) public {\n requireTokenOwner(tokenId); \n _burn(tokenId);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n function requireTokenOwner(uint256 tokenId) public view {\n require(ownerOf(tokenId) == msg.sender, \"Only token owner\");\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0);\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n function _burn(uint256 tokenId) internal {\n _unlockToken(tokenId);\n _transfer(ownerOf(tokenId), address(0x000000000000000000000000000000000000dEaD), tokenId);\n }\n\n /***********************************|\n | Soul bounded |\n |__________________________________*/\n\n function lockToken(uint256 tokenId) public {\n requireTokenOwner(tokenId);\n _lockToken(tokenId);\n }\n\n /***********************************|\n | Function Overrides |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override {\n super._setSalePrice(tokenId, salePrice);\n\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n }\n\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n override\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n require(lockedTokens[tokenId] == false, \"BondedToken: Token is locked\");\n\n // Unlock NFT\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n\n super._transfer(from, to, tokenId);\n }\n}" + }, + "contracts/v1/Universe.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\n\nimport \"./interfaces/IUniverse.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n\n/**\n * @notice Charged Particles Universe Contract\n * @dev Upgradeable Contract\n */\ncontract Universe is IUniverse, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n // The ChargedParticles Contract Address\n address public chargedParticles;\n address public proton;\n address public lepton;\n address public quark;\n address public boson;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // Positive Charge\n uint256 internal photonMaxSupply;\n uint256 internal totalPhotonDischarged;\n\n // Source of Positive Charge\n IERC20Upgradeable public photonSource;\n\n // Asset Token => Electrostatic Attraction Multiplier\n mapping (address => uint256) internal esaMultiplier;\n\n // Account => Electrostatic Attraction Levels\n mapping (address => uint256) internal esaLevel;\n\n // Energizing Account => Referral Source\n mapping (address => address) internal referralSource;\n\n // NFT Token UUID => Bonded Lepton Mass\n mapping (uint256 => uint256) internal bondedLeptonMass;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getStaticCharge(address /* account */) external pure virtual returns (uint256 positiveEnergy) {\n return 0;\n }\n\n function conductElectrostaticDischarge(address /* account */, uint256 /* amount */) external pure virtual returns (uint256 positiveEnergy) {\n return 0;\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n onlyProton\n {\n // no-op\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(controller)\n {\n chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setPhoton(\n address token,\n uint256 maxSupply\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n photonSource = IERC20Upgradeable(token);\n photonMaxSupply = maxSupply;\n emit PhotonSet(token, maxSupply);\n }\n\n function setProtonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n proton = token;\n emit ProtonTokenSet(token);\n }\n\n function setLeptonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n lepton = token;\n emit LeptonTokenSet(token);\n }\n\n function setQuarkToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n quark = token;\n emit QuarkTokenSet(token);\n }\n\n function setBosonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n boson = token;\n emit BosonTokenSet(token);\n }\n\n function setEsaMultiplier(\n address assetToken,\n uint256 multiplier\n )\n external\n virtual\n onlyOwner\n {\n esaMultiplier[assetToken] = multiplier;\n emit EsaMultiplierSet(assetToken, multiplier);\n }\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _electrostaticAttraction(uint256 tokenUuid, address receiver, address assetToken, uint256 baseAmount) internal virtual {\n }\n\n function _conductElectrostaticDischarge(address /* account */, uint256 /* energy */) internal virtual pure returns (uint256) {\n return 0;\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Proton NFT contract\n modifier onlyProton() {\n require(proton == msg.sender, \"UNI:E-110\");\n _;\n }\n}\n" + }, + "contracts/v1/UniverseRP.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"./interfaces/IUniverseRP.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./interfaces/IRewardNft.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\nimport \"./interfaces/IRewardProgram.sol\";\n\n/**\n * @notice Charged Particles Universe Contract with Rewards Program\n * @dev Upgradeable Contract\n */\ncontract UniverseRP is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // The ChargedParticles Contract Address\n address public _chargedParticles;\n\n // The Lepton NFT Contract Address\n address public _multiplierNft;\n\n // Asset Token => Reward Program\n mapping (address => address) internal _assetRewardPrograms;\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\n\n // Token UUID => NFT Staking Data\n mapping (uint256 => NftStake) private _nftStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n function getRewardProgram(address asset) external view override returns (address) {\n return _getRewardProgram(asset);\n }\n\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\n return _nftStake[uuid];\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetDeposit(\n contractAddress,\n tokenId,\n walletManagerId,\n assetAmount\n );\n }\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\n }\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n // \"receiverEnergy\" includes the \"principalAmount\"\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n onlyOwner\n onlyValidContractAddress(controller)\n {\n _chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setMultiplierNft(address nftTokenAddress)\n external\n onlyOwner\n onlyValidContractAddress(nftTokenAddress)\n {\n _multiplierNft = nftTokenAddress;\n }\n\n function setRewardProgram(\n address rewardProgam,\n address assetToken\n )\n external\n onlyOwner\n onlyValidContractAddress(rewardProgam)\n {\n require(assetToken != address(0x0), \"UNI:E-403\");\n _assetRewardPrograms[assetToken] = rewardProgam;\n emit RewardProgramSet(assetToken, rewardProgam);\n }\n\n function removeRewardProgram(address assetToken) external onlyOwner {\n delete _assetRewardPrograms[assetToken];\n emit RewardProgramRemoved(assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getRewardProgram(address assetToken) internal view returns (address) {\n return _assetRewardPrograms[assetToken];\n }\n\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != depositNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n uint256 multiplier = _getNftMultiplier(depositNftAddress, depositNftTokenId);\n\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\n // Add to Multipliers Set\n _multiplierNftsSet[parentNftUuid].add(multiplier);\n\n // Update NFT Stake\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\n } else {\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\n }\n }\n\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\n }\n\n function _registerNftRelease(\n address contractAddress,\n uint256 tokenId,\n address releaseNftAddress,\n uint256 releaseNftTokenId,\n uint256 /* nftTokenAmount */\n )\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != releaseNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n NftStake storage nftStake = _nftStake[parentNftUuid];\n\n // Remove from Multipliers Set\n uint256 multiplier = _getNftMultiplier(releaseNftAddress, releaseNftTokenId);\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\n\n // Determine New Multiplier or Mark as Released\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\n } else {\n nftStake.releaseBlockNumber = block.number;\n }\n\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\n }\n\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\n uint256 i = 0;\n uint256 multiplier = _multiplierNftsSet[parentNftUuid].at(i);\n\n // If holding all 6, Max Multiplier of 10X\n if (len == 6) {\n return LEPTON_MULTIPLIER_SCALE.mul(10);\n }\n\n // If holding multiple; Multiplier = Half of the Sum of all\n if (len > 1) {\n for (; i < len; i++) {\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\n }\n return multiplier.div(2); // Half of the Sum\n }\n\n // Holding single or none\n return multiplier;\n }\n\n function _getNftMultiplier(address contractAddress, uint256 tokenId) internal returns (uint256) {\n bytes4 fnSig = IRewardNft.getMultiplier.selector;\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n\n if (success) {\n return abi.decode(returnData, (uint256));\n } else {\n return 0;\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(_chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/vesting/VestingClaim7.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract VestingClaim7 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"VestingClaim7: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"VestingClaim7: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"VestingClaim7: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"VestingClaim7: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"VestingClaim7: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"VestingClaim7: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveSmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\nimport \"../../interfaces/IAaveBridge.sol\";\nimport \"../../lib/SmartWalletBase.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet for Aave Assets\n * @dev Non-upgradeable Contract\n */\ncontract AaveSmartWallet is SmartWalletBase {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 constant internal RAY = 1e27;\n\n IAaveBridge internal _bridge;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(\n address aaveBridge\n )\n public\n {\n SmartWalletBase.initializeBase();\n _bridge = IAaveBridge(aaveBridge);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _bridge.isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address) {\n return _bridge.getReserveInterestToken(assetToken);\n }\n\n function getPrincipal(address assetToken) external override returns (uint256) {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address assetToken) external override returns (uint256 creatorInterest, uint256 ownerInterest) {\n return _getInterest(assetToken);\n }\n\n function getTotal(address assetToken) external override returns (uint256) {\n return _getTotal(assetToken);\n }\n\n function getRewards(address rewardToken) external override returns (uint256) {\n return IERC20(rewardToken).balanceOf(address(this));\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _deposit(assetToken, assetAmount, referralCode);\n }\n\n\n function withdraw(\n address receiver,\n address creatorRedirect,\n address assetToken\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (, uint256 ownerInterest) = _getInterest(assetToken);\n return _withdraw(receiver, creatorRedirect, assetToken, walletPrincipal.add(ownerInterest));\n }\n\n function withdrawAmount(\n address receiver,\n address creatorRedirect,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return _withdraw(receiver, creatorRedirect, assetToken, assetAmount);\n }\n\n function withdrawAmountForCreator(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return _withdrawForCreator(receiver, assetToken, assetAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _withdrawRewards(receiver, rewardsToken, rewardsAmount);\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n internal\n returns (uint256)\n {\n _trackAssetToken(assetToken);\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n\n // Deposit Assets into Aave (reverts on fail)\n _sendToken(address(_bridge), assetToken, assetAmount);\n uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function _withdraw(\n address receiver,\n address creatorRedirect,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken);\n\n // Withdraw from Interest only\n if (assetAmount < ownerInterest) {\n if (creatorInterest > 0) {\n uint256 ratio = assetAmount.mul(RAY).div(ownerInterest);\n creatorAmount = creatorInterest.add(nftCreatorAmountDischarged).mul(ratio).div(RAY);\n\n if (creatorAmount <= nftCreatorAmountDischarged) {\n nftCreatorAmountDischarged = nftCreatorAmountDischarged.sub(creatorAmount);\n creatorAmount = 0;\n }\n\n else {\n creatorAmount = creatorAmount.sub(nftCreatorAmountDischarged);\n nftCreatorAmountDischarged = 0;\n }\n }\n receiverAmount = assetAmount;\n }\n\n // Withdraw from Interest + Principal\n else {\n uint256 fromPrincipal = assetAmount.sub(ownerInterest);\n if (fromPrincipal > walletPrincipal) {\n fromPrincipal = walletPrincipal.sub(ownerInterest);\n }\n\n creatorAmount = creatorInterest;\n receiverAmount = ownerInterest.add(fromPrincipal);\n nftCreatorAmountDischarged = 0;\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal);\n }\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount));\n\n // Withdraw Assets for Creator\n if (creatorAmount > 0) {\n address receivesForCreator = (creatorRedirect != address(0x0)) ? creatorRedirect : nftCreator;\n _bridge.withdraw(receivesForCreator, assetToken, creatorAmount);\n }\n\n // Withdraw Assets for Receiver\n _bridge.withdraw(receiver, assetToken, receiverAmount);\n }\n\n function _withdrawForCreator(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 receiverAmount)\n {\n (uint256 creatorInterest,) = _getInterest(assetToken);\n if (creatorInterest == 0) { return 0; }\n if (assetAmount > creatorInterest) {\n assetAmount = creatorInterest;\n }\n\n nftCreatorAmountDischarged = nftCreatorAmountDischarged.add(assetAmount);\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, assetAmount);\n\n // Withdraw Assets for Receiver on behalf of Creator\n _bridge.withdraw(receiver, assetToken, assetAmount);\n }\n\n function _withdrawRewards(\n address receiver,\n address rewardsTokenAddress,\n uint256 rewardsAmount\n )\n internal\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"ASW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function _getTotal(address assetToken) internal view returns (uint256) {\n return _bridge.getTotalBalance(address(this), assetToken);\n }\n\n function _getInterest(address assetToken) internal view returns (uint256 creatorInterest, uint256 ownerInterest) {\n uint256 total = _getTotal(assetToken);\n uint256 principal = _getPrincipal(assetToken);\n uint256 interest = total.sub(principal);\n\n // Creator Royalties\n if (nftCreatorAnnuityPct > 0) {\n\n // Interest too small to calculate percentage;\n if (interest <= PERCENTAGE_SCALE) {\n // creatorInterest = interest.div(2); // split evenly?\n creatorInterest = 0; // All to owner\n }\n\n // Calculate percentage for Creator\n else {\n creatorInterest = interest\n .add(nftCreatorAmountDischarged)\n .mul(nftCreatorAnnuityPct)\n .div(PERCENTAGE_SCALE)\n .sub(nftCreatorAmountDischarged);\n }\n }\n\n // Owner Portion\n ownerInterest = interest.sub(creatorInterest);\n }\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveSmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\nimport \"../../interfaces/IAaveBridge.sol\";\nimport \"../../lib/SmartWalletBaseB.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet for Aave Assets\n * @dev Non-upgradeable Contract\n */\ncontract AaveSmartWalletB is SmartWalletBaseB {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 constant internal RAY = 1e27;\n\n IAaveBridge internal _bridge;\n\n uint256 internal _nftCreatorAmountDischarged;\n\n mapping (address => address) internal _assetATokens;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(\n address aaveBridge\n )\n public\n {\n SmartWalletBaseB.initializeBase();\n _bridge = IAaveBridge(aaveBridge);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _bridge.isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address) {\n return _bridge.getReserveInterestToken(assetToken);\n }\n\n function getPrincipal(address assetToken) external override returns (uint256) {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address assetToken, uint256 creatorPct) external override returns (uint256 creatorInterest, uint256 ownerInterest) {\n return _getInterest(assetToken, creatorPct);\n }\n\n function getTotal(address assetToken) external override returns (uint256) {\n return _getTotal(assetToken);\n }\n\n function getRewards(address rewardToken) external override returns (uint256) {\n return IERC20(rewardToken).balanceOf(address(this));\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _deposit(assetToken, assetAmount, referralCode);\n }\n\n\n function withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (, uint256 ownerInterest) = _getInterest(assetToken, creatorPct);\n return _withdraw(receiver, creator, creatorPct, assetToken, walletPrincipal.add(ownerInterest));\n }\n\n function withdrawAmount(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return _withdraw(receiver, creator, creatorPct, assetToken, assetAmount);\n }\n\n function withdrawAmountForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return _withdrawForCreator(receiver, creatorPct, assetToken, assetAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _withdrawRewards(receiver, rewardsToken, rewardsAmount);\n }\n\n function refreshPrincipal(address assetToken) external virtual override onlyWalletManager {\n uint256 aTokenBalance = IERC20(_assetATokens[assetToken]).balanceOf(address(this));\n if (_assetPrincipalBalance[assetToken] > aTokenBalance) {\n _assetPrincipalBalance[assetToken] = aTokenBalance;\n }\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n internal\n returns (uint256)\n {\n _trackAssetToken(assetToken);\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n\n // Deposit Assets into Aave (reverts on fail)\n _sendToken(address(_bridge), assetToken, assetAmount);\n uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function _withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken, creatorPct);\n\n // Withdraw from Interest only\n if (assetAmount < ownerInterest) {\n if (creatorInterest > 0) {\n uint256 ratio = assetAmount.mul(RAY).div(ownerInterest);\n creatorAmount = creatorInterest.add(_nftCreatorAmountDischarged).mul(ratio).div(RAY);\n\n if (creatorAmount <= _nftCreatorAmountDischarged) {\n _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.sub(creatorAmount);\n creatorAmount = 0;\n }\n else {\n creatorAmount = creatorAmount.sub(_nftCreatorAmountDischarged);\n _nftCreatorAmountDischarged = 0;\n }\n }\n receiverAmount = assetAmount;\n }\n\n // Withdraw from Interest + Principal\n else {\n uint256 fromPrincipal = assetAmount.sub(ownerInterest);\n if (fromPrincipal > walletPrincipal) {\n fromPrincipal = walletPrincipal.sub(ownerInterest);\n }\n\n creatorAmount = creatorInterest;\n receiverAmount = ownerInterest.add(fromPrincipal);\n _nftCreatorAmountDischarged = 0;\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal);\n }\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount));\n\n // Withdraw Assets for Creator\n if (creatorAmount > 0) {\n if (creator != address(0)) {\n _bridge.withdraw(creator, assetToken, creatorAmount);\n } else {\n receiverAmount = receiverAmount.add(creatorAmount);\n creatorAmount = 0;\n }\n }\n\n // Withdraw Assets for Receiver\n _bridge.withdraw(receiver, assetToken, receiverAmount);\n }\n\n function _withdrawForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 receiverAmount)\n {\n (uint256 creatorInterest,) = _getInterest(assetToken, creatorPct);\n if (creatorInterest == 0) { return 0; }\n if (assetAmount > creatorInterest) {\n assetAmount = creatorInterest;\n }\n\n _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.add(assetAmount);\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, assetAmount);\n\n // Withdraw Assets for Receiver on behalf of Creator\n _bridge.withdraw(receiver, assetToken, assetAmount);\n }\n\n function _withdrawRewards(\n address receiver,\n address rewardsTokenAddress,\n uint256 rewardsAmount\n )\n internal\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"ASW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function _getTotal(address assetToken) internal view returns (uint256) {\n return _bridge.getTotalBalance(address(this), assetToken);\n }\n\n function _getInterest(address assetToken, uint256 creatorPct) internal view returns (uint256 creatorInterest, uint256 ownerInterest) {\n uint256 total = _getTotal(assetToken);\n uint256 principal = _getPrincipal(assetToken);\n uint256 interest = total.sub(principal);\n\n // Creator Royalties\n if (creatorPct > 0) {\n\n // Interest too small to calculate percentage;\n if (interest <= PERCENTAGE_SCALE) {\n // creatorInterest = interest.div(2); // split evenly?\n creatorInterest = 0; // All to owner\n }\n\n // Calculate percentage for Creator\n else {\n creatorInterest = interest\n .add(_nftCreatorAmountDischarged)\n .mul(creatorPct)\n .div(PERCENTAGE_SCALE)\n .sub(_nftCreatorAmountDischarged);\n }\n }\n\n // Owner Portion\n ownerInterest = interest.sub(creatorInterest);\n }\n\n function _trackAssetToken(address assetToken) internal override {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _assetATokens[assetToken] = aTokenAddress;\n }\n }\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../lib/WalletManagerBase.sol\";\n\nimport \"./AaveSmartWallet.sol\";\n\n/**\n * @notice Wallet Manager for Aave\n * @dev Non-upgradeable Contract\n */\ncontract AaveWalletManager is WalletManagerBase {\n using SafeMath for uint256;\n\n event AaveBridgeSet(address indexed aaveBridge);\n event ValidRewardsTokenSet(address indexed rewardsToken, bool state);\n\n address internal _aaveBridge;\n uint256 internal _referralCode;\n\n mapping (address => bool) public rewardsTokenWhitelist;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new AaveSmartWallet());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return AaveSmartWallet(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return AaveSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return AaveSmartWallet(_wallets[uuid]).getInterest(assetToken);\n }\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getTotal(assetToken);\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getRewards(_rewardToken);\n }\n\n\n /***********************************|\n | Only Controller |\n |__________________________________*/\n\n function energize(\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = AaveSmartWallet(wallet).deposit(assetToken, assetAmount, _referralCode);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(ownerInterest > 0, \"AWM:E-412\");\n\n // Discharge the full amount of interest\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, ownerInterest);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(assetAmount > 0 && ownerInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmountForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address creator,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (uint256 creatorInterest,) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(assetAmount > 0 && creatorInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n receiverAmount = AaveSmartWallet(wallet).withdrawAmountForCreator(receiver, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount);\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = AaveSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0;\n\n // Release from interest first + principal if needed\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n require(rewardsTokenWhitelist[rewardsToken], \"AWM:E-423\");\n\n // Withdraw Rewards to Receiver\n amount = AaveSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 tokenId,\n address externalAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return AaveSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n // no-op\n }\n\n function getWalletAddressById(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPct\n )\n external\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n\n if (creator != address(0x0)) {\n AaveSmartWallet(wallet).setNftCreator(creator, annuityPct);\n }\n\n emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAaveBridge(address aaveBridge) external onlyOwner {\n require(aaveBridge != address(0x0), \"AWM:E-403\");\n _aaveBridge = aaveBridge;\n emit AaveBridgeSet(aaveBridge);\n }\n\n // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool\n function setReferralCode(uint256 referralCode) external onlyOwner {\n _referralCode = referralCode;\n }\n\n function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner {\n rewardsTokenWhitelist[rewardsToken] = state;\n emit ValidRewardsTokenSet(rewardsToken, state);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n AaveSmartWallet(newWallet).initialize(_aaveBridge);\n return newWallet;\n }\n}" + }, + "contracts/v1/yield/aave/AaveWalletManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../lib/WalletManagerBase.sol\";\nimport \"../../interfaces/IChargedSettings.sol\";\nimport \"./AaveSmartWalletB.sol\";\n\n/**\n * @notice Wallet Manager for Aave\n * @dev Non-upgradeable Contract\n */\ncontract AaveWalletManagerB is WalletManagerBase {\n using SafeMath for uint256;\n\n event AaveBridgeSet(address indexed aaveBridge);\n event ChargedSettingsSet(address indexed settings);\n event ValidRewardsTokenSet(address indexed rewardsToken, bool state);\n\n IChargedSettings internal _chargedSettings;\n\n address internal _aaveBridge;\n uint256 internal _referralCode;\n\n mapping (address => bool) public _rewardsTokenWhitelist;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new AaveSmartWalletB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return AaveSmartWalletB(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return AaveSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n return AaveSmartWalletB(_wallets[uuid]).getInterest(assetToken, annuityPct);\n }\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getTotal(assetToken);\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getRewards(_rewardToken);\n }\n\n\n /***********************************|\n | Only Controller |\n |__________________________________*/\n\n function energize(\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = AaveSmartWalletB(wallet).deposit(assetToken, assetAmount, _referralCode);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(ownerInterest > 0, \"AWM:E-412\");\n\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Discharge the full amount of interest\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, ownerInterest);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(assetAmount > 0 && ownerInterest >= assetAmount, \"AWM:E-412\");\n\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Discharge a portion of the interest\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmountForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address creator,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (uint256 creatorInterest,) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(assetAmount > 0 && creatorInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n receiverAmount = AaveSmartWalletB(wallet).withdrawAmountForCreator(receiver, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount);\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Release Principal + Interest\n principalAmount = AaveSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdraw(receiver, creator, annuityPct, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0;\n\n // Release from interest first + principal if needed\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n require(_rewardsTokenWhitelist[rewardsToken], \"AWM:E-423\");\n\n // Withdraw Rewards to Receiver\n amount = AaveSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 tokenId,\n address externalAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return AaveSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n AaveSmartWalletB(wallet).refreshPrincipal(assetToken);\n }\n\n function getWalletAddressById(\n address contractAddress,\n uint256 tokenId,\n address /* creator */,\n uint256 /* annuityPct */\n )\n external\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAaveBridge(address aaveBridge) external onlyOwner {\n require(aaveBridge != address(0x0), \"AWM:E-403\");\n _aaveBridge = aaveBridge;\n emit AaveBridgeSet(aaveBridge);\n }\n\n function setChargedSettings(address settings) external onlyOwner {\n require(settings != address(0x0), \"AWM:E-403\");\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool\n function setReferralCode(uint256 referralCode) external onlyOwner {\n _referralCode = referralCode;\n }\n\n function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner {\n _rewardsTokenWhitelist[rewardsToken] = state;\n emit ValidRewardsTokenSet(rewardsToken, state);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n AaveSmartWalletB(newWallet).initialize(_aaveBridge);\n return newWallet;\n }\n}" + }, + "contracts/v1/yield/aave/v2/AaveBridgeV2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveBridgeV2.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/SafeCast.sol\";\n\nimport \"./IATokenV2.sol\";\nimport \"./ILendingPoolV2.sol\";\nimport \"./ILendingPoolAddressesProviderV2.sol\";\n\nimport \"../../../interfaces/IAaveBridge.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\n\ncontract AaveBridgeV2 is Ownable, IAaveBridge, BlackholePrevention {\n using SafeMath for uint256;\n using SafeCast for uint256;\n using SafeERC20 for IERC20;\n using ReserveLogic for ReserveLogic.ReserveData;\n\n ILendingPoolAddressesProviderV2 public provider;\n ILendingPoolV2 public lendingPool;\n\n constructor (address lendingPoolProvider) public {\n provider = ILendingPoolAddressesProviderV2(lendingPoolProvider);\n lendingPool = ILendingPoolV2(provider.getLendingPool());\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address aTokenAddress) {\n return _getReserveInterestToken(assetToken);\n }\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _isReserveActive(assetToken);\n }\n\n function getTotalBalance(address account, address assetToken) external view override returns (uint256) {\n address aTokenAddress = _getReserveInterestToken(assetToken);\n if (aTokenAddress == address(0x0)) { return 0; }\n return IATokenV2(aTokenAddress).balanceOf(account);\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n returns (uint256)\n {\n address self = address(this);\n address aTokenAddress = _getReserveInterestToken(assetToken);\n require(_isReserveActive(assetToken), \"ABV2:E-424\");\n\n IERC20 token = IERC20(assetToken);\n IATokenV2 aToken = IATokenV2(aTokenAddress);\n\n if (token.allowance(address(this), address(lendingPool)) < assetAmount) {\n token.approve(address(lendingPool), uint256(-1));\n }\n\n // Deposit Assets into Aave\n uint256 preBalance = aToken.balanceOf(self);\n lendingPool.deposit(assetToken, assetAmount, self, referralCode.toUint16());\n uint256 postBalance = aToken.balanceOf(self);\n uint256 aTokensAmount = postBalance.sub(preBalance);\n\n // Transfer back the Interest Tokens\n _sendToken(msg.sender, aTokenAddress, aTokensAmount);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function withdraw(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n {\n address self = address(this);\n require(_isReserveActive(assetToken), \"ABV2:E-424\");\n\n // Redeem aTokens for Asset Tokens\n lendingPool.withdraw(assetToken, assetAmount, self);\n\n // Transfer back the Asset Tokens\n _sendToken(receiver, assetToken, assetAmount);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n\n function _getReserveInterestToken(address assetToken) internal view returns (address aTokenAddress) {\n ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken);\n return config.aTokenAddress;\n }\n\n function _isReserveActive(address assetToken) internal view returns (bool) {\n ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken);\n uint256 isActiveFlag = 2 ** 56; // bit 56: reserve is active\n return (config.configuration.data & isActiveFlag) == isActiveFlag;\n }\n}\n" + }, + "contracts/v1/yield/aave/v2/IATokenV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\n\ninterface IATokenV2 {\n function balanceOf(address account) external view returns (uint256);\n}\n" + }, + "contracts/v1/yield/aave/v2/ILendingPoolAddressesProviderV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\n\ninterface ILendingPoolAddressesProviderV2 {\n function getLendingPool() external view returns (address);\n}" + }, + "contracts/v1/yield/aave/v2/ILendingPoolV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport \"./ILendingPoolAddressesProviderV2.sol\";\n\nlibrary ReserveConfiguration {\n struct Map {\n uint256 data;\n }\n}\n\nlibrary ReserveLogic {\n struct ReserveData {\n ReserveConfiguration.Map configuration;\n uint128 liquidityIndex;\n uint128 variableBorrowIndex;\n uint128 currentLiquidityRate;\n uint128 currentVariableBorrowRate;\n uint128 currentStableBorrowRate;\n uint40 lastUpdateTimestamp;\n address aTokenAddress;\n address stableDebtTokenAddress;\n address variableDebtTokenAddress;\n address interestRateStrategyAddress;\n uint8 id;\n }\n}\n\ninterface ILendingPoolV2 {\n function deposit(address reserve, uint256 amount, address onBehalfOf, uint16 referralCode) external;\n function withdraw(address reserve, uint256 amount, address to) external;\n function getReserveData(address asset) external view returns (ReserveLogic.ReserveData memory);\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericSmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"../../../lib/SmartWalletBase.sol\";\n\n\n/**\n * @notice Generic ERC20-Token Smart-Wallet Bridge\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartWallet is SmartWalletBase {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize()\n public\n {\n SmartWalletBase.initializeBase();\n }\n\n function isReserveActive(address assetToken)\n external\n override\n view\n returns (bool)\n {\n return _getPrincipal(assetToken) == 0;\n }\n\n function getReserveInterestToken(address assetToken)\n external\n override\n view\n returns (address)\n {\n return assetToken;\n }\n\n function getPrincipal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address /* assetToken */)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n return (0, 0);\n }\n\n function getTotal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getRewards(address assetToken)\n external\n override\n returns (uint256)\n {\n return IERC20(assetToken).balanceOf(address(this));\n }\n\n function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n // Track Principal\n _trackAssetToken(assetToken);\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n }\n\n function withdraw(address receiver, address /* creatorRedirect */, address assetToken)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmount(address receiver, address /* creatorRedirect */, address assetToken, uint256 assetAmount)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n if (receiverAmount >= assetAmount) {\n receiverAmount = assetAmount;\n }\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmountForCreator(\n address /* receiver */,\n address /* assetToken */,\n uint256 /* assetID */\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericSmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWalletB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"../../../lib/SmartWalletBaseB.sol\";\n\n\n/**\n * @notice Generic ERC20-Token Smart-Wallet Bridge\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartWalletB is SmartWalletBaseB {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize()\n public\n {\n SmartWalletBaseB.initializeBase();\n }\n\n function isReserveActive(address assetToken)\n external\n override\n view\n returns (bool)\n {\n return _getPrincipal(assetToken) == 0;\n }\n\n function getReserveInterestToken(address assetToken)\n external\n override\n view\n returns (address)\n {\n return assetToken;\n }\n\n function getPrincipal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address /* assetToken */, uint256 /* creatorPct */)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n return (0, 0);\n }\n\n function getTotal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getRewards(address assetToken)\n external\n override\n returns (uint256)\n {\n return IERC20(assetToken).balanceOf(address(this));\n }\n\n function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n // Track Principal\n _trackAssetToken(assetToken);\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n }\n\n function withdraw(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmount(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken, uint256 assetAmount)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n if (receiverAmount >= assetAmount) {\n receiverAmount = assetAmount;\n }\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmountForCreator(\n address /* receiver */,\n uint256 /* creatorPct */,\n address /* assetToken */,\n uint256 /* assetID */\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function refreshPrincipal(address assetToken) external virtual override onlyWalletManager {\n _assetPrincipalBalance[assetToken] = IERC20(assetToken).balanceOf(address(this));\n }\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../../lib/WalletManagerBase.sol\";\nimport \"./GenericSmartWallet.sol\";\n\n/**\n * @notice Generic ERC20 Wallet Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericWalletManager is WalletManagerBase {\n using SafeMath for uint256;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new GenericSmartWallet());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return GenericSmartWallet(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return GenericSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getTotal(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return GenericSmartWallet(_wallets[uuid]).getInterest(assetToken);\n }\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getRewards(rewardToken);\n }\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount)\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = GenericSmartWallet(wallet).deposit(assetToken, assetAmount, 0);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmountForCreator(\n address /* receiver */,\n address /* contractAddress */,\n uint256 /* tokenId */,\n address /* creator */,\n address /* assetToken */,\n uint256 /* assetAmount */\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release from interest first + principal if needed\n principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n external\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return GenericSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n // no-op\n }\n\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct)\n external\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n\n if (creator != address(0x0)) {\n GenericSmartWallet(wallet).setNftCreator(creator, annuityPct);\n }\n\n emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n GenericSmartWallet(newWallet).initialize();\n return newWallet;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericWalletManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericWalletManagerB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../../lib/WalletManagerBase.sol\";\nimport \"./GenericSmartWalletB.sol\";\n\n/**\n * @notice Generic ERC20 Wallet Manager B\n * @dev Non-upgradeable Contract\n */\ncontract GenericWalletManagerB is WalletManagerBase {\n using SafeMath for uint256;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new GenericSmartWalletB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return GenericSmartWalletB(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return GenericSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getTotal(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return GenericSmartWalletB(_wallets[uuid]).getInterest(assetToken, 0);\n }\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getRewards(rewardToken);\n }\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount)\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = GenericSmartWalletB(wallet).deposit(assetToken, assetAmount, 0);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmountForCreator(\n address /* receiver */,\n address /* contractAddress */,\n uint256 /* tokenId */,\n address /* creator */,\n address /* assetToken */,\n uint256 /* assetAmount */\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdraw(receiver, creatorRedirect, 0, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release from interest first + principal if needed\n principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdrawAmount(receiver, creatorRedirect, 0, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyControllerOrExecutor\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n external\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return GenericSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n GenericSmartWalletB(wallet).refreshPrincipal(assetToken);\n }\n\n function getWalletAddressById(address contractAddress, uint256 tokenId, address /* creator */, uint256 /* annuityPct */)\n external\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n GenericSmartWalletB(newWallet).initialize();\n return newWallet;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericBasketManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"../../../interfaces/IBasketManager.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"./GenericSmartBasket.sol\";\n\n/**\n * @notice Generic ERC721 Basket Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericBasketManager is Ownable, BlackholePrevention, IBasketManager {\n using Counters for Counters.Counter;\n using TokenInfo for address;\n\n // The Controller Contract Address\n address internal _controller;\n\n // Template Contract for creating Token Smart-Baskets\n address internal _basketTemplate;\n\n // TokenID => Token Smart-Basket Address\n mapping (uint256 => address) internal _baskets;\n\n mapping (uint256 => Counters.Counter) internal _totalTokens;\n\n // State of Basket Manager\n bool internal _paused;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _basketTemplate = address(new GenericSmartBasket());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n function getTokenTotalCount(\n address contractAddress,\n uint256 tokenId\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n return _totalTokens[uuid].current();\n }\n\n function getTokenCountByType(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n external\n override\n returns (uint256)\n {\n address basket = getBasketAddressById(contractAddress, tokenId);\n return GenericSmartBasket(basket).getTokenCountByType(basketTokenAddress, basketTokenId);\n }\n\n function prepareTransferAmount(uint256 /* nftTokenAmount */) external override onlyController {\n // no-op\n }\n\n function addToBasket(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n whenNotPaused\n returns (bool added)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n added = GenericSmartBasket(basket).addToBasket(basketTokenAddress, basketTokenId);\n\n // Log Event\n if (added) {\n _totalTokens[uuid].increment();\n emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, 1);\n }\n }\n\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n returns (bool removed)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n removed = GenericSmartBasket(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId);\n\n // Log Event\n if (removed) {\n _totalTokens[uuid].decrement();\n emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, 1);\n }\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyController\n returns (uint256 amount)\n {\n // no-op\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n public\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n return GenericSmartBasket(basket).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function getBasketAddressById(address contractAddress, uint256 tokenId)\n public\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n // Create Smart-Basket if none exists\n if (basket == address(0x0)) {\n basket = _createBasket();\n _baskets[uuid] = basket;\n\n emit NewSmartBasket(contractAddress, tokenId, basket);\n }\n\n return basket;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Basket Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartBasket(basket).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n function _createBasket()\n internal\n returns (address)\n {\n address newBasket = _createClone(_basketTemplate);\n GenericSmartBasket(newBasket).initialize();\n return newBasket;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"GBM:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"GBM:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericBasketManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport \"../../../interfaces/IBasketManager.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../interfaces/ITokenInfoProxy.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"../../../lib/NftTokenType.sol\";\nimport \"./GenericSmartBasketB.sol\";\n\n/**\n * @notice Generic ERC721 Basket Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericBasketManagerB is Ownable, BlackholePrevention, IBasketManager {\n using Counters for Counters.Counter;\n using TokenInfo for address;\n using NftTokenType for address;\n\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // The Controller Contract Address\n address internal _controller;\n\n // The Executor Contract Address\n address internal _executor;\n\n // Template Contract for creating Token Smart-Baskets\n address internal _basketTemplate;\n\n // TokenID => Token Smart-Basket Address\n mapping (uint256 => address) internal _baskets;\n\n // Prepared Amount\n uint256 internal _preparedAmount;\n\n // State of Basket Manager\n bool internal _paused;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _basketTemplate = address(new GenericSmartBasketB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n function getTokenTotalCount(\n address contractAddress,\n uint256 tokenId\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n if (basket == address(0)) { return 0; }\n return GenericSmartBasketB(basket).getNestedNftCount();\n }\n\n function getTokenCountByType(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n if (basket == address(0)) { return 0; }\n return GenericSmartBasketB(basket).getTokenCountByType(basketTokenAddress, basketTokenId);\n }\n\n function prepareTransferAmount(uint256 nftTokenAmount) external override onlyController {\n _preparedAmount = nftTokenAmount;\n }\n\n function addToBasket(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n whenNotPaused\n returns (bool added)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n uint256 nftTokenAmount = 1;\n if (_preparedAmount > 0) {\n nftTokenAmount = _preparedAmount;\n _preparedAmount = 0;\n }\n\n added = GenericSmartBasketB(basket).addToBasket(basketTokenAddress, basketTokenId, nftTokenAmount);\n if (added) {\n emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount);\n }\n }\n\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n returns (bool removed)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n uint256 nftTokenAmount = 1;\n if (_preparedAmount > 0) {\n nftTokenAmount = _preparedAmount;\n _preparedAmount = 0;\n }\n\n removed = GenericSmartBasketB(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId, nftTokenAmount);\n if (removed) {\n emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount);\n }\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyControllerOrExecutor\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartBasketB(basket).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit BasketRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n public\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n return GenericSmartBasketB(basket).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function getBasketAddressById(address contractAddress, uint256 tokenId)\n public\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n // Create Smart-Basket if none exists\n if (basket == address(0x0)) {\n basket = _createBasket();\n _baskets[uuid] = basket;\n\n emit NewSmartBasket(contractAddress, tokenId, basket);\n }\n\n return basket;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Basket Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n /**\n * @dev Connects to the ExecForAccount Controller\n */\n function setExecutor(address executor) external onlyOwner {\n _executor = executor;\n emit ExecutorSet(executor);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setTokenInfoProxy(address tokenInfoProxy) external onlyOwner {\n _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartBasket(basket).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createBasket()\n internal\n returns (address)\n {\n address newBasket = _createClone(_basketTemplate);\n GenericSmartBasketB(newBasket).initialize(_tokenInfoProxy);\n return newBasket;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"GBM:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Controller or Executor contract\n modifier onlyControllerOrExecutor() {\n require(_executor == msg.sender || _controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"GBM:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericSmartBasket.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/NftTokenType.sol\";\n\n\n/**\n * @notice Generic ERC721-Token Smart-Basket\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartBasket is ISmartBasket, BlackholePrevention, IERC721Receiver {\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableSet for EnumerableSet.AddressSet;\n using NftTokenType for address;\n\n address internal _basketManager;\n\n // NFT contract address => Token Ids in Basket\n mapping (address => mapping(uint256 => EnumerableSet.UintSet)) internal _nftContractTokens;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public {\n require(_basketManager == address(0x0), \"GSB:E-002\");\n _basketManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n return _nftContractTokens[contractAddress][nftType].length();\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver(0).onERC721Received.selector;\n }\n\n function addToBasket(address contractAddress, uint256 tokenId)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n require(!_nftContractTokens[contractAddress][nftType].contains(tokenId), \"GSB:E-425\");\n\n bool added = _nftContractTokens[contractAddress][nftType].add(tokenId);\n if (added) {\n // NFT should have been Transferred into here via Charged-Particles\n added = (IERC721(contractAddress).ownerOf(tokenId) == address(this));\n }\n return added;\n }\n\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n require(_nftContractTokens[contractAddress][nftType].contains(tokenId), \"GSB:E-426\");\n\n bool removed = _nftContractTokens[contractAddress][nftType].remove(tokenId);\n if (removed) {\n IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId);\n }\n return removed;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyBasketManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the basket manager\n modifier onlyBasketManager() {\n require(_basketManager == msg.sender, \"GSB:E-109\");\n _;\n }\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericSmartBasketB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155Receiver.sol\";\nimport \"../../../interfaces/ISmartBasketB.sol\";\nimport \"../../../interfaces/ITokenInfoProxy.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"../../../lib/NftTokenType.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\n\n/**\n * @notice Generic ERC721-Token Smart-Basket\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartBasketB is ISmartBasketB, BlackholePrevention, IERC721Receiver, ERC1155Receiver {\n using TokenInfo for address;\n using NftTokenType for address;\n\n address internal _basketManager;\n\n // NFT TokenUUID => ERC1155 Balance\n mapping (uint256 => uint256) internal _nftContractTokenBalance;\n uint256 internal _nestedNftCount;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(ITokenInfoProxy /* tokenInfoProxy */) public {\n require(_basketManager == address(0x0), \"GSB:E-002\");\n _basketManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getNestedNftCount() external view override returns (uint256) {\n return _nestedNftCount;\n }\n\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n return _nftContractTokenBalance[contractAddress.getTokenUUID(tokenId)];\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver(0).onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\n return IERC1155Receiver(0).onERC1155Received.selector;\n }\n\n // Unimplemented\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\n return \"\"; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector;\n }\n\n function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n _nftContractTokenBalance[uuid] += nftTokenAmount;\n _nestedNftCount += nftTokenAmount;\n return true;\n }\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n uint256 nftTokenAmount\n )\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n _nftContractTokenBalance[uuid] -= nftTokenAmount;\n _nestedNftCount -= nftTokenAmount;\n\n if (contractAddress.isERC1155()) {\n IERC1155(contractAddress).safeTransferFrom(address(this), receiver, tokenId, nftTokenAmount, \"\");\n } else {\n IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId);\n }\n return true;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyBasketManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSB:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyBasketManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the basket manager\n modifier onlyBasketManager() {\n require(_basketManager == msg.sender, \"GSB:E-109\");\n _;\n }\n}\n" + }, + "erc20permit/contracts/ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"./IERC2612.sol\";\n\n/**\n * @author Georgios Konstantopoulos\n * @dev Extension of {ERC20} that allows token holders to use their tokens\n * without sending any transactions by setting {IERC20-allowance} with a\n * signature using the {permit} method, and then spend them via\n * {IERC20-transferFrom}.\n *\n * The {permit} signature mechanism conforms to the {IERC2612} interface.\n */\nabstract contract ERC20Permit is ERC20, IERC2612 {\n mapping (address => uint256) public override nonces;\n\n bytes32 public immutable PERMIT_TYPEHASH = keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public immutable DOMAIN_SEPARATOR;\n\n constructor(string memory name_, string memory symbol_) internal ERC20(name_, symbol_) {\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name_)),\n keccak256(bytes(\"1\")),\n chainId,\n address(this)\n )\n );\n }\n\n /**\n * @dev See {IERC2612-permit}.\n *\n * In cases where the free option is not a concern, deadline can simply be\n * set to uint(-1), so it should be seen as an optional parameter\n */\n function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {\n require(deadline >= block.timestamp, \"ERC20Permit: expired deadline\");\n\n bytes32 hashStruct = keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n amount,\n nonces[owner]++,\n deadline\n )\n );\n\n bytes32 hash = keccak256(\n abi.encodePacked(\n '\\x19\\x01',\n DOMAIN_SEPARATOR,\n hashStruct\n )\n );\n\n address signer = ecrecover(hash, v, r, s);\n require(\n signer != address(0) && signer == owner,\n \"ERC20Permit: invalid signature\"\n );\n\n _approve(owner, spender, amount);\n }\n}\n" + }, + "erc20permit/contracts/IERC2612.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC2612 standard as defined in the EIP.\n *\n * Adds the {permit} method, which can be used to change one's\n * {IERC20-allowance} without having to send a transaction, by signing a\n * message. This allows users to spend tokens without having to hold Ether.\n *\n * See https://eips.ethereum.org/EIPS/eip-2612.\n */\ninterface IERC2612 {\n /**\n * @dev Sets `amount` 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 * - `owner` cannot be the zero address.\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(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n /**\n * @dev Returns the current ERC2612 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" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "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/deployments/polygon/.chainId b/deployments/polygon/.chainId new file mode 100644 index 0000000..0973804 --- /dev/null +++ b/deployments/polygon/.chainId @@ -0,0 +1 @@ +137 \ No newline at end of file diff --git a/deployments/polygon/DefaultProxyAdmin.json b/deployments/polygon/DefaultProxyAdmin.json new file mode 100644 index 0000000..473e0a4 --- /dev/null +++ b/deployments/polygon/DefaultProxyAdmin.json @@ -0,0 +1,274 @@ +{ + "address": "0x0fD6B09036BF046f2B32E1D7345833bf21db6733", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "initialOwner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + } + ], + "name": "getProxyImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "upgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract TransparentUpgradeableProxy", + "name": "proxy", + "type": "address" + }, + { + "internalType": "address", + "name": "implementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ], + "transactionHash": "0xa8573558c58c3aa8907210e45162ce0542772de8b754a0669cb95bc246056ef9", + "receipt": { + "to": null, + "from": "0xb8D175F16742395F530e0b3bC1d30BD06B78CdA9", + "contractAddress": "0x0fD6B09036BF046f2B32E1D7345833bf21db6733", + "transactionIndex": 32, + "gasUsed": "643983", + "logsBloom": "0x00000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000040000008000000000000000000000000000000000000000000000000000000000800001000000000000000100000000000000000000020000000000000000000800000000000000000080000004000000400000000000000000000000020000000000000000000000000000000000000000200000000000000000000000000000200000000400000000000000000000004000000000000000000001000000000000000000000000000000100000000020000000000000040000000000000000000000010000000000000000000002100000", + "blockHash": "0x875490285156f379e1cbf9d6a14e4b7dd588a7ef422fa45164825c459fa55628", + "transactionHash": "0xa8573558c58c3aa8907210e45162ce0542772de8b754a0669cb95bc246056ef9", + "logs": [ + { + "transactionIndex": 32, + "blockNumber": 46700943, + "transactionHash": "0xa8573558c58c3aa8907210e45162ce0542772de8b754a0669cb95bc246056ef9", + "address": "0x0fD6B09036BF046f2B32E1D7345833bf21db6733", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000b8d175f16742395f530e0b3bc1d30bd06b78cda9" + ], + "data": "0x", + "logIndex": 134, + "blockHash": "0x875490285156f379e1cbf9d6a14e4b7dd588a7ef422fa45164825c459fa55628" + }, + { + "transactionIndex": 32, + "blockNumber": 46700943, + "transactionHash": "0xa8573558c58c3aa8907210e45162ce0542772de8b754a0669cb95bc246056ef9", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000b8d175f16742395f530e0b3bc1d30bd06b78cda9", + "0x000000000000000000000000bdbd4347b082d9d6bdf2da4555a37ce52a2e2120" + ], + "data": "0x0000000000000000000000000000000000000000000000000075e8a856b6a99000000000000000000000000000000000000000000000001a366ae5d5eacee6a000000000000000000000000000000000000000000000346439f4db83bb2c29cf00000000000000000000000000000000000000000000001a35f4fd2d94183d100000000000000000000000000000000000000000000034643a6ac42c11e2d35f", + "logIndex": 135, + "blockHash": "0x875490285156f379e1cbf9d6a14e4b7dd588a7ef422fa45164825c459fa55628" + } + ], + "blockNumber": 46700943, + "cumulativeGasUsed": "6523784", + "status": 1, + "byzantium": true + }, + "args": [ + "0xb8D175F16742395F530e0b3bC1d30BD06B78CdA9" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"initialOwner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"}],\"name\":\"getProxyImplementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract TransparentUpgradeableProxy\",\"name\":\"proxy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\",\"kind\":\"dev\",\"methods\":{\"changeProxyAdmin(address,address)\":{\"details\":\"Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`.\"},\"getProxyAdmin(address)\":{\"details\":\"Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"getProxyImplementation(address)\":{\"details\":\"Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"upgrade(address,address)\":{\"details\":\"Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`.\"},\"upgradeAndCall(address,address,bytes)\":{\"details\":\"Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol\":\"ProxyAdmin\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/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 (address initialOwner) {\\n _transferOwnership(initialOwner);\\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\",\"keccak256\":\"0x9b2bbba5bb04f53f277739c1cdff896ba8b3bf591cfc4eab2098c655e8ac251e\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./TransparentUpgradeableProxy.sol\\\";\\nimport \\\"../../access/Ownable.sol\\\";\\n\\n/**\\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\\n */\\ncontract ProxyAdmin is Ownable {\\n\\n constructor (address initialOwner) Ownable(initialOwner) {}\\n\\n /**\\n * @dev Returns the current implementation of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"implementation()\\\")) == 0x5c60da1b\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"5c60da1b\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Returns the current admin of `proxy`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\\n // We need to manually run the static call since the getter cannot be flagged as view\\n // bytes4(keccak256(\\\"admin()\\\")) == 0xf851a440\\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\\\"f851a440\\\");\\n require(success);\\n return abi.decode(returndata, (address));\\n }\\n\\n /**\\n * @dev Changes the admin of `proxy` to `newAdmin`.\\n *\\n * Requirements:\\n *\\n * - This contract must be the current admin of `proxy`.\\n */\\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\\n proxy.changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\\n proxy.upgradeTo(implementation);\\n }\\n\\n /**\\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\\n *\\n * Requirements:\\n *\\n * - This contract must be the admin of `proxy`.\\n */\\n function upgradeAndCall(\\n TransparentUpgradeableProxy proxy,\\n address implementation,\\n bytes memory data\\n ) public payable virtual onlyOwner {\\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\\n }\\n}\\n\",\"keccak256\":\"0x754888b9c9ab5525343460b0a4fa2e2f4fca9b6a7e0e7ddea4154e2b1182a45d\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev 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\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/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\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50604051610b17380380610b1783398101604081905261002f91610090565b8061003981610040565b50506100c0565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156100a257600080fd5b81516001600160a01b03811681146100b957600080fd5b9392505050565b610a48806100cf6000396000f3fe60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461012b57806399a88ec41461013e578063f2fde38b1461015e578063f3b7dead1461017e57600080fd5b8063204e1c7a14610080578063715018a6146100c95780637eff275e146100e05780638da5cb5b14610100575b600080fd5b34801561008c57600080fd5b506100a061009b3660046107e4565b61019e565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d557600080fd5b506100de610255565b005b3480156100ec57600080fd5b506100de6100fb366004610808565b6102e7565b34801561010c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100a0565b6100de610139366004610870565b6103ee565b34801561014a57600080fd5b506100de610159366004610808565b6104fc565b34801561016a57600080fd5b506100de6101793660046107e4565b6105d1565b34801561018a57600080fd5b506100a06101993660046107e4565b610701565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b600060405180830381855afa9150503d8060008114610225576040519150601f19603f3d011682016040523d82523d6000602084013e61022a565b606091505b50915091508161023957600080fd5b8080602001905181019061024d9190610964565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6102e5600061074d565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610368576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b600060405180830381600087803b1580156103d257600080fd5b505af11580156103e6573d6000803e3d6000fd5b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461046f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef2869034906104c59086908690600401610981565b6000604051808303818588803b1580156104de57600080fd5b505af11580156104f2573d6000803e3d6000fd5b5050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461057d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016103b8565b60005473ffffffffffffffffffffffffffffffffffffffff163314610652576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b73ffffffffffffffffffffffffffffffffffffffff81166106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102d2565b6106fe8161074d565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146106fe57600080fd5b6000602082840312156107f657600080fd5b8135610801816107c2565b9392505050565b6000806040838503121561081b57600080fd5b8235610826816107c2565b91506020830135610836816107c2565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561088557600080fd5b8335610890816107c2565b925060208401356108a0816107c2565b9150604084013567ffffffffffffffff808211156108bd57600080fd5b818601915086601f8301126108d157600080fd5b8135818111156108e3576108e3610841565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561092957610929610841565b8160405282815289602084870101111561094257600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561097657600080fd5b8151610801816107c2565b73ffffffffffffffffffffffffffffffffffffffff8316815260006020604081840152835180604085015260005b818110156109cb578581018301518582016060015282016109af565b818111156109dd576000606083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160600194935050505056fea2646970667358221220bd6c09ab03bfaf9ec60a4bf8cd98903cecb891974e17e2d76a3b2002c97eeb8964736f6c634300080a0033", + "deployedBytecode": "0x60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461012b57806399a88ec41461013e578063f2fde38b1461015e578063f3b7dead1461017e57600080fd5b8063204e1c7a14610080578063715018a6146100c95780637eff275e146100e05780638da5cb5b14610100575b600080fd5b34801561008c57600080fd5b506100a061009b3660046107e4565b61019e565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d557600080fd5b506100de610255565b005b3480156100ec57600080fd5b506100de6100fb366004610808565b6102e7565b34801561010c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100a0565b6100de610139366004610870565b6103ee565b34801561014a57600080fd5b506100de610159366004610808565b6104fc565b34801561016a57600080fd5b506100de6101793660046107e4565b6105d1565b34801561018a57600080fd5b506100a06101993660046107e4565b610701565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b600060405180830381855afa9150503d8060008114610225576040519150601f19603f3d011682016040523d82523d6000602084013e61022a565b606091505b50915091508161023957600080fd5b8080602001905181019061024d9190610964565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6102e5600061074d565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610368576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b600060405180830381600087803b1580156103d257600080fd5b505af11580156103e6573d6000803e3d6000fd5b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461046f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef2869034906104c59086908690600401610981565b6000604051808303818588803b1580156104de57600080fd5b505af11580156104f2573d6000803e3d6000fd5b5050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461057d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016103b8565b60005473ffffffffffffffffffffffffffffffffffffffff163314610652576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016102d2565b73ffffffffffffffffffffffffffffffffffffffff81166106f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016102d2565b6106fe8161074d565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146106fe57600080fd5b6000602082840312156107f657600080fd5b8135610801816107c2565b9392505050565b6000806040838503121561081b57600080fd5b8235610826816107c2565b91506020830135610836816107c2565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060006060848603121561088557600080fd5b8335610890816107c2565b925060208401356108a0816107c2565b9150604084013567ffffffffffffffff808211156108bd57600080fd5b818601915086601f8301126108d157600080fd5b8135818111156108e3576108e3610841565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561092957610929610841565b8160405282815289602084870101111561094257600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561097657600080fd5b8151610801816107c2565b73ffffffffffffffffffffffffffffffffffffffff8316815260006020604081840152835180604085015260005b818110156109cb578581018301518582016060015282016109af565b818111156109dd576000606083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160600194935050505056fea2646970667358221220bd6c09ab03bfaf9ec60a4bf8cd98903cecb891974e17e2d76a3b2002c97eeb8964736f6c634300080a0033", + "devdoc": { + "details": "This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.", + "kind": "dev", + "methods": { + "changeProxyAdmin(address,address)": { + "details": "Changes the admin of `proxy` to `newAdmin`. Requirements: - This contract must be the current admin of `proxy`." + }, + "getProxyAdmin(address)": { + "details": "Returns the current admin of `proxy`. Requirements: - This contract must be the admin of `proxy`." + }, + "getProxyImplementation(address)": { + "details": "Returns the current implementation of `proxy`. Requirements: - This contract must be the admin of `proxy`." + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + }, + "upgrade(address,address)": { + "details": "Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. Requirements: - This contract must be the admin of `proxy`." + }, + "upgradeAndCall(address,address,bytes)": { + "details": "Upgrades `proxy` to `implementation` and calls a function on the new implementation. See {TransparentUpgradeableProxy-upgradeToAndCall}. Requirements: - This contract must be the admin of `proxy`." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 7, + "contract": "solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol:ProxyAdmin", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + } + } + } +} \ No newline at end of file diff --git a/deployments/polygon/Ionx.json b/deployments/polygon/Ionx.json new file mode 100644 index 0000000..b09026e --- /dev/null +++ b/deployments/polygon/Ionx.json @@ -0,0 +1,965 @@ +{ + "address": "0xf80941fA0D07218027435E9028ca21A6e56E3A44", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newMinter", + "type": "address" + } + ], + "name": "MinterChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INFLATION_CAP", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INFLATION_EPOCH", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIAL_SUPPLY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PERMIT_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "minter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "mintingAllowedAfter", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newMinter", + "type": "address" + } + ], + "name": "setMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xeddcca48d33ccffb41a776cd502b215c719803351fd836468ea36d9505c2c436", + "receipt": { + "to": null, + "from": "0x48F54e595bf039CF30fa5F768c0b57EAC6508a06", + "contractAddress": "0xf80941fA0D07218027435E9028ca21A6e56E3A44", + "transactionIndex": 116, + "gasUsed": "1853650", + "logsBloom": "0x02000000000000000000000002000000000000000000000000800000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000010000040800001002000000000000100000000000000000000020000000000000000000800000000000000000080000000000000400000000000000000000000000000000000000000000000000000000000000000200000000004000000000000000000000800000000000000000000000000004000000000000000000001000000000000000000000000000000100000000020000000000000000000000000000000000000000000000000000000000000100000", + "blockHash": "0x11002ccbd7034ff4aa6b2d46d0f303ea090c8fd2751a8edc09eac9f81915b8dd", + "transactionHash": "0xeddcca48d33ccffb41a776cd502b215c719803351fd836468ea36d9505c2c436", + "logs": [ + { + "transactionIndex": 116, + "blockNumber": 55060582, + "transactionHash": "0xeddcca48d33ccffb41a776cd502b215c719803351fd836468ea36d9505c2c436", + "address": "0xf80941fA0D07218027435E9028ca21A6e56E3A44", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000048f54e595bf039cf30fa5f768c0b57eac6508a06" + ], + "data": "0x", + "logIndex": 3471, + "blockHash": "0x11002ccbd7034ff4aa6b2d46d0f303ea090c8fd2751a8edc09eac9f81915b8dd" + }, + { + "transactionIndex": 116, + "blockNumber": 55060582, + "transactionHash": "0xeddcca48d33ccffb41a776cd502b215c719803351fd836468ea36d9505c2c436", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x00000000000000000000000048f54e595bf039cf30fa5f768c0b57eac6508a06", + "0x00000000000000000000000069f5c4d08f6bc8cd29fe5f004d46fb566270868d" + ], + "data": "0x000000000000000000000000000000000000000000000000005179cf22d3022c0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000013bd1ab0e727b482a8780000000000000000000000000000000000000000000000000d8f3ce48490fdd40000000000000000000000000000000000000000000013bd1b0260f6d755aaa4", + "logIndex": 3472, + "blockHash": "0x11002ccbd7034ff4aa6b2d46d0f303ea090c8fd2751a8edc09eac9f81915b8dd" + } + ], + "blockNumber": 55060582, + "cumulativeGasUsed": "24579527", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "d89205a24fa74c6b69fc21ff47ad23be", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newMinter\",\"type\":\"address\"}],\"name\":\"MinterChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC1155\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckEther\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INFLATION_CAP\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INFLATION_EPOCH\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIAL_SUPPLY\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PERMIT_TYPEHASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"mintingAllowedAfter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newMinter\",\"type\":\"address\"}],\"name\":\"setMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawErc20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawEther\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5,05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is called. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"mint(address,uint256)\":{\"params\":{\"amount\":\"The number of tokens to be minted\",\"receiver\":\"The address of the destination account\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC2612-permit}. In cases where the free option is not a concern, deadline can simply be set to uint(-1), so it should be seen as an optional parameter\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"setMinter(address)\":{\"params\":{\"newMinter\":\"The address of the new minter\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}; Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"events\":{\"MinterChanged(address,address)\":{\"notice\":\"An event thats emitted when the minter address is changed\"}},\"kind\":\"user\",\"methods\":{\"INFLATION_CAP()\":{\"notice\":\"Cap on the percentage of totalSupply that can be minted at each mint\"},\"INFLATION_EPOCH()\":{\"notice\":\"Minimum time between mints\"},\"INITIAL_SUPPLY()\":{\"notice\":\"Total number of tokens in circulation\"},\"mint(address,uint256)\":{\"notice\":\"Mint new tokens\"},\"minter()\":{\"notice\":\"Address which may mint new tokens\"},\"mintingAllowedAfter()\":{\"notice\":\"The timestamp after which minting may occur\"},\"setMinter(address)\":{\"notice\":\"Change the minter address\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/v1/tokens/Ionx.sol\":\"Ionx\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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 GSN 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 payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xdb26cbf4d028490f49831a7865c2fe1b28db44b535ca8d343785a3b768aae183\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"../GSN/Context.sol\\\";\\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 */\\ncontract 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 () internal {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view 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 emit OwnershipTransferred(_owner, address(0));\\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x4bd6402ca6b3419008c2b482aff54e66836e8cb4eba2680e42ac5884ae6424fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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\",\"keccak256\":\"0xfa152b6e88a1dc50780e8f1580426dc23ad2e1e2c2f086a088adf206a202f453\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\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 uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\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 sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\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 * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\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 // 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) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts 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 mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9a9cf02622cd7a64261b10534fc3260449da25c98c9e96d1b4ae8110a20e5806\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x31691ad0817f8cb338531b78d2ab2989027d9f27e6f8e62492b754fed9429b10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"../../GSN/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.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 guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 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 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\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 uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name, string memory symbol) public {\\n _name = name;\\n _symbol = symbol;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view 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 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 {_setupDecimals} is\\n * called.\\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 returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal {\\n _decimals = decimals_;\\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 to 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(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0x91e0bd6a6762d2a1700dab0849de8422611355100576c4beef1e80d82a4104a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0x5c26b39d26f7ed489e555d955dcd3e01872972e71fdd1528e93ec164e4f23385\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.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 SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf3b30f8a49631420635a8c35daacfcaa338012755f18a76fdd118730256f9a27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0xaf936da92f3a9a4f98b237323b5eb1d813fb86c4d07a184beba7027cf0509ba3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 in 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 // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n return _functionCallWithValue(target, data, value, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\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 // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf5fa8cbdffa5ef8be49b246b5628facc30b71707e78a45d80d93b64eff3fe390\",\"license\":\"MIT\"},\"contracts/v1/lib/BlackholePrevention.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\\\";\\n\\n/**\\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\\n * the Owner/DAO to pull them out on behalf of a user\\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\\n */\\ncontract BlackholePrevention {\\n using Address for address payable;\\n using SafeERC20 for IERC20;\\n\\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\\n\\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (address(this).balance >= amount) {\\n receiver.sendValue(amount);\\n emit WithdrawStuckEther(receiver, amount);\\n }\\n }\\n\\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\\n IERC20(tokenAddress).safeTransfer(receiver, amount);\\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\\n }\\n }\\n\\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\\n }\\n }\\n\\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \\\"\\\");\\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6a664c8a1c1d7fb32ade2c11f75756b1fdb4c489daa32c1d58e6b867ea2ba8d6\",\"license\":\"MIT\"},\"contracts/v1/tokens/Ionx.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// Ionx.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\n\\nimport \\\"erc20permit/contracts/ERC20Permit.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"../lib/BlackholePrevention.sol\\\";\\n\\n\\ncontract Ionx is ERC20Permit, Ownable, BlackholePrevention {\\n using SafeMath for uint256;\\n\\n /// @notice An event thats emitted when the minter address is changed\\n event MinterChanged(address minter, address newMinter);\\n\\n /// @notice Total number of tokens in circulation\\n uint256 constant public INITIAL_SUPPLY = 1e8 ether;\\n\\n /// @notice Minimum time between mints\\n uint32 public constant INFLATION_EPOCH = 1 days * 365;\\n\\n /// @notice Cap on the percentage of totalSupply that can be minted at each mint\\n uint8 public constant INFLATION_CAP = 2;\\n\\n /// @notice Address which may mint new tokens\\n address public minter;\\n\\n /// @notice The timestamp after which minting may occur\\n uint256 public mintingAllowedAfter;\\n\\n\\n constructor() public ERC20Permit(\\\"Charged Particles - IONX\\\", \\\"IONX\\\") {}\\n\\n\\n /**\\n * @notice Change the minter address\\n * @param newMinter The address of the new minter\\n */\\n function setMinter(address newMinter) external onlyOwner {\\n emit MinterChanged(minter, newMinter);\\n minter = newMinter;\\n }\\n\\n /**\\n * @notice Mint new tokens\\n * @param receiver The address of the destination account\\n * @param amount The number of tokens to be minted\\n */\\n function mint(address receiver, uint256 amount) external onlyMinter {\\n require(block.timestamp >= mintingAllowedAfter, \\\"Ionx:E-114\\\");\\n require(receiver != address(0), \\\"Ionx:E-403\\\");\\n\\n uint256 amountToMint = amount;\\n uint256 _totalSupply = totalSupply();\\n\\n // From Inflationary Supply\\n if (_totalSupply >= INITIAL_SUPPLY) {\\n mintingAllowedAfter = mintingAllowedAfter.add(INFLATION_EPOCH);\\n amountToMint = _totalSupply.mul(INFLATION_CAP).div(100);\\n }\\n\\n // From Initial Supply\\n else {\\n if (_totalSupply.add(amountToMint) > INITIAL_SUPPLY) {\\n amountToMint = INITIAL_SUPPLY.sub(_totalSupply);\\n }\\n if (_totalSupply.add(amountToMint) == INITIAL_SUPPLY) {\\n mintingAllowedAfter = block.timestamp.add(INFLATION_EPOCH);\\n }\\n }\\n\\n // transfer the amount to the recipient\\n _mint(receiver, amountToMint);\\n }\\n\\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n modifier onlyMinter() {\\n require(msg.sender == minter, \\\"Ionx:E-113\\\");\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x248e7f30883795c45e37a90aa8e7cd94cd09fb618122b09d83fd98d2d63fd37d\",\"license\":\"MIT\"},\"erc20permit/contracts/ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\\npragma solidity ^0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"./IERC2612.sol\\\";\\n\\n/**\\n * @author Georgios Konstantopoulos\\n * @dev Extension of {ERC20} that allows token holders to use their tokens\\n * without sending any transactions by setting {IERC20-allowance} with a\\n * signature using the {permit} method, and then spend them via\\n * {IERC20-transferFrom}.\\n *\\n * The {permit} signature mechanism conforms to the {IERC2612} interface.\\n */\\nabstract contract ERC20Permit is ERC20, IERC2612 {\\n mapping (address => uint256) public override nonces;\\n\\n bytes32 public immutable PERMIT_TYPEHASH = keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n bytes32 public immutable DOMAIN_SEPARATOR;\\n\\n constructor(string memory name_, string memory symbol_) internal ERC20(name_, symbol_) {\\n uint256 chainId;\\n assembly {\\n chainId := chainid()\\n }\\n\\n DOMAIN_SEPARATOR = keccak256(\\n abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"),\\n keccak256(bytes(name_)),\\n keccak256(bytes(\\\"1\\\")),\\n chainId,\\n address(this)\\n )\\n );\\n }\\n\\n /**\\n * @dev See {IERC2612-permit}.\\n *\\n * In cases where the free option is not a concern, deadline can simply be\\n * set to uint(-1), so it should be seen as an optional parameter\\n */\\n function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {\\n require(deadline >= block.timestamp, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 hashStruct = keccak256(\\n abi.encode(\\n PERMIT_TYPEHASH,\\n owner,\\n spender,\\n amount,\\n nonces[owner]++,\\n deadline\\n )\\n );\\n\\n bytes32 hash = keccak256(\\n abi.encodePacked(\\n '\\\\x19\\\\x01',\\n DOMAIN_SEPARATOR,\\n hashStruct\\n )\\n );\\n\\n address signer = ecrecover(hash, v, r, s);\\n require(\\n signer != address(0) && signer == owner,\\n \\\"ERC20Permit: invalid signature\\\"\\n );\\n\\n _approve(owner, spender, amount);\\n }\\n}\\n\",\"keccak256\":\"0x2207175c262cdffe2f4e0a31d0c35e02a0ebf2528f21009be6b7743eeb474eaa\",\"license\":\"GPL-3.0-or-later\"},\"erc20permit/contracts/IERC2612.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n// Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Interface of the ERC2612 standard as defined in the EIP.\\n *\\n * Adds the {permit} method, which can be used to change one's\\n * {IERC20-allowance} without having to send a transaction, by signing a\\n * message. This allows users to spend tokens without having to hold Ether.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2612.\\n */\\ninterface IERC2612 {\\n /**\\n * @dev Sets `amount` 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 * - `owner` cannot be the zero address.\\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(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\\n\\n /**\\n * @dev Returns the current ERC2612 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\",\"keccak256\":\"0xe79dd739aaa881172ede4d81472ded9db3a0b4183573c0c01541b4084033b222\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x60c06040527f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c96080523480156200003557600080fd5b50604080518082018252601881527f43686172676564205061727469636c6573202d20494f4e5800000000000000006020808301918252835180850190945260048452630929e9cb60e31b908401528151919291839183916200009b91600391620001c2565b508051620000b1906004906020840190620001c2565b50506005805460ff191660121790555050805160209182012060408051808201825260018152603160f81b9084015280517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81850152808201929092527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608301524660808301523060a08084019190915281518084038201815260c090930190915281519190920120905260006200016a620001be565b600780546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506200025e565b3390565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200020557805160ff191683800117855562000235565b8280016001018555821562000235579182015b828111156200023557825182559160200191906001019062000218565b506200024392915062000247565b5090565b5b8082111562000243576000815560010162000248565b60805160a051611ec16200028c600039806107e35280610d5d5250806107b05280610cf05250611ec16000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80634025feb2116100f957806395d89b4111610097578063d505accf11610071578063d505accf1461050f578063dd62ed3e14610560578063f2fde38b1461058e578063fca3b5aa146105b4576101c4565b806395d89b41146104af578063a457c2d7146104b7578063a9059cbb146104e3576101c4565b806370a08231116100d357806370a0823114610453578063715018a6146104795780637ecebe00146104815780638da5cb5b146104a7576101c4565b80634025feb2146103c557806340c10f19146103fb578063522f681514610427576101c4565b806323b872dd1161016657806330b36cef1161014057806330b36cef14610381578063313ce567146103895780633644e515146103915780633950935114610399576101c4565b806323b872dd1461033b5780632ff2e9dc1461037157806330adf81f14610379576101c4565b80630d1715be116101a25780630d1715be146102aa5780631593dee1146102cb57806318160ddd146103035780631dcb3a3c1461031d576101c4565b806306fdde03146101c95780630754617214610246578063095ea7b31461026a575b600080fd5b6101d16105da565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561020b5781810151838201526020016101f3565b50505050905090810190601f1680156102385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61024e610670565b604080516001600160a01b039092168252519081900360200190f35b6102966004803603604081101561028057600080fd5b506001600160a01b03813516906020013561067f565b604080519115158252519081900360200190f35b6102b261069d565b6040805163ffffffff9092168252519081900360200190f35b610301600480360360608110156102e157600080fd5b506001600160a01b038135811691602081013590911690604001356106a5565b005b61030b61070d565b60408051918252519081900360200190f35b610325610713565b6040805160ff9092168252519081900360200190f35b6102966004803603606081101561035157600080fd5b506001600160a01b03813581169160208101359091169060400135610718565b61030b61079f565b61030b6107ae565b61030b6107d2565b6103256107d8565b61030b6107e1565b610296600480360360408110156103af57600080fd5b506001600160a01b038135169060200135610805565b610301600480360360608110156103db57600080fd5b506001600160a01b03813581169160208101359091169060400135610853565b6103016004803603604081101561041157600080fd5b506001600160a01b0381351690602001356108b6565b6103016004803603604081101561043d57600080fd5b506001600160a01b038135169060200135610a50565b61030b6004803603602081101561046957600080fd5b50356001600160a01b0316610ab6565b610301610ad1565b61030b6004803603602081101561049757600080fd5b50356001600160a01b0316610b73565b61024e610b85565b6101d1610b94565b610296600480360360408110156104cd57600080fd5b506001600160a01b038135169060200135610bf5565b610296600480360360408110156104f957600080fd5b506001600160a01b038135169060200135610c5d565b610301600480360360e081101561052557600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c00135610c71565b61030b6004803603604081101561057657600080fd5b506001600160a01b0381358116916020013516610e9f565b610301600480360360208110156105a457600080fd5b50356001600160a01b0316610eca565b610301600480360360208110156105ca57600080fd5b50356001600160a01b0316610fc3565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106665780601f1061063b57610100808354040283529160200191610666565b820191906000526020600020905b81548152906001019060200180831161064957829003601f168201915b5050505050905090565b6008546001600160a01b031681565b600061069361068c611085565b8484611089565b5060015b92915050565b6301e1338081565b6106ad611085565b6007546001600160a01b039081169116146106fd576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b610708838383611175565b505050565b60025490565b600281565b600061072584848461129f565b61079584610731611085565b61079085604051806060016040528060288152602001611dac602891396001600160a01b038a1660009081526001602052604081209061076f611085565b6001600160a01b0316815260208101919091526040016000205491906113fa565b611089565b5060019392505050565b6a52b7d2dcc80cd2e400000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60095481565b60055460ff1690565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000610693610812611085565b846107908560016000610823611085565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490611491565b61085b611085565b6007546001600160a01b039081169116146108ab576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b6107088383836114f2565b6008546001600160a01b03163314610902576040805162461bcd60e51b815260206004820152600a602482015269496f6e783a452d31313360b01b604482015290519081900360640190fd5b600954421015610946576040805162461bcd60e51b815260206004820152600a602482015269125bdb9e0e914b4c4c4d60b21b604482015290519081900360640190fd5b6001600160a01b03821661098e576040805162461bcd60e51b815260206004820152600a602482015269496f6e783a452d34303360b01b604482015290519081900360640190fd5b80600061099961070d565b90506a52b7d2dcc80cd2e400000081106109de576009546109be906301e13380611491565b6009556109d760646109d1836002611678565b906116d1565b9150610a40565b6a52b7d2dcc80cd2e40000006109f48284611491565b1115610a1257610a0f6a52b7d2dcc80cd2e400000082611713565b91505b6a52b7d2dcc80cd2e4000000610a288284611491565b1415610a4057610a3c426301e13380611491565b6009555b610a4a8483611755565b50505050565b610a58611085565b6007546001600160a01b03908116911614610aa8576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b610ab28282611845565b5050565b6001600160a01b031660009081526020819052604090205490565b610ad9611085565b6007546001600160a01b03908116911614610b29576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b6007546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600780546001600160a01b0319169055565b60066020526000908152604090205481565b6007546001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106665780601f1061063b57610100808354040283529160200191610666565b6000610693610c02611085565b8461079085604051806060016040528060258152602001611e676025913960016000610c2c611085565b6001600160a01b03908116825260208083019390935260409182016000908120918d168152925290205491906113fa565b6000610693610c6a611085565b848461129f565b42841015610cc6576040805162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e65000000604482015290519081900360640190fd5b6001600160a01b0380881660008181526006602090815260408083208054600180820190925582517f00000000000000000000000000000000000000000000000000000000000000008186015280840196909652958c166060860152608085018b905260a085019590955260c08085018a90528151808603909101815260e08501825280519083012061190160f01b6101008601527f000000000000000000000000000000000000000000000000000000000000000061010286015261012280860182905282518087039091018152610142860180845281519185019190912090859052610162860180845281905260ff8a166101828701526101a286018990526101c2860188905291519095919491926101e2808401939192601f1981019281900390910190855afa158015610e01573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610e375750896001600160a01b0316816001600160a01b0316145b610e88576040805162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e61747572650000604482015290519081900360640190fd5b610e938a8a8a611089565b50505050505050505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610ed2611085565b6007546001600160a01b03908116911614610f22576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b6001600160a01b038116610f675760405162461bcd60e51b8152600401808060200182810382526026815260200180611ce36026913960400191505060405180910390fd5b6007546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600780546001600160a01b0319166001600160a01b0392909216919091179055565b610fcb611085565b6007546001600160a01b0390811691161461101b576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b600854604080516001600160a01b039283168152918316602083015280517f3b0007eb941cf645526cbb3a4fdaecda9d28ce4843167d9263b536a1f1edc0f69281900390910190a1600880546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b0383166110ce5760405162461bcd60e51b8152600401808060200182810382526024815260200180611e196024913960400191505060405180910390fd5b6001600160a01b0382166111135760405162461bcd60e51b8152600401808060200182810382526022815260200180611d096022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0383166111bc576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b80826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561120a57600080fd5b505afa15801561121e573d6000803e3d6000fd5b505050506040513d602081101561123457600080fd5b5051106107085761124f6001600160a01b03831684836118e8565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b836040518082815260200191505060405180910390a3505050565b6001600160a01b0383166112e45760405162461bcd60e51b8152600401808060200182810382526025815260200180611df46025913960400191505060405180910390fd5b6001600160a01b0382166113295760405162461bcd60e51b8152600401808060200182810382526023815260200180611cc06023913960400191505060405180910390fd5b611334838383610708565b61137181604051806060016040528060268152602001611d2b602691396001600160a01b03861660009081526020819052604090205491906113fa565b6001600160a01b0380851660009081526020819052604080822093909355908416815220546113a09082611491565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600081848411156114895760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561144e578181015183820152602001611436565b50505050905090810190601f16801561147b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000828201838110156114eb576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038316611539576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b306001600160a01b0316826001600160a01b0316636352211e836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561158757600080fd5b505afa15801561159b573d6000803e3d6000fd5b505050506040513d60208110156115b157600080fd5b50516001600160a01b0316141561070857604080516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018490529151918416916323b872dd9160648082019260009290919082900301818387803b15801561161a57600080fd5b505af115801561162e573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b60008261168757506000610697565b8282028284828161169457fe5b04146114eb5760405162461bcd60e51b8152600401808060200182810382526021815260200180611d8b6021913960400191505060405180910390fd5b60006114eb83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061193a565b60006114eb83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506113fa565b6001600160a01b0382166117b0576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b6117bc60008383610708565b6002546117c99082611491565b6002556001600160a01b0382166000908152602081905260409020546117ef9082611491565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6001600160a01b03821661188c576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b804710610ab2576118a66001600160a01b0383168261199f565b6040805182815290516001600160a01b038416917eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd919081900360200190a25050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610708908490611a84565b600081836119895760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561144e578181015183820152602001611436565b50600083858161199557fe5b0495945050505050565b804710156119f4576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015290519081900360640190fd5b6040516000906001600160a01b0384169083908381818185875af1925050503d8060008114611a3f576040519150601f19603f3d011682016040523d82523d6000602084013e611a44565b606091505b50509050806107085760405162461bcd60e51b815260040180806020018281038252603a815260200180611d51603a913960400191505060405180910390fd5b6060611ad9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611b359092919063ffffffff16565b80519091501561070857808060200190516020811015611af857600080fd5b50516107085760405162461bcd60e51b815260040180806020018281038252602a815260200180611e3d602a913960400191505060405180910390fd5b6060611b448484600085611b4c565b949350505050565b6060611b5785611cb9565b611ba8576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310611be75780518252601f199092019160209182019101611bc8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114611c49576040519150601f19603f3d011682016040523d82523d6000602084013e611c4e565b606091505b50915091508115611c62579150611b449050565b805115611c725780518082602001fd5b60405162461bcd60e51b815260206004820181815286516024840152865187939192839260440191908501908083836000831561144e578181015183820152602001611436565b3b15159056fe45524332303a207472616e7366657220746f20746865207a65726f20616464726573734f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365416464726573733a20756e61626c6520746f2073656e642076616c75652c20726563697069656e74206d61792068617665207265766572746564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657245524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656445524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220bd76b10c65c03359bbab1305b5a901ae77e87d8d92a0ee8769ed8d6354c54b8364736f6c634300060c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101c45760003560e01c80634025feb2116100f957806395d89b4111610097578063d505accf11610071578063d505accf1461050f578063dd62ed3e14610560578063f2fde38b1461058e578063fca3b5aa146105b4576101c4565b806395d89b41146104af578063a457c2d7146104b7578063a9059cbb146104e3576101c4565b806370a08231116100d357806370a0823114610453578063715018a6146104795780637ecebe00146104815780638da5cb5b146104a7576101c4565b80634025feb2146103c557806340c10f19146103fb578063522f681514610427576101c4565b806323b872dd1161016657806330b36cef1161014057806330b36cef14610381578063313ce567146103895780633644e515146103915780633950935114610399576101c4565b806323b872dd1461033b5780632ff2e9dc1461037157806330adf81f14610379576101c4565b80630d1715be116101a25780630d1715be146102aa5780631593dee1146102cb57806318160ddd146103035780631dcb3a3c1461031d576101c4565b806306fdde03146101c95780630754617214610246578063095ea7b31461026a575b600080fd5b6101d16105da565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561020b5781810151838201526020016101f3565b50505050905090810190601f1680156102385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61024e610670565b604080516001600160a01b039092168252519081900360200190f35b6102966004803603604081101561028057600080fd5b506001600160a01b03813516906020013561067f565b604080519115158252519081900360200190f35b6102b261069d565b6040805163ffffffff9092168252519081900360200190f35b610301600480360360608110156102e157600080fd5b506001600160a01b038135811691602081013590911690604001356106a5565b005b61030b61070d565b60408051918252519081900360200190f35b610325610713565b6040805160ff9092168252519081900360200190f35b6102966004803603606081101561035157600080fd5b506001600160a01b03813581169160208101359091169060400135610718565b61030b61079f565b61030b6107ae565b61030b6107d2565b6103256107d8565b61030b6107e1565b610296600480360360408110156103af57600080fd5b506001600160a01b038135169060200135610805565b610301600480360360608110156103db57600080fd5b506001600160a01b03813581169160208101359091169060400135610853565b6103016004803603604081101561041157600080fd5b506001600160a01b0381351690602001356108b6565b6103016004803603604081101561043d57600080fd5b506001600160a01b038135169060200135610a50565b61030b6004803603602081101561046957600080fd5b50356001600160a01b0316610ab6565b610301610ad1565b61030b6004803603602081101561049757600080fd5b50356001600160a01b0316610b73565b61024e610b85565b6101d1610b94565b610296600480360360408110156104cd57600080fd5b506001600160a01b038135169060200135610bf5565b610296600480360360408110156104f957600080fd5b506001600160a01b038135169060200135610c5d565b610301600480360360e081101561052557600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c00135610c71565b61030b6004803603604081101561057657600080fd5b506001600160a01b0381358116916020013516610e9f565b610301600480360360208110156105a457600080fd5b50356001600160a01b0316610eca565b610301600480360360208110156105ca57600080fd5b50356001600160a01b0316610fc3565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106665780601f1061063b57610100808354040283529160200191610666565b820191906000526020600020905b81548152906001019060200180831161064957829003601f168201915b5050505050905090565b6008546001600160a01b031681565b600061069361068c611085565b8484611089565b5060015b92915050565b6301e1338081565b6106ad611085565b6007546001600160a01b039081169116146106fd576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b610708838383611175565b505050565b60025490565b600281565b600061072584848461129f565b61079584610731611085565b61079085604051806060016040528060288152602001611dac602891396001600160a01b038a1660009081526001602052604081209061076f611085565b6001600160a01b0316815260208101919091526040016000205491906113fa565b611089565b5060019392505050565b6a52b7d2dcc80cd2e400000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60095481565b60055460ff1690565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000610693610812611085565b846107908560016000610823611085565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490611491565b61085b611085565b6007546001600160a01b039081169116146108ab576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b6107088383836114f2565b6008546001600160a01b03163314610902576040805162461bcd60e51b815260206004820152600a602482015269496f6e783a452d31313360b01b604482015290519081900360640190fd5b600954421015610946576040805162461bcd60e51b815260206004820152600a602482015269125bdb9e0e914b4c4c4d60b21b604482015290519081900360640190fd5b6001600160a01b03821661098e576040805162461bcd60e51b815260206004820152600a602482015269496f6e783a452d34303360b01b604482015290519081900360640190fd5b80600061099961070d565b90506a52b7d2dcc80cd2e400000081106109de576009546109be906301e13380611491565b6009556109d760646109d1836002611678565b906116d1565b9150610a40565b6a52b7d2dcc80cd2e40000006109f48284611491565b1115610a1257610a0f6a52b7d2dcc80cd2e400000082611713565b91505b6a52b7d2dcc80cd2e4000000610a288284611491565b1415610a4057610a3c426301e13380611491565b6009555b610a4a8483611755565b50505050565b610a58611085565b6007546001600160a01b03908116911614610aa8576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b610ab28282611845565b5050565b6001600160a01b031660009081526020819052604090205490565b610ad9611085565b6007546001600160a01b03908116911614610b29576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b6007546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600780546001600160a01b0319169055565b60066020526000908152604090205481565b6007546001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156106665780601f1061063b57610100808354040283529160200191610666565b6000610693610c02611085565b8461079085604051806060016040528060258152602001611e676025913960016000610c2c611085565b6001600160a01b03908116825260208083019390935260409182016000908120918d168152925290205491906113fa565b6000610693610c6a611085565b848461129f565b42841015610cc6576040805162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e65000000604482015290519081900360640190fd5b6001600160a01b0380881660008181526006602090815260408083208054600180820190925582517f00000000000000000000000000000000000000000000000000000000000000008186015280840196909652958c166060860152608085018b905260a085019590955260c08085018a90528151808603909101815260e08501825280519083012061190160f01b6101008601527f000000000000000000000000000000000000000000000000000000000000000061010286015261012280860182905282518087039091018152610142860180845281519185019190912090859052610162860180845281905260ff8a166101828701526101a286018990526101c2860188905291519095919491926101e2808401939192601f1981019281900390910190855afa158015610e01573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610e375750896001600160a01b0316816001600160a01b0316145b610e88576040805162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e61747572650000604482015290519081900360640190fd5b610e938a8a8a611089565b50505050505050505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610ed2611085565b6007546001600160a01b03908116911614610f22576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b6001600160a01b038116610f675760405162461bcd60e51b8152600401808060200182810382526026815260200180611ce36026913960400191505060405180910390fd5b6007546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600780546001600160a01b0319166001600160a01b0392909216919091179055565b610fcb611085565b6007546001600160a01b0390811691161461101b576040805162461bcd60e51b81526020600482018190526024820152600080516020611dd4833981519152604482015290519081900360640190fd5b600854604080516001600160a01b039283168152918316602083015280517f3b0007eb941cf645526cbb3a4fdaecda9d28ce4843167d9263b536a1f1edc0f69281900390910190a1600880546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b0383166110ce5760405162461bcd60e51b8152600401808060200182810382526024815260200180611e196024913960400191505060405180910390fd5b6001600160a01b0382166111135760405162461bcd60e51b8152600401808060200182810382526022815260200180611d096022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0383166111bc576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b80826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561120a57600080fd5b505afa15801561121e573d6000803e3d6000fd5b505050506040513d602081101561123457600080fd5b5051106107085761124f6001600160a01b03831684836118e8565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b836040518082815260200191505060405180910390a3505050565b6001600160a01b0383166112e45760405162461bcd60e51b8152600401808060200182810382526025815260200180611df46025913960400191505060405180910390fd5b6001600160a01b0382166113295760405162461bcd60e51b8152600401808060200182810382526023815260200180611cc06023913960400191505060405180910390fd5b611334838383610708565b61137181604051806060016040528060268152602001611d2b602691396001600160a01b03861660009081526020819052604090205491906113fa565b6001600160a01b0380851660009081526020819052604080822093909355908416815220546113a09082611491565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600081848411156114895760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561144e578181015183820152602001611436565b50505050905090810190601f16801561147b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000828201838110156114eb576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038316611539576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b306001600160a01b0316826001600160a01b0316636352211e836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561158757600080fd5b505afa15801561159b573d6000803e3d6000fd5b505050506040513d60208110156115b157600080fd5b50516001600160a01b0316141561070857604080516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018490529151918416916323b872dd9160648082019260009290919082900301818387803b15801561161a57600080fd5b505af115801561162e573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b60008261168757506000610697565b8282028284828161169457fe5b04146114eb5760405162461bcd60e51b8152600401808060200182810382526021815260200180611d8b6021913960400191505060405180910390fd5b60006114eb83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061193a565b60006114eb83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506113fa565b6001600160a01b0382166117b0576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b6117bc60008383610708565b6002546117c99082611491565b6002556001600160a01b0382166000908152602081905260409020546117ef9082611491565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6001600160a01b03821661188c576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b804710610ab2576118a66001600160a01b0383168261199f565b6040805182815290516001600160a01b038416917eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd919081900360200190a25050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610708908490611a84565b600081836119895760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561144e578181015183820152602001611436565b50600083858161199557fe5b0495945050505050565b804710156119f4576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015290519081900360640190fd5b6040516000906001600160a01b0384169083908381818185875af1925050503d8060008114611a3f576040519150601f19603f3d011682016040523d82523d6000602084013e611a44565b606091505b50509050806107085760405162461bcd60e51b815260040180806020018281038252603a815260200180611d51603a913960400191505060405180910390fd5b6060611ad9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611b359092919063ffffffff16565b80519091501561070857808060200190516020811015611af857600080fd5b50516107085760405162461bcd60e51b815260040180806020018281038252602a815260200180611e3d602a913960400191505060405180910390fd5b6060611b448484600085611b4c565b949350505050565b6060611b5785611cb9565b611ba8576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310611be75780518252601f199092019160209182019101611bc8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114611c49576040519150601f19603f3d011682016040523d82523d6000602084013e611c4e565b606091505b50915091508115611c62579150611b449050565b805115611c725780518082602001fd5b60405162461bcd60e51b815260206004820181815286516024840152865187939192839260440191908501908083836000831561144e578181015183820152602001611436565b3b15159056fe45524332303a207472616e7366657220746f20746865207a65726f20616464726573734f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365416464726573733a20756e61626c6520746f2073656e642076616c75652c20726563697069656e74206d61792068617665207265766572746564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657245524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656445524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220bd76b10c65c03359bbab1305b5a901ae77e87d8d92a0ee8769ed8d6354c54b8364736f6c634300060c0033", + "devdoc": { + "kind": "dev", + "methods": { + "allowance(address,address)": { + "details": "See {IERC20-allowance}." + }, + "approve(address,uint256)": { + "details": "See {IERC20-approve}. Requirements: - `spender` cannot be the zero address." + }, + "balanceOf(address)": { + "details": "See {IERC20-balanceOf}." + }, + "decimals()": { + "details": "Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5,05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is called. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}." + }, + "decreaseAllowance(address,uint256)": { + "details": "Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`." + }, + "increaseAllowance(address,uint256)": { + "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." + }, + "mint(address,uint256)": { + "params": { + "amount": "The number of tokens to be minted", + "receiver": "The address of the destination account" + } + }, + "name()": { + "details": "Returns the name of the token." + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "permit(address,address,uint256,uint256,uint8,bytes32,bytes32)": { + "details": "See {IERC2612-permit}. In cases where the free option is not a concern, deadline can simply be set to uint(-1), so it should be seen as an optional parameter" + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "setMinter(address)": { + "params": { + "newMinter": "The address of the new minter" + } + }, + "symbol()": { + "details": "Returns the symbol of the token, usually a shorter version of the name." + }, + "totalSupply()": { + "details": "See {IERC20-totalSupply}." + }, + "transfer(address,uint256)": { + "details": "See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`." + }, + "transferFrom(address,address,uint256)": { + "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}; Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "MinterChanged(address,address)": { + "notice": "An event thats emitted when the minter address is changed" + } + }, + "kind": "user", + "methods": { + "INFLATION_CAP()": { + "notice": "Cap on the percentage of totalSupply that can be minted at each mint" + }, + "INFLATION_EPOCH()": { + "notice": "Minimum time between mints" + }, + "INITIAL_SUPPLY()": { + "notice": "Total number of tokens in circulation" + }, + "mint(address,uint256)": { + "notice": "Mint new tokens" + }, + "minter()": { + "notice": "Address which may mint new tokens" + }, + "mintingAllowedAfter()": { + "notice": "The timestamp after which minting may occur" + }, + "setMinter(address)": { + "notice": "Change the minter address" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 6091, + "contract": "contracts/v1/tokens/Ionx.sol:Ionx", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 6097, + "contract": "contracts/v1/tokens/Ionx.sol:Ionx", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 6099, + "contract": "contracts/v1/tokens/Ionx.sol:Ionx", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 6101, + "contract": "contracts/v1/tokens/Ionx.sol:Ionx", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "t_string_storage" + }, + { + "astId": 6103, + "contract": "contracts/v1/tokens/Ionx.sol:Ionx", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "t_string_storage" + }, + { + "astId": 6105, + "contract": "contracts/v1/tokens/Ionx.sol:Ionx", + "label": "_decimals", + "offset": 0, + "slot": "5", + "type": "t_uint8" + }, + { + "astId": 49902, + "contract": "contracts/v1/tokens/Ionx.sol:Ionx", + "label": "nonces", + "offset": 0, + "slot": "6", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 4406, + "contract": "contracts/v1/tokens/Ionx.sol:Ionx", + "label": "_owner", + "offset": 0, + "slot": "7", + "type": "t_address" + }, + { + "astId": 36771, + "contract": "contracts/v1/tokens/Ionx.sol:Ionx", + "label": "minter", + "offset": 0, + "slot": "8", + "type": "t_address" + }, + { + "astId": 36774, + "contract": "contracts/v1/tokens/Ionx.sol:Ionx", + "label": "mintingAllowedAfter", + "offset": 0, + "slot": "9", + "type": "t_uint256" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/polygon/Lepton2.json b/deployments/polygon/Lepton2.json new file mode 100644 index 0000000..b577a88 --- /dev/null +++ b/deployments/polygon/Lepton2.json @@ -0,0 +1,1354 @@ +{ + "address": "0x4d40C9841E4cD0BF84a365cb6ad457dcAAF03e4a", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "count", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "multiplier", + "type": "uint32" + } + ], + "name": "LeptonBatchMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "multiplier", + "type": "uint32" + } + ], + "name": "LeptonMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "tokenUri", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "supply", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "multiplier", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "bonus", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "upperBounds", + "type": "uint256" + } + ], + "name": "LeptonTypeAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "leptonIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "tokenUri", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "supply", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "multiplier", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "bonus", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "upperBounds", + "type": "uint256" + } + ], + "name": "LeptonTypeUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "maxAmount", + "type": "uint256" + } + ], + "name": "MaxMintPerTxSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "isPaused", + "type": "bool" + } + ], + "name": "PausedStateSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "tokenUri", + "type": "string" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "supply", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "multiplier", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "bonus", + "type": "uint32" + } + ], + "name": "addLeptonType", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "count", + "type": "uint256" + } + ], + "name": "batchMintLepton", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getBonus", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNextPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNextType", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "oldLeptonContract", + "type": "address" + }, + { + "internalType": "uint256", + "name": "count", + "type": "uint256" + } + ], + "name": "migrateAccounts", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "mintLepton", + "outputs": [ + { + "internalType": "uint256", + "name": "newTokenId", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maxAmount", + "type": "uint256" + } + ], + "name": "setMaxMintPerTx", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "setPausedState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "leptonIndex", + "type": "uint256" + }, + { + "internalType": "string", + "name": "tokenUri", + "type": "string" + }, + { + "internalType": "uint256", + "name": "price", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "supply", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "multiplier", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "bonus", + "type": "uint32" + } + ], + "name": "updateLeptonType", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x23bc09e860b6e4c09be96923c764c5630e19954e4a022b800aa93a54a4b4a383", + "receipt": { + "to": null, + "from": "0x48F54e595bf039CF30fa5F768c0b57EAC6508a06", + "contractAddress": "0x4d40C9841E4cD0BF84a365cb6ad457dcAAF03e4a", + "transactionIndex": 8, + "gasUsed": "3202356", + "logsBloom": "0x00000000000000000000000002000000000000000000000000800000000000000000000000000000000000000200000000008000000000000000000000000000000000000000000000000010000000800001000000000000000100000000000000000000020000000000000000000800000000000000000080000000000000400000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000800000000000000000000000000004000800000400000000001000000008000000000000000000000100000000020000000020000000000000000000000000000000000000000000000000000100000", + "blockHash": "0xb5270fa07653584c39c0d3ee3437be4ae3ee6ca9c8f4d23939ca4a2f6f2792ed", + "transactionHash": "0x23bc09e860b6e4c09be96923c764c5630e19954e4a022b800aa93a54a4b4a383", + "logs": [ + { + "transactionIndex": 8, + "blockNumber": 55061453, + "transactionHash": "0x23bc09e860b6e4c09be96923c764c5630e19954e4a022b800aa93a54a4b4a383", + "address": "0x4d40C9841E4cD0BF84a365cb6ad457dcAAF03e4a", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000048f54e595bf039cf30fa5f768c0b57eac6508a06" + ], + "data": "0x", + "logIndex": 33, + "blockHash": "0xb5270fa07653584c39c0d3ee3437be4ae3ee6ca9c8f4d23939ca4a2f6f2792ed" + }, + { + "transactionIndex": 8, + "blockNumber": 55061453, + "transactionHash": "0x23bc09e860b6e4c09be96923c764c5630e19954e4a022b800aa93a54a4b4a383", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x00000000000000000000000048f54e595bf039cf30fa5f768c0b57eac6508a06", + "0x00000000000000000000000067b94473d81d0cd00849d563c94d0432ac988b49" + ], + "data": "0x000000000000000000000000000000000000000000000000056da3b5c05d163c0000000000000000000000000000000000000000000000000c8d262d5881bdcf000000000000000000000000000000000000000000001fbb89402c53637c2c8c000000000000000000000000000000000000000000000000071f82779824a793000000000000000000000000000000000000000000001fbb8eadd00923d942c8", + "logIndex": 34, + "blockHash": "0xb5270fa07653584c39c0d3ee3437be4ae3ee6ca9c8f4d23939ca4a2f6f2792ed" + } + ], + "blockNumber": 55061453, + "cumulativeGasUsed": "4129421", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "d89205a24fa74c6b69fc21ff47ad23be", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"multiplier\",\"type\":\"uint32\"}],\"name\":\"LeptonBatchMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"multiplier\",\"type\":\"uint32\"}],\"name\":\"LeptonMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"tokenUri\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"supply\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"multiplier\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"bonus\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"upperBounds\",\"type\":\"uint256\"}],\"name\":\"LeptonTypeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"leptonIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"tokenUri\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"supply\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"multiplier\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"bonus\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"upperBounds\",\"type\":\"uint256\"}],\"name\":\"LeptonTypeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxAmount\",\"type\":\"uint256\"}],\"name\":\"MaxMintPerTxSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"isPaused\",\"type\":\"bool\"}],\"name\":\"PausedStateSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC1155\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckEther\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"tokenUri\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"supply\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"multiplier\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"bonus\",\"type\":\"uint32\"}],\"name\":\"addLeptonType\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"name\":\"batchMintLepton\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getBonus\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getMultiplier\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNextPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNextType\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"oldLeptonContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"name\":\"migrateAccounts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"mintLepton\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"newTokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxAmount\",\"type\":\"uint256\"}],\"name\":\"setMaxMintPerTx\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"state\",\"type\":\"bool\"}],\"name\":\"setPausedState\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"leptonIndex\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"tokenUri\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"supply\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"multiplier\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"bonus\",\"type\":\"uint32\"}],\"name\":\"updateLeptonType\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawErc20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawEther\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"details\":\"See {IERC721-approve}.\"},\"balanceOf(address)\":{\"details\":\"See {IERC721-balanceOf}.\"},\"getApproved(uint256)\":{\"details\":\"See {IERC721-getApproved}.\"},\"isApprovedForAll(address,address)\":{\"details\":\"See {IERC721-isApprovedForAll}.\"},\"name()\":{\"details\":\"See {IERC721Metadata-name}.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"ownerOf(uint256)\":{\"details\":\"See {IERC721-ownerOf}.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"See {IERC721-safeTransferFrom}.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"See {IERC721-setApprovalForAll}.\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}. Time complexity O(1), guaranteed to always use less than 30 000 gas.\"},\"symbol()\":{\"details\":\"See {IERC721Metadata-symbol}.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC721-transferFrom}.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/v1/tokens/Lepton2.sol\":\"Lepton2\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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 GSN 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 payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xdb26cbf4d028490f49831a7865c2fe1b28db44b535ca8d343785a3b768aae183\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"../GSN/Context.sol\\\";\\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 */\\ncontract 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 () internal {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view 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 emit OwnershipTransferred(_owner, address(0));\\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x4bd6402ca6b3419008c2b482aff54e66836e8cb4eba2680e42ac5884ae6424fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts may inherit from this and call {_registerInterface} to declare\\n * their support of an interface.\\n */\\ncontract ERC165 is IERC165 {\\n /*\\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\\n */\\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\\n\\n /**\\n * @dev Mapping of interface ids to whether or not it's supported.\\n */\\n mapping(bytes4 => bool) private _supportedInterfaces;\\n\\n constructor () internal {\\n // Derived contracts need only register support for their own interfaces,\\n // we register support for ERC165 itself here\\n _registerInterface(_INTERFACE_ID_ERC165);\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n *\\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) public view override returns (bool) {\\n return _supportedInterfaces[interfaceId];\\n }\\n\\n /**\\n * @dev Registers the contract as an implementer of the interface defined by\\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\\n * registering its interface id is not required.\\n *\\n * See {IERC165-supportsInterface}.\\n *\\n * Requirements:\\n *\\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\\n */\\n function _registerInterface(bytes4 interfaceId) internal virtual {\\n require(interfaceId != 0xffffffff, \\\"ERC165: invalid interface id\\\");\\n _supportedInterfaces[interfaceId] = true;\\n }\\n}\\n\",\"keccak256\":\"0xb046d18f9d09683ca1c0ed6d80c61da8a8a7d9b30bad70a17b898538683eff74\",\"license\":\"MIT\"},\"@openzeppelin/contracts/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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\",\"keccak256\":\"0xfa152b6e88a1dc50780e8f1580426dc23ad2e1e2c2f086a088adf206a202f453\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\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 uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\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 sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\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 * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\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 // 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) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts 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 mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9a9cf02622cd7a64261b10534fc3260449da25c98c9e96d1b4ae8110a20e5806\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x31691ad0817f8cb338531b78d2ab2989027d9f27e6f8e62492b754fed9429b10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0x5c26b39d26f7ed489e555d955dcd3e01872972e71fdd1528e93ec164e4f23385\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.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 SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf3b30f8a49631420635a8c35daacfcaa338012755f18a76fdd118730256f9a27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0xaf936da92f3a9a4f98b237323b5eb1d813fb86c4d07a184beba7027cf0509ba3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 /**\\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\",\"keccak256\":\"0x3636662804cd8f474536b2875a9038a4c3fb91879f1bbff48af5c3f140fcd2f0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 /**\\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\",\"keccak256\":\"0xe7f984cedc00a138dc27f263c73c32ba9a4b2fd23b6c34ac46f46c074b943538\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address operator, address from, uint256 tokenId, bytes calldata data)\\n external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x321ee37ef4925020aa818a03ec7fe48e057561f65ab009a84f6c20c86026ade7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 in 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 // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n return _functionCallWithValue(target, data, value, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\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 // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf5fa8cbdffa5ef8be49b246b5628facc30b71707e78a45d80d93b64eff3fe390\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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 */\\ncontract 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 () internal {\\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 make 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\",\"keccak256\":\"0x7ff0067f2d7df4187eaa1cb4800949b929602c9d9cb20fcaee6922a7613ef2fb\",\"license\":\"MIT\"},\"contracts/v1/interfaces/ILepton.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// ILepton.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Charged Particles Lepton Interface\\n * @dev ...\\n */\\ninterface ILepton {\\n\\n struct Classification {\\n string tokenUri;\\n uint256 price;\\n uint128 _upperBounds;\\n uint32 supply;\\n uint32 multiplier;\\n uint32 bonus;\\n }\\n\\n function mintLepton() external payable returns (uint256 newTokenId);\\n function batchMintLepton(uint256 count) external payable;\\n function getNextType() external view returns (uint256);\\n function getNextPrice() external view returns (uint256);\\n function getMultiplier(uint256 tokenId) external view returns (uint256);\\n function getBonus(uint256 tokenId) external view returns (uint256);\\n\\n\\n event MaxMintPerTxSet(uint256 maxAmount);\\n event LeptonTypeAdded(string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\\n event LeptonTypeUpdated(uint256 leptonIndex, string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\\n event LeptonMinted(address indexed receiver, uint256 indexed tokenId, uint256 price, uint32 multiplier);\\n event LeptonBatchMinted(address indexed receiver, uint256 indexed tokenId, uint256 count, uint256 price, uint32 multiplier);\\n event PausedStateSet(bool isPaused);\\n}\\n\",\"keccak256\":\"0x4903085427fa5dbee690fe79854fba60afaf21189957406ade55f6fc12556a01\",\"license\":\"MIT\"},\"contracts/v1/lib/BlackholePrevention.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\\\";\\n\\n/**\\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\\n * the Owner/DAO to pull them out on behalf of a user\\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\\n */\\ncontract BlackholePrevention {\\n using Address for address payable;\\n using SafeERC20 for IERC20;\\n\\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\\n\\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (address(this).balance >= amount) {\\n receiver.sendValue(amount);\\n emit WithdrawStuckEther(receiver, amount);\\n }\\n }\\n\\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\\n IERC20(tokenAddress).safeTransfer(receiver, amount);\\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\\n }\\n }\\n\\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\\n }\\n }\\n\\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \\\"\\\");\\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6a664c8a1c1d7fb32ade2c11f75756b1fdb4c489daa32c1d58e6b867ea2ba8d6\",\"license\":\"MIT\"},\"contracts/v1/lib/ERC721Basic.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/GSN/Context.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/introspection/ERC165.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\n/**\\n * @title ERC721 Non-Fungible Token Standard basic implementation\\n * @dev see https://eips.ethereum.org/EIPS/eip-721\\n */\\ncontract ERC721Basic is Context, ERC165, IERC721, IERC721Metadata {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n // Equals to `bytes4(keccak256(\\\"onERC721Received(address,address,uint256,bytes)\\\"))`\\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\\n bytes4 internal constant _ERC721_RECEIVED = 0x150b7a02;\\n\\n // mapping from token ids to their owners\\n mapping (uint256 => address) internal _tokenOwners;\\n\\n // mapping from owner to token balance\\n mapping (address => uint256) internal _ownerBalance;\\n\\n // Mapping from token ID to approved address\\n mapping (uint256 => address) internal _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping (address => mapping (address => bool)) internal _operatorApprovals;\\n\\n // Token name\\n string internal _name;\\n\\n // Token symbol\\n string internal _symbol;\\n\\n // Token Count\\n uint256 internal _tokenCount;\\n\\n /*\\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\\n *\\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\\n */\\n bytes4 internal constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\\n\\n /*\\n * bytes4(keccak256('name()')) == 0x06fdde03\\n * bytes4(keccak256('symbol()')) == 0x95d89b41\\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\\n *\\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\\n */\\n bytes4 internal constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\\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) public {\\n _name = name;\\n _symbol = symbol;\\n\\n // register the supported interfaces to conform to ERC721 via ERC165\\n _registerInterface(_INTERFACE_ID_ERC721);\\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view override returns (uint256) {\\n require(owner != address(0), \\\"ERC721:E-403\\\");\\n return _ownerBalance[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view override returns (address) {\\n return _tokenOwners[tokenId];\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view 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 return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ownerOf(tokenId);\\n require(to != owner, \\\"ERC721:E-111\\\");\\n\\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \\\"ERC721:E-105\\\");\\n\\n _approve(to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-getApproved}.\\n */\\n function getApproved(uint256 tokenId) public view override returns (address) {\\n require(_exists(tokenId), \\\"ERC721:E-405\\\");\\n return _tokenApprovals[tokenId];\\n }\\n\\n /**\\n * @dev See {IERC721-setApprovalForAll}.\\n */\\n function setApprovalForAll(address operator, bool approved) public virtual override {\\n require(operator != _msgSender(), \\\"ERC721:E-111\\\");\\n\\n _operatorApprovals[_msgSender()][operator] = approved;\\n emit ApprovalForAll(_msgSender(), operator, approved);\\n }\\n\\n /**\\n * @dev See {IERC721-isApprovedForAll}.\\n */\\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\\n return _operatorApprovals[owner][operator];\\n }\\n\\n /**\\n * @dev See {IERC721-transferFrom}.\\n */\\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721:E-105\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721:E-105\\\");\\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\\n _transfer(from, to, tokenId);\\n require(_checkOnERC721Received(from, to, tokenId, _data), \\\"ERC721:E-402\\\");\\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 returns (bool) {\\n return _tokenOwners[tokenId] != address(0x0);\\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 returns (bool) {\\n require(_exists(tokenId), \\\"ERC721:E-405\\\");\\n address owner = ownerOf(tokenId);\\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\\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(address to, bytes memory _data) internal virtual returns (uint256) {\\n uint256 tokenId = _mint(to);\\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \\\"ERC721:E-402\\\");\\n return 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 _safeMintBatch(address to, uint256 count, bytes memory _data) internal virtual {\\n uint256 startTokenId = _mintBatch(to, count);\\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \\\"ERC721:E-402\\\");\\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) internal virtual returns (uint256) {\\n require(to != address(0), \\\"ERC721:E-403\\\");\\n\\n _tokenCount = _tokenCount.add(1);\\n uint256 tokenId = _tokenCount;\\n require(!_exists(tokenId), \\\"ERC721:E-407\\\");\\n\\n _tokenOwners[tokenId] = to;\\n _ownerBalance[to] = _ownerBalance[to].add(1);\\n\\n emit Transfer(address(0), to, tokenId);\\n return tokenId;\\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 _mintBatch(address to, uint256 count) internal virtual returns (uint256) {\\n require(to != address(0), \\\"ERC721:E-403\\\");\\n\\n uint256 startTokenId = _tokenCount.add(1);\\n for (uint i = 1; i <= count; i++) {\\n uint256 tokenId = _tokenCount.add(i);\\n _tokenOwners[tokenId] = to;\\n emit Transfer(address(0), to, tokenId);\\n }\\n\\n _tokenCount = _tokenCount.add(count);\\n _ownerBalance[to] = _ownerBalance[to].add(count);\\n return startTokenId;\\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(address from, address to, uint256 tokenId) internal virtual {\\n require(ownerOf(tokenId) == from, \\\"ERC721:E-102\\\");\\n require(to != address(0), \\\"ERC721:E-403\\\");\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _tokenOwners[tokenId] = to;\\n _ownerBalance[from] = _ownerBalance[from].sub(1);\\n _ownerBalance[to] = _ownerBalance[to].add(1);\\n\\n emit Transfer(from, to, tokenId);\\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(address from, address to, uint256 tokenId, bytes memory _data)\\n internal returns (bool)\\n {\\n if (!to.isContract()) {\\n return true;\\n }\\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\\n IERC721Receiver(to).onERC721Received.selector,\\n _msgSender(),\\n from,\\n tokenId,\\n _data\\n ), \\\"ERC721:E-402\\\");\\n bytes4 retval = abi.decode(returndata, (bytes4));\\n return (retval == _ERC721_RECEIVED);\\n }\\n\\n function _approve(address to, uint256 tokenId) internal {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ownerOf(tokenId), to, tokenId);\\n }\\n}\\n\",\"keccak256\":\"0x4b9f68ff101017027a7d963c7ab888d126c3e5f10fb5dd28daba08d49d9bd291\",\"license\":\"MIT\"},\"contracts/v1/tokens/Lepton2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// Lepton2.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\n\\nimport \\\"../lib/ERC721Basic.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/ReentrancyGuard.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\\\";\\n\\nimport \\\"../interfaces/ILepton.sol\\\";\\nimport \\\"../lib/BlackholePrevention.sol\\\";\\n\\ncontract Lepton2 is ILepton, ERC721Basic, Ownable, ReentrancyGuard, BlackholePrevention {\\n using SafeMath for uint256;\\n using Address for address payable;\\n\\n Classification[] internal _leptonTypes;\\n\\n uint256 internal _typeIndex;\\n uint256 internal _maxSupply;\\n uint256 internal _maxMintPerTx;\\n uint256 internal _migratedCount;\\n\\n bool internal _paused;\\n bool internal _migrationComplete;\\n\\n\\n /***********************************|\\n | Initialization |\\n |__________________________________*/\\n\\n constructor() public ERC721Basic(\\\"Charged Particles - Lepton2\\\", \\\"LEPTON2\\\") {\\n _paused = true;\\n _migrationComplete = false;\\n _migratedCount = 0;\\n }\\n\\n\\n /***********************************|\\n | Public |\\n |__________________________________*/\\n\\n function mintLepton() external payable override nonReentrant whenNotPaused returns (uint256 newTokenId) {\\n newTokenId = _mintLepton(msg.sender);\\n }\\n\\n function batchMintLepton(uint256 count) external payable override nonReentrant whenNotPaused {\\n _batchMintLepton(msg.sender, count);\\n }\\n\\n function totalSupply() public view returns (uint256) {\\n return _tokenCount;\\n }\\n\\n function maxSupply() external view returns (uint256) {\\n return _maxSupply;\\n }\\n\\n function getNextType() external view override returns (uint256) {\\n if (_typeIndex >= _leptonTypes.length) { return 0; }\\n return _typeIndex;\\n }\\n\\n function getNextPrice() external view override returns (uint256) {\\n if (_typeIndex >= _leptonTypes.length) { return 0; }\\n return _leptonTypes[_typeIndex].price;\\n }\\n\\n function getMultiplier(uint256 tokenId) external view override returns (uint256) {\\n require(_exists(tokenId), \\\"LPT:E-405\\\");\\n return _getLepton(tokenId).multiplier;\\n }\\n\\n function getBonus(uint256 tokenId) external view override returns (uint256) {\\n require(_exists(tokenId), \\\"LPT:E-405\\\");\\n return _getLepton(tokenId).bonus;\\n }\\n\\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\\n require(_exists(tokenId), \\\"LPT:E-405\\\");\\n return _getLepton(tokenId).tokenUri;\\n }\\n\\n /***********************************|\\n | Only Admin/DAO |\\n |__________________________________*/\\n\\n function addLeptonType(\\n string calldata tokenUri,\\n uint256 price,\\n uint32 supply,\\n uint32 multiplier,\\n uint32 bonus\\n )\\n external\\n onlyOwner\\n {\\n _maxSupply = _maxSupply.add(uint256(supply));\\n\\n Classification memory lepton = Classification({\\n tokenUri: tokenUri,\\n price: price,\\n supply: supply,\\n multiplier: multiplier,\\n bonus: bonus,\\n _upperBounds: uint128(_maxSupply)\\n });\\n _leptonTypes.push(lepton);\\n\\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\\n }\\n\\n function updateLeptonType(\\n uint256 leptonIndex,\\n string calldata tokenUri,\\n uint256 price,\\n uint32 supply,\\n uint32 multiplier,\\n uint32 bonus\\n )\\n external\\n onlyOwner\\n {\\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\\n _leptonTypes[leptonIndex].price = price;\\n _leptonTypes[leptonIndex].supply = supply;\\n _leptonTypes[leptonIndex].multiplier = multiplier;\\n _leptonTypes[leptonIndex].bonus = bonus;\\n\\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\\n }\\n\\n function setMaxMintPerTx(uint256 maxAmount) external onlyOwner {\\n _maxMintPerTx = maxAmount;\\n emit MaxMintPerTxSet(maxAmount);\\n }\\n\\n function setPausedState(bool state) external onlyOwner {\\n _paused = state;\\n emit PausedStateSet(state);\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n | (blackhole prevention) |\\n |__________________________________*/\\n\\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n function migrateAccounts(address oldLeptonContract, uint256 count) external onlyOwner whenNotMigrated {\\n uint256 oldSupply = IERC721Enumerable(oldLeptonContract).totalSupply();\\n require(oldSupply == 0 || oldSupply > _migratedCount, \\\"LPT:E-004\\\");\\n\\n if (oldSupply > 0) {\\n uint256 endTokenId = _migratedCount.add(count);\\n if (endTokenId > oldSupply) {\\n count = count.sub(endTokenId.sub(oldSupply));\\n }\\n\\n for (uint256 i = 1; i <= count; i++) {\\n uint256 tokenId = _migratedCount.add(i);\\n address tokenOwner = IERC721(oldLeptonContract).ownerOf(tokenId);\\n _mint(tokenOwner);\\n }\\n _migratedCount = _migratedCount.add(count);\\n }\\n\\n if (oldSupply == _migratedCount) {\\n _finalizeMigration();\\n }\\n }\\n\\n /***********************************|\\n | Private Functions |\\n |__________________________________*/\\n\\n function _getLepton(uint256 tokenId) internal view returns (Classification memory) {\\n uint256 types = _leptonTypes.length;\\n for (uint256 i = 0; i < types; i++) {\\n Classification memory lepton = _leptonTypes[i];\\n if (tokenId <= lepton._upperBounds) {\\n return lepton;\\n }\\n }\\n }\\n\\n function _mintLepton(address receiver) internal returns (uint256 newTokenId) {\\n require(_typeIndex < _leptonTypes.length, \\\"LPT:E-408\\\");\\n\\n Classification memory lepton = _leptonTypes[_typeIndex];\\n require(msg.value >= lepton.price, \\\"LPT:E-414\\\");\\n\\n newTokenId = _safeMint(receiver, \\\"\\\");\\n\\n // Determine Next Type\\n if (newTokenId == lepton._upperBounds) {\\n _typeIndex = _typeIndex.add(1);\\n }\\n\\n _refundOverpayment(lepton.price);\\n }\\n\\n function _batchMintLepton(address receiver, uint256 count) internal {\\n require(_typeIndex < _leptonTypes.length, \\\"LPT:E-408\\\");\\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \\\"LPT:E-429\\\");\\n\\n Classification memory lepton = _leptonTypes[_typeIndex];\\n\\n uint256 endTokenId = _tokenCount.add(count);\\n if (endTokenId > lepton._upperBounds) {\\n count = count.sub(endTokenId.sub(lepton._upperBounds));\\n }\\n\\n uint256 salePrice = lepton.price.mul(count);\\n require(msg.value >= salePrice, \\\"LPT:E-414\\\");\\n\\n _safeMintBatch(receiver, count, \\\"\\\");\\n\\n // Determine Next Type\\n if (endTokenId >= lepton._upperBounds) {\\n _typeIndex = _typeIndex.add(1);\\n }\\n\\n _refundOverpayment(salePrice);\\n }\\n\\n function _refundOverpayment(uint256 threshold) internal {\\n uint256 overage = msg.value.sub(threshold);\\n if (overage > 0) {\\n payable(_msgSender()).sendValue(overage);\\n }\\n }\\n\\n function _finalizeMigration() internal {\\n // Determine Next Type\\n _typeIndex = 0;\\n for (uint256 i = 0; i < _leptonTypes.length; i++) {\\n Classification memory lepton = _leptonTypes[i];\\n if (_migratedCount >= lepton._upperBounds) {\\n _typeIndex = i + 1;\\n }\\n }\\n _migrationComplete = true;\\n }\\n\\n\\n /***********************************|\\n | Modifiers |\\n |__________________________________*/\\n\\n modifier whenNotMigrated() {\\n require(!_migrationComplete, \\\"LPT:E-004\\\");\\n _;\\n }\\n\\n modifier whenNotPaused() {\\n require(!_paused, \\\"LPT:E-101\\\");\\n _;\\n }\\n}\",\"keccak256\":\"0x308d33f8e4c5dbc7fa986fd93e3f760f8f81c14e0915af9ba9ab9cd5509fae6d\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50604080518082018252601b81527f43686172676564205061727469636c6573202d204c6570746f6e320000000000602080830191909152825180840190935260078352662622a82a27a71960c91b9083015290620000776301ffc9a760e01b62000148565b81516200008c906005906020850190620001d1565b508051620000a2906006906020840190620001d1565b50620000b56380ac58cd60e01b62000148565b620000c7635b5e139f60e01b62000148565b5060009050620000d6620001cd565b600880546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35060016009819055600f805460ff191690911761ff00191690556000600e556200026d565b6001600160e01b03198082161415620001a8576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b3390565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200021457805160ff191683800117855562000244565b8280016001018555821562000244579182015b828111156200024457825182559160200191906001019062000227565b506200025292915062000256565b5090565b5b8082111562000252576000815560010162000257565b61357b806200027d6000396000f3fe6080604052600436106101e35760003560e01c8063681ce98a11610102578063b88d4fde11610095578063db9f60ff11610064578063db9f60ff146108be578063e6089023146108ea578063e985e9c5146108ff578063f2fde38b1461093a576101e3565b8063b88d4fde14610711578063c87b56dd146107e4578063d5abeb011461080e578063da47bb2614610823576101e3565b806395d89b41116100d157806395d89b41146105f5578063a22cb4651461060a578063adf8252d14610645578063b0fde8cf1461066f576101e3565b8063681ce98a1461058357806370a0823114610598578063715018a6146105cb5780638da5cb5b146105e0576101e3565b806323b872dd1161017a578063522f681511610149578063522f6815146104ee5780635fc194ed14610527578063616cdb1e1461052f5780636352211e14610559576101e3565b806323b872dd146103fb5780634025feb21461043e57806342842e0e146104815780634aa66b28146104c4576101e3565b8063095ea7b3116101b6578063095ea7b31461033b5780630afd902b146103745780631593dee11461039157806318160ddd146103d4576101e3565b806301ffc9a7146101e85780630512487a1461023057806306fdde031461026b578063081812fc146102f5575b600080fd5b3480156101f457600080fd5b5061021c6004803603602081101561020b57600080fd5b50356001600160e01b03191661096d565b604080519115158252519081900360200190f35b34801561023c57600080fd5b506102696004803603604081101561025357600080fd5b506001600160a01b038135169060200135610990565b005b34801561027757600080fd5b50610280610bea565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102ba5781810151838201526020016102a2565b50505050905090810190601f1680156102e75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561030157600080fd5b5061031f6004803603602081101561031857600080fd5b5035610c81565b604080516001600160a01b039092168252519081900360200190f35b34801561034757600080fd5b506102696004803603604081101561035e57600080fd5b506001600160a01b038135169060200135610ce8565b6102696004803603602081101561038a57600080fd5b5035610dc8565b34801561039d57600080fd5b50610269600480360360608110156103b457600080fd5b506001600160a01b03813581169160208101359091169060400135610e7b565b3480156103e057600080fd5b506103e9610ede565b60408051918252519081900360200190f35b34801561040757600080fd5b506102696004803603606081101561041e57600080fd5b506001600160a01b03813581169160208101359091169060400135610ee4565b34801561044a57600080fd5b506102696004803603606081101561046157600080fd5b506001600160a01b03813581169160208101359091169060400135610f40565b34801561048d57600080fd5b50610269600480360360608110156104a457600080fd5b506001600160a01b03813581169160208101359091169060400135610fa3565b3480156104d057600080fd5b506103e9600480360360208110156104e757600080fd5b5035610fbe565b3480156104fa57600080fd5b506102696004803603604081101561051157600080fd5b506001600160a01b03813516906020013561101f565b6103e9611085565b34801561053b57600080fd5b506102696004803603602081101561055257600080fd5b503561113b565b34801561056557600080fd5b5061031f6004803603602081101561057c57600080fd5b50356111ce565b34801561058f57600080fd5b506103e96111e9565b3480156105a457600080fd5b506103e9600480360360208110156105bb57600080fd5b50356001600160a01b0316611225565b3480156105d757600080fd5b5061026961128d565b3480156105ec57600080fd5b5061031f61132f565b34801561060157600080fd5b5061028061133e565b34801561061657600080fd5b506102696004803603604081101561062d57600080fd5b506001600160a01b038135169060200135151561139f565b34801561065157600080fd5b506103e96004803603602081101561066857600080fd5b5035611493565b34801561067b57600080fd5b50610269600480360360c081101561069257600080fd5b813591908101906040810160208201356401000000008111156106b457600080fd5b8201836020820111156106c657600080fd5b803590602001918460018302840111640100000000831117156106e857600080fd5b919350915080359063ffffffff60208201358116916040810135821691606090910135166114f4565b34801561071d57600080fd5b506102696004803603608081101561073457600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561076f57600080fd5b82018360208201111561078157600080fd5b803590602001918460018302840111640100000000831117156107a357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506116fd945050505050565b3480156107f057600080fd5b506102806004803603602081101561080757600080fd5b5035611760565b34801561081a57600080fd5b506103e96117b8565b34801561082f57600080fd5b50610269600480360360a081101561084657600080fd5b81019060208101813564010000000081111561086157600080fd5b82018360208201111561087357600080fd5b8035906020019184600183028401116401000000008311171561089557600080fd5b919350915080359063ffffffff60208201358116916040810135821691606090910135166117be565b3480156108ca57600080fd5b50610269600480360360208110156108e157600080fd5b50351515611a3e565b3480156108f657600080fd5b506103e9611add565b34801561090b57600080fd5b5061021c6004803603604081101561092257600080fd5b506001600160a01b0381358116916020013516611afa565b34801561094657600080fd5b506102696004803603602081101561095d57600080fd5b50356001600160a01b0316611b2a565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b610998611c23565b6008546001600160a01b039081169116146109e8576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b600f54610100900460ff1615610a31576040805162461bcd60e51b81526020600482015260096024820152681314150e914b4c0c0d60ba1b604482015290519081900360640190fd5b6000826001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a6c57600080fd5b505afa158015610a80573d6000803e3d6000fd5b505050506040513d6020811015610a9657600080fd5b50519050801580610aa85750600e5481115b610ae5576040805162461bcd60e51b81526020600482015260096024820152681314150e914b4c0c0d60ba1b604482015290519081900360640190fd5b8015610bd357600e54600090610afb9084611c27565b905081811115610b1c57610b19610b128284611c88565b8490611c88565b92505b60015b838111610bc057600e54600090610b369083611c27565b90506000866001600160a01b0316636352211e836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610b7e57600080fd5b505afa158015610b92573d6000803e3d6000fd5b505050506040513d6020811015610ba857600080fd5b50519050610bb581611cca565b505050600101610b1f565b50600e54610bce9084611c27565b600e55505b600e54811415610be557610be5611e01565b505050565b60058054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610c765780601f10610c4b57610100808354040283529160200191610c76565b820191906000526020600020905b815481529060010190602001808311610c5957829003601f168201915b505050505090505b90565b6000610c8c82611f5e565b610ccc576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303560a01b604482015290519081900360640190fd5b506000908152600360205260409020546001600160a01b031690565b6000610cf3826111ce565b9050806001600160a01b0316836001600160a01b03161415610d4b576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d31313160a01b604482015290519081900360640190fd5b806001600160a01b0316610d5d611c23565b6001600160a01b03161480610d7e5750610d7e81610d79611c23565b611afa565b610dbe576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d31303560a01b604482015290519081900360640190fd5b610be58383611f7b565b60026009541415610e20576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002600955600f5460ff1615610e69576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d31303160b81b604482015290519081900360640190fd5b610e733382611fe9565b506001600955565b610e83611c23565b6008546001600160a01b03908116911614610ed3576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b610be5838383612287565b60075490565b610ef5610eef611c23565b826123b1565b610f35576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d31303560a01b604482015290519081900360640190fd5b610be583838361245a565b610f48611c23565b6008546001600160a01b03908116911614610f98576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b610be58383836125d0565b610be5838383604051806020016040528060008152506116fd565b6000610fc982611f5e565b611006576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d34303560b81b604482015290519081900360640190fd5b61100f82612756565b60a0015163ffffffff1692915050565b611027611c23565b6008546001600160a01b03908116911614611077576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b61108182826128ac565b5050565b6000600260095414156110df576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002600955600f5460ff1615611128576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d31303160b81b604482015290519081900360640190fd5b6111313361294f565b6001600955919050565b611143611c23565b6008546001600160a01b03908116911614611193576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b600d8190556040805182815290517f409ba051a4c57ed282ca3d937444126381926068149b2ceb9dcff792655a9b039181900360200190a150565b6000908152600160205260409020546001600160a01b031690565b600a54600b54600091116111ff57506000610c7e565b600a600b548154811061120e57fe5b906000526020600020906003020160010154905090565b60006001600160a01b038216611271576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303360a01b604482015290519081900360640190fd5b506001600160a01b031660009081526002602052604090205490565b611295611c23565b6008546001600160a01b039081169116146112e5576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b6008546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600880546001600160a01b0319169055565b6008546001600160a01b031690565b60068054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610c765780601f10610c4b57610100808354040283529160200191610c76565b6113a7611c23565b6001600160a01b0316826001600160a01b031614156113fc576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d31313160a01b604482015290519081900360640190fd5b8060046000611409611c23565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff19169215159290921790915561144d611c23565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b600061149e82611f5e565b6114db576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d34303560b81b604482015290519081900360640190fd5b6114e482612756565b6080015163ffffffff1692915050565b6114fc611c23565b6008546001600160a01b0390811691161461154c576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b8585600a898154811061155b57fe5b600091825260209091206115759360039092020191613344565b5083600a888154811061158457fe5b90600052602060002090600302016001018190555082600a88815481106115a757fe5b906000526020600020906003020160020160106101000a81548163ffffffff021916908363ffffffff16021790555081600a88815481106115e457fe5b906000526020600020906003020160020160146101000a81548163ffffffff021916908363ffffffff16021790555080600a888154811061162157fe5b906000526020600020906003020160020160186101000a81548163ffffffff021916908363ffffffff1602179055507fc29eb52b178d59612a9ec3dbfed2e3054ea12f735bff5d06a799a4b06cd47c5287878787878787600c5460405180898152602001806020018781526020018663ffffffff1681526020018563ffffffff1681526020018463ffffffff1681526020018381526020018281038252898982818152602001925080828437600083820152604051601f909101601f19169092018290039b50909950505050505050505050a150505050505050565b61170e611708611c23565b836123b1565b61174e576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d31303560a01b604482015290519081900360640190fd5b61175a84848484612b46565b50505050565b606061176b82611f5e565b6117a8576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d34303560b81b604482015290519081900360640190fd5b6117b182612756565b5192915050565b600c5490565b6117c6611c23565b6008546001600160a01b03908116911614611816576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b600c5461182c9063ffffffff80861690611c2716565b600c556118376133c2565b6040518060c0016040528088888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509385525050506020808301899052600c546001600160801b0316604084015263ffffffff80891660608501528781166080850152861660a090930192909252600a8054600181018255915282518051939450849360039092027fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a801926118ff928492909101906133f7565b5060208281015160018301556040808401516002909301805460608087015160808089015160a0998a01516fffffffffffffffffffffffffffffffff199095166001600160801b039099169890981763ffffffff60801b1916600160801b63ffffffff938416021763ffffffff60a01b1916600160a01b988316989098029790971763ffffffff60c01b1916600160c01b9382169390930292909217909255600c5483519485018c90528a8216938501939093528881169184019190915286169282019290925291820181905260c080835282018890527f03a96a3a809ae0740a794cb4d254030e999b01bb9985f4b0b5f5e524dc8e0667918991899189918991899189918060e08101898980828437600083820152604051601f909101601f19169092018290039a509098505050505050505050a150505050505050565b611a46611c23565b6008546001600160a01b03908116911614611a96576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b600f805482151560ff19909116811790915560408051918252517fa9bfed3d98385b3777389e321dbde773cf7d335fa604fefbae3dca93564f55869181900360200190a150565b600a54600b5460009111611af357506000610c7e565b50600b5490565b6001600160a01b0380831660009081526004602090815260408083209385168352929052205460ff165b92915050565b611b32611c23565b6008546001600160a01b03908116911614611b82576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b6001600160a01b038116611bc75760405162461bcd60e51b815260040180806020018281038252602681526020018061347b6026913960400191505060405180910390fd5b6008546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600880546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b600082820183811015611c81576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000611c8183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612b9d565b60006001600160a01b038216611d16576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303360a01b604482015290519081900360640190fd5b600754611d24906001611c27565b6007819055611d3281611f5e565b15611d73576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303760a01b604482015290519081900360640190fd5b600081815260016020818152604080842080546001600160a01b0319166001600160a01b0389169081179091558452600290915290912054611db491611c27565b6001600160a01b0384166000818152600260205260408082209390935591518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a492915050565b6000600b8190555b600a54811015611f4c57611e1b6133c2565b600a8281548110611e2857fe5b600091825260209182902060408051600393909302909101805460026001821615610100026000190190911604601f8101859004909402830160e090810190925260c0830184815292939092849290918491840182828015611ecb5780601f10611ea057610100808354040283529160200191611ecb565b820191906000526020600020905b815481529060010190602001808311611eae57829003601f168201915b5050509183525050600182015460208201526002909101546001600160801b0380821660408085019190915263ffffffff600160801b840481166060860152600160a01b840481166080860152600160c01b90930490921660a090930192909252820151600e549293501611611f435760018201600b555b50600101611e09565b50600f805461ff001916610100179055565b6000908152600160205260409020546001600160a01b0316151590565b600081815260036020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611fb0826111ce565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600a54600b541061202d576040805162461bcd60e51b8152602060048201526009602482015268098a0a8748a5a6860760bb1b604482015290519081900360640190fd5b600d54158061203e5750600d548111155b61207b576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d34323960b81b604482015290519081900360640190fd5b6120836133c2565b600a600b548154811061209257fe5b600091825260209182902060408051600393909302909101805460026001821615610100026000190190911604601f8101859004909402830160e090810190925260c08301848152929390928492909184918401828280156121355780601f1061210a57610100808354040283529160200191612135565b820191906000526020600020905b81548152906001019060200180831161211857829003601f168201915b5050509183525050600182015460208201526002909101546001600160801b038116604083015263ffffffff600160801b820481166060840152600160a01b820481166080840152600160c01b909104811660a0909201919091526007549192506000916121a5918590611c2716565b905081604001516001600160801b03168111156121e2576121df610b1283604001516001600160801b031683611c8890919063ffffffff16565b92505b60208201516000906121f49085612c34565b905080341015612237576040805162461bcd60e51b81526020600482015260096024820152681314150e914b4d0c4d60ba1b604482015290519081900360640190fd5b612251858560405180602001604052806000815250612c8d565b82604001516001600160801b0316821061227757600b54612273906001611c27565b600b555b61228081612ca8565b5050505050565b6001600160a01b0383166122ce576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b80826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561231c57600080fd5b505afa158015612330573d6000803e3d6000fd5b505050506040513d602081101561234657600080fd5b505110610be5576123616001600160a01b0383168483612cd7565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b836040518082815260200191505060405180910390a3505050565b60006123bc82611f5e565b6123fc576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303560a01b604482015290519081900360640190fd5b6000612407836111ce565b9050806001600160a01b0316846001600160a01b031614806124425750836001600160a01b031661243784610c81565b6001600160a01b0316145b8061245257506124528185611afa565b949350505050565b826001600160a01b031661246d826111ce565b6001600160a01b0316146124b7576040805162461bcd60e51b815260206004820152600c60248201526b22a9219b99189d229698981960a11b604482015290519081900360640190fd5b6001600160a01b038216612501576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303360a01b604482015290519081900360640190fd5b61250c600082611f7b565b600081815260016020818152604080842080546001600160a01b0319166001600160a01b03888116919091179091558716845260029091529091205461255191611c88565b6001600160a01b038085166000908152600260205260408082209390935590841681522054612581906001611c27565b6001600160a01b03808416600081815260026020526040808220949094559251849391928716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b038316612617576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b306001600160a01b0316826001600160a01b0316636352211e836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561266557600080fd5b505afa158015612679573d6000803e3d6000fd5b505050506040513d602081101561268f57600080fd5b50516001600160a01b03161415610be557604080516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018490529151918416916323b872dd9160648082019260009290919082900301818387803b1580156126f857600080fd5b505af115801561270c573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b61275e6133c2565b600a5460005b818110156128a5576127746133c2565b600a828154811061278157fe5b600091825260209182902060408051600393909302909101805460026001821615610100026000190190911604601f8101859004909402830160e090810190925260c08301848152929390928492909184918401828280156128245780601f106127f957610100808354040283529160200191612824565b820191906000526020600020905b81548152906001019060200180831161280757829003601f168201915b5050509183525050600182015460208201526002909101546001600160801b0380821660408085019190915263ffffffff600160801b840481166060860152600160a01b840481166080860152600160c01b90930490921660a09093019290925282015191925016851161289c57925061098b915050565b50600101612764565b5050919050565b6001600160a01b0382166128f3576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b8047106110815761290d6001600160a01b03831682612d29565b6040805182815290516001600160a01b038416917eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd919081900360200190a25050565b600a54600b5460009111612996576040805162461bcd60e51b8152602060048201526009602482015268098a0a8748a5a6860760bb1b604482015290519081900360640190fd5b61299e6133c2565b600a600b54815481106129ad57fe5b600091825260209182902060408051600393909302909101805460026001821615610100026000190190911604601f8101859004909402830160e090810190925260c0830184815292939092849290918491840182828015612a505780601f10612a2557610100808354040283529160200191612a50565b820191906000526020600020905b815481529060010190602001808311612a3357829003601f168201915b505050918352505060018201546020808301919091526002909201546001600160801b038116604083015263ffffffff600160801b820481166060840152600160a01b820481166080840152600160c01b9091041660a090910152810151909150341015612af1576040805162461bcd60e51b81526020600482015260096024820152681314150e914b4d0c4d60ba1b604482015290519081900360640190fd5b612b0a8360405180602001604052806000815250612e0e565b915080604001516001600160801b0316821415612b3357600b54612b2f906001611c27565b600b555b612b408160200151612ca8565b50919050565b612b5184848461245a565b612b5d84848484612e69565b61175a576040805162461bcd60e51b815260206004820152600c60248201526b22a9219b99189d22969a181960a11b604482015290519081900360640190fd5b60008184841115612c2c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612bf1578181015183820152602001612bd9565b50505050905090810190601f168015612c1e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082612c4357506000611b24565b82820282848281612c5057fe5b0414611c815760405162461bcd60e51b81526004018080602001828103825260218152602001806134db6021913960400191505060405180910390fd5b6000612c998484612fe5565b9050612b5d6000858385612e69565b6000612cb43483611c88565b905080156110815761108181612cc8611c23565b6001600160a01b031690612d29565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610be5908490613116565b80471015612d7e576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015290519081900360640190fd5b6040516000906001600160a01b0384169083908381818185875af1925050503d8060008114612dc9576040519150601f19603f3d011682016040523d82523d6000602084013e612dce565b606091505b5050905080610be55760405162461bcd60e51b815260040180806020018281038252603a8152602001806134a1603a913960400191505060405180910390fd5b600080612e1a84611cca565b9050612e296000858386612e69565b611c81576040805162461bcd60e51b815260206004820152600c60248201526b22a9219b99189d22969a181960a11b604482015290519081900360640190fd5b6000612e7d846001600160a01b03166131c7565b612e8957506001612452565b6060612fab630a85bd0160e11b612e9e611c23565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612f05578181015183820152602001612eed565b50505050905090810190601f168015612f325780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b0383818316178352505050506040518060400160405280600c81526020016b22a9219b99189d22969a181960a11b815250876001600160a01b03166131cd9092919063ffffffff16565b90506000818060200190516020811015612fc457600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b60006001600160a01b038316613031576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303360a01b604482015290519081900360640190fd5b600754600090613042906001611c27565b905060015b8381116130c15760075460009061305e9083611c27565b60008181526001602052604080822080546001600160a01b0319166001600160a01b038b16908117909155905192935083929091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a450600101613047565b506007546130cf9084611c27565b6007556001600160a01b0384166000908152600260205260409020546130f59084611c27565b6001600160a01b038516600090815260026020526040902055905092915050565b606061316b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131cd9092919063ffffffff16565b805190915015610be55780806020019051602081101561318a57600080fd5b5051610be55760405162461bcd60e51b815260040180806020018281038252602a81526020018061351c602a913960400191505060405180910390fd5b3b151590565b6060612452848460008560606131e2856131c7565b613233576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106132725780518252601f199092019160209182019101613253565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146132d4576040519150601f19603f3d011682016040523d82523d6000602084013e6132d9565b606091505b509150915081156132ed5791506124529050565b8051156132fd5780518082602001fd5b60405162461bcd60e51b8152602060048201818152865160248401528651879391928392604401919085019080838360008315612bf1578181015183820152602001612bd9565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106133855782800160ff198235161785556133b2565b828001600101855582156133b2579182015b828111156133b2578235825591602001919060010190613397565b506133be929150613465565b5090565b6040805160c081018252606080825260006020830181905292820183905281018290526080810182905260a081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061343857805160ff19168380011785556133b2565b828001600101855582156133b2579182015b828111156133b257825182559160200191906001019061344a565b5b808211156133be576000815560010161346656fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373416464726573733a20756e61626c6520746f2073656e642076616c75652c20726563697069656e74206d61792068617665207265766572746564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220d7e45e90b00ada93bf14e609b381114d3130c10d66c4fda21c728f1176b4ffd264736f6c634300060c0033", + "deployedBytecode": "0x6080604052600436106101e35760003560e01c8063681ce98a11610102578063b88d4fde11610095578063db9f60ff11610064578063db9f60ff146108be578063e6089023146108ea578063e985e9c5146108ff578063f2fde38b1461093a576101e3565b8063b88d4fde14610711578063c87b56dd146107e4578063d5abeb011461080e578063da47bb2614610823576101e3565b806395d89b41116100d157806395d89b41146105f5578063a22cb4651461060a578063adf8252d14610645578063b0fde8cf1461066f576101e3565b8063681ce98a1461058357806370a0823114610598578063715018a6146105cb5780638da5cb5b146105e0576101e3565b806323b872dd1161017a578063522f681511610149578063522f6815146104ee5780635fc194ed14610527578063616cdb1e1461052f5780636352211e14610559576101e3565b806323b872dd146103fb5780634025feb21461043e57806342842e0e146104815780634aa66b28146104c4576101e3565b8063095ea7b3116101b6578063095ea7b31461033b5780630afd902b146103745780631593dee11461039157806318160ddd146103d4576101e3565b806301ffc9a7146101e85780630512487a1461023057806306fdde031461026b578063081812fc146102f5575b600080fd5b3480156101f457600080fd5b5061021c6004803603602081101561020b57600080fd5b50356001600160e01b03191661096d565b604080519115158252519081900360200190f35b34801561023c57600080fd5b506102696004803603604081101561025357600080fd5b506001600160a01b038135169060200135610990565b005b34801561027757600080fd5b50610280610bea565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102ba5781810151838201526020016102a2565b50505050905090810190601f1680156102e75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561030157600080fd5b5061031f6004803603602081101561031857600080fd5b5035610c81565b604080516001600160a01b039092168252519081900360200190f35b34801561034757600080fd5b506102696004803603604081101561035e57600080fd5b506001600160a01b038135169060200135610ce8565b6102696004803603602081101561038a57600080fd5b5035610dc8565b34801561039d57600080fd5b50610269600480360360608110156103b457600080fd5b506001600160a01b03813581169160208101359091169060400135610e7b565b3480156103e057600080fd5b506103e9610ede565b60408051918252519081900360200190f35b34801561040757600080fd5b506102696004803603606081101561041e57600080fd5b506001600160a01b03813581169160208101359091169060400135610ee4565b34801561044a57600080fd5b506102696004803603606081101561046157600080fd5b506001600160a01b03813581169160208101359091169060400135610f40565b34801561048d57600080fd5b50610269600480360360608110156104a457600080fd5b506001600160a01b03813581169160208101359091169060400135610fa3565b3480156104d057600080fd5b506103e9600480360360208110156104e757600080fd5b5035610fbe565b3480156104fa57600080fd5b506102696004803603604081101561051157600080fd5b506001600160a01b03813516906020013561101f565b6103e9611085565b34801561053b57600080fd5b506102696004803603602081101561055257600080fd5b503561113b565b34801561056557600080fd5b5061031f6004803603602081101561057c57600080fd5b50356111ce565b34801561058f57600080fd5b506103e96111e9565b3480156105a457600080fd5b506103e9600480360360208110156105bb57600080fd5b50356001600160a01b0316611225565b3480156105d757600080fd5b5061026961128d565b3480156105ec57600080fd5b5061031f61132f565b34801561060157600080fd5b5061028061133e565b34801561061657600080fd5b506102696004803603604081101561062d57600080fd5b506001600160a01b038135169060200135151561139f565b34801561065157600080fd5b506103e96004803603602081101561066857600080fd5b5035611493565b34801561067b57600080fd5b50610269600480360360c081101561069257600080fd5b813591908101906040810160208201356401000000008111156106b457600080fd5b8201836020820111156106c657600080fd5b803590602001918460018302840111640100000000831117156106e857600080fd5b919350915080359063ffffffff60208201358116916040810135821691606090910135166114f4565b34801561071d57600080fd5b506102696004803603608081101561073457600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561076f57600080fd5b82018360208201111561078157600080fd5b803590602001918460018302840111640100000000831117156107a357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506116fd945050505050565b3480156107f057600080fd5b506102806004803603602081101561080757600080fd5b5035611760565b34801561081a57600080fd5b506103e96117b8565b34801561082f57600080fd5b50610269600480360360a081101561084657600080fd5b81019060208101813564010000000081111561086157600080fd5b82018360208201111561087357600080fd5b8035906020019184600183028401116401000000008311171561089557600080fd5b919350915080359063ffffffff60208201358116916040810135821691606090910135166117be565b3480156108ca57600080fd5b50610269600480360360208110156108e157600080fd5b50351515611a3e565b3480156108f657600080fd5b506103e9611add565b34801561090b57600080fd5b5061021c6004803603604081101561092257600080fd5b506001600160a01b0381358116916020013516611afa565b34801561094657600080fd5b506102696004803603602081101561095d57600080fd5b50356001600160a01b0316611b2a565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b610998611c23565b6008546001600160a01b039081169116146109e8576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b600f54610100900460ff1615610a31576040805162461bcd60e51b81526020600482015260096024820152681314150e914b4c0c0d60ba1b604482015290519081900360640190fd5b6000826001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a6c57600080fd5b505afa158015610a80573d6000803e3d6000fd5b505050506040513d6020811015610a9657600080fd5b50519050801580610aa85750600e5481115b610ae5576040805162461bcd60e51b81526020600482015260096024820152681314150e914b4c0c0d60ba1b604482015290519081900360640190fd5b8015610bd357600e54600090610afb9084611c27565b905081811115610b1c57610b19610b128284611c88565b8490611c88565b92505b60015b838111610bc057600e54600090610b369083611c27565b90506000866001600160a01b0316636352211e836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610b7e57600080fd5b505afa158015610b92573d6000803e3d6000fd5b505050506040513d6020811015610ba857600080fd5b50519050610bb581611cca565b505050600101610b1f565b50600e54610bce9084611c27565b600e55505b600e54811415610be557610be5611e01565b505050565b60058054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610c765780601f10610c4b57610100808354040283529160200191610c76565b820191906000526020600020905b815481529060010190602001808311610c5957829003601f168201915b505050505090505b90565b6000610c8c82611f5e565b610ccc576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303560a01b604482015290519081900360640190fd5b506000908152600360205260409020546001600160a01b031690565b6000610cf3826111ce565b9050806001600160a01b0316836001600160a01b03161415610d4b576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d31313160a01b604482015290519081900360640190fd5b806001600160a01b0316610d5d611c23565b6001600160a01b03161480610d7e5750610d7e81610d79611c23565b611afa565b610dbe576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d31303560a01b604482015290519081900360640190fd5b610be58383611f7b565b60026009541415610e20576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002600955600f5460ff1615610e69576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d31303160b81b604482015290519081900360640190fd5b610e733382611fe9565b506001600955565b610e83611c23565b6008546001600160a01b03908116911614610ed3576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b610be5838383612287565b60075490565b610ef5610eef611c23565b826123b1565b610f35576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d31303560a01b604482015290519081900360640190fd5b610be583838361245a565b610f48611c23565b6008546001600160a01b03908116911614610f98576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b610be58383836125d0565b610be5838383604051806020016040528060008152506116fd565b6000610fc982611f5e565b611006576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d34303560b81b604482015290519081900360640190fd5b61100f82612756565b60a0015163ffffffff1692915050565b611027611c23565b6008546001600160a01b03908116911614611077576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b61108182826128ac565b5050565b6000600260095414156110df576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002600955600f5460ff1615611128576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d31303160b81b604482015290519081900360640190fd5b6111313361294f565b6001600955919050565b611143611c23565b6008546001600160a01b03908116911614611193576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b600d8190556040805182815290517f409ba051a4c57ed282ca3d937444126381926068149b2ceb9dcff792655a9b039181900360200190a150565b6000908152600160205260409020546001600160a01b031690565b600a54600b54600091116111ff57506000610c7e565b600a600b548154811061120e57fe5b906000526020600020906003020160010154905090565b60006001600160a01b038216611271576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303360a01b604482015290519081900360640190fd5b506001600160a01b031660009081526002602052604090205490565b611295611c23565b6008546001600160a01b039081169116146112e5576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b6008546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600880546001600160a01b0319169055565b6008546001600160a01b031690565b60068054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610c765780601f10610c4b57610100808354040283529160200191610c76565b6113a7611c23565b6001600160a01b0316826001600160a01b031614156113fc576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d31313160a01b604482015290519081900360640190fd5b8060046000611409611c23565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff19169215159290921790915561144d611c23565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b600061149e82611f5e565b6114db576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d34303560b81b604482015290519081900360640190fd5b6114e482612756565b6080015163ffffffff1692915050565b6114fc611c23565b6008546001600160a01b0390811691161461154c576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b8585600a898154811061155b57fe5b600091825260209091206115759360039092020191613344565b5083600a888154811061158457fe5b90600052602060002090600302016001018190555082600a88815481106115a757fe5b906000526020600020906003020160020160106101000a81548163ffffffff021916908363ffffffff16021790555081600a88815481106115e457fe5b906000526020600020906003020160020160146101000a81548163ffffffff021916908363ffffffff16021790555080600a888154811061162157fe5b906000526020600020906003020160020160186101000a81548163ffffffff021916908363ffffffff1602179055507fc29eb52b178d59612a9ec3dbfed2e3054ea12f735bff5d06a799a4b06cd47c5287878787878787600c5460405180898152602001806020018781526020018663ffffffff1681526020018563ffffffff1681526020018463ffffffff1681526020018381526020018281038252898982818152602001925080828437600083820152604051601f909101601f19169092018290039b50909950505050505050505050a150505050505050565b61170e611708611c23565b836123b1565b61174e576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d31303560a01b604482015290519081900360640190fd5b61175a84848484612b46565b50505050565b606061176b82611f5e565b6117a8576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d34303560b81b604482015290519081900360640190fd5b6117b182612756565b5192915050565b600c5490565b6117c6611c23565b6008546001600160a01b03908116911614611816576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b600c5461182c9063ffffffff80861690611c2716565b600c556118376133c2565b6040518060c0016040528088888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509385525050506020808301899052600c546001600160801b0316604084015263ffffffff80891660608501528781166080850152861660a090930192909252600a8054600181018255915282518051939450849360039092027fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a801926118ff928492909101906133f7565b5060208281015160018301556040808401516002909301805460608087015160808089015160a0998a01516fffffffffffffffffffffffffffffffff199095166001600160801b039099169890981763ffffffff60801b1916600160801b63ffffffff938416021763ffffffff60a01b1916600160a01b988316989098029790971763ffffffff60c01b1916600160c01b9382169390930292909217909255600c5483519485018c90528a8216938501939093528881169184019190915286169282019290925291820181905260c080835282018890527f03a96a3a809ae0740a794cb4d254030e999b01bb9985f4b0b5f5e524dc8e0667918991899189918991899189918060e08101898980828437600083820152604051601f909101601f19169092018290039a509098505050505050505050a150505050505050565b611a46611c23565b6008546001600160a01b03908116911614611a96576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b600f805482151560ff19909116811790915560408051918252517fa9bfed3d98385b3777389e321dbde773cf7d335fa604fefbae3dca93564f55869181900360200190a150565b600a54600b5460009111611af357506000610c7e565b50600b5490565b6001600160a01b0380831660009081526004602090815260408083209385168352929052205460ff165b92915050565b611b32611c23565b6008546001600160a01b03908116911614611b82576040805162461bcd60e51b815260206004820181905260248201526000805160206134fc833981519152604482015290519081900360640190fd5b6001600160a01b038116611bc75760405162461bcd60e51b815260040180806020018281038252602681526020018061347b6026913960400191505060405180910390fd5b6008546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600880546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b600082820183811015611c81576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000611c8183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612b9d565b60006001600160a01b038216611d16576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303360a01b604482015290519081900360640190fd5b600754611d24906001611c27565b6007819055611d3281611f5e565b15611d73576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303760a01b604482015290519081900360640190fd5b600081815260016020818152604080842080546001600160a01b0319166001600160a01b0389169081179091558452600290915290912054611db491611c27565b6001600160a01b0384166000818152600260205260408082209390935591518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a492915050565b6000600b8190555b600a54811015611f4c57611e1b6133c2565b600a8281548110611e2857fe5b600091825260209182902060408051600393909302909101805460026001821615610100026000190190911604601f8101859004909402830160e090810190925260c0830184815292939092849290918491840182828015611ecb5780601f10611ea057610100808354040283529160200191611ecb565b820191906000526020600020905b815481529060010190602001808311611eae57829003601f168201915b5050509183525050600182015460208201526002909101546001600160801b0380821660408085019190915263ffffffff600160801b840481166060860152600160a01b840481166080860152600160c01b90930490921660a090930192909252820151600e549293501611611f435760018201600b555b50600101611e09565b50600f805461ff001916610100179055565b6000908152600160205260409020546001600160a01b0316151590565b600081815260036020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611fb0826111ce565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600a54600b541061202d576040805162461bcd60e51b8152602060048201526009602482015268098a0a8748a5a6860760bb1b604482015290519081900360640190fd5b600d54158061203e5750600d548111155b61207b576040805162461bcd60e51b81526020600482015260096024820152684c50543a452d34323960b81b604482015290519081900360640190fd5b6120836133c2565b600a600b548154811061209257fe5b600091825260209182902060408051600393909302909101805460026001821615610100026000190190911604601f8101859004909402830160e090810190925260c08301848152929390928492909184918401828280156121355780601f1061210a57610100808354040283529160200191612135565b820191906000526020600020905b81548152906001019060200180831161211857829003601f168201915b5050509183525050600182015460208201526002909101546001600160801b038116604083015263ffffffff600160801b820481166060840152600160a01b820481166080840152600160c01b909104811660a0909201919091526007549192506000916121a5918590611c2716565b905081604001516001600160801b03168111156121e2576121df610b1283604001516001600160801b031683611c8890919063ffffffff16565b92505b60208201516000906121f49085612c34565b905080341015612237576040805162461bcd60e51b81526020600482015260096024820152681314150e914b4d0c4d60ba1b604482015290519081900360640190fd5b612251858560405180602001604052806000815250612c8d565b82604001516001600160801b0316821061227757600b54612273906001611c27565b600b555b61228081612ca8565b5050505050565b6001600160a01b0383166122ce576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b80826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561231c57600080fd5b505afa158015612330573d6000803e3d6000fd5b505050506040513d602081101561234657600080fd5b505110610be5576123616001600160a01b0383168483612cd7565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b836040518082815260200191505060405180910390a3505050565b60006123bc82611f5e565b6123fc576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303560a01b604482015290519081900360640190fd5b6000612407836111ce565b9050806001600160a01b0316846001600160a01b031614806124425750836001600160a01b031661243784610c81565b6001600160a01b0316145b8061245257506124528185611afa565b949350505050565b826001600160a01b031661246d826111ce565b6001600160a01b0316146124b7576040805162461bcd60e51b815260206004820152600c60248201526b22a9219b99189d229698981960a11b604482015290519081900360640190fd5b6001600160a01b038216612501576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303360a01b604482015290519081900360640190fd5b61250c600082611f7b565b600081815260016020818152604080842080546001600160a01b0319166001600160a01b03888116919091179091558716845260029091529091205461255191611c88565b6001600160a01b038085166000908152600260205260408082209390935590841681522054612581906001611c27565b6001600160a01b03808416600081815260026020526040808220949094559251849391928716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b038316612617576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b306001600160a01b0316826001600160a01b0316636352211e836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561266557600080fd5b505afa158015612679573d6000803e3d6000fd5b505050506040513d602081101561268f57600080fd5b50516001600160a01b03161415610be557604080516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018490529151918416916323b872dd9160648082019260009290919082900301818387803b1580156126f857600080fd5b505af115801561270c573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b61275e6133c2565b600a5460005b818110156128a5576127746133c2565b600a828154811061278157fe5b600091825260209182902060408051600393909302909101805460026001821615610100026000190190911604601f8101859004909402830160e090810190925260c08301848152929390928492909184918401828280156128245780601f106127f957610100808354040283529160200191612824565b820191906000526020600020905b81548152906001019060200180831161280757829003601f168201915b5050509183525050600182015460208201526002909101546001600160801b0380821660408085019190915263ffffffff600160801b840481166060860152600160a01b840481166080860152600160c01b90930490921660a09093019290925282015191925016851161289c57925061098b915050565b50600101612764565b5050919050565b6001600160a01b0382166128f3576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b8047106110815761290d6001600160a01b03831682612d29565b6040805182815290516001600160a01b038416917eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd919081900360200190a25050565b600a54600b5460009111612996576040805162461bcd60e51b8152602060048201526009602482015268098a0a8748a5a6860760bb1b604482015290519081900360640190fd5b61299e6133c2565b600a600b54815481106129ad57fe5b600091825260209182902060408051600393909302909101805460026001821615610100026000190190911604601f8101859004909402830160e090810190925260c0830184815292939092849290918491840182828015612a505780601f10612a2557610100808354040283529160200191612a50565b820191906000526020600020905b815481529060010190602001808311612a3357829003601f168201915b505050918352505060018201546020808301919091526002909201546001600160801b038116604083015263ffffffff600160801b820481166060840152600160a01b820481166080840152600160c01b9091041660a090910152810151909150341015612af1576040805162461bcd60e51b81526020600482015260096024820152681314150e914b4d0c4d60ba1b604482015290519081900360640190fd5b612b0a8360405180602001604052806000815250612e0e565b915080604001516001600160801b0316821415612b3357600b54612b2f906001611c27565b600b555b612b408160200151612ca8565b50919050565b612b5184848461245a565b612b5d84848484612e69565b61175a576040805162461bcd60e51b815260206004820152600c60248201526b22a9219b99189d22969a181960a11b604482015290519081900360640190fd5b60008184841115612c2c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612bf1578181015183820152602001612bd9565b50505050905090810190601f168015612c1e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082612c4357506000611b24565b82820282848281612c5057fe5b0414611c815760405162461bcd60e51b81526004018080602001828103825260218152602001806134db6021913960400191505060405180910390fd5b6000612c998484612fe5565b9050612b5d6000858385612e69565b6000612cb43483611c88565b905080156110815761108181612cc8611c23565b6001600160a01b031690612d29565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610be5908490613116565b80471015612d7e576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015290519081900360640190fd5b6040516000906001600160a01b0384169083908381818185875af1925050503d8060008114612dc9576040519150601f19603f3d011682016040523d82523d6000602084013e612dce565b606091505b5050905080610be55760405162461bcd60e51b815260040180806020018281038252603a8152602001806134a1603a913960400191505060405180910390fd5b600080612e1a84611cca565b9050612e296000858386612e69565b611c81576040805162461bcd60e51b815260206004820152600c60248201526b22a9219b99189d22969a181960a11b604482015290519081900360640190fd5b6000612e7d846001600160a01b03166131c7565b612e8957506001612452565b6060612fab630a85bd0160e11b612e9e611c23565b88878760405160240180856001600160a01b03168152602001846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612f05578181015183820152602001612eed565b50505050905090810190601f168015612f325780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b0383818316178352505050506040518060400160405280600c81526020016b22a9219b99189d22969a181960a11b815250876001600160a01b03166131cd9092919063ffffffff16565b90506000818060200190516020811015612fc457600080fd5b50516001600160e01b031916630a85bd0160e11b1492505050949350505050565b60006001600160a01b038316613031576040805162461bcd60e51b815260206004820152600c60248201526b4552433732313a452d34303360a01b604482015290519081900360640190fd5b600754600090613042906001611c27565b905060015b8381116130c15760075460009061305e9083611c27565b60008181526001602052604080822080546001600160a01b0319166001600160a01b038b16908117909155905192935083929091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a450600101613047565b506007546130cf9084611c27565b6007556001600160a01b0384166000908152600260205260409020546130f59084611c27565b6001600160a01b038516600090815260026020526040902055905092915050565b606061316b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166131cd9092919063ffffffff16565b805190915015610be55780806020019051602081101561318a57600080fd5b5051610be55760405162461bcd60e51b815260040180806020018281038252602a81526020018061351c602a913960400191505060405180910390fd5b3b151590565b6060612452848460008560606131e2856131c7565b613233576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106132725780518252601f199092019160209182019101613253565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146132d4576040519150601f19603f3d011682016040523d82523d6000602084013e6132d9565b606091505b509150915081156132ed5791506124529050565b8051156132fd5780518082602001fd5b60405162461bcd60e51b8152602060048201818152865160248401528651879391928392604401919085019080838360008315612bf1578181015183820152602001612bd9565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106133855782800160ff198235161785556133b2565b828001600101855582156133b2579182015b828111156133b2578235825591602001919060010190613397565b506133be929150613465565b5090565b6040805160c081018252606080825260006020830181905292820183905281018290526080810182905260a081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061343857805160ff19168380011785556133b2565b828001600101855582156133b2579182015b828111156133b257825182559160200191906001019061344a565b5b808211156133be576000815560010161346656fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373416464726573733a20756e61626c6520746f2073656e642076616c75652c20726563697069656e74206d61792068617665207265766572746564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220d7e45e90b00ada93bf14e609b381114d3130c10d66c4fda21c728f1176b4ffd264736f6c634300060c0033", + "devdoc": { + "kind": "dev", + "methods": { + "approve(address,uint256)": { + "details": "See {IERC721-approve}." + }, + "balanceOf(address)": { + "details": "See {IERC721-balanceOf}." + }, + "getApproved(uint256)": { + "details": "See {IERC721-getApproved}." + }, + "isApprovedForAll(address,address)": { + "details": "See {IERC721-isApprovedForAll}." + }, + "name()": { + "details": "See {IERC721Metadata-name}." + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "ownerOf(uint256)": { + "details": "See {IERC721-ownerOf}." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "safeTransferFrom(address,address,uint256)": { + "details": "See {IERC721-safeTransferFrom}." + }, + "safeTransferFrom(address,address,uint256,bytes)": { + "details": "See {IERC721-safeTransferFrom}." + }, + "setApprovalForAll(address,bool)": { + "details": "See {IERC721-setApprovalForAll}." + }, + "supportsInterface(bytes4)": { + "details": "See {IERC165-supportsInterface}. Time complexity O(1), guaranteed to always use less than 30 000 gas." + }, + "symbol()": { + "details": "See {IERC721Metadata-symbol}." + }, + "transferFrom(address,address,uint256)": { + "details": "See {IERC721-transferFrom}." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 4592, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_supportedInterfaces", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_bytes4,t_bool)" + }, + { + "astId": 33423, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_tokenOwners", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_uint256,t_address)" + }, + { + "astId": 33427, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_ownerBalance", + "offset": 0, + "slot": "2", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 33431, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_tokenApprovals", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_address)" + }, + { + "astId": 33437, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_operatorApprovals", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_address,t_mapping(t_address,t_bool))" + }, + { + "astId": 33439, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_name", + "offset": 0, + "slot": "5", + "type": "t_string_storage" + }, + { + "astId": 33441, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_symbol", + "offset": 0, + "slot": "6", + "type": "t_string_storage" + }, + { + "astId": 33443, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_tokenCount", + "offset": 0, + "slot": "7", + "type": "t_uint256" + }, + { + "astId": 4406, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_owner", + "offset": 0, + "slot": "8", + "type": "t_address" + }, + { + "astId": 9097, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_status", + "offset": 0, + "slot": "9", + "type": "t_uint256" + }, + { + "astId": 37627, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_leptonTypes", + "offset": 0, + "slot": "10", + "type": "t_array(t_struct(Classification)28748_storage)dyn_storage" + }, + { + "astId": 37629, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_typeIndex", + "offset": 0, + "slot": "11", + "type": "t_uint256" + }, + { + "astId": 37631, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_maxSupply", + "offset": 0, + "slot": "12", + "type": "t_uint256" + }, + { + "astId": 37633, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_maxMintPerTx", + "offset": 0, + "slot": "13", + "type": "t_uint256" + }, + { + "astId": 37635, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_migratedCount", + "offset": 0, + "slot": "14", + "type": "t_uint256" + }, + { + "astId": 37637, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_paused", + "offset": 0, + "slot": "15", + "type": "t_bool" + }, + { + "astId": 37639, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_migrationComplete", + "offset": 1, + "slot": "15", + "type": "t_bool" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_struct(Classification)28748_storage)dyn_storage": { + "base": "t_struct(Classification)28748_storage", + "encoding": "dynamic_array", + "label": "struct ILepton.Classification[]", + "numberOfBytes": "32" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes4": { + "encoding": "inplace", + "label": "bytes4", + "numberOfBytes": "4" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_mapping(t_address,t_bool))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => bool))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_bool)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes4,t_bool)": { + "encoding": "mapping", + "key": "t_bytes4", + "label": "mapping(bytes4 => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_uint256,t_address)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(Classification)28748_storage": { + "encoding": "inplace", + "label": "struct ILepton.Classification", + "members": [ + { + "astId": 28737, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "tokenUri", + "offset": 0, + "slot": "0", + "type": "t_string_storage" + }, + { + "astId": 28739, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "price", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 28741, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "_upperBounds", + "offset": 0, + "slot": "2", + "type": "t_uint128" + }, + { + "astId": 28743, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "supply", + "offset": 16, + "slot": "2", + "type": "t_uint32" + }, + { + "astId": 28745, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "multiplier", + "offset": 20, + "slot": "2", + "type": "t_uint32" + }, + { + "astId": 28747, + "contract": "contracts/v1/tokens/Lepton2.sol:Lepton2", + "label": "bonus", + "offset": 24, + "slot": "2", + "type": "t_uint32" + } + ], + "numberOfBytes": "96" + }, + "t_uint128": { + "encoding": "inplace", + "label": "uint128", + "numberOfBytes": "16" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint32": { + "encoding": "inplace", + "label": "uint32", + "numberOfBytes": "4" + } + } + } +} \ No newline at end of file diff --git a/deployments/polygon/LeptonsStore.json b/deployments/polygon/LeptonsStore.json new file mode 100644 index 0000000..0dbb460 --- /dev/null +++ b/deployments/polygon/LeptonsStore.json @@ -0,0 +1,595 @@ +{ + "address": "0xB29a57a2AEa56be5c8C05A931773882EA48C047ea", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_lepton", + "type": "address" + }, + { + "internalType": "address", + "name": "_ionx", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_ionxPerLepton", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "buyer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "price", + "type": "uint256" + } + ], + "name": "SoldLepton", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "leptonAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "buyWithIonx", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "ionx", + "outputs": [ + { + "internalType": "contract Ionx", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ionxPerLepton", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lepton", + "outputs": [ + { + "internalType": "contract Lepton2", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "load", + "outputs": [], + "stateMutability": "payable", + "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": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_ionx", + "type": "address" + } + ], + "name": "setIonx", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "ionxAmount", + "type": "uint256" + } + ], + "name": "setIonxPerLepton", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_lepton", + "type": "address" + } + ], + "name": "setLepton", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xde46ee96316f88450ad55cd4109f048d91b5e4020693b44202b30fd8d14ce830", + "receipt": { + "to": null, + "from": "0x48F54e595bf039CF30fa5F768c0b57EAC6508a06", + "contractAddress": "0xB29a57a2AEa56be5c8C05A931773882EA48C0470", + "transactionIndex": 84, + "gasUsed": "1503492", + "logsBloom": "0x00000000000000000000000002000000000000000000000000800000000000000000000000001000000008000000000000008000000000000000000000000000000000000000000000000010000000800001000000000000000100020000000000000000020000000000000000000800000000000000000080000000000000400000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000800000000000000000000000000004000000000000000000001000000000000000000000000000000100000020020000000000000000008000000000000000000000000000000000000000020100000", + "blockHash": "0x221a140c39578b76a5cd26c08ad1678f19c1355fb1ee5dbd00859b3973aea237", + "transactionHash": "0xde46ee96316f88450ad55cd4109f048d91b5e4020693b44202b30fd8d14ce830", + "logs": [ + { + "transactionIndex": 84, + "blockNumber": 55142567, + "transactionHash": "0xde46ee96316f88450ad55cd4109f048d91b5e4020693b44202b30fd8d14ce830", + "address": "0xB29a57a2AEa56be5c8C05A931773882EA48C0470", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000048f54e595bf039cf30fa5f768c0b57eac6508a06" + ], + "data": "0x", + "logIndex": 403, + "blockHash": "0x221a140c39578b76a5cd26c08ad1678f19c1355fb1ee5dbd00859b3973aea237" + }, + { + "transactionIndex": 84, + "blockNumber": 55142567, + "transactionHash": "0xde46ee96316f88450ad55cd4109f048d91b5e4020693b44202b30fd8d14ce830", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x00000000000000000000000048f54e595bf039cf30fa5f768c0b57eac6508a06", + "0x000000000000000000000000794e44d1334a56fea7f4df12633b88820d0c5888" + ], + "data": "0x00000000000000000000000000000000000000000000000000a2290efcaa1c680000000000000000000000000000000000000000000000000de40dc17204acf8000000000000000000000000000000000000000000000169d8a1a141f8ec848c0000000000000000000000000000000000000000000000000d41e4b2755a9090000000000000000000000000000000000000000000000169d943ca50f596a0f4", + "logIndex": 404, + "blockHash": "0x221a140c39578b76a5cd26c08ad1678f19c1355fb1ee5dbd00859b3973aea237" + } + ], + "blockNumber": 55142567, + "cumulativeGasUsed": "16501435", + "status": 1, + "byzantium": true + }, + "args": [ + "0x4d40C9841E4cD0BF84a365cb6ad457dcAAF03e4a", + "0xf80941fA0D07218027435E9028ca21A6e56E3A44", + 1 + ], + "numDeployments": 2, + "solcInputHash": "a3c560866d7e9e0d097f164180bfa9ae", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_lepton\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_ionx\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_ionxPerLepton\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"buyer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"}],\"name\":\"SoldLepton\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC1155\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckEther\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"leptonAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"buyWithIonx\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ionx\",\"outputs\":[{\"internalType\":\"contract Ionx\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ionxPerLepton\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lepton\",\"outputs\":[{\"internalType\":\"contract Lepton2\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"load\",\"outputs\":[],\"stateMutability\":\"payable\",\"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\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_ionx\",\"type\":\"address\"}],\"name\":\"setIonx\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"ionxAmount\",\"type\":\"uint256\"}],\"name\":\"setIonxPerLepton\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_lepton\",\"type\":\"address\"}],\"name\":\"setLepton\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC1155\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawErc20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawEther\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/v1/leptons/store.sol\":\"LeptonsStore\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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 GSN 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 payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xdb26cbf4d028490f49831a7865c2fe1b28db44b535ca8d343785a3b768aae183\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"../GSN/Context.sol\\\";\\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 */\\ncontract 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 () internal {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view 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 emit OwnershipTransferred(_owner, address(0));\\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x4bd6402ca6b3419008c2b482aff54e66836e8cb4eba2680e42ac5884ae6424fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts may inherit from this and call {_registerInterface} to declare\\n * their support of an interface.\\n */\\ncontract ERC165 is IERC165 {\\n /*\\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\\n */\\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\\n\\n /**\\n * @dev Mapping of interface ids to whether or not it's supported.\\n */\\n mapping(bytes4 => bool) private _supportedInterfaces;\\n\\n constructor () internal {\\n // Derived contracts need only register support for their own interfaces,\\n // we register support for ERC165 itself here\\n _registerInterface(_INTERFACE_ID_ERC165);\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n *\\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) public view override returns (bool) {\\n return _supportedInterfaces[interfaceId];\\n }\\n\\n /**\\n * @dev Registers the contract as an implementer of the interface defined by\\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\\n * registering its interface id is not required.\\n *\\n * See {IERC165-supportsInterface}.\\n *\\n * Requirements:\\n *\\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\\n */\\n function _registerInterface(bytes4 interfaceId) internal virtual {\\n require(interfaceId != 0xffffffff, \\\"ERC165: invalid interface id\\\");\\n _supportedInterfaces[interfaceId] = true;\\n }\\n}\\n\",\"keccak256\":\"0xb046d18f9d09683ca1c0ed6d80c61da8a8a7d9b30bad70a17b898538683eff74\",\"license\":\"MIT\"},\"@openzeppelin/contracts/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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\",\"keccak256\":\"0xfa152b6e88a1dc50780e8f1580426dc23ad2e1e2c2f086a088adf206a202f453\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\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 uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\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 sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\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 * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\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 // 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) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts 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 mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9a9cf02622cd7a64261b10534fc3260449da25c98c9e96d1b4ae8110a20e5806\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x31691ad0817f8cb338531b78d2ab2989027d9f27e6f8e62492b754fed9429b10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"../../GSN/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.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 guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 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 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\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 uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name, string memory symbol) public {\\n _name = name;\\n _symbol = symbol;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view 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 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 {_setupDecimals} is\\n * called.\\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 returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal {\\n _decimals = decimals_;\\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 to 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(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0x91e0bd6a6762d2a1700dab0849de8422611355100576c4beef1e80d82a4104a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0x5c26b39d26f7ed489e555d955dcd3e01872972e71fdd1528e93ec164e4f23385\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.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 SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf3b30f8a49631420635a8c35daacfcaa338012755f18a76fdd118730256f9a27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0xaf936da92f3a9a4f98b237323b5eb1d813fb86c4d07a184beba7027cf0509ba3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 /**\\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\",\"keccak256\":\"0x3636662804cd8f474536b2875a9038a4c3fb91879f1bbff48af5c3f140fcd2f0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 /**\\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\",\"keccak256\":\"0xe7f984cedc00a138dc27f263c73c32ba9a4b2fd23b6c34ac46f46c074b943538\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address operator, address from, uint256 tokenId, bytes calldata data)\\n external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x321ee37ef4925020aa818a03ec7fe48e057561f65ab009a84f6c20c86026ade7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 in 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 // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n return _functionCallWithValue(target, data, value, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\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 // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf5fa8cbdffa5ef8be49b246b5628facc30b71707e78a45d80d93b64eff3fe390\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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 */\\ncontract 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 () internal {\\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 make 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\",\"keccak256\":\"0x7ff0067f2d7df4187eaa1cb4800949b929602c9d9cb20fcaee6922a7613ef2fb\",\"license\":\"MIT\"},\"contracts/v1/interfaces/ILepton.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// ILepton.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Charged Particles Lepton Interface\\n * @dev ...\\n */\\ninterface ILepton {\\n\\n struct Classification {\\n string tokenUri;\\n uint256 price;\\n uint128 _upperBounds;\\n uint32 supply;\\n uint32 multiplier;\\n uint32 bonus;\\n }\\n\\n function mintLepton() external payable returns (uint256 newTokenId);\\n function batchMintLepton(uint256 count) external payable;\\n function getNextType() external view returns (uint256);\\n function getNextPrice() external view returns (uint256);\\n function getMultiplier(uint256 tokenId) external view returns (uint256);\\n function getBonus(uint256 tokenId) external view returns (uint256);\\n\\n\\n event MaxMintPerTxSet(uint256 maxAmount);\\n event LeptonTypeAdded(string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\\n event LeptonTypeUpdated(uint256 leptonIndex, string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\\n event LeptonMinted(address indexed receiver, uint256 indexed tokenId, uint256 price, uint32 multiplier);\\n event LeptonBatchMinted(address indexed receiver, uint256 indexed tokenId, uint256 count, uint256 price, uint32 multiplier);\\n event PausedStateSet(bool isPaused);\\n}\\n\",\"keccak256\":\"0x4903085427fa5dbee690fe79854fba60afaf21189957406ade55f6fc12556a01\",\"license\":\"MIT\"},\"contracts/v1/leptons/store.sol\":{\"content\":\"pragma solidity 0.6.12;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"../lib/BlackholePrevention.sol\\\";\\nimport \\\"../tokens/Ionx.sol\\\";\\nimport \\\"../tokens/Lepton2.sol\\\";\\n\\ninterface ILepsonsStore {\\n function load(uint256 amount) external payable;\\n function setLepton(address _lepton) external;\\n}\\n\\ncontract LeptonsStore is ILepsonsStore, IERC721Receiver, Ownable, BlackholePrevention {\\n using SafeMath for uint256;\\n\\n event SoldLepton(address indexed buyer, uint256 amount, uint256 price);\\n\\n Lepton2 public lepton;\\n Ionx public ionx;\\n\\n uint256 internal nextTokenId;\\n uint256 public ionxPerLepton;\\n\\n constructor(address _lepton, address _ionx, uint256 _ionxPerLepton) public {\\n lepton = Lepton2(_lepton);\\n ionx = Ionx(_ionx);\\n ionxPerLepton = _ionxPerLepton;\\n }\\n\\n function buyWithIonx(\\n uint256 leptonAmount,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external {\\n uint256 ionxAmount = leptonAmount * ionxPerLepton;\\n require(ionx.balanceOf(msg.sender) >= ionxAmount, \\\"Insufficient IONX balance\\\");\\n\\n ionx.permit(msg.sender, address(this), ionxAmount, deadline, v, r, s);\\n ionx.transferFrom(msg.sender, address(this), ionxAmount);\\n\\n for (uint256 i = 0; i < leptonAmount; ++i) {\\n uint256 tokenId = nextTokenId;\\n nextTokenId = nextTokenId.add(1);\\n\\n lepton.safeTransferFrom(address(this), msg.sender, tokenId);\\n }\\n\\n emit SoldLepton(msg.sender, leptonAmount, ionxAmount);\\n }\\n\\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\\n return IERC721Receiver.onERC721Received.selector;\\n }\\n\\n /***********************************|\\n | Only Admin/DAO |\\n |__________________________________*/\\n\\n function load(uint256 amount) external payable override onlyOwner {\\n require(lepton.balanceOf(address(this)) == 0, \\\"store not empty\\\");\\n nextTokenId = lepton.totalSupply().add(1);\\n lepton.batchMintLepton{ value: msg.value }(amount);\\n }\\n\\n function setLepton(address _lepton) external override onlyOwner {\\n require(_lepton != address(0), \\\"Invalid address\\\");\\n lepton = Lepton2(_lepton);\\n }\\n\\n function setIonx(address _ionx) external onlyOwner {\\n require(_ionx != address(0), \\\"Invalid address\\\");\\n ionx = Ionx(_ionx);\\n }\\n\\n function setIonxPerLepton(uint256 ionxAmount) external onlyOwner {\\n ionxPerLepton = ionxAmount;\\n }\\n\\n /***********************************|\\n | Only Admin/DAO |\\n | (blackhole prevention) |\\n |__________________________________*/\\n\\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n}\",\"keccak256\":\"0x73e9c1b2fb7da10b4eba50c31a1b615c6c4220aa6110f8758a555bcba108c841\"},\"contracts/v1/lib/BlackholePrevention.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\\\";\\n\\n/**\\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\\n * the Owner/DAO to pull them out on behalf of a user\\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\\n */\\ncontract BlackholePrevention {\\n using Address for address payable;\\n using SafeERC20 for IERC20;\\n\\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\\n\\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (address(this).balance >= amount) {\\n receiver.sendValue(amount);\\n emit WithdrawStuckEther(receiver, amount);\\n }\\n }\\n\\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\\n IERC20(tokenAddress).safeTransfer(receiver, amount);\\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\\n }\\n }\\n\\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\\n }\\n }\\n\\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \\\"\\\");\\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6a664c8a1c1d7fb32ade2c11f75756b1fdb4c489daa32c1d58e6b867ea2ba8d6\",\"license\":\"MIT\"},\"contracts/v1/lib/ERC721Basic.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/GSN/Context.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/introspection/ERC165.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\n/**\\n * @title ERC721 Non-Fungible Token Standard basic implementation\\n * @dev see https://eips.ethereum.org/EIPS/eip-721\\n */\\ncontract ERC721Basic is Context, ERC165, IERC721, IERC721Metadata {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n // Equals to `bytes4(keccak256(\\\"onERC721Received(address,address,uint256,bytes)\\\"))`\\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\\n bytes4 internal constant _ERC721_RECEIVED = 0x150b7a02;\\n\\n // mapping from token ids to their owners\\n mapping (uint256 => address) internal _tokenOwners;\\n\\n // mapping from owner to token balance\\n mapping (address => uint256) internal _ownerBalance;\\n\\n // Mapping from token ID to approved address\\n mapping (uint256 => address) internal _tokenApprovals;\\n\\n // Mapping from owner to operator approvals\\n mapping (address => mapping (address => bool)) internal _operatorApprovals;\\n\\n // Token name\\n string internal _name;\\n\\n // Token symbol\\n string internal _symbol;\\n\\n // Token Count\\n uint256 internal _tokenCount;\\n\\n /*\\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\\n *\\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\\n */\\n bytes4 internal constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\\n\\n /*\\n * bytes4(keccak256('name()')) == 0x06fdde03\\n * bytes4(keccak256('symbol()')) == 0x95d89b41\\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\\n *\\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\\n */\\n bytes4 internal constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\\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) public {\\n _name = name;\\n _symbol = symbol;\\n\\n // register the supported interfaces to conform to ERC721 via ERC165\\n _registerInterface(_INTERFACE_ID_ERC721);\\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view override returns (uint256) {\\n require(owner != address(0), \\\"ERC721:E-403\\\");\\n return _ownerBalance[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view override returns (address) {\\n return _tokenOwners[tokenId];\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view 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 return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual override {\\n address owner = ownerOf(tokenId);\\n require(to != owner, \\\"ERC721:E-111\\\");\\n\\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \\\"ERC721:E-105\\\");\\n\\n _approve(to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-getApproved}.\\n */\\n function getApproved(uint256 tokenId) public view override returns (address) {\\n require(_exists(tokenId), \\\"ERC721:E-405\\\");\\n return _tokenApprovals[tokenId];\\n }\\n\\n /**\\n * @dev See {IERC721-setApprovalForAll}.\\n */\\n function setApprovalForAll(address operator, bool approved) public virtual override {\\n require(operator != _msgSender(), \\\"ERC721:E-111\\\");\\n\\n _operatorApprovals[_msgSender()][operator] = approved;\\n emit ApprovalForAll(_msgSender(), operator, approved);\\n }\\n\\n /**\\n * @dev See {IERC721-isApprovedForAll}.\\n */\\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\\n return _operatorApprovals[owner][operator];\\n }\\n\\n /**\\n * @dev See {IERC721-transferFrom}.\\n */\\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\\n //solhint-disable-next-line max-line-length\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721:E-105\\\");\\n\\n _transfer(from, to, tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\\n require(_isApprovedOrOwner(_msgSender(), tokenId), \\\"ERC721:E-105\\\");\\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\\n _transfer(from, to, tokenId);\\n require(_checkOnERC721Received(from, to, tokenId, _data), \\\"ERC721:E-402\\\");\\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 returns (bool) {\\n return _tokenOwners[tokenId] != address(0x0);\\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 returns (bool) {\\n require(_exists(tokenId), \\\"ERC721:E-405\\\");\\n address owner = ownerOf(tokenId);\\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\\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(address to, bytes memory _data) internal virtual returns (uint256) {\\n uint256 tokenId = _mint(to);\\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \\\"ERC721:E-402\\\");\\n return 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 _safeMintBatch(address to, uint256 count, bytes memory _data) internal virtual {\\n uint256 startTokenId = _mintBatch(to, count);\\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \\\"ERC721:E-402\\\");\\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) internal virtual returns (uint256) {\\n require(to != address(0), \\\"ERC721:E-403\\\");\\n\\n _tokenCount = _tokenCount.add(1);\\n uint256 tokenId = _tokenCount;\\n require(!_exists(tokenId), \\\"ERC721:E-407\\\");\\n\\n _tokenOwners[tokenId] = to;\\n _ownerBalance[to] = _ownerBalance[to].add(1);\\n\\n emit Transfer(address(0), to, tokenId);\\n return tokenId;\\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 _mintBatch(address to, uint256 count) internal virtual returns (uint256) {\\n require(to != address(0), \\\"ERC721:E-403\\\");\\n\\n uint256 startTokenId = _tokenCount.add(1);\\n for (uint i = 1; i <= count; i++) {\\n uint256 tokenId = _tokenCount.add(i);\\n _tokenOwners[tokenId] = to;\\n emit Transfer(address(0), to, tokenId);\\n }\\n\\n _tokenCount = _tokenCount.add(count);\\n _ownerBalance[to] = _ownerBalance[to].add(count);\\n return startTokenId;\\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(address from, address to, uint256 tokenId) internal virtual {\\n require(ownerOf(tokenId) == from, \\\"ERC721:E-102\\\");\\n require(to != address(0), \\\"ERC721:E-403\\\");\\n\\n // Clear approvals from the previous owner\\n _approve(address(0), tokenId);\\n\\n _tokenOwners[tokenId] = to;\\n _ownerBalance[from] = _ownerBalance[from].sub(1);\\n _ownerBalance[to] = _ownerBalance[to].add(1);\\n\\n emit Transfer(from, to, tokenId);\\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(address from, address to, uint256 tokenId, bytes memory _data)\\n internal returns (bool)\\n {\\n if (!to.isContract()) {\\n return true;\\n }\\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\\n IERC721Receiver(to).onERC721Received.selector,\\n _msgSender(),\\n from,\\n tokenId,\\n _data\\n ), \\\"ERC721:E-402\\\");\\n bytes4 retval = abi.decode(returndata, (bytes4));\\n return (retval == _ERC721_RECEIVED);\\n }\\n\\n function _approve(address to, uint256 tokenId) internal {\\n _tokenApprovals[tokenId] = to;\\n emit Approval(ownerOf(tokenId), to, tokenId);\\n }\\n}\\n\",\"keccak256\":\"0x4b9f68ff101017027a7d963c7ab888d126c3e5f10fb5dd28daba08d49d9bd291\",\"license\":\"MIT\"},\"contracts/v1/tokens/Ionx.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// Ionx.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\n\\nimport \\\"erc20permit/contracts/ERC20Permit.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"../lib/BlackholePrevention.sol\\\";\\n\\n\\ncontract Ionx is ERC20Permit, Ownable, BlackholePrevention {\\n using SafeMath for uint256;\\n\\n /// @notice An event thats emitted when the minter address is changed\\n event MinterChanged(address minter, address newMinter);\\n\\n /// @notice Total number of tokens in circulation\\n uint256 constant public INITIAL_SUPPLY = 1e8 ether;\\n\\n /// @notice Minimum time between mints\\n uint32 public constant INFLATION_EPOCH = 1 days * 365;\\n\\n /// @notice Cap on the percentage of totalSupply that can be minted at each mint\\n uint8 public constant INFLATION_CAP = 2;\\n\\n /// @notice Address which may mint new tokens\\n address public minter;\\n\\n /// @notice The timestamp after which minting may occur\\n uint256 public mintingAllowedAfter;\\n\\n\\n constructor() public ERC20Permit(\\\"Charged Particles - IONX\\\", \\\"IONX\\\") {}\\n\\n\\n /**\\n * @notice Change the minter address\\n * @param newMinter The address of the new minter\\n */\\n function setMinter(address newMinter) external onlyOwner {\\n emit MinterChanged(minter, newMinter);\\n minter = newMinter;\\n }\\n\\n /**\\n * @notice Mint new tokens\\n * @param receiver The address of the destination account\\n * @param amount The number of tokens to be minted\\n */\\n function mint(address receiver, uint256 amount) external onlyMinter {\\n require(block.timestamp >= mintingAllowedAfter, \\\"Ionx:E-114\\\");\\n require(receiver != address(0), \\\"Ionx:E-403\\\");\\n\\n uint256 amountToMint = amount;\\n uint256 _totalSupply = totalSupply();\\n\\n // From Inflationary Supply\\n if (_totalSupply >= INITIAL_SUPPLY) {\\n mintingAllowedAfter = mintingAllowedAfter.add(INFLATION_EPOCH);\\n amountToMint = _totalSupply.mul(INFLATION_CAP).div(100);\\n }\\n\\n // From Initial Supply\\n else {\\n if (_totalSupply.add(amountToMint) > INITIAL_SUPPLY) {\\n amountToMint = INITIAL_SUPPLY.sub(_totalSupply);\\n }\\n if (_totalSupply.add(amountToMint) == INITIAL_SUPPLY) {\\n mintingAllowedAfter = block.timestamp.add(INFLATION_EPOCH);\\n }\\n }\\n\\n // transfer the amount to the recipient\\n _mint(receiver, amountToMint);\\n }\\n\\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n modifier onlyMinter() {\\n require(msg.sender == minter, \\\"Ionx:E-113\\\");\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x248e7f30883795c45e37a90aa8e7cd94cd09fb618122b09d83fd98d2d63fd37d\",\"license\":\"MIT\"},\"contracts/v1/tokens/Lepton2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// Lepton2.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\n\\nimport \\\"../lib/ERC721Basic.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/ReentrancyGuard.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\\\";\\n\\nimport \\\"../interfaces/ILepton.sol\\\";\\nimport \\\"../lib/BlackholePrevention.sol\\\";\\n\\ncontract Lepton2 is ILepton, ERC721Basic, Ownable, ReentrancyGuard, BlackholePrevention {\\n using SafeMath for uint256;\\n using Address for address payable;\\n\\n Classification[] internal _leptonTypes;\\n\\n uint256 internal _typeIndex;\\n uint256 internal _maxSupply;\\n uint256 internal _maxMintPerTx;\\n uint256 internal _migratedCount;\\n\\n bool internal _paused;\\n bool internal _migrationComplete;\\n\\n\\n /***********************************|\\n | Initialization |\\n |__________________________________*/\\n\\n constructor() public ERC721Basic(\\\"Charged Particles - Lepton2\\\", \\\"LEPTON2\\\") {\\n _paused = true;\\n _migrationComplete = false;\\n _migratedCount = 0;\\n }\\n\\n\\n /***********************************|\\n | Public |\\n |__________________________________*/\\n\\n function mintLepton() external payable override nonReentrant whenNotPaused returns (uint256 newTokenId) {\\n newTokenId = _mintLepton(msg.sender);\\n }\\n\\n function batchMintLepton(uint256 count) external payable override nonReentrant whenNotPaused {\\n _batchMintLepton(msg.sender, count);\\n }\\n\\n function totalSupply() public view returns (uint256) {\\n return _tokenCount;\\n }\\n\\n function maxSupply() external view returns (uint256) {\\n return _maxSupply;\\n }\\n\\n function getNextType() external view override returns (uint256) {\\n if (_typeIndex >= _leptonTypes.length) { return 0; }\\n return _typeIndex;\\n }\\n\\n function getNextPrice() external view override returns (uint256) {\\n if (_typeIndex >= _leptonTypes.length) { return 0; }\\n return _leptonTypes[_typeIndex].price;\\n }\\n\\n function getMultiplier(uint256 tokenId) external view override returns (uint256) {\\n require(_exists(tokenId), \\\"LPT:E-405\\\");\\n return _getLepton(tokenId).multiplier;\\n }\\n\\n function getBonus(uint256 tokenId) external view override returns (uint256) {\\n require(_exists(tokenId), \\\"LPT:E-405\\\");\\n return _getLepton(tokenId).bonus;\\n }\\n\\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\\n require(_exists(tokenId), \\\"LPT:E-405\\\");\\n return _getLepton(tokenId).tokenUri;\\n }\\n\\n /***********************************|\\n | Only Admin/DAO |\\n |__________________________________*/\\n\\n function addLeptonType(\\n string calldata tokenUri,\\n uint256 price,\\n uint32 supply,\\n uint32 multiplier,\\n uint32 bonus\\n )\\n external\\n onlyOwner\\n {\\n _maxSupply = _maxSupply.add(uint256(supply));\\n\\n Classification memory lepton = Classification({\\n tokenUri: tokenUri,\\n price: price,\\n supply: supply,\\n multiplier: multiplier,\\n bonus: bonus,\\n _upperBounds: uint128(_maxSupply)\\n });\\n _leptonTypes.push(lepton);\\n\\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\\n }\\n\\n function updateLeptonType(\\n uint256 leptonIndex,\\n string calldata tokenUri,\\n uint256 price,\\n uint32 supply,\\n uint32 multiplier,\\n uint32 bonus\\n )\\n external\\n onlyOwner\\n {\\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\\n _leptonTypes[leptonIndex].price = price;\\n _leptonTypes[leptonIndex].supply = supply;\\n _leptonTypes[leptonIndex].multiplier = multiplier;\\n _leptonTypes[leptonIndex].bonus = bonus;\\n\\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\\n }\\n\\n function setMaxMintPerTx(uint256 maxAmount) external onlyOwner {\\n _maxMintPerTx = maxAmount;\\n emit MaxMintPerTxSet(maxAmount);\\n }\\n\\n function setPausedState(bool state) external onlyOwner {\\n _paused = state;\\n emit PausedStateSet(state);\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n | (blackhole prevention) |\\n |__________________________________*/\\n\\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n function migrateAccounts(address oldLeptonContract, uint256 count) external onlyOwner whenNotMigrated {\\n uint256 oldSupply = IERC721Enumerable(oldLeptonContract).totalSupply();\\n require(oldSupply == 0 || oldSupply > _migratedCount, \\\"LPT:E-004\\\");\\n\\n if (oldSupply > 0) {\\n uint256 endTokenId = _migratedCount.add(count);\\n if (endTokenId > oldSupply) {\\n count = count.sub(endTokenId.sub(oldSupply));\\n }\\n\\n for (uint256 i = 1; i <= count; i++) {\\n uint256 tokenId = _migratedCount.add(i);\\n address tokenOwner = IERC721(oldLeptonContract).ownerOf(tokenId);\\n _mint(tokenOwner);\\n }\\n _migratedCount = _migratedCount.add(count);\\n }\\n\\n if (oldSupply == _migratedCount) {\\n _finalizeMigration();\\n }\\n }\\n\\n /***********************************|\\n | Private Functions |\\n |__________________________________*/\\n\\n function _getLepton(uint256 tokenId) internal view returns (Classification memory) {\\n uint256 types = _leptonTypes.length;\\n for (uint256 i = 0; i < types; i++) {\\n Classification memory lepton = _leptonTypes[i];\\n if (tokenId <= lepton._upperBounds) {\\n return lepton;\\n }\\n }\\n }\\n\\n function _mintLepton(address receiver) internal returns (uint256 newTokenId) {\\n require(_typeIndex < _leptonTypes.length, \\\"LPT:E-408\\\");\\n\\n Classification memory lepton = _leptonTypes[_typeIndex];\\n require(msg.value >= lepton.price, \\\"LPT:E-414\\\");\\n\\n newTokenId = _safeMint(receiver, \\\"\\\");\\n\\n // Determine Next Type\\n if (newTokenId == lepton._upperBounds) {\\n _typeIndex = _typeIndex.add(1);\\n }\\n\\n _refundOverpayment(lepton.price);\\n }\\n\\n function _batchMintLepton(address receiver, uint256 count) internal {\\n require(_typeIndex < _leptonTypes.length, \\\"LPT:E-408\\\");\\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \\\"LPT:E-429\\\");\\n\\n Classification memory lepton = _leptonTypes[_typeIndex];\\n\\n uint256 endTokenId = _tokenCount.add(count);\\n if (endTokenId > lepton._upperBounds) {\\n count = count.sub(endTokenId.sub(lepton._upperBounds));\\n }\\n\\n uint256 salePrice = lepton.price.mul(count);\\n require(msg.value >= salePrice, \\\"LPT:E-414\\\");\\n\\n _safeMintBatch(receiver, count, \\\"\\\");\\n\\n // Determine Next Type\\n if (endTokenId >= lepton._upperBounds) {\\n _typeIndex = _typeIndex.add(1);\\n }\\n\\n _refundOverpayment(salePrice);\\n }\\n\\n function _refundOverpayment(uint256 threshold) internal {\\n uint256 overage = msg.value.sub(threshold);\\n if (overage > 0) {\\n payable(_msgSender()).sendValue(overage);\\n }\\n }\\n\\n function _finalizeMigration() internal {\\n // Determine Next Type\\n _typeIndex = 0;\\n for (uint256 i = 0; i < _leptonTypes.length; i++) {\\n Classification memory lepton = _leptonTypes[i];\\n if (_migratedCount >= lepton._upperBounds) {\\n _typeIndex = i + 1;\\n }\\n }\\n _migrationComplete = true;\\n }\\n\\n\\n /***********************************|\\n | Modifiers |\\n |__________________________________*/\\n\\n modifier whenNotMigrated() {\\n require(!_migrationComplete, \\\"LPT:E-004\\\");\\n _;\\n }\\n\\n modifier whenNotPaused() {\\n require(!_paused, \\\"LPT:E-101\\\");\\n _;\\n }\\n}\",\"keccak256\":\"0x308d33f8e4c5dbc7fa986fd93e3f760f8f81c14e0915af9ba9ab9cd5509fae6d\",\"license\":\"MIT\"},\"erc20permit/contracts/ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\\npragma solidity ^0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"./IERC2612.sol\\\";\\n\\n/**\\n * @author Georgios Konstantopoulos\\n * @dev Extension of {ERC20} that allows token holders to use their tokens\\n * without sending any transactions by setting {IERC20-allowance} with a\\n * signature using the {permit} method, and then spend them via\\n * {IERC20-transferFrom}.\\n *\\n * The {permit} signature mechanism conforms to the {IERC2612} interface.\\n */\\nabstract contract ERC20Permit is ERC20, IERC2612 {\\n mapping (address => uint256) public override nonces;\\n\\n bytes32 public immutable PERMIT_TYPEHASH = keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n bytes32 public immutable DOMAIN_SEPARATOR;\\n\\n constructor(string memory name_, string memory symbol_) internal ERC20(name_, symbol_) {\\n uint256 chainId;\\n assembly {\\n chainId := chainid()\\n }\\n\\n DOMAIN_SEPARATOR = keccak256(\\n abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"),\\n keccak256(bytes(name_)),\\n keccak256(bytes(\\\"1\\\")),\\n chainId,\\n address(this)\\n )\\n );\\n }\\n\\n /**\\n * @dev See {IERC2612-permit}.\\n *\\n * In cases where the free option is not a concern, deadline can simply be\\n * set to uint(-1), so it should be seen as an optional parameter\\n */\\n function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {\\n require(deadline >= block.timestamp, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 hashStruct = keccak256(\\n abi.encode(\\n PERMIT_TYPEHASH,\\n owner,\\n spender,\\n amount,\\n nonces[owner]++,\\n deadline\\n )\\n );\\n\\n bytes32 hash = keccak256(\\n abi.encodePacked(\\n '\\\\x19\\\\x01',\\n DOMAIN_SEPARATOR,\\n hashStruct\\n )\\n );\\n\\n address signer = ecrecover(hash, v, r, s);\\n require(\\n signer != address(0) && signer == owner,\\n \\\"ERC20Permit: invalid signature\\\"\\n );\\n\\n _approve(owner, spender, amount);\\n }\\n}\\n\",\"keccak256\":\"0x2207175c262cdffe2f4e0a31d0c35e02a0ebf2528f21009be6b7743eeb474eaa\",\"license\":\"GPL-3.0-or-later\"},\"erc20permit/contracts/IERC2612.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n// Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Interface of the ERC2612 standard as defined in the EIP.\\n *\\n * Adds the {permit} method, which can be used to change one's\\n * {IERC20-allowance} without having to send a transaction, by signing a\\n * message. This allows users to spend tokens without having to hold Ether.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2612.\\n */\\ninterface IERC2612 {\\n /**\\n * @dev Sets `amount` 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 * - `owner` cannot be the zero address.\\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(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\\n\\n /**\\n * @dev Returns the current ERC2612 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\",\"keccak256\":\"0xe79dd739aaa881172ede4d81472ded9db3a0b4183573c0c01541b4084033b222\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506040516119693803806119698339818101604052606081101561003357600080fd5b5080516020820151604090920151909190600061004e6100d0565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600180546001600160a01b039485166001600160a01b03199182161790915560028054939094169216919091179091556004556100d4565b3390565b611886806100e36000396000f3fe6080604052600436106100f35760003560e01c806399d548aa1161008a578063d2a1267311610059578063d2a12673146103b8578063e27e1b08146103fd578063efeab4ab14610430578063f2fde38b14610445576100f3565b806399d548aa146102f55780639a20f66514610312578063a0edb48b1461033c578063b8d820f814610385576100f3565b8063522f6815116100c6578063522f681514610261578063715018a61461029a5780637d0e13a5146102af5780638da5cb5b146102e0576100f3565b8063150b7a02146100f85780631593dee1146101b25780634025feb2146101f75780634cf65a481461023a575b600080fd5b34801561010457600080fd5b506101956004803603608081101561011b57600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561015657600080fd5b82018360208201111561016857600080fd5b8035906020019184600183028401116401000000008311171561018a57600080fd5b509092509050610478565b604080516001600160e01b03199092168252519081900360200190f35b3480156101be57600080fd5b506101f5600480360360608110156101d557600080fd5b506001600160a01b03813581169160208101359091169060400135610489565b005b34801561020357600080fd5b506101f56004803603606081101561021a57600080fd5b506001600160a01b038135811691602081013590911690604001356104f1565b34801561024657600080fd5b5061024f610554565b60408051918252519081900360200190f35b34801561026d57600080fd5b506101f56004803603604081101561028457600080fd5b506001600160a01b03813516906020013561055a565b3480156102a657600080fd5b506101f56105c0565b3480156102bb57600080fd5b506102c4610662565b604080516001600160a01b039092168252519081900360200190f35b3480156102ec57600080fd5b506102c4610671565b6101f56004803603602081101561030b57600080fd5b5035610680565b34801561031e57600080fd5b506101f56004803603602081101561033557600080fd5b503561087a565b34801561034857600080fd5b506101f56004803603608081101561035f57600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356108d7565b34801561039157600080fd5b506101f5600480360360208110156103a857600080fd5b50356001600160a01b0316610941565b3480156103c457600080fd5b506101f5600480360360a08110156103db57600080fd5b5080359060208101359060ff6040820135169060608101359060800135610a08565b34801561040957600080fd5b506101f56004803603602081101561042057600080fd5b50356001600160a01b0316610ccf565b34801561043c57600080fd5b506102c4610d96565b34801561045157600080fd5b506101f56004803603602081101561046857600080fd5b50356001600160a01b0316610da5565b630a85bd0160e11b95945050505050565b610491610e9d565b6000546001600160a01b039081169116146104e1576040805162461bcd60e51b81526020600482018190526024820152600080516020611807833981519152604482015290519081900360640190fd5b6104ec838383610ea1565b505050565b6104f9610e9d565b6000546001600160a01b03908116911614610549576040805162461bcd60e51b81526020600482018190526024820152600080516020611807833981519152604482015290519081900360640190fd5b6104ec838383610fcb565b60045481565b610562610e9d565b6000546001600160a01b039081169116146105b2576040805162461bcd60e51b81526020600482018190526024820152600080516020611807833981519152604482015290519081900360640190fd5b6105bc8282611151565b5050565b6105c8610e9d565b6000546001600160a01b03908116911614610618576040805162461bcd60e51b81526020600482018190526024820152600080516020611807833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6001546001600160a01b031681565b6000546001600160a01b031690565b610688610e9d565b6000546001600160a01b039081169116146106d8576040805162461bcd60e51b81526020600482018190526024820152600080516020611807833981519152604482015290519081900360640190fd5b600154604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b15801561072357600080fd5b505afa158015610737573d6000803e3d6000fd5b505050506040513d602081101561074d57600080fd5b505115610793576040805162461bcd60e51b815260206004820152600f60248201526e73746f7265206e6f7420656d70747960881b604482015290519081900360640190fd5b60018054604080516318160ddd60e01b8152905161080d93926001600160a01b0316916318160ddd916004808301926020929190829003018186803b1580156107db57600080fd5b505afa1580156107ef573d6000803e3d6000fd5b505050506040513d602081101561080557600080fd5b5051906111f4565b60035560015460408051630afd902b60e01b81526004810184905290516001600160a01b0390921691630afd902b913491602480830192600092919082900301818588803b15801561085e57600080fd5b505af1158015610872573d6000803e3d6000fd5b505050505050565b610882610e9d565b6000546001600160a01b039081169116146108d2576040805162461bcd60e51b81526020600482018190526024820152600080516020611807833981519152604482015290519081900360640190fd5b600455565b6108df610e9d565b6000546001600160a01b0390811691161461092f576040805162461bcd60e51b81526020600482018190526024820152600080516020611807833981519152604482015290519081900360640190fd5b61093b84848484611255565b50505050565b610949610e9d565b6000546001600160a01b03908116911614610999576040805162461bcd60e51b81526020600482018190526024820152600080516020611807833981519152604482015290519081900360640190fd5b6001600160a01b0381166109e6576040805162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60048054600254604080516370a0823160e01b81523394810194909452519188029283926001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015610a5e57600080fd5b505afa158015610a72573d6000803e3d6000fd5b505050506040513d6020811015610a8857600080fd5b50511015610add576040805162461bcd60e51b815260206004820152601960248201527f496e73756666696369656e7420494f4e582062616c616e636500000000000000604482015290519081900360640190fd5b6002546040805163d505accf60e01b8152336004820152306024820152604481018490526064810188905260ff8716608482015260a4810186905260c4810185905290516001600160a01b039092169163d505accf9160e48082019260009290919082900301818387803b158015610b5457600080fd5b505af1158015610b68573d6000803e3d6000fd5b5050600254604080516323b872dd60e01b81523360048201523060248201526044810186905290516001600160a01b0390921693506323b872dd92506064808201926020929091908290030181600087803b158015610bc657600080fd5b505af1158015610bda573d6000803e3d6000fd5b505050506040513d6020811015610bf057600080fd5b50600090505b86811015610c8c57600354610c0c8160016111f4565b60035560015460408051632142170760e11b81523060048201523360248201526044810184905290516001600160a01b03909216916342842e0e9160648082019260009290919082900301818387803b158015610c6857600080fd5b505af1158015610c7c573d6000803e3d6000fd5b5050505050806001019050610bf6565b506040805187815260208101839052815133927f56d4a3892345beae7b80a9cb4d571ef4929baf938bc67960aa0f17606a934bc0928290030190a2505050505050565b610cd7610e9d565b6000546001600160a01b03908116911614610d27576040805162461bcd60e51b81526020600482018190526024820152600080516020611807833981519152604482015290519081900360640190fd5b6001600160a01b038116610d74576040805162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015290519081900360640190fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031681565b610dad610e9d565b6000546001600160a01b03908116911614610dfd576040805162461bcd60e51b81526020600482018190526024820152600080516020611807833981519152604482015290519081900360640190fd5b6001600160a01b038116610e425760405162461bcd60e51b81526004018080602001828103825260268152602001806117a76026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b038316610ee8576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b80826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610f3657600080fd5b505afa158015610f4a573d6000803e3d6000fd5b505050506040513d6020811015610f6057600080fd5b5051106104ec57610f7b6001600160a01b03831684836113f6565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b836040518082815260200191505060405180910390a3505050565b6001600160a01b038316611012576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b306001600160a01b0316826001600160a01b0316636352211e836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561106057600080fd5b505afa158015611074573d6000803e3d6000fd5b505050506040513d602081101561108a57600080fd5b50516001600160a01b031614156104ec57604080516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018490529151918416916323b872dd9160648082019260009290919082900301818387803b1580156110f357600080fd5b505af1158015611107573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b038216611198576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b8047106105bc576111b26001600160a01b03831682611448565b6040805182815290516001600160a01b038416917eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd919081900360200190a25050565b60008282018381101561124e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b03841661129c576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b80836001600160a01b031662fdd58e30856040518363ffffffff1660e01b815260040180836001600160a01b031681526020018281526020019250505060206040518083038186803b1580156112f157600080fd5b505afa158015611305573d6000803e3d6000fd5b505050506040513d602081101561131b57600080fd5b50511061093b5760408051637921219560e11b81523060048201526001600160a01b038681166024830152604482018590526064820184905260a06084830152600060a4830181905292519086169263f242432a9260e4808201939182900301818387803b15801561138c57600080fd5b505af11580156113a0573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b846040518082815260200191505060405180910390a450505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526104ec90849061152d565b8047101561149d576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015290519081900360640190fd5b6040516000906001600160a01b0384169083908381818185875af1925050503d80600081146114e8576040519150601f19603f3d011682016040523d82523d6000602084013e6114ed565b606091505b50509050806104ec5760405162461bcd60e51b815260040180806020018281038252603a8152602001806117cd603a913960400191505060405180910390fd5b6060611582826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166115de9092919063ffffffff16565b8051909150156104ec578080602001905160208110156115a157600080fd5b50516104ec5760405162461bcd60e51b815260040180806020018281038252602a815260200180611827602a913960400191505060405180910390fd5b60606115ed84846000856115f5565b949350505050565b6060611600856117a0565b611651576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106116905780518252601f199092019160209182019101611671565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146116f2576040519150601f19603f3d011682016040523d82523d6000602084013e6116f7565b606091505b5091509150811561170b5791506115ed9050565b80511561171b5780518082602001fd5b8360405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561176557818101518382015260200161174d565b50505050905090810190601f1680156117925780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b3b15159056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373416464726573733a20756e61626c6520746f2073656e642076616c75652c20726563697069656e74206d617920686176652072657665727465644f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a264697066735822122051ba5767ca1c001a60cbb1e9870b3ce0e92bc5f97027c9a5f565e13e57eed86564736f6c634300060c0033", + "deployedBytecode": "0x6080604052600436106100f35760003560e01c806399d548aa1161008a578063d2a1267311610059578063d2a12673146103b8578063e27e1b08146103fd578063efeab4ab14610430578063f2fde38b14610445576100f3565b806399d548aa146102f55780639a20f66514610312578063a0edb48b1461033c578063b8d820f814610385576100f3565b8063522f6815116100c6578063522f681514610261578063715018a61461029a5780637d0e13a5146102af5780638da5cb5b146102e0576100f3565b8063150b7a02146100f85780631593dee1146101b25780634025feb2146101f75780634cf65a481461023a575b600080fd5b34801561010457600080fd5b506101956004803603608081101561011b57600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561015657600080fd5b82018360208201111561016857600080fd5b8035906020019184600183028401116401000000008311171561018a57600080fd5b509092509050610478565b604080516001600160e01b03199092168252519081900360200190f35b3480156101be57600080fd5b506101f5600480360360608110156101d557600080fd5b506001600160a01b03813581169160208101359091169060400135610489565b005b34801561020357600080fd5b506101f56004803603606081101561021a57600080fd5b506001600160a01b038135811691602081013590911690604001356104f1565b34801561024657600080fd5b5061024f610554565b60408051918252519081900360200190f35b34801561026d57600080fd5b506101f56004803603604081101561028457600080fd5b506001600160a01b03813516906020013561055a565b3480156102a657600080fd5b506101f56105c0565b3480156102bb57600080fd5b506102c4610662565b604080516001600160a01b039092168252519081900360200190f35b3480156102ec57600080fd5b506102c4610671565b6101f56004803603602081101561030b57600080fd5b5035610680565b34801561031e57600080fd5b506101f56004803603602081101561033557600080fd5b503561087a565b34801561034857600080fd5b506101f56004803603608081101561035f57600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356108d7565b34801561039157600080fd5b506101f5600480360360208110156103a857600080fd5b50356001600160a01b0316610941565b3480156103c457600080fd5b506101f5600480360360a08110156103db57600080fd5b5080359060208101359060ff6040820135169060608101359060800135610a08565b34801561040957600080fd5b506101f56004803603602081101561042057600080fd5b50356001600160a01b0316610ccf565b34801561043c57600080fd5b506102c4610d96565b34801561045157600080fd5b506101f56004803603602081101561046857600080fd5b50356001600160a01b0316610da5565b630a85bd0160e11b95945050505050565b610491610e9d565b6000546001600160a01b039081169116146104e1576040805162461bcd60e51b81526020600482018190526024820152600080516020611807833981519152604482015290519081900360640190fd5b6104ec838383610ea1565b505050565b6104f9610e9d565b6000546001600160a01b03908116911614610549576040805162461bcd60e51b81526020600482018190526024820152600080516020611807833981519152604482015290519081900360640190fd5b6104ec838383610fcb565b60045481565b610562610e9d565b6000546001600160a01b039081169116146105b2576040805162461bcd60e51b81526020600482018190526024820152600080516020611807833981519152604482015290519081900360640190fd5b6105bc8282611151565b5050565b6105c8610e9d565b6000546001600160a01b03908116911614610618576040805162461bcd60e51b81526020600482018190526024820152600080516020611807833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6001546001600160a01b031681565b6000546001600160a01b031690565b610688610e9d565b6000546001600160a01b039081169116146106d8576040805162461bcd60e51b81526020600482018190526024820152600080516020611807833981519152604482015290519081900360640190fd5b600154604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b15801561072357600080fd5b505afa158015610737573d6000803e3d6000fd5b505050506040513d602081101561074d57600080fd5b505115610793576040805162461bcd60e51b815260206004820152600f60248201526e73746f7265206e6f7420656d70747960881b604482015290519081900360640190fd5b60018054604080516318160ddd60e01b8152905161080d93926001600160a01b0316916318160ddd916004808301926020929190829003018186803b1580156107db57600080fd5b505afa1580156107ef573d6000803e3d6000fd5b505050506040513d602081101561080557600080fd5b5051906111f4565b60035560015460408051630afd902b60e01b81526004810184905290516001600160a01b0390921691630afd902b913491602480830192600092919082900301818588803b15801561085e57600080fd5b505af1158015610872573d6000803e3d6000fd5b505050505050565b610882610e9d565b6000546001600160a01b039081169116146108d2576040805162461bcd60e51b81526020600482018190526024820152600080516020611807833981519152604482015290519081900360640190fd5b600455565b6108df610e9d565b6000546001600160a01b0390811691161461092f576040805162461bcd60e51b81526020600482018190526024820152600080516020611807833981519152604482015290519081900360640190fd5b61093b84848484611255565b50505050565b610949610e9d565b6000546001600160a01b03908116911614610999576040805162461bcd60e51b81526020600482018190526024820152600080516020611807833981519152604482015290519081900360640190fd5b6001600160a01b0381166109e6576040805162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60048054600254604080516370a0823160e01b81523394810194909452519188029283926001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015610a5e57600080fd5b505afa158015610a72573d6000803e3d6000fd5b505050506040513d6020811015610a8857600080fd5b50511015610add576040805162461bcd60e51b815260206004820152601960248201527f496e73756666696369656e7420494f4e582062616c616e636500000000000000604482015290519081900360640190fd5b6002546040805163d505accf60e01b8152336004820152306024820152604481018490526064810188905260ff8716608482015260a4810186905260c4810185905290516001600160a01b039092169163d505accf9160e48082019260009290919082900301818387803b158015610b5457600080fd5b505af1158015610b68573d6000803e3d6000fd5b5050600254604080516323b872dd60e01b81523360048201523060248201526044810186905290516001600160a01b0390921693506323b872dd92506064808201926020929091908290030181600087803b158015610bc657600080fd5b505af1158015610bda573d6000803e3d6000fd5b505050506040513d6020811015610bf057600080fd5b50600090505b86811015610c8c57600354610c0c8160016111f4565b60035560015460408051632142170760e11b81523060048201523360248201526044810184905290516001600160a01b03909216916342842e0e9160648082019260009290919082900301818387803b158015610c6857600080fd5b505af1158015610c7c573d6000803e3d6000fd5b5050505050806001019050610bf6565b506040805187815260208101839052815133927f56d4a3892345beae7b80a9cb4d571ef4929baf938bc67960aa0f17606a934bc0928290030190a2505050505050565b610cd7610e9d565b6000546001600160a01b03908116911614610d27576040805162461bcd60e51b81526020600482018190526024820152600080516020611807833981519152604482015290519081900360640190fd5b6001600160a01b038116610d74576040805162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b604482015290519081900360640190fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031681565b610dad610e9d565b6000546001600160a01b03908116911614610dfd576040805162461bcd60e51b81526020600482018190526024820152600080516020611807833981519152604482015290519081900360640190fd5b6001600160a01b038116610e425760405162461bcd60e51b81526004018080602001828103825260268152602001806117a76026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b038316610ee8576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b80826001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610f3657600080fd5b505afa158015610f4a573d6000803e3d6000fd5b505050506040513d6020811015610f6057600080fd5b5051106104ec57610f7b6001600160a01b03831684836113f6565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b836040518082815260200191505060405180910390a3505050565b6001600160a01b038316611012576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b306001600160a01b0316826001600160a01b0316636352211e836040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561106057600080fd5b505afa158015611074573d6000803e3d6000fd5b505050506040513d602081101561108a57600080fd5b50516001600160a01b031614156104ec57604080516323b872dd60e01b81523060048201526001600160a01b038581166024830152604482018490529151918416916323b872dd9160648082019260009290919082900301818387803b1580156110f357600080fd5b505af1158015611107573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b038216611198576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b8047106105bc576111b26001600160a01b03831682611448565b6040805182815290516001600160a01b038416917eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd919081900360200190a25050565b60008282018381101561124e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b03841661129c576040805162461bcd60e51b81526020600482015260096024820152684248503a452d34303360b81b604482015290519081900360640190fd5b80836001600160a01b031662fdd58e30856040518363ffffffff1660e01b815260040180836001600160a01b031681526020018281526020019250505060206040518083038186803b1580156112f157600080fd5b505afa158015611305573d6000803e3d6000fd5b505050506040513d602081101561131b57600080fd5b50511061093b5760408051637921219560e11b81523060048201526001600160a01b038681166024830152604482018590526064820184905260a06084830152600060a4830181905292519086169263f242432a9260e4808201939182900301818387803b15801561138c57600080fd5b505af11580156113a0573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b846040518082815260200191505060405180910390a450505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526104ec90849061152d565b8047101561149d576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015290519081900360640190fd5b6040516000906001600160a01b0384169083908381818185875af1925050503d80600081146114e8576040519150601f19603f3d011682016040523d82523d6000602084013e6114ed565b606091505b50509050806104ec5760405162461bcd60e51b815260040180806020018281038252603a8152602001806117cd603a913960400191505060405180910390fd5b6060611582826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166115de9092919063ffffffff16565b8051909150156104ec578080602001905160208110156115a157600080fd5b50516104ec5760405162461bcd60e51b815260040180806020018281038252602a815260200180611827602a913960400191505060405180910390fd5b60606115ed84846000856115f5565b949350505050565b6060611600856117a0565b611651576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b602083106116905780518252601f199092019160209182019101611671565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146116f2576040519150601f19603f3d011682016040523d82523d6000602084013e6116f7565b606091505b5091509150811561170b5791506115ed9050565b80511561171b5780518082602001fd5b8360405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561176557818101518382015260200161174d565b50505050905090810190601f1680156117925780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b3b15159056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373416464726573733a20756e61626c6520746f2073656e642076616c75652c20726563697069656e74206d617920686176652072657665727465644f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a264697066735822122051ba5767ca1c001a60cbb1e9870b3ce0e92bc5f97027c9a5f565e13e57eed86564736f6c634300060c0033", + "devdoc": { + "kind": "dev", + "methods": { + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 4406, + "contract": "contracts/v1/leptons/store.sol:LeptonsStore", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 30764, + "contract": "contracts/v1/leptons/store.sol:LeptonsStore", + "label": "lepton", + "offset": 0, + "slot": "1", + "type": "t_contract(Lepton2)38399" + }, + { + "astId": 30766, + "contract": "contracts/v1/leptons/store.sol:LeptonsStore", + "label": "ionx", + "offset": 0, + "slot": "2", + "type": "t_contract(Ionx)36961" + }, + { + "astId": 30768, + "contract": "contracts/v1/leptons/store.sol:LeptonsStore", + "label": "nextTokenId", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 30770, + "contract": "contracts/v1/leptons/store.sol:LeptonsStore", + "label": "ionxPerLepton", + "offset": 0, + "slot": "4", + "type": "t_uint256" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_contract(Ionx)36961": { + "encoding": "inplace", + "label": "contract Ionx", + "numberOfBytes": "20" + }, + "t_contract(Lepton2)38399": { + "encoding": "inplace", + "label": "contract Lepton2", + "numberOfBytes": "20" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/deployments/polygon/RewardProgramDAI.json b/deployments/polygon/RewardProgramDAI.json new file mode 100644 index 0000000..652e3ef --- /dev/null +++ b/deployments/polygon/RewardProgramDAI.json @@ -0,0 +1,814 @@ +{ + "address": "0x35830BfF05240D95F628cf1225ad0E3147DBbb81", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "AssetDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "AssetRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "AssetRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardProgramFunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "RewardProgramOutOfFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewarded", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remaining", + "type": "uint256" + } + ], + "name": "RewardsClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "parentNftUuid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "calculateRewardsEarned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "fundProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "parentNftUuid", + "type": "uint256" + } + ], + "name": "getAssetStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimableRewards", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + } + ], + "internalType": "struct IRewardProgram.AssetStake", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getClaimableRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFundBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProgramData", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + } + ], + "internalType": "struct IRewardProgram.ProgramRewardData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + }, + { + "internalType": "address", + "name": "chargedManagers", + "type": "address" + }, + { + "internalType": "address", + "name": "universe", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "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": "nonpayable", + "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": "nonpayable", + "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": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "registerAssetDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "registerAssetRelease", + "outputs": [ + { + "internalType": "uint256", + "name": "rewards", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + } + ], + "name": "registerExistingDeposits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newMultiplier", + "type": "uint256" + } + ], + "name": "setBaseMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "setChargedManagers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newRewardToken", + "type": "address" + } + ], + "name": "setRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newStakingToken", + "type": "address" + } + ], + "name": "setStakingToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "universe", + "type": "address" + } + ], + "name": "setUniverse", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xa0e2423e34298f0a673c272f8f5d5081983b490da8d5e775acda537c778d240e", + "numDeployments": 1 +} \ No newline at end of file diff --git a/deployments/polygon/RewardProgramFactory.json b/deployments/polygon/RewardProgramFactory.json new file mode 100644 index 0000000..373d5d1 --- /dev/null +++ b/deployments/polygon/RewardProgramFactory.json @@ -0,0 +1,418 @@ +{ + "address": "0xD7487B7A749491f8433Ad5168430d6Ce6731a80B", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "rewardProgram", + "type": "address" + } + ], + "name": "RewardProgramCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [], + "name": "_template", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + }, + { + "internalType": "address", + "name": "chargedManagers", + "type": "address" + }, + { + "internalType": "address", + "name": "universe", + "type": "address" + } + ], + "name": "createRewardProgram", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xf27a734e7084b0809505a289cbaaeb1c6ae70fa1213db6d6045cc1e7a622dc7b", + "receipt": { + "to": null, + "from": "0xb8D175F16742395F530e0b3bC1d30BD06B78CdA9", + "contractAddress": "0xD7487B7A749491f8433Ad5168430d6Ce6731a80B", + "transactionIndex": 26, + "gasUsed": "3259530", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000400000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800001000000400000000100000000000000000000020000000000000000000800000000000000000080000000000000400000000000000000000000020000000000000000000000000000200000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000800000000000000100000000020000000000000000000000000000000000000010000000000000004000002100000", + "blockHash": "0x31a05cc38c364d91527b152e816ce79349e437983cb62648c4773321425b0d04", + "transactionHash": "0xf27a734e7084b0809505a289cbaaeb1c6ae70fa1213db6d6045cc1e7a622dc7b", + "logs": [ + { + "transactionIndex": 26, + "blockNumber": 46700954, + "transactionHash": "0xf27a734e7084b0809505a289cbaaeb1c6ae70fa1213db6d6045cc1e7a622dc7b", + "address": "0xD7487B7A749491f8433Ad5168430d6Ce6731a80B", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000b8d175f16742395f530e0b3bc1d30bd06b78cda9" + ], + "data": "0x", + "logIndex": 372, + "blockHash": "0x31a05cc38c364d91527b152e816ce79349e437983cb62648c4773321425b0d04" + }, + { + "transactionIndex": 26, + "blockNumber": 46700954, + "transactionHash": "0xf27a734e7084b0809505a289cbaaeb1c6ae70fa1213db6d6045cc1e7a622dc7b", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000b8d175f16742395f530e0b3bc1d30bd06b78cda9", + "0x0000000000000000000000007c7379531b2aee82e4ca06d4175d13b9cbeafd49" + ], + "data": "0x0000000000000000000000000000000000000000000000000202bece103b36ce00000000000000000000000000000000000000000000001a30e24fee13c55aa0000000000000000000000000000000000000000000024af641b9e773c6e66fe700000000000000000000000000000000000000000000001a2edf9120038a23d2000000000000000000000000000000000000000000024af643bca641d721a6b5", + "logIndex": 373, + "blockHash": "0x31a05cc38c364d91527b152e816ce79349e437983cb62648c4773321425b0d04" + } + ], + "blockNumber": 46700954, + "cumulativeGasUsed": "9652084", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "39876b9d6995fafd8c4442fb1a03f418", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"rewardProgram\",\"type\":\"address\"}],\"name\":\"RewardProgramCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC1155\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckEther\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"_template\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"stakingToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"rewardToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"baseMultiplier\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"chargedManagers\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"universe\",\"type\":\"address\"}],\"name\":\"createRewardProgram\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC1155\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawErc20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawEther\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/v1/incentives/RewardProgramFactory.sol\":\"RewardProgramFactory\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <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\",\"keccak256\":\"0x4784c3f8a520a739dd25d76f514833a653990902d0e21601aed45bda44c87524\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0xa1931c47a617014f858580db625aa0dcf343796f39acd4b5b51effc092a1f0a9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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 GSN 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 payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xdb26cbf4d028490f49831a7865c2fe1b28db44b535ca8d343785a3b768aae183\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"../GSN/Context.sol\\\";\\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 */\\ncontract 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 () internal {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view 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 emit OwnershipTransferred(_owner, address(0));\\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x4bd6402ca6b3419008c2b482aff54e66836e8cb4eba2680e42ac5884ae6424fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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\",\"keccak256\":\"0xfa152b6e88a1dc50780e8f1580426dc23ad2e1e2c2f086a088adf206a202f453\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\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 uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\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 sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\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 * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\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 // 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) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts 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 mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9a9cf02622cd7a64261b10534fc3260449da25c98c9e96d1b4ae8110a20e5806\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x31691ad0817f8cb338531b78d2ab2989027d9f27e6f8e62492b754fed9429b10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"../../introspection/IERC165.sol\\\";\\n\\n/**\\n * _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n\\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 )\\n external\\n 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 )\\n external\\n returns(bytes4);\\n}\\n\",\"keccak256\":\"0x0bc1d0b8fa3b262a6fb98b88dceab8b3348903b95dcc5909b9074fb19a3d2da5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0x5c26b39d26f7ed489e555d955dcd3e01872972e71fdd1528e93ec164e4f23385\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.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 SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf3b30f8a49631420635a8c35daacfcaa338012755f18a76fdd118730256f9a27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0xaf936da92f3a9a4f98b237323b5eb1d813fb86c4d07a184beba7027cf0509ba3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 /**\\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\",\"keccak256\":\"0x3636662804cd8f474536b2875a9038a4c3fb91879f1bbff48af5c3f140fcd2f0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address operator, address from, uint256 tokenId, bytes calldata data)\\n external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x321ee37ef4925020aa818a03ec7fe48e057561f65ab009a84f6c20c86026ade7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 in 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 // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n return _functionCallWithValue(target, data, value, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\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 // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf5fa8cbdffa5ef8be49b246b5628facc30b71707e78a45d80d93b64eff3fe390\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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.0.0, only sets of type `address` (`AddressSet`) and `uint256`\\n * (`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\\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\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] = toDeleteIndex + 1; // All indexes are 1-based\\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 require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\n return set._values[index];\\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(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(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(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(uint256(_at(set._inner, index)));\\n }\\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\",\"keccak256\":\"0xb2a11b236f073662f5a196995863f51c11d006bf7c3de158b316dfa1506c4b79\",\"license\":\"MIT\"},\"contracts/v1/incentives/RewardProgram.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// RewardProgram.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../interfaces/IRewardProgram.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/introspection/IERC165.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/EnumerableSet.sol\\\";\\n\\nimport \\\"../interfaces/IUniverseRP.sol\\\";\\nimport \\\"../interfaces/IChargedManagers.sol\\\";\\nimport \\\"../interfaces/IWalletManager.sol\\\";\\nimport \\\"../lib/TokenInfo.sol\\\";\\nimport \\\"../lib/ReentrancyGuard.sol\\\";\\nimport \\\"../lib/BlackholePrevention.sol\\\";\\nimport \\\"../interfaces/IERC20Detailed.sol\\\";\\n\\ncontract RewardProgram is\\n IRewardProgram,\\n BlackholePrevention,\\n IERC165,\\n ReentrancyGuard,\\n IERC721Receiver,\\n IERC1155Receiver\\n{\\n using SafeMath for uint256;\\n using TokenInfo for address;\\n using SafeERC20 for IERC20;\\n using EnumerableSet for EnumerableSet.UintSet;\\n\\n uint256 constant private PERCENTAGE_SCALE = 1e4; // 10000 (100%)\\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\\n\\n address private _owner;\\n IUniverseRP private _universe;\\n IChargedManagers private _chargedManagers;\\n ProgramRewardData private _programData;\\n mapping(uint256 => AssetStake) private _assetStake;\\n\\n\\n /***********************************|\\n | Initialization |\\n |__________________________________*/\\n\\n constructor() public {}\\n\\n function initialize(\\n address stakingToken,\\n address rewardToken,\\n uint256 baseMultiplier,\\n address chargedManagers,\\n address universe,\\n address owner\\n ) external override {\\n require(_owner == address(0x0), \\\"Already initialized\\\");\\n _owner = owner;\\n\\n // Prepare Reward Program\\n _programData.stakingToken = stakingToken;\\n _programData.rewardToken = rewardToken;\\n _programData.baseMultiplier = baseMultiplier; // Basis Points\\n\\n // Connect to Charged Particles\\n _chargedManagers = IChargedManagers(chargedManagers);\\n _universe = IUniverseRP(universe);\\n }\\n\\n\\n /***********************************|\\n | Public Functions |\\n |__________________________________*/\\n\\n function getProgramData() external view override returns (ProgramRewardData memory) {\\n return _programData;\\n }\\n\\n function getAssetStake(uint256 parentNftUuid) external view override returns (AssetStake memory) {\\n return _assetStake[parentNftUuid];\\n }\\n\\n function getFundBalance() external view override returns (uint256) {\\n return _getFundBalance();\\n }\\n\\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) public view override returns (uint256) {\\n return _calculateRewardsEarned(parentNftUuid, interestAmount);\\n }\\n\\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view override returns (uint256) {\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n return _assetStake[parentNftUuid].claimableRewards;\\n }\\n\\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\\n return IERC721Receiver.onERC721Received.selector;\\n }\\n\\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\\n return IERC1155Receiver.onERC1155BatchReceived.selector;\\n }\\n\\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\\n return \\\"\\\";\\n }\\n\\n function supportsInterface(bytes4 interfaceId)\\n public\\n view\\n virtual\\n override(IERC165)\\n returns (bool)\\n {\\n // default interface support\\n if (\\n interfaceId == type(IERC721Receiver).interfaceId ||\\n interfaceId == type(IERC1155Receiver).interfaceId ||\\n interfaceId == type(IERC165).interfaceId\\n ) {\\n return true;\\n }\\n }\\n\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n\\n /***********************************|\\n | Only Universe |\\n |__________________________________*/\\n\\n function registerAssetDeposit(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n uint256 principalAmount\\n )\\n external\\n override\\n onlyUniverse\\n {\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n AssetStake storage assetStake = _assetStake[parentNftUuid];\\n\\n if (assetStake.start == 0) {\\n assetStake.start = block.number;\\n assetStake.walletManagerId = walletManagerId;\\n }\\n emit AssetDeposit(contractAddress, tokenId, walletManagerId, principalAmount);\\n }\\n\\n function registerAssetRelease(\\n address contractAddress,\\n uint256 tokenId,\\n uint256 interestAmount\\n )\\n external\\n override\\n onlyUniverse\\n nonReentrant\\n returns (uint256 rewards)\\n {\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n AssetStake storage assetStake = _assetStake[parentNftUuid];\\n\\n // Update Claimable Rewards\\n uint256 newRewards = _calculateRewardsEarned(parentNftUuid, interestAmount);\\n assetStake.claimableRewards = assetStake.claimableRewards.add(newRewards);\\n\\n // Reset Stake if Principal Balance falls to Zero\\n IWalletManager walletMgr = _chargedManagers.getWalletManager(assetStake.walletManagerId);\\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\\n if (principal == 0) {\\n assetStake.start = 0;\\n }\\n\\n // Issue Rewards to NFT Owner\\n rewards = _claimRewards(contractAddress, tokenId);\\n\\n emit AssetRelease(contractAddress, tokenId, interestAmount);\\n }\\n\\n\\n /***********************************|\\n | Reward Calculation |\\n |__________________________________*/\\n\\n function _calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) internal view returns (uint256 totalReward) {\\n uint256 baseReward = _calculateBaseReward(interestAmount);\\n uint256 leptonMultipliedReward = _calculateMultipliedReward(parentNftUuid, baseReward);\\n totalReward = _convertDecimals(leptonMultipliedReward);\\n }\\n\\n function _calculateBaseReward(uint256 amount) internal view returns(uint256 baseReward) {\\n baseReward = amount.mul(_programData.baseMultiplier).div(PERCENTAGE_SCALE);\\n }\\n\\n function _calculateMultipliedReward(uint256 parentNftUuid, uint256 baseReward) internal view returns(uint256) {\\n AssetStake storage assetStake = _assetStake[parentNftUuid];\\n if (assetStake.start == 0) { return baseReward; }\\n\\n IUniverseRP.NftStake memory nftStake = _universe.getNftStake(parentNftUuid);\\n uint256 multiplierBP = nftStake.multiplier;\\n\\n uint256 assetDepositLength = block.number.sub(assetStake.start);\\n uint256 nftDepositLength = 0;\\n if (nftStake.releaseBlockNumber > 0) {\\n nftDepositLength = nftStake.releaseBlockNumber.sub(nftStake.depositBlockNumber);\\n } else {\\n nftDepositLength = block.number.sub(nftStake.depositBlockNumber);\\n }\\n\\n if (multiplierBP == 0 || nftDepositLength == 0 || assetDepositLength == 0) {\\n return baseReward;\\n }\\n\\n if (nftDepositLength > assetDepositLength) {\\n nftDepositLength = assetDepositLength;\\n }\\n\\n // Percentage of the total program that the Multiplier Nft was deposited for\\n uint256 nftRewardRatioBP = nftDepositLength.mul(PERCENTAGE_SCALE).div(assetDepositLength);\\n\\n // Amount of reward that the Multiplier Nft is responsible for\\n uint256 amountGeneratedDuringNftDeposit = baseReward.mul(nftRewardRatioBP).div(PERCENTAGE_SCALE);\\n\\n // Amount of Multiplied Reward from NFT\\n uint256 multipliedReward = amountGeneratedDuringNftDeposit.mul(multiplierBP.mul(LEPTON_MULTIPLIER_SCALE)).div(PERCENTAGE_SCALE);\\n\\n // Amount of Base Reward without Multiplied NFT Rewards\\n uint256 amountGeneratedWithoutNftDeposit = baseReward.sub(amountGeneratedDuringNftDeposit);\\n\\n // Amount of Base Rewards + Multiplied NFT Rewards\\n return amountGeneratedWithoutNftDeposit.add(multipliedReward);\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n |__________________________________*/\\n\\n function fundProgram(uint256 amount) external onlyOwner {\\n require(_programData.rewardToken != address(0), \\\"RP:E-405\\\");\\n IERC20(_programData.rewardToken).safeTransferFrom(msg.sender, address(this), amount);\\n emit RewardProgramFunded(amount);\\n }\\n\\n function setStakingToken(address newStakingToken) external onlyOwner {\\n _programData.stakingToken = newStakingToken;\\n }\\n\\n function setRewardToken(address newRewardToken) external onlyOwner {\\n _programData.rewardToken = newRewardToken;\\n }\\n\\n function setBaseMultiplier(uint256 newMultiplier) external onlyOwner {\\n _programData.baseMultiplier = newMultiplier; // Basis Points\\n }\\n\\n function setChargedManagers(address manager) external onlyOwner {\\n _chargedManagers = IChargedManagers(manager);\\n }\\n\\n function setUniverse(address universe) external onlyOwner {\\n _universe = IUniverseRP(universe);\\n }\\n\\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external override onlyOwner {\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n\\n // Initiate Asset Stake\\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\\n if (principal > 0) {\\n _assetStake[parentNftUuid] = AssetStake(block.number, 0, walletManagerId);\\n emit AssetRegistered(contractAddress, tokenId, walletManagerId, principal);\\n }\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n | (blackhole prevention) |\\n |__________________________________*/\\n\\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n\\n\\n /***********************************|\\n | Private Functions |\\n |__________________________________*/\\n\\n function _claimRewards(\\n address contractAddress,\\n uint256 tokenId\\n )\\n internal\\n returns (uint256 totalReward)\\n {\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n AssetStake storage assetStake = _assetStake[parentNftUuid];\\n\\n // Rewards Receiver\\n address receiver = IERC721(contractAddress).ownerOf(tokenId);\\n\\n // Ensure Reward Pool has Sufficient Balance\\n totalReward = assetStake.claimableRewards;\\n uint256 fundBalance = _getFundBalance();\\n uint256 unavailReward = totalReward > fundBalance ? totalReward.sub(fundBalance) : 0;\\n\\n // Determine amount of Rewards to Transfer\\n if (unavailReward > 0) {\\n totalReward = totalReward.sub(unavailReward);\\n emit RewardProgramOutOfFunds();\\n }\\n\\n // Update Asset Stake\\n assetStake.claimableRewards = unavailReward;\\n\\n if (totalReward > 0) {\\n // Transfer Available Rewards to Receiver\\n IERC20(_programData.rewardToken).safeTransfer(receiver, totalReward);\\n }\\n\\n emit RewardsClaimed(contractAddress, tokenId, receiver, totalReward, unavailReward);\\n }\\n\\n function _convertDecimals(uint256 reward) internal view returns (uint256) {\\n uint8 stakingTokenDecimals = IERC20Detailed(_programData.stakingToken).decimals();\\n return reward.mul(10**(18 - uint256(stakingTokenDecimals)));\\n }\\n\\n function _getFundBalance() internal view returns (uint256) {\\n return IERC20Detailed(_programData.rewardToken).balanceOf(address(this));\\n }\\n\\n\\n modifier onlyOwner() {\\n require(_owner == msg.sender, \\\"Caller is not the owner\\\");\\n _;\\n }\\n\\n modifier onlyUniverse() {\\n require(msg.sender == address(_universe), \\\"RP:E-108\\\");\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x2c6b66490dda8cea12387706aa49742f7d8c90ff3b699abd3c84dae227277e3f\",\"license\":\"MIT\"},\"contracts/v1/incentives/RewardProgramFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// RewardProgramFactory.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\nimport \\\"./RewardProgram.sol\\\";\\nimport \\\"../lib/BlackholePrevention.sol\\\";\\n\\ncontract RewardProgramFactory is BlackholePrevention, Ownable {\\n event RewardProgramCreated(address indexed rewardProgram);\\n\\n address public _template;\\n\\n constructor () public {\\n _template = address(new RewardProgram());\\n }\\n\\n // function _msgSender() internal view override returns (address payable) {\\n // return msg.sender;\\n // }\\n\\n function createRewardProgram(\\n address stakingToken,\\n address rewardToken,\\n uint256 baseMultiplier,\\n address chargedManagers,\\n address universe\\n )\\n external\\n onlyOwner\\n returns (address)\\n {\\n address newRewardProgram = _createClone(_template);\\n RewardProgram rewardProgram = RewardProgram(newRewardProgram);\\n rewardProgram.initialize(stakingToken, rewardToken, baseMultiplier, chargedManagers, universe, _msgSender());\\n emit RewardProgramCreated(newRewardProgram);\\n return newRewardProgram;\\n }\\n\\n /**\\n * @dev Creates Contracts from a Template via Cloning\\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\\n */\\n function _createClone(address target) internal returns (address result) {\\n bytes20 targetBytes = bytes20(target);\\n assembly {\\n let clone := mload(0x40)\\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\\n mstore(add(clone, 0x14), targetBytes)\\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\\n result := create(0, clone, 0x37)\\n }\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n | (blackhole prevention) |\\n |__________________________________*/\\n\\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n}\\n\",\"keccak256\":\"0x5a3692f0c9dee582d05013bc2f808cca4e7257756ed8125d81586d674c166559\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IBasketManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IBasketManager.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Particle Basket Manager interface\\n * @dev The basket-manager for underlying assets attached to Charged Particles\\n * @dev Manages the link between NFTs and their respective Smart-Baskets\\n */\\ninterface IBasketManager {\\n\\n event ControllerSet(address indexed controller);\\n event ExecutorSet(address indexed executor);\\n event PausedStateSet(bool isPaused);\\n event NewSmartBasket(address indexed contractAddress, uint256 indexed tokenId, address indexed smartBasket);\\n event BasketAdd(address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\\n event BasketRemove(address indexed receiver, address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\\n event BasketRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\\n event RewardProgramSet(address indexed rewardProgram);\\n\\n function isPaused() external view returns (bool);\\n\\n function getTokenTotalCount(address contractAddress, uint256 tokenId) external view returns (uint256);\\n function getTokenCountByType(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (uint256);\\n\\n function prepareTransferAmount(uint256 nftTokenAmount) external;\\n function addToBasket(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\\n function getBasketAddressById(address contractAddress, uint256 tokenId) external returns (address);\\n\\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount) external;\\n}\\n\",\"keccak256\":\"0x20367a08a95c30ed283f46877bef9c5f1ccd0f07409fe632f4f82a5d33b6a0c3\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IChargedManagers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"./IWalletManager.sol\\\";\\nimport \\\"./IBasketManager.sol\\\";\\n\\n/**\\n * @notice Interface for Charged Wallet-Managers\\n */\\ninterface IChargedManagers {\\n\\n /***********************************|\\n | Public API |\\n |__________________________________*/\\n\\n function isContractOwner(address contractAddress, address account) external view returns (bool);\\n\\n // ERC20\\n function isWalletManagerEnabled(string calldata walletManagerId) external view returns (bool);\\n function getWalletManager(string calldata walletManagerId) external view returns (IWalletManager);\\n\\n // ERC721\\n function isNftBasketEnabled(string calldata basketId) external view returns (bool);\\n function getBasketManager(string calldata basketId) external view returns (IBasketManager);\\n\\n // Validation\\n function validateDeposit(\\n address sender,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external;\\n function validateNftDeposit(\\n address sender,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external;\\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external;\\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external;\\n\\n /***********************************|\\n | Particle Events |\\n |__________________________________*/\\n\\n event Initialized(address indexed initiator);\\n event ControllerSet(address indexed controllerAddress, string controllerId);\\n event WalletManagerRegistered(string indexed walletManagerId, address indexed walletManager);\\n event BasketManagerRegistered(string indexed basketId, address indexed basketManager);\\n}\\n\",\"keccak256\":\"0x98103c0832064c1e446dcfebfdeeec1a9189675e9cf630f568c65c16c94d5478\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IERC20Detailed.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Detailed {\\n function decimals() external view returns (uint8);\\n function symbol() external view returns (string memory);\\n function name() external view returns (string memory);\\n\\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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0x96b8e4b6723a052ec16a1a729854532c953fb2eb758a0e01f75a3eafe242ccd8\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IERC721Chargeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IERC721Chargeable.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\\\";\\n\\ninterface IERC721Chargeable is IERC165Upgradeable {\\n function owner() external view returns (address);\\n function creatorOf(uint256 tokenId) external view returns (address);\\n function balanceOf(address tokenOwner) external view returns (uint256 balance);\\n function ownerOf(uint256 tokenId) external view returns (address tokenOwner);\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n function transferFrom(address from, address to, uint256 tokenId) external;\\n function approve(address to, uint256 tokenId) external;\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n function setApprovalForAll(address operator, bool _approved) external;\\n function isApprovedForAll(address tokenOwner, address operator) external view returns (bool);\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x459e57b2d35c7cd78e6c3d47eb9f3e981529a18c89e2c318b10fe369c479c737\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IRewardProgram.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IRewardProgram.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\npragma experimental ABIEncoderV2;\\n\\ninterface IRewardProgram {\\n /* admin events */\\n event RewardProgramFunded(uint256 amount);\\n event RewardProgramOutOfFunds();\\n\\n /* user events */\\n event RewardsClaimed(address indexed contractAddress, uint256 tokenId, address indexed receiver, uint256 rewarded, uint256 remaining);\\n\\n event AssetRegistered(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\\n event AssetDeposit(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\\n event AssetRelease(address indexed contractAddress, uint256 tokenId, uint256 interestAmount);\\n\\n /* data types */\\n struct ProgramRewardData {\\n address stakingToken;\\n address rewardToken;\\n uint256 baseMultiplier; // Basis Points\\n }\\n\\n struct AssetStake {\\n uint256 start;\\n uint256 claimableRewards;\\n string walletManagerId;\\n }\\n\\n function initialize(address stakingToken, address rewardToken, uint256 baseMultiplier, address chargedManagers, address universe, address owner) external;\\n\\n /* user functions */\\n function getProgramData() external view returns (ProgramRewardData memory programData);\\n function getAssetStake(uint256 uuid) external view returns (AssetStake memory);\\n function getFundBalance() external view returns (uint256);\\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) external view returns (uint256);\\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view returns (uint256);\\n\\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external;\\n function registerAssetDeposit(address contractAddress, uint256 tokenId, string calldata walletManagerId, uint256 principalAmount) external;\\n function registerAssetRelease(address contractAddress, uint256 tokenId, uint256 interestAmount) external returns (uint256 rewards);\\n}\",\"keccak256\":\"0xe0f4076a4b001856c54cb8a63decedc81ca34c71708f8cbe9b3a26603dc9c050\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IUniverse.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IUniverse.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Universal Controller interface\\n * @dev ...\\n */\\ninterface IUniverse {\\n\\n event ChargedParticlesSet(address indexed chargedParticles);\\n event PhotonSet(address indexed photonToken, uint256 maxSupply);\\n event ProtonTokenSet(address indexed protonToken);\\n event LeptonTokenSet(address indexed leptonToken);\\n event QuarkTokenSet(address indexed quarkToken);\\n event BosonTokenSet(address indexed bosonToken);\\n event EsaMultiplierSet(address indexed assetToken, uint256 multiplier);\\n event ElectrostaticAttraction(address indexed account, address photonSource, uint256 energy, uint256 multiplier);\\n event ElectrostaticDischarge(address indexed account, address photonSource, uint256 energy);\\n\\n function onEnergize(\\n address sender,\\n address referrer,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 assetEnergy\\n ) external;\\n\\n function onDischarge(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onDischargeForCreator(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address creator,\\n address assetToken,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onRelease(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 principalEnergy,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onCovalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n\\n function onCovalentBreak(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n\\n function onProtonSale(\\n address contractAddress,\\n uint256 tokenId,\\n address oldOwner,\\n address newOwner,\\n uint256 salePrice,\\n address creator,\\n uint256 creatorRoyalties\\n ) external;\\n}\\n\",\"keccak256\":\"0x6cebb97ce4d32c61afc746e4a6538eb605bb01276dfa66fa4bd6f63362bdc9ef\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IUniverseRP.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IUniverseRP.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"./IUniverse.sol\\\";\\n\\n/**\\n * @title Universal Controller interface for Rewards Program\\n * @dev ...\\n */\\ninterface IUniverseRP is IUniverse {\\n event RewardProgramSet(address indexed assetToken, address indexed rewardProgram);\\n event RewardProgramRemoved(address indexed assetToken);\\n event NftDeposit(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\\n event NftRelease(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\\n\\n struct NftStake {\\n uint256 multiplier; // in Basis Points\\n uint256 depositBlockNumber;\\n uint256 releaseBlockNumber;\\n }\\n\\n function getRewardProgram(address asset) external view returns (address);\\n function getNftStake(uint256 uuid) external view returns (NftStake memory);\\n}\\n\",\"keccak256\":\"0xd9c5a996bbb7f2a27bb85dde52587f7368c7b6512fc1064821a3975acdf4b7db\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IWalletManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IWalletManager.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Particle Wallet Manager interface\\n * @dev The wallet-manager for underlying assets attached to Charged Particles\\n * @dev Manages the link between NFTs and their respective Smart-Wallets\\n */\\ninterface IWalletManager {\\n\\n event ControllerSet(address indexed controller);\\n event ExecutorSet(address indexed executor);\\n event PausedStateSet(bool isPaused);\\n event NewSmartWallet(address indexed contractAddress, uint256 indexed tokenId, address indexed smartWallet, address creator, uint256 annuityPct);\\n event WalletEnergized(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 assetAmount, uint256 yieldTokensAmount);\\n event WalletDischarged(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 creatorAmount, uint256 receiverAmount);\\n event WalletDischargedForCreator(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, address creator, uint256 receiverAmount);\\n event WalletReleased(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address assetToken, uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\\n event WalletRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\\n\\n function isPaused() external view returns (bool);\\n\\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view returns (bool);\\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view returns (address);\\n\\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\\n function getInterest(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken) external returns (uint256);\\n\\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount) external returns (uint256 yieldTokensAmount);\\n function discharge(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n function dischargeAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n function dischargeAmountForCreator(address receiver, address contractAddress, uint256 tokenId, address creator, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\\n function release(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\\n function releaseAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken) external;\\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct) external returns (address);\\n\\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\\n}\\n\",\"keccak256\":\"0xb03ee0e216d7444e72af388814d219ad9aa87006ec96d660b45dcad0875ef0d7\",\"license\":\"MIT\"},\"contracts/v1/lib/BlackholePrevention.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\\\";\\n\\n/**\\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\\n * the Owner/DAO to pull them out on behalf of a user\\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\\n */\\ncontract BlackholePrevention {\\n using Address for address payable;\\n using SafeERC20 for IERC20;\\n\\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\\n\\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (address(this).balance >= amount) {\\n receiver.sendValue(amount);\\n emit WithdrawStuckEther(receiver, amount);\\n }\\n }\\n\\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\\n IERC20(tokenAddress).safeTransfer(receiver, amount);\\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\\n }\\n }\\n\\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\\n }\\n }\\n\\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \\\"\\\");\\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6a664c8a1c1d7fb32ade2c11f75756b1fdb4c489daa32c1d58e6b867ea2ba8d6\",\"license\":\"MIT\"},\"contracts/v1/lib/ReentrancyGuard.sol\":{\"content\":\"pragma solidity 0.6.12;\\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 () public {\\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 _nonReentrantBefore();\\n _;\\n _nonReentrantAfter();\\n }\\n\\n function _nonReentrantBefore() private {\\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n }\\n\\n function _nonReentrantAfter() private {\\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 /**\\n * @dev Returns true if the reentrancy guard is currently set to \\\"entered\\\", which indicates there is a\\n * `nonReentrant` function in the call stack.\\n */\\n function _reentrancyGuardEntered() internal view returns (bool) {\\n return _status == _ENTERED;\\n }\\n}\",\"keccak256\":\"0x4897c6fee5e1601d203efa54d29b2cef20825cab134b8e63b0b13ee9603642ad\"},\"contracts/v1/lib/TokenInfo.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// TokenInfo.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport \\\"../interfaces/IERC721Chargeable.sol\\\";\\n\\nlibrary TokenInfo {\\n function getTokenUUID(address contractAddress, uint256 tokenId) internal pure virtual returns (uint256) {\\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n function getTokenOwner(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n return tokenInterface.ownerOf(tokenId);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n function getTokenCreator(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n return tokenInterface.creatorOf(tokenId);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Owner of an External NFT contract\\n /// @param contractAddress The Address to the Contract of the NFT to check\\n /// @param account The Address of the Account to check\\n /// @return True if the account owns the contract\\n function isContractOwner(address contractAddress, address account) internal view virtual returns (bool) {\\n address contractOwner = IERC721Chargeable(contractAddress).owner();\\n return contractOwner != address(0x0) && contractOwner == account;\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Creator of a Proton-based NFT\\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\\n /// @param tokenId The Token ID of the Proton-based NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the creator of the Proton-based NFT\\n function isTokenCreator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenCreator = tokenInterface.creatorOf(tokenId);\\n return (sender == tokenCreator);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\\n /// @param tokenId The Token ID of the Proton-based NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the creator of the Proton-based NFT or the Contract itself\\n function isTokenContractOrCreator(address contractAddress, uint256 tokenId, address creator, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenCreator = tokenInterface.creatorOf(tokenId);\\n if (sender == contractAddress && creator == tokenCreator) { return true; }\\n return (sender == tokenCreator);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Owner or Operator of an External NFT\\n /// @param contractAddress The Address to the Contract of the External NFT to check\\n /// @param tokenId The Token ID of the External NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the Owner or Operator of the External NFT\\n function isErc721OwnerOrOperator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenOwner = tokenInterface.ownerOf(tokenId);\\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\\n }\\n\\n /**\\n * @dev Returns true if `account` is a contract.\\n * @dev Taken from OpenZeppelin library\\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { codehash := extcodehash(account) }\\n return (codehash != accountHash && codehash != 0x0);\\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 * @dev Taken from OpenZeppelin library\\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, uint256 gasLimit) internal {\\n require(address(this).balance >= amount, \\\"TokenInfo: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = (gasLimit > 0)\\n ? recipient.call{ value: amount, gas: gasLimit }(\\\"\\\")\\n : recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"TokenInfo: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0xbc78c6173db068d95084288246642402d0f4af399e1eb754182cae2d9173af5e\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50600061001b6100b3565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350604051610071906100b7565b604051809103906000f08015801561008d573d6000803e3d6000fd5b50600180546001600160a01b0319166001600160a01b03929092169190911790556100c4565b3390565b6127bd8061115483390190565b611081806100d36000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c80636fe6fabb116100665780636fe6fabb146100fc578063715018a6146101045780638da5cb5b1461010c578063a0edb48b14610114578063f2fde38b1461012757610093565b80631593dee1146100985780634025feb2146100ad578063522f6815146100c05780636f9d5f78146100d3575b600080fd5b6100ab6100a6366004610be7565b61013a565b005b6100ab6100bb366004610be7565b610188565b6100ab6100ce366004610c6c565b6101c8565b6100e66100e1366004610c97565b61020b565b6040516100f39190610d55565b60405180910390f35b6100e661030b565b6100ab61031a565b6100e6610399565b6100ab610122366004610c27565b6103a8565b6100ab610135366004610ba8565b6103ef565b6101426104a5565b6000546001600160a01b039081169116146101785760405162461bcd60e51b815260040161016f90610f48565b60405180910390fd5b6101838383836104a9565b505050565b6101906104a5565b6000546001600160a01b039081169116146101bd5760405162461bcd60e51b815260040161016f90610f48565b6101838383836105b6565b6101d06104a5565b6000546001600160a01b039081169116146101fd5760405162461bcd60e51b815260040161016f90610f48565b6102078282610711565b5050565b60006102156104a5565b6000546001600160a01b039081169116146102425760405162461bcd60e51b815260040161016f90610f48565b60015460009061025a906001600160a01b0316610795565b9050806001600160a01b03811663ff9935cb89898989896102796104a5565b6040518763ffffffff1660e01b815260040161029a96959493929190610dc5565b600060405180830381600087803b1580156102b457600080fd5b505af11580156102c8573d6000803e3d6000fd5b50506040516001600160a01b03851692507f6ecb2838bef4560681475e8bb5e7feccefe33df915df2d6757024bc6fe4c616a9150600090a2509695505050505050565b6001546001600160a01b031681565b6103226104a5565b6000546001600160a01b0390811691161461034f5760405162461bcd60e51b815260040161016f90610f48565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b6103b06104a5565b6000546001600160a01b039081169116146103dd5760405162461bcd60e51b815260040161016f90610f48565b6103e9848484846107e7565b50505050565b6103f76104a5565b6000546001600160a01b039081169116146104245760405162461bcd60e51b815260040161016f90610f48565b6001600160a01b03811661044a5760405162461bcd60e51b815260040161016f90610e4b565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b0383166104cf5760405162461bcd60e51b815260040161016f90610e91565b6040516370a0823160e01b815281906001600160a01b038416906370a08231906104fd903090600401610d55565b60206040518083038186803b15801561051557600080fd5b505afa158015610529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061054d9190610d1e565b10610183576105666001600160a01b0383168483610946565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b836040516105a99190610ffe565b60405180910390a3505050565b6001600160a01b0383166105dc5760405162461bcd60e51b815260040161016f90610e91565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e9061060a908590600401610ffe565b60206040518083038186803b15801561062257600080fd5b505afa158015610636573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065a9190610bcb565b6001600160a01b03161415610183576040516323b872dd60e01b81526001600160a01b038316906323b872dd9061069990309087908690600401610d69565b600060405180830381600087803b1580156106b357600080fd5b505af11580156106c7573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b0382166107375760405162461bcd60e51b815260040161016f90610e91565b804710610207576107516001600160a01b0383168261099c565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd826040516107899190610ffe565b60405180910390a25050565b6000808260601b9050604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528160148201526e5af43d82803e903d91602b57fd5bf360881b60288201526037816000f0949350505050565b6001600160a01b03841661080d5760405162461bcd60e51b815260040161016f90610e91565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e9061083b9030908790600401610dff565b60206040518083038186803b15801561085357600080fd5b505afa158015610867573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088b9190610d1e565b106103e957604051637921219560e11b81526001600160a01b0384169063f242432a906108c2903090889087908790600401610d8d565b600060405180830381600087803b1580156108dc57600080fd5b505af11580156108f0573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b846040516109389190610ffe565b60405180910390a450505050565b6101838363a9059cbb60e01b8484604051602401610965929190610dff565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610a38565b804710156109bc5760405162461bcd60e51b815260040161016f90610f11565b6000826001600160a01b0316826040516109d590610d52565b60006040518083038185875af1925050503d8060008114610a12576040519150601f19603f3d011682016040523d82523d6000602084013e610a17565b606091505b50509050806101835760405162461bcd60e51b815260040161016f90610eb4565b6060610a8d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610ac79092919063ffffffff16565b8051909150156101835780806020019051810190610aab9190610cfe565b6101835760405162461bcd60e51b815260040161016f90610fb4565b6060610ad68484600085610ade565b949350505050565b6060610ae985610ba2565b610b055760405162461bcd60e51b815260040161016f90610f7d565b60006060866001600160a01b03168587604051610b229190610d36565b60006040518083038185875af1925050503d8060008114610b5f576040519150601f19603f3d011682016040523d82523d6000602084013e610b64565b606091505b50915091508115610b78579150610ad69050565b805115610b885780518082602001fd5b8360405162461bcd60e51b815260040161016f9190610e18565b3b151590565b600060208284031215610bb9578081fd5b8135610bc481611033565b9392505050565b600060208284031215610bdc578081fd5b8151610bc481611033565b600080600060608486031215610bfb578182fd5b8335610c0681611033565b92506020840135610c1681611033565b929592945050506040919091013590565b60008060008060808587031215610c3c578081fd5b8435610c4781611033565b93506020850135610c5781611033565b93969395505050506040820135916060013590565b60008060408385031215610c7e578182fd5b8235610c8981611033565b946020939093013593505050565b600080600080600060a08688031215610cae578081fd5b8535610cb981611033565b94506020860135610cc981611033565b9350604086013592506060860135610ce081611033565b91506080860135610cf081611033565b809150509295509295909350565b600060208284031215610d0f578081fd5b81518015158114610bc4578182fd5b600060208284031215610d2f578081fd5b5051919050565b60008251610d48818460208701611007565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b0396871681529486166020860152604085019390935290841660608401528316608083015290911660a082015260c00190565b6001600160a01b03929092168252602082015260400190565b6000602082528251806020840152610e37816040850160208701611007565b601f01601f19169190910160400192915050565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b90815260200190565b60005b8381101561102257818101518382015260200161100a565b838111156103e95750506000910152565b6001600160a01b038116811461104857600080fd5b5056fea2646970667358221220260383f23709db660967a522664682b39439430262c686f1ff999462e44f3aff64736f6c634300060c0033608060405234801561001057600080fd5b506001600055612798806100256000396000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c8063533f852e116100c3578063ae9704cd1161007c578063ae9704cd146102f6578063bc197c8114610309578063dae9e3791461031c578063e3043ee814610324578063f23a6e6114610337578063ff9935cb1461034a57610158565b8063533f852e1461027557806370d2e5cd14610288578063784483491461029b5780638aee8127146102bb5780638da5cb5b146102ce578063a0edb48b146102e357610158565b8063352685bc11610115578063352685bc146101f65780634025feb21461020957806346c65f621461021c578063494b01001461022f57806350d0c63c14610242578063522f68151461026257610158565b806301ffc9a71461015d57806314e5f66814610186578063150b7a021461019b5780631593dee1146101bb5780631e9b12ef146101d05780631f5b149f146101e3575b600080fd5b61017061016b3660046120c8565b61035d565b60405161017d91906122fc565b60405180910390f35b61018e6103b7565b60405161017d919061268b565b6101ae6101a9366004611ecd565b6103f0565b60405161017d9190612307565b6101ce6101c9366004611cea565b610401565b005b6101ce6101de366004611cb2565b610444565b6101ce6101f1366004611cb2565b610490565b6101ce610204366004612147565b6104dc565b6101ce610217366004611cea565b610580565b6101ce61022a366004612012565b6105b5565b6101ce61023d366004611fb8565b61066f565b610255610250366004612074565b61089f565b60405161017d91906126ba565b6101ce610270366004611d6f565b610a9a565b610255610283366004611d6f565b610ad2565b6101ce610296366004612147565b610b04565b6102ae6102a9366004612147565b610b33565b60405161017d919061265c565b6101ce6102c9366004611cb2565b610c16565b6102d6610c62565b60405161017d9190612250565b6101ce6102f1366004611d2a565b610c71565b6101ce610304366004611cb2565b610cad565b6101ae610317366004611d9a565b610cf9565b610255610d07565b610255610332366004612177565b610d16565b6101ae610345366004611f3e565b610d22565b6101ce610358366004611e55565b610d34565b60006001600160e01b03198216630a85bd0160e11b148061038e57506001600160e01b03198216630271189760e51b145b806103a957506001600160e01b031982166301ffc9a760e01b145b156103b2575060015b919050565b6103bf611ac6565b50604080516060810182526004546001600160a01b0390811682526005541660208201526006549181019190915290565b630a85bd0160e11b95945050505050565b6001546001600160a01b031633146104345760405162461bcd60e51b815260040161042b906123cd565b60405180910390fd5b61043f838383610dbf565b505050565b6001546001600160a01b0316331461046e5760405162461bcd60e51b815260040161042b906123cd565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633146104ba5760405162461bcd60e51b815260040161042b906123cd565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633146105065760405162461bcd60e51b815260040161042b906123cd565b6005546001600160a01b031661052e5760405162461bcd60e51b815260040161042b90612514565b600554610546906001600160a01b0316333084610ecc565b7fcbd64454da4b3587b11b8f8170d7656cbe58e29ee18fd715b0e79ad85edb6e5d8160405161057591906126ba565b60405180910390a150565b6001546001600160a01b031633146105aa5760405162461bcd60e51b815260040161042b906123cd565b61043f838383610f24565b6002546001600160a01b031633146105df5760405162461bcd60e51b815260040161042b906124f2565b60006105f46001600160a01b0387168661107f565b600081815260076020526040902080549192509061061f5743815561061d600282018686611ae6565b505b866001600160a01b03167f30d53e48465c48642e346a636a4eef45c72095b65bef5825308376e2f59f09e28787878760405161065e94939291906126c3565b60405180910390a250505050505050565b6001546001600160a01b031633146106995760405162461bcd60e51b815260040161042b906123cd565b60006106ae6001600160a01b0386168561107f565b6003546040516334b7328d60e01b81529192506000916001600160a01b03909116906334b7328d906106e6908790879060040161231c565b60206040518083038186803b1580156106fe57600080fd5b505afa158015610712573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107369190611cce565b60048054604051632da9ef8160e01b81529293506000926001600160a01b0380861693632da9ef8193610770938d938d93921691016122d9565b602060405180830381600087803b15801561078a57600080fd5b505af115801561079e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107c2919061215f565b905080156108965760405180606001604052804381526020016000815260200186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093909452505085815260076020908152604091829020845181558482015160018201559184015180519293506108539260028501929190910190611b64565b50905050866001600160a01b03167fdd1b8616b3983aa94529955a2f7d0dd75e5a93e53875372ea41a9eab5e3ef3268787878560405161065e94939291906126c3565b50505050505050565b6002546000906001600160a01b031633146108cc5760405162461bcd60e51b815260040161042b906124f2565b6108d46110b3565b60006108e96001600160a01b0386168561107f565b600081815260076020526040812091925061090483866110dd565b6001830154909150610916908261110b565b60018301556003546040516334b7328d60e01b81526000916001600160a01b0316906334b7328d9061094f906002870190600401612343565b60206040518083038186803b15801561096757600080fd5b505afa15801561097b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099f9190611cce565b60048054604051632da9ef8160e01b81529293506000926001600160a01b0380861693632da9ef81936109d9938f938f93921691016122d9565b602060405180830381600087803b1580156109f357600080fd5b505af1158015610a07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2b919061215f565b905080610a3757600084555b610a418989611130565b9550886001600160a01b03167f8abeaea5da22bf1966530d4f970ac7c71ae0999eb1d2181afaeff8b56c394f3f8989604051610a7e9291906126ee565b60405180910390a25050505050610a936112c0565b9392505050565b6001546001600160a01b03163314610ac45760405162461bcd60e51b815260040161042b906123cd565b610ace82826112c7565b5050565b600080610ae86001600160a01b0385168461107f565b6000908152600760205260409020600101549150505b92915050565b6001546001600160a01b03163314610b2e5760405162461bcd60e51b815260040161042b906123cd565b600655565b610b3b611bd2565b600760008381526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610c065780601f10610bdb57610100808354040283529160200191610c06565b820191906000526020600020905b815481529060010190602001808311610be957829003601f168201915b5050505050815250509050919050565b6001546001600160a01b03163314610c405760405162461bcd60e51b815260040161042b906123cd565b600580546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031690565b6001546001600160a01b03163314610c9b5760405162461bcd60e51b815260040161042b906123cd565b610ca78484848461134b565b50505050565b6001546001600160a01b03163314610cd75760405162461bcd60e51b815260040161042b906123cd565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b600098975050505050505050565b6000610d116114aa565b905090565b6000610a9383836110dd565b63bc197c8160e01b9695505050505050565b6001546001600160a01b031615610d5d5760405162461bcd60e51b815260040161042b906125ae565b600180546001600160a01b03199081166001600160a01b03938416179091556004805482169783169790971790965560058054871695821695909517909455600692909255600380548516918416919091179055600280549093169116179055565b6001600160a01b038316610de55760405162461bcd60e51b815260040161042b90612404565b6040516370a0823160e01b815281906001600160a01b038416906370a0823190610e13903090600401612250565b60206040518083038186803b158015610e2b57600080fd5b505afa158015610e3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e63919061215f565b1061043f57610e7c6001600160a01b038316848361152b565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b83604051610ebf91906126ba565b60405180910390a3505050565b610ca7846323b872dd60e01b858585604051602401610eed93929190612264565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261154a565b6001600160a01b038316610f4a5760405162461bcd60e51b815260040161042b90612404565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e90610f789085906004016126ba565b60206040518083038186803b158015610f9057600080fd5b505afa158015610fa4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc89190611cce565b6001600160a01b0316141561043f576040516323b872dd60e01b81526001600160a01b038316906323b872dd9061100790309087908690600401612264565b600060405180830381600087803b15801561102157600080fd5b505af1158015611035573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6000828260405160200161109492919061220f565b60408051601f1981840301815291905280516020909101209392505050565b600260005414156110d65760405162461bcd60e51b815260040161042b90612625565b6002600055565b6000806110e9836115d9565b905060006110f785836115ff565b905061110281611797565b95945050505050565b600082820183811015610a935760405162461bcd60e51b815260040161042b90612427565b6000806111466001600160a01b0385168461107f565b60008181526007602052604080822090516331a9108f60e11b8152929350916001600160a01b03871690636352211e906111849088906004016126ba565b60206040518083038186803b15801561119c57600080fd5b505afa1580156111b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d49190611cce565b90508160010154935060006111e76114aa565b905060008186116111f9576000611203565b6112038683611828565b90508015611242576112158682611828565b6040519096507f9fc735fd421d3eb45362ea6d0d94945975bce33842b1bc94840719e66d937e4790600090a15b60018401819055851561126657600554611266906001600160a01b0316848861152b565b826001600160a01b0316886001600160a01b03167fb918e5bcd5ce5aadd59ae96fe4c568669afc7af190dbf16061540816cb407c738989856040516112ad939291906126fc565b60405180910390a3505050505092915050565b6001600055565b6001600160a01b0382166112ed5760405162461bcd60e51b815260040161042b90612404565b804710610ace576113076001600160a01b0383168261186a565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd8260405161133f91906126ba565b60405180910390a25050565b6001600160a01b0384166113715760405162461bcd60e51b815260040161042b90612404565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e9061139f90309087906004016122c0565b60206040518083038186803b1580156113b757600080fd5b505afa1580156113cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ef919061215f565b10610ca757604051637921219560e11b81526001600160a01b0384169063f242432a90611426903090889087908790600401612288565b600060405180830381600087803b15801561144057600080fd5b505af1158015611454573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b8460405161149c91906126ba565b60405180910390a450505050565b6005546040516370a0823160e01b81526000916001600160a01b0316906370a08231906114db903090600401612250565b60206040518083038186803b1580156114f357600080fd5b505afa158015611507573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d11919061215f565b61043f8363a9059cbb60e01b8484604051602401610eed9291906122c0565b606061159f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166119069092919063ffffffff16565b80519091501561043f57808060200190518101906115bd91906120a8565b61043f5760405162461bcd60e51b815260040161042b906125db565b6000610afe6127106115f96004600201548561191d90919063ffffffff16565b90611957565b6000828152600760205260408120805461161c5782915050610afe565b611624611bf3565b60025460405163836c478d60e01b81526001600160a01b039091169063836c478d906116549088906004016126ba565b60606040518083038186803b15801561166c57600080fd5b505afa158015611680573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a491906120f0565b80518354919250906000906116ba904390611828565b9050600080846040015111156116e457602084015160408501516116dd91611828565b90506116f7565b60208401516116f4904390611828565b90505b821580611702575080155b8061170b575081155b1561171d578695505050505050610afe565b818111156117285750805b600061173a836115f98461271061191d565b9050600061174e6127106115f98b8561191d565b9050600061176d6127106115f961176689606461191d565b859061191d565b9050600061177b8b84611828565b9050611787818361110b565b9c9b505050505050505050505050565b600480546040805163313ce56760e01b8152905160009384936001600160a01b03169263313ce5679281830192602092829003018186803b1580156117db57600080fd5b505afa1580156117ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118139190612198565b9050610a938360ff8316601203600a0a61191d565b6000610a9383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611999565b8047101561188a5760405162461bcd60e51b815260040161042b906124bb565b6000826001600160a01b0316826040516118a39061224d565b60006040518083038185875af1925050503d80600081146118e0576040519150601f19603f3d011682016040523d82523d6000602084013e6118e5565b606091505b505090508061043f5760405162461bcd60e51b815260040161042b9061245e565b606061191584846000856119c5565b949350505050565b60008261192c57506000610afe565b8282028284828161193957fe5b0414610a935760405162461bcd60e51b815260040161042b90612536565b6000610a9383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611a89565b600081848411156119bd5760405162461bcd60e51b815260040161042b9190612330565b505050900390565b60606119d085611ac0565b6119ec5760405162461bcd60e51b815260040161042b90612577565b60006060866001600160a01b03168587604051611a099190612231565b60006040518083038185875af1925050503d8060008114611a46576040519150601f19603f3d011682016040523d82523d6000602084013e611a4b565b606091505b50915091508115611a5f5791506119159050565b805115611a6f5780518082602001fd5b8360405162461bcd60e51b815260040161042b9190612330565b60008183611aaa5760405162461bcd60e51b815260040161042b9190612330565b506000838581611ab657fe5b0495945050505050565b3b151590565b604080516060810182526000808252602082018190529181019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611b275782800160ff19823516178555611b54565b82800160010185558215611b54579182015b82811115611b54578235825591602001919060010190611b39565b50611b60929150611c14565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611ba557805160ff1916838001178555611b54565b82800160010185558215611b54579182015b82811115611b54578251825591602001919060010190611bb7565b60405180606001604052806000815260200160008152602001606081525090565b60405180606001604052806000815260200160008152602001600081525090565b5b80821115611b605760008155600101611c15565b60008083601f840112611c3a578182fd5b50813567ffffffffffffffff811115611c51578182fd5b6020830191508360208083028501011115611c6b57600080fd5b9250929050565b60008083601f840112611c83578182fd5b50813567ffffffffffffffff811115611c9a578182fd5b602083019150836020828501011115611c6b57600080fd5b600060208284031215611cc3578081fd5b8135610a938161274a565b600060208284031215611cdf578081fd5b8151610a938161274a565b600080600060608486031215611cfe578182fd5b8335611d098161274a565b92506020840135611d198161274a565b929592945050506040919091013590565b60008060008060808587031215611d3f578081fd5b8435611d4a8161274a565b93506020850135611d5a8161274a565b93969395505050506040820135916060013590565b60008060408385031215611d81578182fd5b8235611d8c8161274a565b946020939093013593505050565b60008060008060008060008060a0898b031215611db5578384fd5b8835611dc08161274a565b97506020890135611dd08161274a565b9650604089013567ffffffffffffffff80821115611dec578586fd5b611df88c838d01611c29565b909850965060608b0135915080821115611e10578586fd5b611e1c8c838d01611c29565b909650945060808b0135915080821115611e34578384fd5b50611e418b828c01611c72565b999c989b5096995094979396929594505050565b60008060008060008060c08789031215611e6d578182fd5b8635611e788161274a565b95506020870135611e888161274a565b9450604087013593506060870135611e9f8161274a565b92506080870135611eaf8161274a565b915060a0870135611ebf8161274a565b809150509295509295509295565b600080600080600060808688031215611ee4578081fd5b8535611eef8161274a565b94506020860135611eff8161274a565b935060408601359250606086013567ffffffffffffffff811115611f21578182fd5b611f2d88828901611c72565b969995985093965092949392505050565b60008060008060008060a08789031215611f56578384fd5b8635611f618161274a565b95506020870135611f718161274a565b94506040870135935060608701359250608087013567ffffffffffffffff811115611f9a578283fd5b611fa689828a01611c72565b979a9699509497509295939492505050565b60008060008060608587031215611fcd578182fd5b8435611fd88161274a565b935060208501359250604085013567ffffffffffffffff811115611ffa578283fd5b61200687828801611c72565b95989497509550505050565b600080600080600060808688031215612029578283fd5b85356120348161274a565b945060208601359350604086013567ffffffffffffffff811115612056578384fd5b61206288828901611c72565b96999598509660600135949350505050565b600080600060608486031215612088578081fd5b83356120938161274a565b95602085013595506040909401359392505050565b6000602082840312156120b9578081fd5b81518015158114610a93578182fd5b6000602082840312156120d9578081fd5b81356001600160e01b031981168114610a93578182fd5b600060608284031215612101578081fd5b6040516060810181811067ffffffffffffffff82111715612120578283fd5b80604052508251815260208301516020820152604083015160408201528091505092915050565b600060208284031215612158578081fd5b5035919050565b600060208284031215612170578081fd5b5051919050565b60008060408385031215612189578182fd5b50508035926020909101359150565b6000602082840312156121a9578081fd5b815160ff81168114610a93578182fd5b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526121fb81602086016020860161271e565b601f01601f19169290920160200192915050565b60609290921b6bffffffffffffffffffffffff19168252601482015260340190565b6000825161224381846020870161271e565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b901515815260200190565b6001600160e01b031991909116815260200190565b6000602082526119156020830184866121b9565b600060208252610a9360208301846121e3565b6000602080830181845282855460018082166000811461236a5760018114612388576123c0565b60028304607f16855260ff19831660408901526060880193506123c0565b600283048086526123988a612712565b885b828110156123b65781548b82016040015290840190880161239a565b8a01604001955050505b5091979650505050505050565b60208082526017908201527f43616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252600890820152670a4a0748a5a6260760c31b604082015260600190565b60208082526008908201526752503a452d34303560c01b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b602080825260139082015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6000602082528251602083015260208301516040830152604083015160608084015261191560808401826121e3565b81516001600160a01b039081168252602080840151909116908201526040918201519181019190915260600190565b90815260200190565b6000858252606060208301526126dd6060830185876121b9565b905082604083015295945050505050565b918252602082015260400190565b9283526020830191909152604082015260600190565b60009081526020902090565b60005b83811015612739578181015183820152602001612721565b83811115610ca75750506000910152565b6001600160a01b038116811461275f57600080fd5b5056fea264697066735822122089923bf05c0e88235caef82d9eb9c338dbdb5c9a300cc0b182773089e351721e64736f6c634300060c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100935760003560e01c80636fe6fabb116100665780636fe6fabb146100fc578063715018a6146101045780638da5cb5b1461010c578063a0edb48b14610114578063f2fde38b1461012757610093565b80631593dee1146100985780634025feb2146100ad578063522f6815146100c05780636f9d5f78146100d3575b600080fd5b6100ab6100a6366004610be7565b61013a565b005b6100ab6100bb366004610be7565b610188565b6100ab6100ce366004610c6c565b6101c8565b6100e66100e1366004610c97565b61020b565b6040516100f39190610d55565b60405180910390f35b6100e661030b565b6100ab61031a565b6100e6610399565b6100ab610122366004610c27565b6103a8565b6100ab610135366004610ba8565b6103ef565b6101426104a5565b6000546001600160a01b039081169116146101785760405162461bcd60e51b815260040161016f90610f48565b60405180910390fd5b6101838383836104a9565b505050565b6101906104a5565b6000546001600160a01b039081169116146101bd5760405162461bcd60e51b815260040161016f90610f48565b6101838383836105b6565b6101d06104a5565b6000546001600160a01b039081169116146101fd5760405162461bcd60e51b815260040161016f90610f48565b6102078282610711565b5050565b60006102156104a5565b6000546001600160a01b039081169116146102425760405162461bcd60e51b815260040161016f90610f48565b60015460009061025a906001600160a01b0316610795565b9050806001600160a01b03811663ff9935cb89898989896102796104a5565b6040518763ffffffff1660e01b815260040161029a96959493929190610dc5565b600060405180830381600087803b1580156102b457600080fd5b505af11580156102c8573d6000803e3d6000fd5b50506040516001600160a01b03851692507f6ecb2838bef4560681475e8bb5e7feccefe33df915df2d6757024bc6fe4c616a9150600090a2509695505050505050565b6001546001600160a01b031681565b6103226104a5565b6000546001600160a01b0390811691161461034f5760405162461bcd60e51b815260040161016f90610f48565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b6103b06104a5565b6000546001600160a01b039081169116146103dd5760405162461bcd60e51b815260040161016f90610f48565b6103e9848484846107e7565b50505050565b6103f76104a5565b6000546001600160a01b039081169116146104245760405162461bcd60e51b815260040161016f90610f48565b6001600160a01b03811661044a5760405162461bcd60e51b815260040161016f90610e4b565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b0383166104cf5760405162461bcd60e51b815260040161016f90610e91565b6040516370a0823160e01b815281906001600160a01b038416906370a08231906104fd903090600401610d55565b60206040518083038186803b15801561051557600080fd5b505afa158015610529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061054d9190610d1e565b10610183576105666001600160a01b0383168483610946565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b836040516105a99190610ffe565b60405180910390a3505050565b6001600160a01b0383166105dc5760405162461bcd60e51b815260040161016f90610e91565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e9061060a908590600401610ffe565b60206040518083038186803b15801561062257600080fd5b505afa158015610636573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065a9190610bcb565b6001600160a01b03161415610183576040516323b872dd60e01b81526001600160a01b038316906323b872dd9061069990309087908690600401610d69565b600060405180830381600087803b1580156106b357600080fd5b505af11580156106c7573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b0382166107375760405162461bcd60e51b815260040161016f90610e91565b804710610207576107516001600160a01b0383168261099c565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd826040516107899190610ffe565b60405180910390a25050565b6000808260601b9050604051733d602d80600a3d3981f3363d3d373d3d3d363d7360601b81528160148201526e5af43d82803e903d91602b57fd5bf360881b60288201526037816000f0949350505050565b6001600160a01b03841661080d5760405162461bcd60e51b815260040161016f90610e91565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e9061083b9030908790600401610dff565b60206040518083038186803b15801561085357600080fd5b505afa158015610867573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088b9190610d1e565b106103e957604051637921219560e11b81526001600160a01b0384169063f242432a906108c2903090889087908790600401610d8d565b600060405180830381600087803b1580156108dc57600080fd5b505af11580156108f0573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b846040516109389190610ffe565b60405180910390a450505050565b6101838363a9059cbb60e01b8484604051602401610965929190610dff565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610a38565b804710156109bc5760405162461bcd60e51b815260040161016f90610f11565b6000826001600160a01b0316826040516109d590610d52565b60006040518083038185875af1925050503d8060008114610a12576040519150601f19603f3d011682016040523d82523d6000602084013e610a17565b606091505b50509050806101835760405162461bcd60e51b815260040161016f90610eb4565b6060610a8d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316610ac79092919063ffffffff16565b8051909150156101835780806020019051810190610aab9190610cfe565b6101835760405162461bcd60e51b815260040161016f90610fb4565b6060610ad68484600085610ade565b949350505050565b6060610ae985610ba2565b610b055760405162461bcd60e51b815260040161016f90610f7d565b60006060866001600160a01b03168587604051610b229190610d36565b60006040518083038185875af1925050503d8060008114610b5f576040519150601f19603f3d011682016040523d82523d6000602084013e610b64565b606091505b50915091508115610b78579150610ad69050565b805115610b885780518082602001fd5b8360405162461bcd60e51b815260040161016f9190610e18565b3b151590565b600060208284031215610bb9578081fd5b8135610bc481611033565b9392505050565b600060208284031215610bdc578081fd5b8151610bc481611033565b600080600060608486031215610bfb578182fd5b8335610c0681611033565b92506020840135610c1681611033565b929592945050506040919091013590565b60008060008060808587031215610c3c578081fd5b8435610c4781611033565b93506020850135610c5781611033565b93969395505050506040820135916060013590565b60008060408385031215610c7e578182fd5b8235610c8981611033565b946020939093013593505050565b600080600080600060a08688031215610cae578081fd5b8535610cb981611033565b94506020860135610cc981611033565b9350604086013592506060860135610ce081611033565b91506080860135610cf081611033565b809150509295509295909350565b600060208284031215610d0f578081fd5b81518015158114610bc4578182fd5b600060208284031215610d2f578081fd5b5051919050565b60008251610d48818460208701611007565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b0396871681529486166020860152604085019390935290841660608401528316608083015290911660a082015260c00190565b6001600160a01b03929092168252602082015260400190565b6000602082528251806020840152610e37816040850160208701611007565b601f01601f19169190910160400192915050565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b90815260200190565b60005b8381101561102257818101518382015260200161100a565b838111156103e95750506000910152565b6001600160a01b038116811461104857600080fd5b5056fea2646970667358221220260383f23709db660967a522664682b39439430262c686f1ff999462e44f3aff64736f6c634300060c0033", + "devdoc": { + "kind": "dev", + "methods": { + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 4406, + "contract": "contracts/v1/incentives/RewardProgramFactory.sol:RewardProgramFactory", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 19454, + "contract": "contracts/v1/incentives/RewardProgramFactory.sol:RewardProgramFactory", + "label": "_template", + "offset": 0, + "slot": "1", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + } + } + } +} \ No newline at end of file diff --git a/deployments/polygon/RewardProgramUSDC.json b/deployments/polygon/RewardProgramUSDC.json new file mode 100644 index 0000000..51797be --- /dev/null +++ b/deployments/polygon/RewardProgramUSDC.json @@ -0,0 +1,814 @@ +{ + "address": "0xF695eB287Db7e91dE909f4a386a1AC68373F69D1", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "AssetDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "AssetRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "AssetRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardProgramFunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "RewardProgramOutOfFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewarded", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remaining", + "type": "uint256" + } + ], + "name": "RewardsClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "parentNftUuid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "calculateRewardsEarned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "fundProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "parentNftUuid", + "type": "uint256" + } + ], + "name": "getAssetStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimableRewards", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + } + ], + "internalType": "struct IRewardProgram.AssetStake", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getClaimableRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFundBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProgramData", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + } + ], + "internalType": "struct IRewardProgram.ProgramRewardData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + }, + { + "internalType": "address", + "name": "chargedManagers", + "type": "address" + }, + { + "internalType": "address", + "name": "universe", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "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": "nonpayable", + "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": "nonpayable", + "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": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "registerAssetDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "registerAssetRelease", + "outputs": [ + { + "internalType": "uint256", + "name": "rewards", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + } + ], + "name": "registerExistingDeposits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newMultiplier", + "type": "uint256" + } + ], + "name": "setBaseMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "setChargedManagers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newRewardToken", + "type": "address" + } + ], + "name": "setRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newStakingToken", + "type": "address" + } + ], + "name": "setStakingToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "universe", + "type": "address" + } + ], + "name": "setUniverse", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xafc3abf68defecc02244ad32f99fd1ba017a0786343f519b1dca5777e61a6dbe", + "numDeployments": 1 +} \ No newline at end of file diff --git a/deployments/polygon/RewardProgramUSDT.json b/deployments/polygon/RewardProgramUSDT.json new file mode 100644 index 0000000..c0579a2 --- /dev/null +++ b/deployments/polygon/RewardProgramUSDT.json @@ -0,0 +1,814 @@ +{ + "address": "0xA4e107c9523D6a17ACbC294d8B8A8A7a82B84b9e", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "AssetDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "AssetRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "AssetRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardProgramFunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "RewardProgramOutOfFunds", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewarded", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remaining", + "type": "uint256" + } + ], + "name": "RewardsClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "parentNftUuid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "calculateRewardsEarned", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "fundProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "parentNftUuid", + "type": "uint256" + } + ], + "name": "getAssetStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimableRewards", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + } + ], + "internalType": "struct IRewardProgram.AssetStake", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getClaimableRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFundBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProgramData", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + } + ], + "internalType": "struct IRewardProgram.ProgramRewardData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "stakingToken", + "type": "address" + }, + { + "internalType": "address", + "name": "rewardToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "baseMultiplier", + "type": "uint256" + }, + { + "internalType": "address", + "name": "chargedManagers", + "type": "address" + }, + { + "internalType": "address", + "name": "universe", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "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": "nonpayable", + "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": "nonpayable", + "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": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + } + ], + "name": "registerAssetDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interestAmount", + "type": "uint256" + } + ], + "name": "registerAssetRelease", + "outputs": [ + { + "internalType": "uint256", + "name": "rewards", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + } + ], + "name": "registerExistingDeposits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newMultiplier", + "type": "uint256" + } + ], + "name": "setBaseMultiplier", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "manager", + "type": "address" + } + ], + "name": "setChargedManagers", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newRewardToken", + "type": "address" + } + ], + "name": "setRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newStakingToken", + "type": "address" + } + ], + "name": "setStakingToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "universe", + "type": "address" + } + ], + "name": "setUniverse", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xf36f5d17f98417611d9a3bb3a262bb5892cc1bd6eed9a8810f84f8f073c06e8d", + "numDeployments": 1 +} \ No newline at end of file diff --git a/deployments/polygon/UniverseRP.json b/deployments/polygon/UniverseRP.json new file mode 100644 index 0000000..42596e9 --- /dev/null +++ b/deployments/polygon/UniverseRP.json @@ -0,0 +1,1192 @@ +{ + "address": "0x60d85948075c106b7605B2F549d0861e55608F19", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bosonToken", + "type": "address" + } + ], + "name": "BosonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "chargedParticles", + "type": "address" + } + ], + "name": "ChargedParticlesSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "photonSource", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "energy", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "ElectrostaticAttraction", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "photonSource", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "energy", + "type": "uint256" + } + ], + "name": "ElectrostaticDischarge", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "EsaMultiplierSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "leptonToken", + "type": "address" + } + ], + "name": "LeptonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + } + ], + "name": "NftDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + } + ], + "name": "NftRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "photonToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxSupply", + "type": "uint256" + } + ], + "name": "PhotonSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "protonToken", + "type": "address" + } + ], + "name": "ProtonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "quarkToken", + "type": "address" + } + ], + "name": "QuarkTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "RewardProgramRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardProgram", + "type": "address" + } + ], + "name": "RewardProgramSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [], + "name": "_chargedParticles", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_multiplierNft", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "uuid", + "type": "uint256" + } + ], + "name": "getNftStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositBlockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "releaseBlockNumber", + "type": "uint256" + } + ], + "internalType": "struct IUniverseRP.NftStake", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getRewardProgram", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nftTokenAmount", + "type": "uint256" + } + ], + "name": "onCovalentBond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nftTokenAmount", + "type": "uint256" + } + ], + "name": "onCovalentBreak", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creatorEnergy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onDischarge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onDischargeForCreator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assetAmount", + "type": "uint256" + } + ], + "name": "onEnergize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "newOwner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "salePrice", + "type": "uint256" + }, + { + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creatorRoyalties", + "type": "uint256" + } + ], + "name": "onProtonSale", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "creatorEnergy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onRelease", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "removeRewardProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "controller", + "type": "address" + } + ], + "name": "setChargedParticles", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + } + ], + "name": "setMultiplierNft", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "rewardProgam", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "setRewardProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x507c836b98c9c0f8a8e78c51fecb2c4bab8c0873ee6299e4276beca7c94bc695", + "receipt": { + "to": null, + "from": "0xb8D175F16742395F530e0b3bC1d30BD06B78CdA9", + "contractAddress": "0x60d85948075c106b7605B2F549d0861e55608F19", + "transactionIndex": 27, + "gasUsed": "769446", + "logsBloom": "0x00000000000000000000000000000000400000000000000000800000000000402000000000000000000000000000000000008000000000000000000000000000000080000000000100000000000002800001000000400000000100000000000000000000020000000000400000000800000000800000000080000000000000400000000000000000000000020000000000000000000000000000000000800000220000000000000000000000000000000000000004000000000000000000004000000020000000000001000000000000000000000400000000100000000020000000000000000000000000000000000000010000000000000000000002100000", + "blockHash": "0x9ce9e7f299ae68bd8a7cbb5707bd3c833b14e6f61eaa177257e35c285efff24d", + "transactionHash": "0x507c836b98c9c0f8a8e78c51fecb2c4bab8c0873ee6299e4276beca7c94bc695", + "logs": [ + { + "transactionIndex": 27, + "blockNumber": 46700950, + "transactionHash": "0x507c836b98c9c0f8a8e78c51fecb2c4bab8c0873ee6299e4276beca7c94bc695", + "address": "0x60d85948075c106b7605B2F549d0861e55608F19", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000001aa013d7a31557ae1a60578394a8acc785935d06" + ], + "data": "0x", + "logIndex": 131, + "blockHash": "0x9ce9e7f299ae68bd8a7cbb5707bd3c833b14e6f61eaa177257e35c285efff24d" + }, + { + "transactionIndex": 27, + "blockNumber": 46700950, + "transactionHash": "0x507c836b98c9c0f8a8e78c51fecb2c4bab8c0873ee6299e4276beca7c94bc695", + "address": "0x60d85948075c106b7605B2F549d0861e55608F19", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000b8d175f16742395f530e0b3bc1d30bd06b78cda9" + ], + "data": "0x", + "logIndex": 132, + "blockHash": "0x9ce9e7f299ae68bd8a7cbb5707bd3c833b14e6f61eaa177257e35c285efff24d" + }, + { + "transactionIndex": 27, + "blockNumber": 46700950, + "transactionHash": "0x507c836b98c9c0f8a8e78c51fecb2c4bab8c0873ee6299e4276beca7c94bc695", + "address": "0x60d85948075c106b7605B2F549d0861e55608F19", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fd6b09036bf046f2b32e1d7345833bf21db6733", + "logIndex": 133, + "blockHash": "0x9ce9e7f299ae68bd8a7cbb5707bd3c833b14e6f61eaa177257e35c285efff24d" + }, + { + "transactionIndex": 27, + "blockNumber": 46700950, + "transactionHash": "0x507c836b98c9c0f8a8e78c51fecb2c4bab8c0873ee6299e4276beca7c94bc695", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000b8d175f16742395f530e0b3bc1d30bd06b78cda9", + "0x0000000000000000000000007c7379531b2aee82e4ca06d4175d13b9cbeafd49" + ], + "data": "0x000000000000000000000000000000000000000000000000006b5f699062507c00000000000000000000000000000000000000000000001a320f02b4e531a2a0000000000000000000000000000000000000000000024af6263b5650da18070300000000000000000000000000000000000000000000001a31a3a34b54cf5224000000000000000000000000000000000000000000024af626a6b5ba6a7a577f", + "logIndex": 134, + "blockHash": "0x9ce9e7f299ae68bd8a7cbb5707bd3c833b14e6f61eaa177257e35c285efff24d" + } + ], + "blockNumber": 46700950, + "cumulativeGasUsed": "6150147", + "status": 1, + "byzantium": true + }, + "args": [ + "0x1aA013d7A31557Ae1A60578394a8ACC785935D06", + "0x0fD6B09036BF046f2B32E1D7345833bf21db6733", + "0x8129fc1c" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev 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\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "execute": { + "methodName": "initialize", + "args": [] + }, + "implementation": "0x1aA013d7A31557Ae1A60578394a8ACC785935D06", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/polygon/UniverseRPPolygon.json b/deployments/polygon/UniverseRPPolygon.json new file mode 100644 index 0000000..b609c0b --- /dev/null +++ b/deployments/polygon/UniverseRPPolygon.json @@ -0,0 +1,1192 @@ +{ + "address": "0xfAB2741B0d67D33c40144b3c4C4595ffFaBf36B3", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bosonToken", + "type": "address" + } + ], + "name": "BosonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "chargedParticles", + "type": "address" + } + ], + "name": "ChargedParticlesSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "photonSource", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "energy", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "ElectrostaticAttraction", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "photonSource", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "energy", + "type": "uint256" + } + ], + "name": "ElectrostaticDischarge", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "EsaMultiplierSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "leptonToken", + "type": "address" + } + ], + "name": "LeptonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + } + ], + "name": "NftDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + } + ], + "name": "NftRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "photonToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxSupply", + "type": "uint256" + } + ], + "name": "PhotonSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "protonToken", + "type": "address" + } + ], + "name": "ProtonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "quarkToken", + "type": "address" + } + ], + "name": "QuarkTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "RewardProgramRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardProgram", + "type": "address" + } + ], + "name": "RewardProgramSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [], + "name": "_chargedParticles", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_multiplierNft", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "uuid", + "type": "uint256" + } + ], + "name": "getNftStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositBlockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "releaseBlockNumber", + "type": "uint256" + } + ], + "internalType": "struct IUniverseRP.NftStake", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getRewardProgram", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nftTokenAmount", + "type": "uint256" + } + ], + "name": "onCovalentBond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nftTokenAmount", + "type": "uint256" + } + ], + "name": "onCovalentBreak", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creatorEnergy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onDischarge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onDischargeForCreator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assetAmount", + "type": "uint256" + } + ], + "name": "onEnergize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "newOwner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "salePrice", + "type": "uint256" + }, + { + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creatorRoyalties", + "type": "uint256" + } + ], + "name": "onProtonSale", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "creatorEnergy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onRelease", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "removeRewardProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "controller", + "type": "address" + } + ], + "name": "setChargedParticles", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + } + ], + "name": "setMultiplierNft", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "rewardProgam", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "setRewardProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x459eb009a26ea58f8ae567da7e9a05a55f89865d4e373af77762946e55cc9a4f", + "receipt": { + "to": null, + "from": "0xb8D175F16742395F530e0b3bC1d30BD06B78CdA9", + "contractAddress": "0xfAB2741B0d67D33c40144b3c4C4595ffFaBf36B3", + "transactionIndex": 49, + "gasUsed": "769446", + "logsBloom": "0x00000000000000000000000000000000400000000000000000800000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000002800001000000000000000100000000000000000000020000008000000000000800000000800100000880000000000000400000004000000000000000020000000000000000000000000000000000800000220000000000000000000000000000000000000000000000000020000000004000000020000000000021008000000000000000000400000000100000000020000010000000000000000000000000000000010000000000000000000002100000", + "blockHash": "0x8ef406b6cb85deca5e2a7314528655a676d135d765625c2b7b3a1056a43c19bc", + "transactionHash": "0x459eb009a26ea58f8ae567da7e9a05a55f89865d4e373af77762946e55cc9a4f", + "logs": [ + { + "transactionIndex": 49, + "blockNumber": 47456748, + "transactionHash": "0x459eb009a26ea58f8ae567da7e9a05a55f89865d4e373af77762946e55cc9a4f", + "address": "0xfAB2741B0d67D33c40144b3c4C4595ffFaBf36B3", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000003e2c421af4e595548fac0a6e5c06e933f7c2f037" + ], + "data": "0x", + "logIndex": 724, + "blockHash": "0x8ef406b6cb85deca5e2a7314528655a676d135d765625c2b7b3a1056a43c19bc" + }, + { + "transactionIndex": 49, + "blockNumber": 47456748, + "transactionHash": "0x459eb009a26ea58f8ae567da7e9a05a55f89865d4e373af77762946e55cc9a4f", + "address": "0xfAB2741B0d67D33c40144b3c4C4595ffFaBf36B3", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000b8d175f16742395f530e0b3bc1d30bd06b78cda9" + ], + "data": "0x", + "logIndex": 725, + "blockHash": "0x8ef406b6cb85deca5e2a7314528655a676d135d765625c2b7b3a1056a43c19bc" + }, + { + "transactionIndex": 49, + "blockNumber": 47456748, + "transactionHash": "0x459eb009a26ea58f8ae567da7e9a05a55f89865d4e373af77762946e55cc9a4f", + "address": "0xfAB2741B0d67D33c40144b3c4C4595ffFaBf36B3", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fd6b09036bf046f2b32e1d7345833bf21db6733", + "logIndex": 726, + "blockHash": "0x8ef406b6cb85deca5e2a7314528655a676d135d765625c2b7b3a1056a43c19bc" + }, + { + "transactionIndex": 49, + "blockNumber": 47456748, + "transactionHash": "0x459eb009a26ea58f8ae567da7e9a05a55f89865d4e373af77762946e55cc9a4f", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000b8d175f16742395f530e0b3bc1d30bd06b78cda9", + "0x000000000000000000000000eedba2484aaf940f37cd3cd21a5d7c4a7dafbfc0" + ], + "data": "0x000000000000000000000000000000000000000000000000008921816c321f1c0000000000000000000000000000000000000000000000191d0875d43b883c73000000000000000000000000000000000000000000009e2a768cb08e1d84d3af0000000000000000000000000000000000000000000000191c7f5452cf561d57000000000000000000000000000000000000000000009e2a7715d20f89b6f2cb", + "logIndex": 727, + "blockHash": "0x8ef406b6cb85deca5e2a7314528655a676d135d765625c2b7b3a1056a43c19bc" + } + ], + "blockNumber": 47456748, + "cumulativeGasUsed": "11194786", + "status": 1, + "byzantium": true + }, + "args": [ + "0x3E2c421Af4e595548fAC0A6E5c06E933F7C2f037", + "0x0fD6B09036BF046f2B32E1D7345833bf21db6733", + "0x8129fc1c" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev 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\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "execute": { + "methodName": "initialize", + "args": [] + }, + "implementation": "0x3E2c421Af4e595548fAC0A6E5c06E933F7C2f037", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/polygon/UniverseRPPolygon_Implementation.json b/deployments/polygon/UniverseRPPolygon_Implementation.json new file mode 100644 index 0000000..052ef0a --- /dev/null +++ b/deployments/polygon/UniverseRPPolygon_Implementation.json @@ -0,0 +1,1209 @@ +{ + "address": "0x3E2c421Af4e595548fAC0A6E5c06E933F7C2f037", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bosonToken", + "type": "address" + } + ], + "name": "BosonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "chargedParticles", + "type": "address" + } + ], + "name": "ChargedParticlesSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "photonSource", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "energy", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "ElectrostaticAttraction", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "photonSource", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "energy", + "type": "uint256" + } + ], + "name": "ElectrostaticDischarge", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "EsaMultiplierSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "leptonToken", + "type": "address" + } + ], + "name": "LeptonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + } + ], + "name": "NftDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + } + ], + "name": "NftRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "photonToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxSupply", + "type": "uint256" + } + ], + "name": "PhotonSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "protonToken", + "type": "address" + } + ], + "name": "ProtonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "quarkToken", + "type": "address" + } + ], + "name": "QuarkTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "RewardProgramRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardProgram", + "type": "address" + } + ], + "name": "RewardProgramSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [], + "name": "_chargedParticles", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_multiplierNft", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "uuid", + "type": "uint256" + } + ], + "name": "getNftStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositBlockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "releaseBlockNumber", + "type": "uint256" + } + ], + "internalType": "struct IUniverseRP.NftStake", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getRewardProgram", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nftTokenAmount", + "type": "uint256" + } + ], + "name": "onCovalentBond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nftTokenAmount", + "type": "uint256" + } + ], + "name": "onCovalentBreak", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creatorEnergy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onDischarge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onDischargeForCreator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assetAmount", + "type": "uint256" + } + ], + "name": "onEnergize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "newOwner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "salePrice", + "type": "uint256" + }, + { + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creatorRoyalties", + "type": "uint256" + } + ], + "name": "onProtonSale", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "creatorEnergy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onRelease", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "removeRewardProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "controller", + "type": "address" + } + ], + "name": "setChargedParticles", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + } + ], + "name": "setMultiplierNft", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "rewardProgam", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "setRewardProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xf168b4e84600613460ea6cc36e8811cfe29c48a6e3f5e45cd3bc84836b6f10fc", + "receipt": { + "to": null, + "from": "0xb8D175F16742395F530e0b3bC1d30BD06B78CdA9", + "contractAddress": "0x3E2c421Af4e595548fAC0A6E5c06E933F7C2f037", + "transactionIndex": 29, + "gasUsed": "2206721", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000000000000000100000080000000000000000000004000000000000000020000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000020000000004000000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000000010000000000000000000002100000", + "blockHash": "0x10d227922b8ad7bae91c3e64e0e771d6cf28ebdb39a2cfa6dc2b40f3adbb211e", + "transactionHash": "0xf168b4e84600613460ea6cc36e8811cfe29c48a6e3f5e45cd3bc84836b6f10fc", + "logs": [ + { + "transactionIndex": 29, + "blockNumber": 47456745, + "transactionHash": "0xf168b4e84600613460ea6cc36e8811cfe29c48a6e3f5e45cd3bc84836b6f10fc", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000b8d175f16742395f530e0b3bc1d30bd06b78cda9", + "0x000000000000000000000000eedba2484aaf940f37cd3cd21a5d7c4a7dafbfc0" + ], + "data": "0x0000000000000000000000000000000000000000000000000183423e73f281e100000000000000000000000000000000000000000000001921a06ffcda0a9873000000000000000000000000000000000000000000009e2a4871c793870ec3d5000000000000000000000000000000000000000000000019201d2dbe66181692000000000000000000000000000000000000000000009e2a49f509d1fb0145b6", + "logIndex": 123, + "blockHash": "0x10d227922b8ad7bae91c3e64e0e771d6cf28ebdb39a2cfa6dc2b40f3adbb211e" + } + ], + "blockNumber": 47456745, + "cumulativeGasUsed": "7298296", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "3690d415d9dd47a6d97f03bb58afbf9e", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bosonToken\",\"type\":\"address\"}],\"name\":\"BosonTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"chargedParticles\",\"type\":\"address\"}],\"name\":\"ChargedParticlesSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"photonSource\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"energy\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"multiplier\",\"type\":\"uint256\"}],\"name\":\"ElectrostaticAttraction\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"photonSource\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"energy\",\"type\":\"uint256\"}],\"name\":\"ElectrostaticDischarge\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"multiplier\",\"type\":\"uint256\"}],\"name\":\"EsaMultiplierSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"leptonToken\",\"type\":\"address\"}],\"name\":\"LeptonTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"}],\"name\":\"NftDeposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"}],\"name\":\"NftRelease\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"photonToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxSupply\",\"type\":\"uint256\"}],\"name\":\"PhotonSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"protonToken\",\"type\":\"address\"}],\"name\":\"ProtonTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"quarkToken\",\"type\":\"address\"}],\"name\":\"QuarkTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"RewardProgramRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"rewardProgram\",\"type\":\"address\"}],\"name\":\"RewardProgramSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC1155\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckEther\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"_chargedParticles\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"_multiplierNft\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"uuid\",\"type\":\"uint256\"}],\"name\":\"getNftStake\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"multiplier\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"depositBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"releaseBlockNumber\",\"type\":\"uint256\"}],\"internalType\":\"struct IUniverseRP.NftStake\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"getRewardProgram\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"onCovalentBond\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"onCovalentBreak\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"creatorEnergy\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverEnergy\",\"type\":\"uint256\"}],\"name\":\"onDischarge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"receiverEnergy\",\"type\":\"uint256\"}],\"name\":\"onDischargeForCreator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"}],\"name\":\"onEnergize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"salePrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"creatorRoyalties\",\"type\":\"uint256\"}],\"name\":\"onProtonSale\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"principalAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creatorEnergy\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverEnergy\",\"type\":\"uint256\"}],\"name\":\"onRelease\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"removeRewardProgram\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"controller\",\"type\":\"address\"}],\"name\":\"setChargedParticles\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"}],\"name\":\"setMultiplierNft\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rewardProgam\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"setRewardProgram\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC1155\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawErc20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawEther\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Upgradeable Contract\",\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Charged Particles Universe Contract with Rewards Program\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/v1/UniveserRPPolygon.sol\":\"UniverseRPPolygon\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/Initializable.sol\\\";\\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 initializer {\\n __Context_init_unchained();\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal initializer {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), 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 emit OwnershipTransferred(_owner, address(0));\\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xb419e68addcb82ecda3ad3974b0d2db76435ce9b08435a04d5b119a0c5d45ea5\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <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\",\"keccak256\":\"0x4784c3f8a520a739dd25d76f514833a653990902d0e21601aed45bda44c87524\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMathUpgradeable {\\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 uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\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 if (b > a) return (false, 0);\\n return (true, a - b);\\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 // 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 * @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 if (b == 0) return (false, 0);\\n return (true, a / b);\\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 if (b == 0) return (false, 0);\\n return (true, a % b);\\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 uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\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 require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\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 if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\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. 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(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\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 require(b > 0, \\\"SafeMath: modulo by zero\\\");\\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x0dd1e9b19801e3e7d900fbf4182d81e1afd23ad7be39504e33df6bbcba91d724\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// solhint-disable-next-line compiler-version\\npragma solidity >=0.4.24 <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 {UpgradeableProxy-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 */\\nabstract contract Initializable {\\n\\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 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 /// @dev Returns true if and only if the function is running in the constructor\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0xd8e4eb08dcc1d1860fb347ba5ffd595242b9a1b66d49a47f2b4cb51c3f35017e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0xa1931c47a617014f858580db625aa0dcf343796f39acd4b5b51effc092a1f0a9\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"../../math/SafeMathUpgradeable.sol\\\";\\nimport \\\"../../utils/AddressUpgradeable.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 SafeERC20Upgradeable {\\n using SafeMathUpgradeable for uint256;\\n using AddressUpgradeable for address;\\n\\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) 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(IERC20Upgradeable token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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(IERC20Upgradeable 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) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x8457e15aa90badabe0d6ef6f572f1ebd47bebf156921c825ae6e009dda15b706\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.2 <0.8.0;\\n\\nimport \\\"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x3dab19bb4a63bcbda1ee153ca291694f92f9009fad28626126b15a8503b0e5ff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.2 <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 // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) 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 // solhint-disable-next-line avoid-low-level-calls\\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(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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 // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfc5ea91fa9ceb1961023b2a6c978b902888c52b90847ac7813fe3b79524165f6\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\nimport \\\"../proxy/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 GSN 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 initializer {\\n __Context_init_unchained();\\n }\\n\\n function __Context_init_unchained() internal initializer {\\n }\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xbbf8a21b9a66c48d45ff771b8563c6df19ba451d63dfb8380a865c1e1f29d1a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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\",\"keccak256\":\"0xfa152b6e88a1dc50780e8f1580426dc23ad2e1e2c2f086a088adf206a202f453\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\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 uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\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 sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\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 * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\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 // 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) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts 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 mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9a9cf02622cd7a64261b10534fc3260449da25c98c9e96d1b4ae8110a20e5806\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x31691ad0817f8cb338531b78d2ab2989027d9f27e6f8e62492b754fed9429b10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0x5c26b39d26f7ed489e555d955dcd3e01872972e71fdd1528e93ec164e4f23385\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.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 SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf3b30f8a49631420635a8c35daacfcaa338012755f18a76fdd118730256f9a27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0xaf936da92f3a9a4f98b237323b5eb1d813fb86c4d07a184beba7027cf0509ba3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 in 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 // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n return _functionCallWithValue(target, data, value, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\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 // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf5fa8cbdffa5ef8be49b246b5628facc30b71707e78a45d80d93b64eff3fe390\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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.0.0, only sets of type `address` (`AddressSet`) and `uint256`\\n * (`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\\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\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] = toDeleteIndex + 1; // All indexes are 1-based\\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 require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\n return set._values[index];\\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(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(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(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(uint256(_at(set._inner, index)));\\n }\\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\",\"keccak256\":\"0xb2a11b236f073662f5a196995863f51c11d006bf7c3de158b316dfa1506c4b79\",\"license\":\"MIT\"},\"contracts/v1/UniveserRPPolygon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// Universe.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/EnumerableSet.sol\\\";\\n\\nimport \\\"./interfaces/IUniverseRP.sol\\\";\\nimport \\\"./interfaces/IChargedParticles.sol\\\";\\nimport \\\"./interfaces/ILepton.sol\\\";\\nimport \\\"./interfaces/IRewardNft.sol\\\";\\nimport \\\"./lib/TokenInfo.sol\\\";\\nimport \\\"./lib/BlackholePrevention.sol\\\";\\nimport \\\"./interfaces/IRewardProgram.sol\\\";\\n\\n/**\\n * @notice Charged Particles Universe Contract with Rewards Program\\n * @dev Upgradeable Contract\\n */\\ncontract UniverseRPPolygon is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\\n using SafeMathUpgradeable for uint256;\\n using TokenInfo for address;\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n using EnumerableSet for EnumerableSet.UintSet;\\n\\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\\n\\n // The ChargedParticles Contract Address\\n address public _chargedParticles;\\n\\n // The Lepton NFT Contract Address\\n address public _multiplierNft;\\n\\n // Asset Token => Reward Program\\n mapping (address => address) internal _assetRewardPrograms;\\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\\n\\n // Token UUID => NFT Staking Data\\n mapping (uint256 => NftStake) private _nftStake;\\n\\n\\n /***********************************|\\n | Initialization |\\n |__________________________________*/\\n\\n function initialize() public initializer {\\n __Ownable_init();\\n }\\n\\n function getRewardProgram(address asset) external view override returns (address) {\\n return _getRewardProgram(asset);\\n }\\n\\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\\n return _nftStake[uuid];\\n }\\n\\n /***********************************|\\n | Only Charged Particles |\\n |__________________________________*/\\n\\n function onEnergize(\\n address /* sender */,\\n address /* referrer */,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n address rewardProgram = _getRewardProgram(assetToken);\\n if (rewardProgram != address(0)) {\\n IRewardProgram(rewardProgram).registerAssetDeposit(\\n contractAddress,\\n tokenId,\\n walletManagerId,\\n assetAmount\\n );\\n }\\n }\\n\\n function onDischarge(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* walletManagerId */,\\n address assetToken,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n address rewardProgram = _getRewardProgram(assetToken);\\n if (rewardProgram != address(0)) {\\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\\n }\\n }\\n\\n function onDischargeForCreator(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* walletManagerId */,\\n address /* creator */,\\n address assetToken,\\n uint256 receiverEnergy\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n address rewardProgram = _getRewardProgram(assetToken);\\n if (rewardProgram != address(0)) {\\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\\n }\\n }\\n\\n function onRelease(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* walletManagerId */,\\n address assetToken,\\n uint256 principalAmount,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n address rewardProgram = _getRewardProgram(assetToken);\\n if (rewardProgram != address(0)) {\\n // \\\"receiverEnergy\\\" includes the \\\"principalAmount\\\"\\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\\n }\\n }\\n\\n function onCovalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* managerId */,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\\n }\\n\\n function onCovalentBreak(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* managerId */,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\\n }\\n\\n function onProtonSale(\\n address contractAddress,\\n uint256 tokenId,\\n address oldOwner,\\n address newOwner,\\n uint256 salePrice,\\n address creator,\\n uint256 creatorRoyalties\\n )\\n external\\n virtual\\n override\\n {\\n // no-op\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n |__________________________________*/\\n\\n function setChargedParticles(\\n address controller\\n )\\n external\\n onlyOwner\\n onlyValidContractAddress(controller)\\n {\\n _chargedParticles = controller;\\n emit ChargedParticlesSet(controller);\\n }\\n\\n function setMultiplierNft(address nftTokenAddress)\\n external\\n onlyOwner\\n onlyValidContractAddress(nftTokenAddress)\\n {\\n _multiplierNft = nftTokenAddress;\\n }\\n\\n function setRewardProgram(\\n address rewardProgam,\\n address assetToken\\n )\\n external\\n onlyOwner\\n onlyValidContractAddress(rewardProgam)\\n {\\n require(assetToken != address(0x0), \\\"UNI:E-403\\\");\\n _assetRewardPrograms[assetToken] = rewardProgam;\\n emit RewardProgramSet(assetToken, rewardProgam);\\n }\\n\\n function removeRewardProgram(address assetToken) external onlyOwner {\\n delete _assetRewardPrograms[assetToken];\\n emit RewardProgramRemoved(assetToken);\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n | (blackhole prevention) |\\n |__________________________________*/\\n\\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n\\n\\n /***********************************|\\n | Private Functions |\\n |__________________________________*/\\n\\n function _getRewardProgram(address assetToken) internal view returns (address) {\\n return _assetRewardPrograms[assetToken];\\n }\\n\\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\\n internal\\n {\\n // We only care about the Multiplier NFT\\n if (_multiplierNft != depositNftAddress) { return; }\\n\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n uint256 multiplier = _getNftMultiplier(depositNftTokenId);\\n\\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\\n // Add to Multipliers Set\\n _multiplierNftsSet[parentNftUuid].add(multiplier);\\n\\n // Update NFT Stake\\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\\n } else {\\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\\n }\\n }\\n\\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\\n }\\n\\n function _registerNftRelease(\\n address contractAddress,\\n uint256 tokenId,\\n address releaseNftAddress,\\n uint256 releaseNftTokenId,\\n uint256 /* nftTokenAmount */\\n )\\n internal\\n {\\n // We only care about the Multiplier NFT\\n if (_multiplierNft != releaseNftAddress) { return; }\\n\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n NftStake storage nftStake = _nftStake[parentNftUuid];\\n\\n // Remove from Multipliers Set\\n uint256 multiplier = _getNftMultiplier(releaseNftTokenId);\\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\\n\\n // Determine New Multiplier or Mark as Released\\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\\n } else {\\n nftStake.releaseBlockNumber = block.number;\\n }\\n\\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\\n }\\n\\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\\n uint256 multiplier = 0;\\n uint256 loss = 50;\\n uint256 i = 0;\\n\\n for (; i < len; i++) {\\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\\n }\\n if (len > 1) {\\n multiplier = multiplier.sub(loss.mul(len));\\n }\\n return multiplier;\\n }\\n\\n function _getNftMultiplier(uint256 tokenId) internal pure returns (uint256) {\\n if (tokenId >= 1 && tokenId <= 721) {\\n return 110;\\n } else if (tokenId > 721 && tokenId <= 1122) {\\n return 130;\\n } else if (tokenId > 1122 && tokenId <= 1423) {\\n return 150;\\n } else if (tokenId > 1423 && tokenId <= 1624) {\\n return 180;\\n } else if (tokenId > 1624 && tokenId <= 1712) {\\n return 230;\\n } else if (tokenId > 1712 && tokenId <= 1733) {\\n return 510;\\n } else {\\n return 1;\\n }\\n }\\n\\n\\n /***********************************|\\n | Modifiers |\\n |__________________________________*/\\n\\n /// @dev Throws if called by any non-account\\n modifier onlyValidContractAddress(address account) {\\n require(account != address(0x0) && account.isContract(), \\\"UNI:E-417\\\");\\n _;\\n }\\n\\n /// @dev Throws if called by any account other than the Charged Particles contract\\n modifier onlyChargedParticles() {\\n require(_chargedParticles == msg.sender, \\\"UNI:E-108\\\");\\n _;\\n }\\n}\\n\",\"keccak256\":\"0xf0b7955ab6f1b8c74bbed41d4d0474867c163108df7d5c851fdbf1afd6893b40\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IChargedParticles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @notice Interface for Charged Particles\\n */\\ninterface IChargedParticles {\\n\\n /***********************************|\\n | Public API |\\n |__________________________________*/\\n\\n function getStateAddress() external view returns (address stateAddress);\\n function getSettingsAddress() external view returns (address settingsAddress);\\n function getManagersAddress() external view returns (address managersAddress);\\n\\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\\n\\n /***********************************|\\n | Particle Mechanics |\\n |__________________________________*/\\n\\n function energizeParticle(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount,\\n address referrer\\n ) external returns (uint256 yieldTokensAmount);\\n\\n function dischargeParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function dischargeParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function dischargeParticleForCreator(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 receiverAmount);\\n\\n function releaseParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function releaseParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function covalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success);\\n\\n function breakCovalentBond(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success);\\n\\n /***********************************|\\n | Particle Events |\\n |__________________________________*/\\n\\n event Initialized(address indexed initiator);\\n event ControllerSet(address indexed controllerAddress, string controllerId);\\n event DepositFeeSet(uint256 depositFee);\\n event ProtocolFeesCollected(address indexed assetToken, uint256 depositAmount, uint256 feesCollected);\\n}\\n\",\"keccak256\":\"0x37104c629e40193ddc8677af8a632adf53754e7915f055a5a14861cd9b417729\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IERC721Chargeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IERC721Chargeable.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\\\";\\n\\ninterface IERC721Chargeable is IERC165Upgradeable {\\n function owner() external view returns (address);\\n function creatorOf(uint256 tokenId) external view returns (address);\\n function balanceOf(address tokenOwner) external view returns (uint256 balance);\\n function ownerOf(uint256 tokenId) external view returns (address tokenOwner);\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n function transferFrom(address from, address to, uint256 tokenId) external;\\n function approve(address to, uint256 tokenId) external;\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n function setApprovalForAll(address operator, bool _approved) external;\\n function isApprovedForAll(address tokenOwner, address operator) external view returns (bool);\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x459e57b2d35c7cd78e6c3d47eb9f3e981529a18c89e2c318b10fe369c479c737\",\"license\":\"MIT\"},\"contracts/v1/interfaces/ILepton.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// ILepton.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Charged Particles Lepton Interface\\n * @dev ...\\n */\\ninterface ILepton {\\n\\n struct Classification {\\n string tokenUri;\\n uint256 price;\\n uint128 _upperBounds;\\n uint32 supply;\\n uint32 multiplier;\\n uint32 bonus;\\n }\\n\\n function mintLepton() external payable returns (uint256 newTokenId);\\n function batchMintLepton(uint256 count) external payable;\\n function getNextType() external view returns (uint256);\\n function getNextPrice() external view returns (uint256);\\n function getMultiplier(uint256 tokenId) external view returns (uint256);\\n function getBonus(uint256 tokenId) external view returns (uint256);\\n\\n\\n event MaxMintPerTxSet(uint256 maxAmount);\\n event LeptonTypeAdded(string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\\n event LeptonTypeUpdated(uint256 leptonIndex, string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\\n event LeptonMinted(address indexed receiver, uint256 indexed tokenId, uint256 price, uint32 multiplier);\\n event LeptonBatchMinted(address indexed receiver, uint256 indexed tokenId, uint256 count, uint256 price, uint32 multiplier);\\n event PausedStateSet(bool isPaused);\\n}\\n\",\"keccak256\":\"0x4903085427fa5dbee690fe79854fba60afaf21189957406ade55f6fc12556a01\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IRewardNft.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IRewardNft.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Charged Particles Reward-NFT Interface\\n * @dev ...\\n */\\ninterface IRewardNft {\\n function getMultiplier(uint256 tokenId) external view returns (uint256);\\n function getBonus(uint256 tokenId) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x51a5666003af460a55356974a286dde959c5f166104c75b4d563e8294a90b07a\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IRewardProgram.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IRewardProgram.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\npragma experimental ABIEncoderV2;\\n\\ninterface IRewardProgram {\\n /* admin events */\\n event RewardProgramFunded(uint256 amount);\\n event RewardProgramOutOfFunds();\\n\\n /* user events */\\n event RewardsClaimed(address indexed contractAddress, uint256 tokenId, address indexed receiver, uint256 rewarded, uint256 remaining);\\n\\n event AssetRegistered(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\\n event AssetDeposit(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\\n event AssetRelease(address indexed contractAddress, uint256 tokenId, uint256 interestAmount);\\n\\n /* data types */\\n struct ProgramRewardData {\\n address stakingToken;\\n address rewardToken;\\n uint256 baseMultiplier; // Basis Points\\n }\\n\\n struct AssetStake {\\n uint256 start;\\n uint256 claimableRewards;\\n string walletManagerId;\\n }\\n\\n function initialize(address stakingToken, address rewardToken, uint256 baseMultiplier, address chargedManagers, address universe, address owner) external;\\n\\n /* user functions */\\n function getProgramData() external view returns (ProgramRewardData memory programData);\\n function getAssetStake(uint256 uuid) external view returns (AssetStake memory);\\n function getFundBalance() external view returns (uint256);\\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) external view returns (uint256);\\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view returns (uint256);\\n\\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external;\\n function registerAssetDeposit(address contractAddress, uint256 tokenId, string calldata walletManagerId, uint256 principalAmount) external;\\n function registerAssetRelease(address contractAddress, uint256 tokenId, uint256 interestAmount) external returns (uint256 rewards);\\n}\",\"keccak256\":\"0xe0f4076a4b001856c54cb8a63decedc81ca34c71708f8cbe9b3a26603dc9c050\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IUniverse.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IUniverse.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Universal Controller interface\\n * @dev ...\\n */\\ninterface IUniverse {\\n\\n event ChargedParticlesSet(address indexed chargedParticles);\\n event PhotonSet(address indexed photonToken, uint256 maxSupply);\\n event ProtonTokenSet(address indexed protonToken);\\n event LeptonTokenSet(address indexed leptonToken);\\n event QuarkTokenSet(address indexed quarkToken);\\n event BosonTokenSet(address indexed bosonToken);\\n event EsaMultiplierSet(address indexed assetToken, uint256 multiplier);\\n event ElectrostaticAttraction(address indexed account, address photonSource, uint256 energy, uint256 multiplier);\\n event ElectrostaticDischarge(address indexed account, address photonSource, uint256 energy);\\n\\n function onEnergize(\\n address sender,\\n address referrer,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 assetEnergy\\n ) external;\\n\\n function onDischarge(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onDischargeForCreator(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address creator,\\n address assetToken,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onRelease(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 principalEnergy,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onCovalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n\\n function onCovalentBreak(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n\\n function onProtonSale(\\n address contractAddress,\\n uint256 tokenId,\\n address oldOwner,\\n address newOwner,\\n uint256 salePrice,\\n address creator,\\n uint256 creatorRoyalties\\n ) external;\\n}\\n\",\"keccak256\":\"0x6cebb97ce4d32c61afc746e4a6538eb605bb01276dfa66fa4bd6f63362bdc9ef\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IUniverseRP.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IUniverseRP.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"./IUniverse.sol\\\";\\n\\n/**\\n * @title Universal Controller interface for Rewards Program\\n * @dev ...\\n */\\ninterface IUniverseRP is IUniverse {\\n event RewardProgramSet(address indexed assetToken, address indexed rewardProgram);\\n event RewardProgramRemoved(address indexed assetToken);\\n event NftDeposit(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\\n event NftRelease(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\\n\\n struct NftStake {\\n uint256 multiplier; // in Basis Points\\n uint256 depositBlockNumber;\\n uint256 releaseBlockNumber;\\n }\\n\\n function getRewardProgram(address asset) external view returns (address);\\n function getNftStake(uint256 uuid) external view returns (NftStake memory);\\n}\\n\",\"keccak256\":\"0xd9c5a996bbb7f2a27bb85dde52587f7368c7b6512fc1064821a3975acdf4b7db\",\"license\":\"MIT\"},\"contracts/v1/lib/BlackholePrevention.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\\\";\\n\\n/**\\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\\n * the Owner/DAO to pull them out on behalf of a user\\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\\n */\\ncontract BlackholePrevention {\\n using Address for address payable;\\n using SafeERC20 for IERC20;\\n\\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\\n\\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (address(this).balance >= amount) {\\n receiver.sendValue(amount);\\n emit WithdrawStuckEther(receiver, amount);\\n }\\n }\\n\\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\\n IERC20(tokenAddress).safeTransfer(receiver, amount);\\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\\n }\\n }\\n\\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\\n }\\n }\\n\\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \\\"\\\");\\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6a664c8a1c1d7fb32ade2c11f75756b1fdb4c489daa32c1d58e6b867ea2ba8d6\",\"license\":\"MIT\"},\"contracts/v1/lib/TokenInfo.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// TokenInfo.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport \\\"../interfaces/IERC721Chargeable.sol\\\";\\n\\nlibrary TokenInfo {\\n function getTokenUUID(address contractAddress, uint256 tokenId) internal pure virtual returns (uint256) {\\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n function getTokenOwner(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n return tokenInterface.ownerOf(tokenId);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n function getTokenCreator(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n return tokenInterface.creatorOf(tokenId);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Owner of an External NFT contract\\n /// @param contractAddress The Address to the Contract of the NFT to check\\n /// @param account The Address of the Account to check\\n /// @return True if the account owns the contract\\n function isContractOwner(address contractAddress, address account) internal view virtual returns (bool) {\\n address contractOwner = IERC721Chargeable(contractAddress).owner();\\n return contractOwner != address(0x0) && contractOwner == account;\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Creator of a Proton-based NFT\\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\\n /// @param tokenId The Token ID of the Proton-based NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the creator of the Proton-based NFT\\n function isTokenCreator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenCreator = tokenInterface.creatorOf(tokenId);\\n return (sender == tokenCreator);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\\n /// @param tokenId The Token ID of the Proton-based NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the creator of the Proton-based NFT or the Contract itself\\n function isTokenContractOrCreator(address contractAddress, uint256 tokenId, address creator, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenCreator = tokenInterface.creatorOf(tokenId);\\n if (sender == contractAddress && creator == tokenCreator) { return true; }\\n return (sender == tokenCreator);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Owner or Operator of an External NFT\\n /// @param contractAddress The Address to the Contract of the External NFT to check\\n /// @param tokenId The Token ID of the External NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the Owner or Operator of the External NFT\\n function isErc721OwnerOrOperator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenOwner = tokenInterface.ownerOf(tokenId);\\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\\n }\\n\\n /**\\n * @dev Returns true if `account` is a contract.\\n * @dev Taken from OpenZeppelin library\\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { codehash := extcodehash(account) }\\n return (codehash != accountHash && codehash != 0x0);\\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 * @dev Taken from OpenZeppelin library\\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, uint256 gasLimit) internal {\\n require(address(this).balance >= amount, \\\"TokenInfo: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = (gasLimit > 0)\\n ? recipient.call{ value: amount, gas: gasLimit }(\\\"\\\")\\n : recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"TokenInfo: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0xbc78c6173db068d95084288246642402d0f4af399e1eb754182cae2d9173af5e\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b506126f4806100206000396000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c80638da5cb5b116100c3578063b9e09b4b1161007c578063b9e09b4b1461028e578063bbf1da84146102a1578063bea38be0146102a9578063c5d1d706146102bc578063f2fde38b146102cf578063fbf5ca14146102e25761014d565b80638da5cb5b14610227578063945233e21461022f57806395469dfc146102425780639a87c0de14610255578063a0edb48b14610268578063aa29542d1461027b5761014d565b8063522f681511610115578063522f6815146101be5780636e5559fd146101d1578063715018a6146101e45780638129fc1c146101ec578063836c478d146101f45780638b9309b2146102145761014d565b80631593dee1146101525780632bdbb77f1461016757806330219ef41461017a5780634025feb21461019857806341db85d6146101ab575b600080fd5b610165610160366004611d56565b6102f5565b005b610165610175366004611fe6565b61034d565b61018261038d565b60405161018f9190612185565b60405180910390f35b6101656101a6366004611d56565b61039c565b6101656101b9366004611fe6565b6103e6565b6101656101cc366004611ddb565b6104ca565b6101656101df366004611d1e565b610517565b6101656105e3565b61016561066c565b610207610202366004612114565b6106f7565b60405161018f9190612645565b610165610222366004611ede565b610384565b61018261073b565b61016561023d366004611d1e565b61074a565b610165610250366004611e06565b6107d8565b610165610263366004611d1e565b6108d7565b610165610276366004611d96565b61097b565b610165610289366004611f58565b6109cc565b61016561029c366004611e3e565b610a9f565b610182610b56565b6101656102b7366004611fe6565b610b65565b6101826102ca366004611d1e565b610b9c565b6101656102dd366004611d1e565b610bad565b6101656102f036600461206a565b610c6e565b6102fd610d5c565b6001600160a01b031661030e61073b565b6001600160a01b03161461033d5760405162461bcd60e51b81526004016103349061256c565b60405180910390fd5b610348838383610d60565b505050565b6065546001600160a01b031633146103775760405162461bcd60e51b8152600401610334906125a1565b6103848787858585610e6d565b50505050505050565b6065546001600160a01b031681565b6103a4610d5c565b6001600160a01b03166103b561073b565b6001600160a01b0316146103db5760405162461bcd60e51b81526004016103349061256c565b610348838383610fff565b6065546001600160a01b031633146104105760405162461bcd60e51b8152600401610334906125a1565b600061041b8461115a565b90506001600160a01b038116156104c05760006104388385611178565b604051631434318f60e21b81529091506001600160a01b038316906350d0c63c9061046b908c908c90869060040161225f565b602060405180830381600087803b15801561048557600080fd5b505af1158015610499573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bd919061212c565b50505b5050505050505050565b6104d2610d5c565b6001600160a01b03166104e361073b565b6001600160a01b0316146105095760405162461bcd60e51b81526004016103349061256c565b61051382826111a4565b5050565b61051f610d5c565b6001600160a01b031661053061073b565b6001600160a01b0316146105565760405162461bcd60e51b81526004016103349061256c565b806001600160a01b0381161580159061057c575061057c816001600160a01b0316611228565b6105985760405162461bcd60e51b815260040161033490612381565b606580546001600160a01b0319166001600160a01b0384169081179091556040517f5ce0e6b7fd36339ee97339831b6c72694ecee88c62aab49919d9cabe0a732e4190600090a25050565b6105eb610d5c565b6001600160a01b03166105fc61073b565b6001600160a01b0316146106225760405162461bcd60e51b81526004016103349061256c565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b600054610100900460ff16806106855750610685611264565b80610693575060005460ff16155b6106af5760405162461bcd60e51b8152600401610334906124dd565b600054610100900460ff161580156106da576000805460ff1961ff0019909116610100171660011790555b6106e2611275565b80156106f4576000805461ff00191690555b50565b6106ff611cb6565b5060008181526069602090815260409182902082516060810184528154815260018201549281019290925260020154918101919091525b919050565b6033546001600160a01b031690565b610752610d5c565b6001600160a01b031661076361073b565b6001600160a01b0316146107895760405162461bcd60e51b81526004016103349061256c565b6001600160a01b03811660008181526067602052604080822080546001600160a01b0319169055517f87e1027e3dc61d1977f39f0dfe911b66a943946b4ceb39210dee01495621de529190a250565b6107e0610d5c565b6001600160a01b03166107f161073b565b6001600160a01b0316146108175760405162461bcd60e51b81526004016103349061256c565b816001600160a01b0381161580159061083d575061083d816001600160a01b0316611228565b6108595760405162461bcd60e51b815260040161033490612381565b6001600160a01b03821661087f5760405162461bcd60e51b8152600401610334906122f5565b6001600160a01b0382811660008181526067602052604080822080546001600160a01b0319169488169485179055517f3b76c6366ef8a1f8d2dbb75e4be27be1e0749716fff3e6bc327da9c6158deada9190a3505050565b6108df610d5c565b6001600160a01b03166108f061073b565b6001600160a01b0316146109165760405162461bcd60e51b81526004016103349061256c565b806001600160a01b0381161580159061093c575061093c816001600160a01b0316611228565b6109585760405162461bcd60e51b815260040161033490612381565b50606680546001600160a01b0319166001600160a01b0392909216919091179055565b610983610d5c565b6001600160a01b031661099461073b565b6001600160a01b0316146109ba5760405162461bcd60e51b81526004016103349061256c565b6109c6848484846112f3565b50505050565b6065546001600160a01b031633146109f65760405162461bcd60e51b8152600401610334906125a1565b6000610a018361115a565b90506001600160a01b038116156104c057604051631434318f60e21b81526001600160a01b038216906350d0c63c90610a42908b908b90879060040161225f565b602060405180830381600087803b158015610a5c57600080fd5b505af1158015610a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a94919061212c565b505050505050505050565b6065546001600160a01b03163314610ac95760405162461bcd60e51b8152600401610334906125a1565b6000610ad48361115a565b90506001600160a01b03811615610a94576040516323632fb160e11b81526001600160a01b038216906346c65f6290610b19908a908a908a908a90899060040161220e565b600060405180830381600087803b158015610b3357600080fd5b505af1158015610b47573d6000803e3d6000fd5b50505050505050505050505050565b6066546001600160a01b031681565b6065546001600160a01b03163314610b8f5760405162461bcd60e51b8152600401610334906125a1565b6103848787858585611452565b6000610ba78261115a565b92915050565b610bb5610d5c565b6001600160a01b0316610bc661073b565b6001600160a01b031614610bec5760405162461bcd60e51b81526004016103349061256c565b6001600160a01b038116610c125760405162461bcd60e51b815260040161033490612318565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6065546001600160a01b03163314610c985760405162461bcd60e51b8152600401610334906125a1565b6000610ca38561115a565b90506001600160a01b03811615610a94576000610cca84610cc48588611542565b90611178565b604051631434318f60e21b81529091506001600160a01b038316906350d0c63c90610cfd908d908d90869060040161225f565b602060405180830381600087803b158015610d1757600080fd5b505af1158015610d2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4f919061212c565b5050505050505050505050565b3390565b6001600160a01b038316610d865760405162461bcd60e51b81526004016103349061235e565b6040516370a0823160e01b815281906001600160a01b038416906370a0823190610db4903090600401612185565b60206040518083038186803b158015610dcc57600080fd5b505afa158015610de0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e04919061212c565b1061034857610e1d6001600160a01b038316848361156a565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b83604051610e609190612666565b60405180910390a3505050565b6066546001600160a01b03848116911614610e8757610ff8565b6000610e9c6001600160a01b038716866115c0565b90506000610ea9846115f4565b9050600081118015610ed057506000828152606860205260409020610ece90826116bf565b155b15610fa8576000828152606860205260409020610eed90826116cb565b506000610ef9836116d7565b600084815260696020526040902060010154909150610f5357604080516060810182528281524360208083019182526000838501818152888252606990925293909320915182555160018201559051600290910155610fa6565b60008381526069602052604090206001810154908290554303610f92610f7a826002611757565b60008681526069602052604090206001015490611178565b600085815260696020526040902060010155505b505b846001600160a01b0316876001600160a01b03167f186ebbe503be539e070ca73b33a78f4266d96003e62b888dc31f88a39ddc9c878887604051610fed92919061266f565b60405180910390a350505b5050505050565b6001600160a01b0383166110255760405162461bcd60e51b81526004016103349061235e565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e90611053908590600401612666565b60206040518083038186803b15801561106b57600080fd5b505afa15801561107f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a39190611d3a565b6001600160a01b03161415610348576040516323b872dd60e01b81526001600160a01b038316906323b872dd906110e290309087908690600401612199565b600060405180830381600087803b1580156110fc57600080fd5b505af1158015611110573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b039081166000908152606760205260409020541690565b60008282018381101561119d5760405162461bcd60e51b8152600401610334906123a4565b9392505050565b6001600160a01b0382166111ca5760405162461bcd60e51b81526004016103349061235e565b804710610513576111e46001600160a01b03831682611789565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd8260405161121c9190612666565b60405180910390a25050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061125c57508115155b949350505050565b600061126f30611825565b15905090565b600054610100900460ff168061128e575061128e611264565b8061129c575060005460ff16155b6112b85760405162461bcd60e51b8152600401610334906124dd565b600054610100900460ff161580156112e3576000805460ff1961ff0019909116610100171660011790555b6112eb61182b565b6106e26118ac565b6001600160a01b0384166113195760405162461bcd60e51b81526004016103349061235e565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e9061134790309087906004016121f5565b60206040518083038186803b15801561135f57600080fd5b505afa158015611373573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611397919061212c565b106109c657604051637921219560e11b81526001600160a01b0384169063f242432a906113ce9030908890879087906004016121bd565b600060405180830381600087803b1580156113e857600080fd5b505af11580156113fc573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b846040516114449190612666565b60405180910390a450505050565b6066546001600160a01b0384811691161461146c57610ff8565b60006114816001600160a01b038716866115c0565b600081815260696020526040812091925061149b856115f4565b60008481526068602052604090209091506114b69082611986565b5060008381526068602052604081206114ce90611992565b11156114e4576114dd836116d7565b82556114eb565b4360028301555b856001600160a01b0316886001600160a01b03167ff3cfcfc091fdd683cf6c013de9806af93f3af27b256a57cb776331291cef4085898860405161153092919061266f565b60405180910390a35050505050505050565b6000828211156115645760405162461bcd60e51b8152600401610334906123db565b50900390565b6103488363a9059cbb60e01b84846040516024016115899291906121f5565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261199d565b600082826040516020016115d5929190612144565b60408051601f1981840301815291905280516020909101209392505050565b60006001821015801561160957506102d18211155b156116165750606e610736565b6102d18211801561162957506104628211155b1561163657506082610736565b61046282118015611649575061058f8211155b1561165657506096610736565b61058f8211801561166957506106588211155b15611676575060b4610736565b6106588211801561168957506106b08211155b15611696575060e6610736565b6106b0821180156116a957506106c58211155b156116b757506101fe610736565b506001610736565b600061119d8383611a2c565b600061119d8383611a44565b600081815260686020526040812081906116f090611992565b905060006032815b8381101561172d5760008681526068602052604090206117239061171c9083611a8e565b8490611178565b92506001016116f8565b600184111561174d5761174a6117438386611a9a565b8490611542565b92505b5090949350505050565b60008082116117785760405162461bcd60e51b8152600401610334906124a6565b81838161178157fe5b049392505050565b804710156117a95760405162461bcd60e51b81526004016103349061246f565b6000826001600160a01b0316826040516117c290612182565b60006040518083038185875af1925050503d80600081146117ff576040519150601f19603f3d011682016040523d82523d6000602084013e611804565b606091505b50509050806103485760405162461bcd60e51b815260040161033490612412565b3b151590565b600054610100900460ff16806118445750611844611264565b80611852575060005460ff16155b61186e5760405162461bcd60e51b8152600401610334906124dd565b600054610100900460ff161580156106e2576000805460ff1961ff00199091166101001716600117905580156106f4576000805461ff001916905550565b600054610100900460ff16806118c557506118c5611264565b806118d3575060005460ff16155b6118ef5760405162461bcd60e51b8152600401610334906124dd565b600054610100900460ff1615801561191a576000805460ff1961ff0019909116610100171660011790555b6000611924610d5c565b603380546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35080156106f4576000805461ff001916905550565b600061119d8383611ad4565b6000610ba782611b9a565b60606119f2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611b9e9092919063ffffffff16565b8051909150156103485780806020019051810190611a1091906120f4565b6103485760405162461bcd60e51b8152600401610334906125fb565b60009081526001919091016020526040902054151590565b6000611a508383611a2c565b611a8657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ba7565b506000610ba7565b600061119d8383611bad565b600082611aa957506000610ba7565b82820282848281611ab657fe5b041461119d5760405162461bcd60e51b81526004016103349061252b565b60008181526001830160205260408120548015611b905783546000198083019190810190600090879083908110611b0757fe5b9060005260206000200154905080876000018481548110611b2457fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080611b5457fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610ba7565b6000915050610ba7565b5490565b606061125c8484600085611bf2565b81546000908210611bd05760405162461bcd60e51b8152600401610334906122b3565b826000018281548110611bdf57fe5b9060005260206000200154905092915050565b6060611bfd85611825565b611c195760405162461bcd60e51b8152600401610334906125c4565b60006060866001600160a01b03168587604051611c369190612166565b60006040518083038185875af1925050503d8060008114611c73576040519150601f19603f3d011682016040523d82523d6000602084013e611c78565b606091505b50915091508115611c8c57915061125c9050565b805115611c9c5780518082602001fd5b8360405162461bcd60e51b81526004016103349190612280565b60405180606001604052806000815260200160008152602001600081525090565b60008083601f840112611ce8578182fd5b50813567ffffffffffffffff811115611cff578182fd5b602083019150836020828501011115611d1757600080fd5b9250929050565b600060208284031215611d2f578081fd5b813561119d816126a9565b600060208284031215611d4b578081fd5b815161119d816126a9565b600080600060608486031215611d6a578182fd5b8335611d75816126a9565b92506020840135611d85816126a9565b929592945050506040919091013590565b60008060008060808587031215611dab578081fd5b8435611db6816126a9565b93506020850135611dc6816126a9565b93969395505050506040820135916060013590565b60008060408385031215611ded578182fd5b8235611df8816126a9565b946020939093013593505050565b60008060408385031215611e18578182fd5b8235611e23816126a9565b91506020830135611e33816126a9565b809150509250929050565b60008060008060008060008060e0898b031215611e59578384fd5b8835611e64816126a9565b97506020890135611e74816126a9565b96506040890135611e84816126a9565b955060608901359450608089013567ffffffffffffffff811115611ea6578485fd5b611eb28b828c01611cd7565b90955093505060a0890135611ec6816126a9565b8092505060c089013590509295985092959890939650565b600080600080600080600060e0888a031215611ef8578283fd5b8735611f03816126a9565b9650602088013595506040880135611f1a816126a9565b94506060880135611f2a816126a9565b93506080880135925060a0880135611f41816126a9565b8092505060c0880135905092959891949750929550565b600080600080600080600060c0888a031215611f72578283fd5b8735611f7d816126a9565b965060208801359550604088013567ffffffffffffffff811115611f9f578384fd5b611fab8a828b01611cd7565b9096509450506060880135611fbf816126a9565b92506080880135611fcf816126a9565b8092505060a0880135905092959891949750929550565b600080600080600080600060c0888a031215612000578081fd5b873561200b816126a9565b965060208801359550604088013567ffffffffffffffff81111561202d578182fd5b6120398a828b01611cd7565b909650945050606088013561204d816126a9565b969995985093969295946080840135945060a09093013592915050565b60008060008060008060008060e0898b031215612085578182fd5b8835612090816126a9565b975060208901359650604089013567ffffffffffffffff8111156120b2578283fd5b6120be8b828c01611cd7565b90975095505060608901356120d2816126a9565b979a96995094979396956080850135955060a08501359460c001359350915050565b600060208284031215612105578081fd5b8151801515811461119d578182fd5b600060208284031215612125578081fd5b5035919050565b60006020828403121561213d578081fd5b5051919050565b60609290921b6bffffffffffffffffffffffff19168252601482015260340190565b6000825161217881846020870161267d565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03861681526020810185905260806040820181905281018390526000838560a08401378060a0858401015260a0601f19601f86011683010190508260608301529695505050505050565b6001600160a01b039390931683526020830191909152604082015260600190565b600060208252825180602084015261229f81604085016020870161267d565b601f01601f19169190910160400192915050565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b602080825260099082015268554e493a452d34303360b81b604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b602080825260099082015268554e493a452d34313760b81b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252600990820152680aa9c92748a5a6260760bb1b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b81518152602080830151908201526040918201519181019190915260600190565b90815260200190565b918252602082015260400190565b60005b83811015612698578181015183820152602001612680565b838111156109c65750506000910152565b6001600160a01b03811681146106f457600080fdfea2646970667358221220908905795c480c2c185fe7feaf7d583443e16cf0d7e33c254f739c3df482266664736f6c634300060c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061014d5760003560e01c80638da5cb5b116100c3578063b9e09b4b1161007c578063b9e09b4b1461028e578063bbf1da84146102a1578063bea38be0146102a9578063c5d1d706146102bc578063f2fde38b146102cf578063fbf5ca14146102e25761014d565b80638da5cb5b14610227578063945233e21461022f57806395469dfc146102425780639a87c0de14610255578063a0edb48b14610268578063aa29542d1461027b5761014d565b8063522f681511610115578063522f6815146101be5780636e5559fd146101d1578063715018a6146101e45780638129fc1c146101ec578063836c478d146101f45780638b9309b2146102145761014d565b80631593dee1146101525780632bdbb77f1461016757806330219ef41461017a5780634025feb21461019857806341db85d6146101ab575b600080fd5b610165610160366004611d56565b6102f5565b005b610165610175366004611fe6565b61034d565b61018261038d565b60405161018f9190612185565b60405180910390f35b6101656101a6366004611d56565b61039c565b6101656101b9366004611fe6565b6103e6565b6101656101cc366004611ddb565b6104ca565b6101656101df366004611d1e565b610517565b6101656105e3565b61016561066c565b610207610202366004612114565b6106f7565b60405161018f9190612645565b610165610222366004611ede565b610384565b61018261073b565b61016561023d366004611d1e565b61074a565b610165610250366004611e06565b6107d8565b610165610263366004611d1e565b6108d7565b610165610276366004611d96565b61097b565b610165610289366004611f58565b6109cc565b61016561029c366004611e3e565b610a9f565b610182610b56565b6101656102b7366004611fe6565b610b65565b6101826102ca366004611d1e565b610b9c565b6101656102dd366004611d1e565b610bad565b6101656102f036600461206a565b610c6e565b6102fd610d5c565b6001600160a01b031661030e61073b565b6001600160a01b03161461033d5760405162461bcd60e51b81526004016103349061256c565b60405180910390fd5b610348838383610d60565b505050565b6065546001600160a01b031633146103775760405162461bcd60e51b8152600401610334906125a1565b6103848787858585610e6d565b50505050505050565b6065546001600160a01b031681565b6103a4610d5c565b6001600160a01b03166103b561073b565b6001600160a01b0316146103db5760405162461bcd60e51b81526004016103349061256c565b610348838383610fff565b6065546001600160a01b031633146104105760405162461bcd60e51b8152600401610334906125a1565b600061041b8461115a565b90506001600160a01b038116156104c05760006104388385611178565b604051631434318f60e21b81529091506001600160a01b038316906350d0c63c9061046b908c908c90869060040161225f565b602060405180830381600087803b15801561048557600080fd5b505af1158015610499573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bd919061212c565b50505b5050505050505050565b6104d2610d5c565b6001600160a01b03166104e361073b565b6001600160a01b0316146105095760405162461bcd60e51b81526004016103349061256c565b61051382826111a4565b5050565b61051f610d5c565b6001600160a01b031661053061073b565b6001600160a01b0316146105565760405162461bcd60e51b81526004016103349061256c565b806001600160a01b0381161580159061057c575061057c816001600160a01b0316611228565b6105985760405162461bcd60e51b815260040161033490612381565b606580546001600160a01b0319166001600160a01b0384169081179091556040517f5ce0e6b7fd36339ee97339831b6c72694ecee88c62aab49919d9cabe0a732e4190600090a25050565b6105eb610d5c565b6001600160a01b03166105fc61073b565b6001600160a01b0316146106225760405162461bcd60e51b81526004016103349061256c565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b600054610100900460ff16806106855750610685611264565b80610693575060005460ff16155b6106af5760405162461bcd60e51b8152600401610334906124dd565b600054610100900460ff161580156106da576000805460ff1961ff0019909116610100171660011790555b6106e2611275565b80156106f4576000805461ff00191690555b50565b6106ff611cb6565b5060008181526069602090815260409182902082516060810184528154815260018201549281019290925260020154918101919091525b919050565b6033546001600160a01b031690565b610752610d5c565b6001600160a01b031661076361073b565b6001600160a01b0316146107895760405162461bcd60e51b81526004016103349061256c565b6001600160a01b03811660008181526067602052604080822080546001600160a01b0319169055517f87e1027e3dc61d1977f39f0dfe911b66a943946b4ceb39210dee01495621de529190a250565b6107e0610d5c565b6001600160a01b03166107f161073b565b6001600160a01b0316146108175760405162461bcd60e51b81526004016103349061256c565b816001600160a01b0381161580159061083d575061083d816001600160a01b0316611228565b6108595760405162461bcd60e51b815260040161033490612381565b6001600160a01b03821661087f5760405162461bcd60e51b8152600401610334906122f5565b6001600160a01b0382811660008181526067602052604080822080546001600160a01b0319169488169485179055517f3b76c6366ef8a1f8d2dbb75e4be27be1e0749716fff3e6bc327da9c6158deada9190a3505050565b6108df610d5c565b6001600160a01b03166108f061073b565b6001600160a01b0316146109165760405162461bcd60e51b81526004016103349061256c565b806001600160a01b0381161580159061093c575061093c816001600160a01b0316611228565b6109585760405162461bcd60e51b815260040161033490612381565b50606680546001600160a01b0319166001600160a01b0392909216919091179055565b610983610d5c565b6001600160a01b031661099461073b565b6001600160a01b0316146109ba5760405162461bcd60e51b81526004016103349061256c565b6109c6848484846112f3565b50505050565b6065546001600160a01b031633146109f65760405162461bcd60e51b8152600401610334906125a1565b6000610a018361115a565b90506001600160a01b038116156104c057604051631434318f60e21b81526001600160a01b038216906350d0c63c90610a42908b908b90879060040161225f565b602060405180830381600087803b158015610a5c57600080fd5b505af1158015610a70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a94919061212c565b505050505050505050565b6065546001600160a01b03163314610ac95760405162461bcd60e51b8152600401610334906125a1565b6000610ad48361115a565b90506001600160a01b03811615610a94576040516323632fb160e11b81526001600160a01b038216906346c65f6290610b19908a908a908a908a90899060040161220e565b600060405180830381600087803b158015610b3357600080fd5b505af1158015610b47573d6000803e3d6000fd5b50505050505050505050505050565b6066546001600160a01b031681565b6065546001600160a01b03163314610b8f5760405162461bcd60e51b8152600401610334906125a1565b6103848787858585611452565b6000610ba78261115a565b92915050565b610bb5610d5c565b6001600160a01b0316610bc661073b565b6001600160a01b031614610bec5760405162461bcd60e51b81526004016103349061256c565b6001600160a01b038116610c125760405162461bcd60e51b815260040161033490612318565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6065546001600160a01b03163314610c985760405162461bcd60e51b8152600401610334906125a1565b6000610ca38561115a565b90506001600160a01b03811615610a94576000610cca84610cc48588611542565b90611178565b604051631434318f60e21b81529091506001600160a01b038316906350d0c63c90610cfd908d908d90869060040161225f565b602060405180830381600087803b158015610d1757600080fd5b505af1158015610d2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4f919061212c565b5050505050505050505050565b3390565b6001600160a01b038316610d865760405162461bcd60e51b81526004016103349061235e565b6040516370a0823160e01b815281906001600160a01b038416906370a0823190610db4903090600401612185565b60206040518083038186803b158015610dcc57600080fd5b505afa158015610de0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e04919061212c565b1061034857610e1d6001600160a01b038316848361156a565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b83604051610e609190612666565b60405180910390a3505050565b6066546001600160a01b03848116911614610e8757610ff8565b6000610e9c6001600160a01b038716866115c0565b90506000610ea9846115f4565b9050600081118015610ed057506000828152606860205260409020610ece90826116bf565b155b15610fa8576000828152606860205260409020610eed90826116cb565b506000610ef9836116d7565b600084815260696020526040902060010154909150610f5357604080516060810182528281524360208083019182526000838501818152888252606990925293909320915182555160018201559051600290910155610fa6565b60008381526069602052604090206001810154908290554303610f92610f7a826002611757565b60008681526069602052604090206001015490611178565b600085815260696020526040902060010155505b505b846001600160a01b0316876001600160a01b03167f186ebbe503be539e070ca73b33a78f4266d96003e62b888dc31f88a39ddc9c878887604051610fed92919061266f565b60405180910390a350505b5050505050565b6001600160a01b0383166110255760405162461bcd60e51b81526004016103349061235e565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e90611053908590600401612666565b60206040518083038186803b15801561106b57600080fd5b505afa15801561107f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a39190611d3a565b6001600160a01b03161415610348576040516323b872dd60e01b81526001600160a01b038316906323b872dd906110e290309087908690600401612199565b600060405180830381600087803b1580156110fc57600080fd5b505af1158015611110573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b039081166000908152606760205260409020541690565b60008282018381101561119d5760405162461bcd60e51b8152600401610334906123a4565b9392505050565b6001600160a01b0382166111ca5760405162461bcd60e51b81526004016103349061235e565b804710610513576111e46001600160a01b03831682611789565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd8260405161121c9190612666565b60405180910390a25050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061125c57508115155b949350505050565b600061126f30611825565b15905090565b600054610100900460ff168061128e575061128e611264565b8061129c575060005460ff16155b6112b85760405162461bcd60e51b8152600401610334906124dd565b600054610100900460ff161580156112e3576000805460ff1961ff0019909116610100171660011790555b6112eb61182b565b6106e26118ac565b6001600160a01b0384166113195760405162461bcd60e51b81526004016103349061235e565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e9061134790309087906004016121f5565b60206040518083038186803b15801561135f57600080fd5b505afa158015611373573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611397919061212c565b106109c657604051637921219560e11b81526001600160a01b0384169063f242432a906113ce9030908890879087906004016121bd565b600060405180830381600087803b1580156113e857600080fd5b505af11580156113fc573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b846040516114449190612666565b60405180910390a450505050565b6066546001600160a01b0384811691161461146c57610ff8565b60006114816001600160a01b038716866115c0565b600081815260696020526040812091925061149b856115f4565b60008481526068602052604090209091506114b69082611986565b5060008381526068602052604081206114ce90611992565b11156114e4576114dd836116d7565b82556114eb565b4360028301555b856001600160a01b0316886001600160a01b03167ff3cfcfc091fdd683cf6c013de9806af93f3af27b256a57cb776331291cef4085898860405161153092919061266f565b60405180910390a35050505050505050565b6000828211156115645760405162461bcd60e51b8152600401610334906123db565b50900390565b6103488363a9059cbb60e01b84846040516024016115899291906121f5565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261199d565b600082826040516020016115d5929190612144565b60408051601f1981840301815291905280516020909101209392505050565b60006001821015801561160957506102d18211155b156116165750606e610736565b6102d18211801561162957506104628211155b1561163657506082610736565b61046282118015611649575061058f8211155b1561165657506096610736565b61058f8211801561166957506106588211155b15611676575060b4610736565b6106588211801561168957506106b08211155b15611696575060e6610736565b6106b0821180156116a957506106c58211155b156116b757506101fe610736565b506001610736565b600061119d8383611a2c565b600061119d8383611a44565b600081815260686020526040812081906116f090611992565b905060006032815b8381101561172d5760008681526068602052604090206117239061171c9083611a8e565b8490611178565b92506001016116f8565b600184111561174d5761174a6117438386611a9a565b8490611542565b92505b5090949350505050565b60008082116117785760405162461bcd60e51b8152600401610334906124a6565b81838161178157fe5b049392505050565b804710156117a95760405162461bcd60e51b81526004016103349061246f565b6000826001600160a01b0316826040516117c290612182565b60006040518083038185875af1925050503d80600081146117ff576040519150601f19603f3d011682016040523d82523d6000602084013e611804565b606091505b50509050806103485760405162461bcd60e51b815260040161033490612412565b3b151590565b600054610100900460ff16806118445750611844611264565b80611852575060005460ff16155b61186e5760405162461bcd60e51b8152600401610334906124dd565b600054610100900460ff161580156106e2576000805460ff1961ff00199091166101001716600117905580156106f4576000805461ff001916905550565b600054610100900460ff16806118c557506118c5611264565b806118d3575060005460ff16155b6118ef5760405162461bcd60e51b8152600401610334906124dd565b600054610100900460ff1615801561191a576000805460ff1961ff0019909116610100171660011790555b6000611924610d5c565b603380546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35080156106f4576000805461ff001916905550565b600061119d8383611ad4565b6000610ba782611b9a565b60606119f2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611b9e9092919063ffffffff16565b8051909150156103485780806020019051810190611a1091906120f4565b6103485760405162461bcd60e51b8152600401610334906125fb565b60009081526001919091016020526040902054151590565b6000611a508383611a2c565b611a8657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ba7565b506000610ba7565b600061119d8383611bad565b600082611aa957506000610ba7565b82820282848281611ab657fe5b041461119d5760405162461bcd60e51b81526004016103349061252b565b60008181526001830160205260408120548015611b905783546000198083019190810190600090879083908110611b0757fe5b9060005260206000200154905080876000018481548110611b2457fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080611b5457fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610ba7565b6000915050610ba7565b5490565b606061125c8484600085611bf2565b81546000908210611bd05760405162461bcd60e51b8152600401610334906122b3565b826000018281548110611bdf57fe5b9060005260206000200154905092915050565b6060611bfd85611825565b611c195760405162461bcd60e51b8152600401610334906125c4565b60006060866001600160a01b03168587604051611c369190612166565b60006040518083038185875af1925050503d8060008114611c73576040519150601f19603f3d011682016040523d82523d6000602084013e611c78565b606091505b50915091508115611c8c57915061125c9050565b805115611c9c5780518082602001fd5b8360405162461bcd60e51b81526004016103349190612280565b60405180606001604052806000815260200160008152602001600081525090565b60008083601f840112611ce8578182fd5b50813567ffffffffffffffff811115611cff578182fd5b602083019150836020828501011115611d1757600080fd5b9250929050565b600060208284031215611d2f578081fd5b813561119d816126a9565b600060208284031215611d4b578081fd5b815161119d816126a9565b600080600060608486031215611d6a578182fd5b8335611d75816126a9565b92506020840135611d85816126a9565b929592945050506040919091013590565b60008060008060808587031215611dab578081fd5b8435611db6816126a9565b93506020850135611dc6816126a9565b93969395505050506040820135916060013590565b60008060408385031215611ded578182fd5b8235611df8816126a9565b946020939093013593505050565b60008060408385031215611e18578182fd5b8235611e23816126a9565b91506020830135611e33816126a9565b809150509250929050565b60008060008060008060008060e0898b031215611e59578384fd5b8835611e64816126a9565b97506020890135611e74816126a9565b96506040890135611e84816126a9565b955060608901359450608089013567ffffffffffffffff811115611ea6578485fd5b611eb28b828c01611cd7565b90955093505060a0890135611ec6816126a9565b8092505060c089013590509295985092959890939650565b600080600080600080600060e0888a031215611ef8578283fd5b8735611f03816126a9565b9650602088013595506040880135611f1a816126a9565b94506060880135611f2a816126a9565b93506080880135925060a0880135611f41816126a9565b8092505060c0880135905092959891949750929550565b600080600080600080600060c0888a031215611f72578283fd5b8735611f7d816126a9565b965060208801359550604088013567ffffffffffffffff811115611f9f578384fd5b611fab8a828b01611cd7565b9096509450506060880135611fbf816126a9565b92506080880135611fcf816126a9565b8092505060a0880135905092959891949750929550565b600080600080600080600060c0888a031215612000578081fd5b873561200b816126a9565b965060208801359550604088013567ffffffffffffffff81111561202d578182fd5b6120398a828b01611cd7565b909650945050606088013561204d816126a9565b969995985093969295946080840135945060a09093013592915050565b60008060008060008060008060e0898b031215612085578182fd5b8835612090816126a9565b975060208901359650604089013567ffffffffffffffff8111156120b2578283fd5b6120be8b828c01611cd7565b90975095505060608901356120d2816126a9565b979a96995094979396956080850135955060a08501359460c001359350915050565b600060208284031215612105578081fd5b8151801515811461119d578182fd5b600060208284031215612125578081fd5b5035919050565b60006020828403121561213d578081fd5b5051919050565b60609290921b6bffffffffffffffffffffffff19168252601482015260340190565b6000825161217881846020870161267d565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03861681526020810185905260806040820181905281018390526000838560a08401378060a0858401015260a0601f19601f86011683010190508260608301529695505050505050565b6001600160a01b039390931683526020830191909152604082015260600190565b600060208252825180602084015261229f81604085016020870161267d565b601f01601f19169190910160400192915050565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b602080825260099082015268554e493a452d34303360b81b604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b602080825260099082015268554e493a452d34313760b81b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252600990820152680aa9c92748a5a6260760bb1b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b81518152602080830151908201526040918201519181019190915260600190565b90815260200190565b918252602082015260400190565b60005b83811015612698578181015183820152602001612680565b838111156109c65750506000910152565b6001600160a01b03811681146106f457600080fdfea2646970667358221220908905795c480c2c185fe7feaf7d583443e16cf0d7e33c254f739c3df482266664736f6c634300060c0033", + "devdoc": { + "details": "Upgradeable Contract", + "kind": "dev", + "methods": { + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Charged Particles Universe Contract with Rewards Program", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 680, + "contract": "contracts/v1/UniveserRPPolygon.sol:UniverseRPPolygon", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 683, + "contract": "contracts/v1/UniveserRPPolygon.sol:UniverseRPPolygon", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 3177, + "contract": "contracts/v1/UniveserRPPolygon.sol:UniverseRPPolygon", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 111, + "contract": "contracts/v1/UniveserRPPolygon.sol:UniverseRPPolygon", + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "t_address" + }, + { + "astId": 230, + "contract": "contracts/v1/UniveserRPPolygon.sol:UniverseRPPolygon", + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 17621, + "contract": "contracts/v1/UniveserRPPolygon.sol:UniverseRPPolygon", + "label": "_chargedParticles", + "offset": 0, + "slot": "101", + "type": "t_address" + }, + { + "astId": 17623, + "contract": "contracts/v1/UniveserRPPolygon.sol:UniverseRPPolygon", + "label": "_multiplierNft", + "offset": 0, + "slot": "102", + "type": "t_address" + }, + { + "astId": 17627, + "contract": "contracts/v1/UniveserRPPolygon.sol:UniverseRPPolygon", + "label": "_assetRewardPrograms", + "offset": 0, + "slot": "103", + "type": "t_mapping(t_address,t_address)" + }, + { + "astId": 17631, + "contract": "contracts/v1/UniveserRPPolygon.sol:UniverseRPPolygon", + "label": "_multiplierNftsSet", + "offset": 0, + "slot": "104", + "type": "t_mapping(t_uint256,t_struct(UintSet)8991_storage)" + }, + { + "astId": 17635, + "contract": "contracts/v1/UniveserRPPolygon.sol:UniverseRPPolygon", + "label": "_nftStake", + "offset": 0, + "slot": "105", + "type": "t_mapping(t_uint256,t_struct(NftStake)30343_storage)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_address)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_uint256,t_struct(NftStake)30343_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct IUniverseRP.NftStake)", + "numberOfBytes": "32", + "value": "t_struct(NftStake)30343_storage" + }, + "t_mapping(t_uint256,t_struct(UintSet)8991_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct EnumerableSet.UintSet)", + "numberOfBytes": "32", + "value": "t_struct(UintSet)8991_storage" + }, + "t_struct(NftStake)30343_storage": { + "encoding": "inplace", + "label": "struct IUniverseRP.NftStake", + "members": [ + { + "astId": 30338, + "contract": "contracts/v1/UniveserRPPolygon.sol:UniverseRPPolygon", + "label": "multiplier", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 30340, + "contract": "contracts/v1/UniveserRPPolygon.sol:UniverseRPPolygon", + "label": "depositBlockNumber", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 30342, + "contract": "contracts/v1/UniveserRPPolygon.sol:UniverseRPPolygon", + "label": "releaseBlockNumber", + "offset": 0, + "slot": "2", + "type": "t_uint256" + } + ], + "numberOfBytes": "96" + }, + "t_struct(Set)8702_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 8697, + "contract": "contracts/v1/UniveserRPPolygon.sol:UniverseRPPolygon", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 8701, + "contract": "contracts/v1/UniveserRPPolygon.sol:UniverseRPPolygon", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_struct(UintSet)8991_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.UintSet", + "members": [ + { + "astId": 8990, + "contract": "contracts/v1/UniveserRPPolygon.sol:UniverseRPPolygon", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)8702_storage" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/deployments/polygon/UniverseRPPolygon_Proxy.json b/deployments/polygon/UniverseRPPolygon_Proxy.json new file mode 100644 index 0000000..c6b02b2 --- /dev/null +++ b/deployments/polygon/UniverseRPPolygon_Proxy.json @@ -0,0 +1,264 @@ +{ + "address": "0xfAB2741B0d67D33c40144b3c4C4595ffFaBf36B3", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x459eb009a26ea58f8ae567da7e9a05a55f89865d4e373af77762946e55cc9a4f", + "receipt": { + "to": null, + "from": "0xb8D175F16742395F530e0b3bC1d30BD06B78CdA9", + "contractAddress": "0xfAB2741B0d67D33c40144b3c4C4595ffFaBf36B3", + "transactionIndex": 49, + "gasUsed": "769446", + "logsBloom": "0x00000000000000000000000000000000400000000000000000800000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000002800001000000000000000100000000000000000000020000008000000000000800000000800100000880000000000000400000004000000000000000020000000000000000000000000000000000800000220000000000000000000000000000000000000000000000000020000000004000000020000000000021008000000000000000000400000000100000000020000010000000000000000000000000000000010000000000000000000002100000", + "blockHash": "0x8ef406b6cb85deca5e2a7314528655a676d135d765625c2b7b3a1056a43c19bc", + "transactionHash": "0x459eb009a26ea58f8ae567da7e9a05a55f89865d4e373af77762946e55cc9a4f", + "logs": [ + { + "transactionIndex": 49, + "blockNumber": 47456748, + "transactionHash": "0x459eb009a26ea58f8ae567da7e9a05a55f89865d4e373af77762946e55cc9a4f", + "address": "0xfAB2741B0d67D33c40144b3c4C4595ffFaBf36B3", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000003e2c421af4e595548fac0a6e5c06e933f7c2f037" + ], + "data": "0x", + "logIndex": 724, + "blockHash": "0x8ef406b6cb85deca5e2a7314528655a676d135d765625c2b7b3a1056a43c19bc" + }, + { + "transactionIndex": 49, + "blockNumber": 47456748, + "transactionHash": "0x459eb009a26ea58f8ae567da7e9a05a55f89865d4e373af77762946e55cc9a4f", + "address": "0xfAB2741B0d67D33c40144b3c4C4595ffFaBf36B3", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000b8d175f16742395f530e0b3bc1d30bd06b78cda9" + ], + "data": "0x", + "logIndex": 725, + "blockHash": "0x8ef406b6cb85deca5e2a7314528655a676d135d765625c2b7b3a1056a43c19bc" + }, + { + "transactionIndex": 49, + "blockNumber": 47456748, + "transactionHash": "0x459eb009a26ea58f8ae567da7e9a05a55f89865d4e373af77762946e55cc9a4f", + "address": "0xfAB2741B0d67D33c40144b3c4C4595ffFaBf36B3", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fd6b09036bf046f2b32e1d7345833bf21db6733", + "logIndex": 726, + "blockHash": "0x8ef406b6cb85deca5e2a7314528655a676d135d765625c2b7b3a1056a43c19bc" + }, + { + "transactionIndex": 49, + "blockNumber": 47456748, + "transactionHash": "0x459eb009a26ea58f8ae567da7e9a05a55f89865d4e373af77762946e55cc9a4f", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000b8d175f16742395f530e0b3bc1d30bd06b78cda9", + "0x000000000000000000000000eedba2484aaf940f37cd3cd21a5d7c4a7dafbfc0" + ], + "data": "0x000000000000000000000000000000000000000000000000008921816c321f1c0000000000000000000000000000000000000000000000191d0875d43b883c73000000000000000000000000000000000000000000009e2a768cb08e1d84d3af0000000000000000000000000000000000000000000000191c7f5452cf561d57000000000000000000000000000000000000000000009e2a7715d20f89b6f2cb", + "logIndex": 727, + "blockHash": "0x8ef406b6cb85deca5e2a7314528655a676d135d765625c2b7b3a1056a43c19bc" + } + ], + "blockNumber": 47456748, + "cumulativeGasUsed": "11194786", + "status": 1, + "byzantium": true + }, + "args": [ + "0x3E2c421Af4e595548fAC0A6E5c06E933F7C2f037", + "0x0fD6B09036BF046f2B32E1D7345833bf21db6733", + "0x8129fc1c" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev 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\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/polygon/UniverseRP_Implementation.json b/deployments/polygon/UniverseRP_Implementation.json new file mode 100644 index 0000000..bfd32c0 --- /dev/null +++ b/deployments/polygon/UniverseRP_Implementation.json @@ -0,0 +1,1209 @@ +{ + "address": "0x1aA013d7A31557Ae1A60578394a8ACC785935D06", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bosonToken", + "type": "address" + } + ], + "name": "BosonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "chargedParticles", + "type": "address" + } + ], + "name": "ChargedParticlesSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "photonSource", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "energy", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "ElectrostaticAttraction", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "photonSource", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "energy", + "type": "uint256" + } + ], + "name": "ElectrostaticDischarge", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "EsaMultiplierSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "leptonToken", + "type": "address" + } + ], + "name": "LeptonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + } + ], + "name": "NftDeposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + } + ], + "name": "NftRelease", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "photonToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maxSupply", + "type": "uint256" + } + ], + "name": "PhotonSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "protonToken", + "type": "address" + } + ], + "name": "ProtonTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "quarkToken", + "type": "address" + } + ], + "name": "QuarkTokenSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "RewardProgramRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardProgram", + "type": "address" + } + ], + "name": "RewardProgramSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC1155", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "WithdrawStuckERC721", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "WithdrawStuckEther", + "type": "event" + }, + { + "inputs": [], + "name": "_chargedParticles", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_multiplierNft", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "uuid", + "type": "uint256" + } + ], + "name": "getNftStake", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "depositBlockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "releaseBlockNumber", + "type": "uint256" + } + ], + "internalType": "struct IUniverseRP.NftStake", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getRewardProgram", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nftTokenAmount", + "type": "uint256" + } + ], + "name": "onCovalentBond", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nftTokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nftTokenAmount", + "type": "uint256" + } + ], + "name": "onCovalentBreak", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creatorEnergy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onDischarge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onDischargeForCreator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "walletManagerId", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "assetAmount", + "type": "uint256" + } + ], + "name": "onEnergize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "newOwner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "salePrice", + "type": "uint256" + }, + { + "internalType": "address", + "name": "creator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creatorRoyalties", + "type": "uint256" + } + ], + "name": "onProtonSale", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "principalAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "creatorEnergy", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receiverEnergy", + "type": "uint256" + } + ], + "name": "onRelease", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "removeRewardProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "controller", + "type": "address" + } + ], + "name": "setChargedParticles", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "nftTokenAddress", + "type": "address" + } + ], + "name": "setMultiplierNft", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "rewardProgam", + "type": "address" + }, + { + "internalType": "address", + "name": "assetToken", + "type": "address" + } + ], + "name": "setRewardProgram", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawERC1155", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "withdrawERC721", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawErc20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawEther", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x833a53ff66d10703f5eb161a2e804f482b9af141521352e7dc6695bee42394dc", + "receipt": { + "to": null, + "from": "0xb8D175F16742395F530e0b3bC1d30BD06B78CdA9", + "contractAddress": "0x1aA013d7A31557Ae1A60578394a8ACC785935D06", + "transactionIndex": 54, + "gasUsed": "2211420", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000400000000100000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000020000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000000010000000000000000000002100000", + "blockHash": "0xa0dee3511437bb272814340ad020a940711c6bd0b55747154e6212f0fd931d4e", + "transactionHash": "0x833a53ff66d10703f5eb161a2e804f482b9af141521352e7dc6695bee42394dc", + "logs": [ + { + "transactionIndex": 54, + "blockNumber": 46700947, + "transactionHash": "0x833a53ff66d10703f5eb161a2e804f482b9af141521352e7dc6695bee42394dc", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000b8d175f16742395f530e0b3bc1d30bd06b78cda9", + "0x0000000000000000000000007c7379531b2aee82e4ca06d4175d13b9cbeafd49" + ], + "data": "0x000000000000000000000000000000000000000000000000018dafbe202bec3400000000000000000000000000000000000000000000001a356f3aee839af2a0000000000000000000000000000000000000000000024af5f1d4cd023788012100000000000000000000000000000000000000000000001a33e18b30636f066c000000000000000000000000000000000000000000024af5f3627cc057b3ed55", + "logIndex": 292, + "blockHash": "0xa0dee3511437bb272814340ad020a940711c6bd0b55747154e6212f0fd931d4e" + } + ], + "blockNumber": 46700947, + "cumulativeGasUsed": "12981323", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "39876b9d6995fafd8c4442fb1a03f418", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bosonToken\",\"type\":\"address\"}],\"name\":\"BosonTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"chargedParticles\",\"type\":\"address\"}],\"name\":\"ChargedParticlesSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"photonSource\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"energy\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"multiplier\",\"type\":\"uint256\"}],\"name\":\"ElectrostaticAttraction\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"photonSource\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"energy\",\"type\":\"uint256\"}],\"name\":\"ElectrostaticDischarge\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"multiplier\",\"type\":\"uint256\"}],\"name\":\"EsaMultiplierSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"leptonToken\",\"type\":\"address\"}],\"name\":\"LeptonTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"}],\"name\":\"NftDeposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"}],\"name\":\"NftRelease\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"photonToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"maxSupply\",\"type\":\"uint256\"}],\"name\":\"PhotonSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"protonToken\",\"type\":\"address\"}],\"name\":\"ProtonTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"quarkToken\",\"type\":\"address\"}],\"name\":\"QuarkTokenSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"RewardProgramRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"rewardProgram\",\"type\":\"address\"}],\"name\":\"RewardProgramSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC1155\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC20\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckERC721\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"WithdrawStuckEther\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"_chargedParticles\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"_multiplierNft\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"uuid\",\"type\":\"uint256\"}],\"name\":\"getNftStake\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"multiplier\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"depositBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"releaseBlockNumber\",\"type\":\"uint256\"}],\"internalType\":\"struct IUniverseRP.NftStake\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"getRewardProgram\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"onCovalentBond\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nftTokenAmount\",\"type\":\"uint256\"}],\"name\":\"onCovalentBreak\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"creatorEnergy\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverEnergy\",\"type\":\"uint256\"}],\"name\":\"onDischarge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"receiverEnergy\",\"type\":\"uint256\"}],\"name\":\"onDischargeForCreator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"walletManagerId\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"assetAmount\",\"type\":\"uint256\"}],\"name\":\"onEnergize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"salePrice\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"creator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"creatorRoyalties\",\"type\":\"uint256\"}],\"name\":\"onProtonSale\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"contractAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"principalAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creatorEnergy\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"receiverEnergy\",\"type\":\"uint256\"}],\"name\":\"onRelease\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"removeRewardProgram\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"controller\",\"type\":\"address\"}],\"name\":\"setChargedParticles\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nftTokenAddress\",\"type\":\"address\"}],\"name\":\"setMultiplierNft\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"rewardProgam\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"assetToken\",\"type\":\"address\"}],\"name\":\"setRewardProgram\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawERC1155\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"withdrawERC721\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawErc20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawEther\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"Upgradeable Contract\",\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Charged Particles Universe Contract with Rewards Program\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/v1/UniverseRP.sol\":\"UniverseRP\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../proxy/Initializable.sol\\\";\\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 initializer {\\n __Context_init_unchained();\\n __Ownable_init_unchained();\\n }\\n\\n function __Ownable_init_unchained() internal initializer {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), 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 emit OwnershipTransferred(_owner, address(0));\\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xb419e68addcb82ecda3ad3974b0d2db76435ce9b08435a04d5b119a0c5d45ea5\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <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\",\"keccak256\":\"0x4784c3f8a520a739dd25d76f514833a653990902d0e21601aed45bda44c87524\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMathUpgradeable {\\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 uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\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 if (b > a) return (false, 0);\\n return (true, a - b);\\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 // 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 * @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 if (b == 0) return (false, 0);\\n return (true, a / b);\\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 if (b == 0) return (false, 0);\\n return (true, a % b);\\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 uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\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 require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\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 if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\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. 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(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\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 require(b > 0, \\\"SafeMath: modulo by zero\\\");\\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x0dd1e9b19801e3e7d900fbf4182d81e1afd23ad7be39504e33df6bbcba91d724\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// solhint-disable-next-line compiler-version\\npragma solidity >=0.4.24 <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 {UpgradeableProxy-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 */\\nabstract contract Initializable {\\n\\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 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 /// @dev Returns true if and only if the function is running in the constructor\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0xd8e4eb08dcc1d1860fb347ba5ffd595242b9a1b66d49a47f2b4cb51c3f35017e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0xa1931c47a617014f858580db625aa0dcf343796f39acd4b5b51effc092a1f0a9\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"../../math/SafeMathUpgradeable.sol\\\";\\nimport \\\"../../utils/AddressUpgradeable.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 SafeERC20Upgradeable {\\n using SafeMathUpgradeable for uint256;\\n using AddressUpgradeable for address;\\n\\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) 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(IERC20Upgradeable token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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(IERC20Upgradeable 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) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x8457e15aa90badabe0d6ef6f572f1ebd47bebf156921c825ae6e009dda15b706\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.2 <0.8.0;\\n\\nimport \\\"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x3dab19bb4a63bcbda1ee153ca291694f92f9009fad28626126b15a8503b0e5ff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.2 <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 // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) 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 // solhint-disable-next-line avoid-low-level-calls\\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(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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 // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfc5ea91fa9ceb1961023b2a6c978b902888c52b90847ac7813fe3b79524165f6\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\nimport \\\"../proxy/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 GSN 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 initializer {\\n __Context_init_unchained();\\n }\\n\\n function __Context_init_unchained() internal initializer {\\n }\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xbbf8a21b9a66c48d45ff771b8563c6df19ba451d63dfb8380a865c1e1f29d1a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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\",\"keccak256\":\"0xfa152b6e88a1dc50780e8f1580426dc23ad2e1e2c2f086a088adf206a202f453\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\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 uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\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 sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\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 * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\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 // 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) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts 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 mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x9a9cf02622cd7a64261b10534fc3260449da25c98c9e96d1b4ae8110a20e5806\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x31691ad0817f8cb338531b78d2ab2989027d9f27e6f8e62492b754fed9429b10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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\",\"keccak256\":\"0x5c26b39d26f7ed489e555d955dcd3e01872972e71fdd1528e93ec164e4f23385\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.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 SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\\n require((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(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\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) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf3b30f8a49631420635a8c35daacfcaa338012755f18a76fdd118730256f9a27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\n\\nimport \\\"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0xaf936da92f3a9a4f98b237323b5eb1d813fb86c4d07a184beba7027cf0509ba3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.2;\\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 in 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 // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n return _functionCallWithValue(target, data, value, errorMessage);\\n }\\n\\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\\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 // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf5fa8cbdffa5ef8be49b246b5628facc30b71707e78a45d80d93b64eff3fe390\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.6.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.0.0, only sets of type `address` (`AddressSet`) and `uint256`\\n * (`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\\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\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] = toDeleteIndex + 1; // All indexes are 1-based\\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 require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\n return set._values[index];\\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(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(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(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(uint256(_at(set._inner, index)));\\n }\\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\",\"keccak256\":\"0xb2a11b236f073662f5a196995863f51c11d006bf7c3de158b316dfa1506c4b79\",\"license\":\"MIT\"},\"contracts/v1/UniverseRP.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// Universe.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/EnumerableSet.sol\\\";\\n\\nimport \\\"./interfaces/IUniverseRP.sol\\\";\\nimport \\\"./interfaces/IChargedParticles.sol\\\";\\nimport \\\"./interfaces/ILepton.sol\\\";\\nimport \\\"./interfaces/IRewardNft.sol\\\";\\nimport \\\"./lib/TokenInfo.sol\\\";\\nimport \\\"./lib/BlackholePrevention.sol\\\";\\nimport \\\"./interfaces/IRewardProgram.sol\\\";\\n\\n/**\\n * @notice Charged Particles Universe Contract with Rewards Program\\n * @dev Upgradeable Contract\\n */\\ncontract UniverseRP is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\\n using SafeMathUpgradeable for uint256;\\n using TokenInfo for address;\\n using SafeERC20Upgradeable for IERC20Upgradeable;\\n using EnumerableSet for EnumerableSet.UintSet;\\n\\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\\n\\n // The ChargedParticles Contract Address\\n address public _chargedParticles;\\n\\n // The Lepton NFT Contract Address\\n address public _multiplierNft;\\n\\n // Asset Token => Reward Program\\n mapping (address => address) internal _assetRewardPrograms;\\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\\n\\n // Token UUID => NFT Staking Data\\n mapping (uint256 => NftStake) private _nftStake;\\n\\n\\n /***********************************|\\n | Initialization |\\n |__________________________________*/\\n\\n function initialize() public initializer {\\n __Ownable_init();\\n }\\n\\n function getRewardProgram(address asset) external view override returns (address) {\\n return _getRewardProgram(asset);\\n }\\n\\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\\n return _nftStake[uuid];\\n }\\n\\n /***********************************|\\n | Only Charged Particles |\\n |__________________________________*/\\n\\n function onEnergize(\\n address /* sender */,\\n address /* referrer */,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n address rewardProgram = _getRewardProgram(assetToken);\\n if (rewardProgram != address(0)) {\\n IRewardProgram(rewardProgram).registerAssetDeposit(\\n contractAddress,\\n tokenId,\\n walletManagerId,\\n assetAmount\\n );\\n }\\n }\\n\\n function onDischarge(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* walletManagerId */,\\n address assetToken,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n address rewardProgram = _getRewardProgram(assetToken);\\n if (rewardProgram != address(0)) {\\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\\n }\\n }\\n\\n function onDischargeForCreator(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* walletManagerId */,\\n address /* creator */,\\n address assetToken,\\n uint256 receiverEnergy\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n address rewardProgram = _getRewardProgram(assetToken);\\n if (rewardProgram != address(0)) {\\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\\n }\\n }\\n\\n function onRelease(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* walletManagerId */,\\n address assetToken,\\n uint256 principalAmount,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n address rewardProgram = _getRewardProgram(assetToken);\\n if (rewardProgram != address(0)) {\\n // \\\"receiverEnergy\\\" includes the \\\"principalAmount\\\"\\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\\n }\\n }\\n\\n function onCovalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* managerId */,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\\n }\\n\\n function onCovalentBreak(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata /* managerId */,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n )\\n external\\n virtual\\n override\\n onlyChargedParticles\\n {\\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\\n }\\n\\n function onProtonSale(\\n address contractAddress,\\n uint256 tokenId,\\n address oldOwner,\\n address newOwner,\\n uint256 salePrice,\\n address creator,\\n uint256 creatorRoyalties\\n )\\n external\\n virtual\\n override\\n {\\n // no-op\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n |__________________________________*/\\n\\n function setChargedParticles(\\n address controller\\n )\\n external\\n onlyOwner\\n onlyValidContractAddress(controller)\\n {\\n _chargedParticles = controller;\\n emit ChargedParticlesSet(controller);\\n }\\n\\n function setMultiplierNft(address nftTokenAddress)\\n external\\n onlyOwner\\n onlyValidContractAddress(nftTokenAddress)\\n {\\n _multiplierNft = nftTokenAddress;\\n }\\n\\n function setRewardProgram(\\n address rewardProgam,\\n address assetToken\\n )\\n external\\n onlyOwner\\n onlyValidContractAddress(rewardProgam)\\n {\\n require(assetToken != address(0x0), \\\"UNI:E-403\\\");\\n _assetRewardPrograms[assetToken] = rewardProgam;\\n emit RewardProgramSet(assetToken, rewardProgam);\\n }\\n\\n function removeRewardProgram(address assetToken) external onlyOwner {\\n delete _assetRewardPrograms[assetToken];\\n emit RewardProgramRemoved(assetToken);\\n }\\n\\n\\n /***********************************|\\n | Only Admin/DAO |\\n | (blackhole prevention) |\\n |__________________________________*/\\n\\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\\n _withdrawEther(receiver, amount);\\n }\\n\\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\\n _withdrawERC20(receiver, tokenAddress, amount);\\n }\\n\\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\\n _withdrawERC721(receiver, tokenAddress, tokenId);\\n }\\n\\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n\\n\\n /***********************************|\\n | Private Functions |\\n |__________________________________*/\\n\\n function _getRewardProgram(address assetToken) internal view returns (address) {\\n return _assetRewardPrograms[assetToken];\\n }\\n\\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\\n internal\\n {\\n // We only care about the Multiplier NFT\\n if (_multiplierNft != depositNftAddress) { return; }\\n\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n uint256 multiplier = _getNftMultiplier(depositNftAddress, depositNftTokenId);\\n\\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\\n // Add to Multipliers Set\\n _multiplierNftsSet[parentNftUuid].add(multiplier);\\n\\n // Update NFT Stake\\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\\n } else {\\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\\n }\\n }\\n\\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\\n }\\n\\n function _registerNftRelease(\\n address contractAddress,\\n uint256 tokenId,\\n address releaseNftAddress,\\n uint256 releaseNftTokenId,\\n uint256 /* nftTokenAmount */\\n )\\n internal\\n {\\n // We only care about the Multiplier NFT\\n if (_multiplierNft != releaseNftAddress) { return; }\\n\\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\\n NftStake storage nftStake = _nftStake[parentNftUuid];\\n\\n // Remove from Multipliers Set\\n uint256 multiplier = _getNftMultiplier(releaseNftAddress, releaseNftTokenId);\\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\\n\\n // Determine New Multiplier or Mark as Released\\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\\n } else {\\n nftStake.releaseBlockNumber = block.number;\\n }\\n\\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\\n }\\n\\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\\n uint256 multiplier = 0;\\n uint256 loss = 50;\\n uint256 i = 0;\\n\\n for (; i < len; i++) {\\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\\n }\\n if (len > 1) {\\n multiplier = multiplier.sub(loss.mul(len));\\n }\\n return multiplier;\\n }\\n\\n function _getNftMultiplier(address contractAddress, uint256 tokenId) internal returns (uint256) {\\n bytes4 fnSig = IRewardNft.getMultiplier.selector;\\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\\n\\n if (success) {\\n return abi.decode(returnData, (uint256));\\n } else {\\n return 0;\\n }\\n }\\n\\n\\n /***********************************|\\n | Modifiers |\\n |__________________________________*/\\n\\n /// @dev Throws if called by any non-account\\n modifier onlyValidContractAddress(address account) {\\n require(account != address(0x0) && account.isContract(), \\\"UNI:E-417\\\");\\n _;\\n }\\n\\n /// @dev Throws if called by any account other than the Charged Particles contract\\n modifier onlyChargedParticles() {\\n require(_chargedParticles == msg.sender, \\\"UNI:E-108\\\");\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x5ec2e8a1bbcbb7cc8bb11a500e29df20aaa34c76a3c6963b508a377da076ba0b\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IChargedParticles.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @notice Interface for Charged Particles\\n */\\ninterface IChargedParticles {\\n\\n /***********************************|\\n | Public API |\\n |__________________________________*/\\n\\n function getStateAddress() external view returns (address stateAddress);\\n function getSettingsAddress() external view returns (address settingsAddress);\\n function getManagersAddress() external view returns (address managersAddress);\\n\\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\\n\\n /***********************************|\\n | Particle Mechanics |\\n |__________________________________*/\\n\\n function energizeParticle(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount,\\n address referrer\\n ) external returns (uint256 yieldTokensAmount);\\n\\n function dischargeParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function dischargeParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function dischargeParticleForCreator(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 receiverAmount);\\n\\n function releaseParticle(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function releaseParticleAmount(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata walletManagerId,\\n address assetToken,\\n uint256 assetAmount\\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\\n\\n function covalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success);\\n\\n function breakCovalentBond(\\n address receiver,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata basketManagerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external returns (bool success);\\n\\n /***********************************|\\n | Particle Events |\\n |__________________________________*/\\n\\n event Initialized(address indexed initiator);\\n event ControllerSet(address indexed controllerAddress, string controllerId);\\n event DepositFeeSet(uint256 depositFee);\\n event ProtocolFeesCollected(address indexed assetToken, uint256 depositAmount, uint256 feesCollected);\\n}\\n\",\"keccak256\":\"0x37104c629e40193ddc8677af8a632adf53754e7915f055a5a14861cd9b417729\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IERC721Chargeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IERC721Chargeable.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\\\";\\n\\ninterface IERC721Chargeable is IERC165Upgradeable {\\n function owner() external view returns (address);\\n function creatorOf(uint256 tokenId) external view returns (address);\\n function balanceOf(address tokenOwner) external view returns (uint256 balance);\\n function ownerOf(uint256 tokenId) external view returns (address tokenOwner);\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n function transferFrom(address from, address to, uint256 tokenId) external;\\n function approve(address to, uint256 tokenId) external;\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n function setApprovalForAll(address operator, bool _approved) external;\\n function isApprovedForAll(address tokenOwner, address operator) external view returns (bool);\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x459e57b2d35c7cd78e6c3d47eb9f3e981529a18c89e2c318b10fe369c479c737\",\"license\":\"MIT\"},\"contracts/v1/interfaces/ILepton.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// ILepton.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Charged Particles Lepton Interface\\n * @dev ...\\n */\\ninterface ILepton {\\n\\n struct Classification {\\n string tokenUri;\\n uint256 price;\\n uint128 _upperBounds;\\n uint32 supply;\\n uint32 multiplier;\\n uint32 bonus;\\n }\\n\\n function mintLepton() external payable returns (uint256 newTokenId);\\n function batchMintLepton(uint256 count) external payable;\\n function getNextType() external view returns (uint256);\\n function getNextPrice() external view returns (uint256);\\n function getMultiplier(uint256 tokenId) external view returns (uint256);\\n function getBonus(uint256 tokenId) external view returns (uint256);\\n\\n\\n event MaxMintPerTxSet(uint256 maxAmount);\\n event LeptonTypeAdded(string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\\n event LeptonTypeUpdated(uint256 leptonIndex, string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\\n event LeptonMinted(address indexed receiver, uint256 indexed tokenId, uint256 price, uint32 multiplier);\\n event LeptonBatchMinted(address indexed receiver, uint256 indexed tokenId, uint256 count, uint256 price, uint32 multiplier);\\n event PausedStateSet(bool isPaused);\\n}\\n\",\"keccak256\":\"0x4903085427fa5dbee690fe79854fba60afaf21189957406ade55f6fc12556a01\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IRewardNft.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IRewardNft.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Charged Particles Reward-NFT Interface\\n * @dev ...\\n */\\ninterface IRewardNft {\\n function getMultiplier(uint256 tokenId) external view returns (uint256);\\n function getBonus(uint256 tokenId) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x51a5666003af460a55356974a286dde959c5f166104c75b4d563e8294a90b07a\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IRewardProgram.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IRewardProgram.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2023 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\npragma experimental ABIEncoderV2;\\n\\ninterface IRewardProgram {\\n /* admin events */\\n event RewardProgramFunded(uint256 amount);\\n event RewardProgramOutOfFunds();\\n\\n /* user events */\\n event RewardsClaimed(address indexed contractAddress, uint256 tokenId, address indexed receiver, uint256 rewarded, uint256 remaining);\\n\\n event AssetRegistered(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\\n event AssetDeposit(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\\n event AssetRelease(address indexed contractAddress, uint256 tokenId, uint256 interestAmount);\\n\\n /* data types */\\n struct ProgramRewardData {\\n address stakingToken;\\n address rewardToken;\\n uint256 baseMultiplier; // Basis Points\\n }\\n\\n struct AssetStake {\\n uint256 start;\\n uint256 claimableRewards;\\n string walletManagerId;\\n }\\n\\n function initialize(address stakingToken, address rewardToken, uint256 baseMultiplier, address chargedManagers, address universe, address owner) external;\\n\\n /* user functions */\\n function getProgramData() external view returns (ProgramRewardData memory programData);\\n function getAssetStake(uint256 uuid) external view returns (AssetStake memory);\\n function getFundBalance() external view returns (uint256);\\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) external view returns (uint256);\\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view returns (uint256);\\n\\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external;\\n function registerAssetDeposit(address contractAddress, uint256 tokenId, string calldata walletManagerId, uint256 principalAmount) external;\\n function registerAssetRelease(address contractAddress, uint256 tokenId, uint256 interestAmount) external returns (uint256 rewards);\\n}\",\"keccak256\":\"0xe0f4076a4b001856c54cb8a63decedc81ca34c71708f8cbe9b3a26603dc9c050\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IUniverse.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IUniverse.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\n/**\\n * @title Universal Controller interface\\n * @dev ...\\n */\\ninterface IUniverse {\\n\\n event ChargedParticlesSet(address indexed chargedParticles);\\n event PhotonSet(address indexed photonToken, uint256 maxSupply);\\n event ProtonTokenSet(address indexed protonToken);\\n event LeptonTokenSet(address indexed leptonToken);\\n event QuarkTokenSet(address indexed quarkToken);\\n event BosonTokenSet(address indexed bosonToken);\\n event EsaMultiplierSet(address indexed assetToken, uint256 multiplier);\\n event ElectrostaticAttraction(address indexed account, address photonSource, uint256 energy, uint256 multiplier);\\n event ElectrostaticDischarge(address indexed account, address photonSource, uint256 energy);\\n\\n function onEnergize(\\n address sender,\\n address referrer,\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 assetEnergy\\n ) external;\\n\\n function onDischarge(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onDischargeForCreator(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address creator,\\n address assetToken,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onRelease(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address assetToken,\\n uint256 principalEnergy,\\n uint256 creatorEnergy,\\n uint256 receiverEnergy\\n ) external;\\n\\n function onCovalentBond(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n\\n function onCovalentBreak(\\n address contractAddress,\\n uint256 tokenId,\\n string calldata managerId,\\n address nftTokenAddress,\\n uint256 nftTokenId,\\n uint256 nftTokenAmount\\n ) external;\\n\\n function onProtonSale(\\n address contractAddress,\\n uint256 tokenId,\\n address oldOwner,\\n address newOwner,\\n uint256 salePrice,\\n address creator,\\n uint256 creatorRoyalties\\n ) external;\\n}\\n\",\"keccak256\":\"0x6cebb97ce4d32c61afc746e4a6538eb605bb01276dfa66fa4bd6f63362bdc9ef\",\"license\":\"MIT\"},\"contracts/v1/interfaces/IUniverseRP.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// IUniverseRP.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"./IUniverse.sol\\\";\\n\\n/**\\n * @title Universal Controller interface for Rewards Program\\n * @dev ...\\n */\\ninterface IUniverseRP is IUniverse {\\n event RewardProgramSet(address indexed assetToken, address indexed rewardProgram);\\n event RewardProgramRemoved(address indexed assetToken);\\n event NftDeposit(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\\n event NftRelease(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\\n\\n struct NftStake {\\n uint256 multiplier; // in Basis Points\\n uint256 depositBlockNumber;\\n uint256 releaseBlockNumber;\\n }\\n\\n function getRewardProgram(address asset) external view returns (address);\\n function getNftStake(uint256 uuid) external view returns (NftStake memory);\\n}\\n\",\"keccak256\":\"0xd9c5a996bbb7f2a27bb85dde52587f7368c7b6512fc1064821a3975acdf4b7db\",\"license\":\"MIT\"},\"contracts/v1/lib/BlackholePrevention.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity >=0.6.0;\\n\\nimport \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\\\";\\n\\n/**\\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\\n * the Owner/DAO to pull them out on behalf of a user\\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\\n */\\ncontract BlackholePrevention {\\n using Address for address payable;\\n using SafeERC20 for IERC20;\\n\\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\\n\\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (address(this).balance >= amount) {\\n receiver.sendValue(amount);\\n emit WithdrawStuckEther(receiver, amount);\\n }\\n }\\n\\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\\n IERC20(tokenAddress).safeTransfer(receiver, amount);\\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\\n }\\n }\\n\\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\\n }\\n }\\n\\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\\n require(receiver != address(0x0), \\\"BHP:E-403\\\");\\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \\\"\\\");\\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6a664c8a1c1d7fb32ade2c11f75756b1fdb4c489daa32c1d58e6b867ea2ba8d6\",\"license\":\"MIT\"},\"contracts/v1/lib/TokenInfo.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\n// TokenInfo.sol -- Part of the Charged Particles Protocol\\n// Copyright (c) 2021 Firma Lux, Inc. \\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy\\n// of this software and associated documentation files (the \\\"Software\\\"), to deal\\n// in the Software without restriction, including without limitation the rights\\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\n// copies of the Software, and to permit persons to whom the Software is\\n// furnished to do so, subject to the following conditions:\\n//\\n// The above copyright notice and this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n//\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\npragma solidity 0.6.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport \\\"../interfaces/IERC721Chargeable.sol\\\";\\n\\nlibrary TokenInfo {\\n function getTokenUUID(address contractAddress, uint256 tokenId) internal pure virtual returns (uint256) {\\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n function getTokenOwner(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n return tokenInterface.ownerOf(tokenId);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n function getTokenCreator(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n return tokenInterface.creatorOf(tokenId);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Owner of an External NFT contract\\n /// @param contractAddress The Address to the Contract of the NFT to check\\n /// @param account The Address of the Account to check\\n /// @return True if the account owns the contract\\n function isContractOwner(address contractAddress, address account) internal view virtual returns (bool) {\\n address contractOwner = IERC721Chargeable(contractAddress).owner();\\n return contractOwner != address(0x0) && contractOwner == account;\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Creator of a Proton-based NFT\\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\\n /// @param tokenId The Token ID of the Proton-based NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the creator of the Proton-based NFT\\n function isTokenCreator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenCreator = tokenInterface.creatorOf(tokenId);\\n return (sender == tokenCreator);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\\n /// @param tokenId The Token ID of the Proton-based NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the creator of the Proton-based NFT or the Contract itself\\n function isTokenContractOrCreator(address contractAddress, uint256 tokenId, address creator, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenCreator = tokenInterface.creatorOf(tokenId);\\n if (sender == contractAddress && creator == tokenCreator) { return true; }\\n return (sender == tokenCreator);\\n }\\n\\n /// @dev DEPRECATED; Prefer TokenInfoProxy\\n /// @dev Checks if an account is the Owner or Operator of an External NFT\\n /// @param contractAddress The Address to the Contract of the External NFT to check\\n /// @param tokenId The Token ID of the External NFT to check\\n /// @param sender The Address of the Account to check\\n /// @return True if the account is the Owner or Operator of the External NFT\\n function isErc721OwnerOrOperator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\\n address tokenOwner = tokenInterface.ownerOf(tokenId);\\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\\n }\\n\\n /**\\n * @dev Returns true if `account` is a contract.\\n * @dev Taken from OpenZeppelin library\\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\\n // for accounts without code, i.e. `keccak256('')`\\n bytes32 codehash;\\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { codehash := extcodehash(account) }\\n return (codehash != accountHash && codehash != 0x0);\\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 * @dev Taken from OpenZeppelin library\\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, uint256 gasLimit) internal {\\n require(address(this).balance >= amount, \\\"TokenInfo: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = (gasLimit > 0)\\n ? recipient.call{ value: amount, gas: gasLimit }(\\\"\\\")\\n : recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"TokenInfo: unable to send value, recipient may have reverted\\\");\\n }\\n}\\n\",\"keccak256\":\"0xbc78c6173db068d95084288246642402d0f4af399e1eb754182cae2d9173af5e\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061270a806100206000396000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c80638da5cb5b116100c3578063b9e09b4b1161007c578063b9e09b4b1461028e578063bbf1da84146102a1578063bea38be0146102a9578063c5d1d706146102bc578063f2fde38b146102cf578063fbf5ca14146102e25761014d565b80638da5cb5b14610227578063945233e21461022f57806395469dfc146102425780639a87c0de14610255578063a0edb48b14610268578063aa29542d1461027b5761014d565b8063522f681511610115578063522f6815146101be5780636e5559fd146101d1578063715018a6146101e45780638129fc1c146101ec578063836c478d146101f45780638b9309b2146102145761014d565b80631593dee1146101525780632bdbb77f1461016757806330219ef41461017a5780634025feb21461019857806341db85d6146101ab575b600080fd5b610165610160366004611d6c565b6102f5565b005b610165610175366004611ffc565b61034d565b61018261038d565b60405161018f919061219b565b60405180910390f35b6101656101a6366004611d6c565b61039c565b6101656101b9366004611ffc565b6103e6565b6101656101cc366004611df1565b6104ca565b6101656101df366004611d34565b610517565b6101656105e3565b61016561066c565b61020761020236600461212a565b6106f7565b60405161018f919061265b565b610165610222366004611ef4565b610384565b610182610738565b61016561023d366004611d34565b610747565b610165610250366004611e1c565b6107d5565b610165610263366004611d34565b6108d4565b610165610276366004611dac565b610978565b610165610289366004611f6e565b6109c9565b61016561029c366004611e54565b610a9c565b610182610b53565b6101656102b7366004611ffc565b610b62565b6101826102ca366004611d34565b610b99565b6101656102dd366004611d34565b610baa565b6101656102f0366004612080565b610c6b565b6102fd610d59565b6001600160a01b031661030e610738565b6001600160a01b03161461033d5760405162461bcd60e51b815260040161033490612582565b60405180910390fd5b610348838383610d5d565b505050565b6065546001600160a01b031633146103775760405162461bcd60e51b8152600401610334906125b7565b6103848787858585610e6a565b50505050505050565b6065546001600160a01b031681565b6103a4610d59565b6001600160a01b03166103b5610738565b6001600160a01b0316146103db5760405162461bcd60e51b815260040161033490612582565b610348838383610ffd565b6065546001600160a01b031633146104105760405162461bcd60e51b8152600401610334906125b7565b600061041b84611158565b90506001600160a01b038116156104c05760006104388385611176565b604051631434318f60e21b81529091506001600160a01b038316906350d0c63c9061046b908c908c908690600401612275565b602060405180830381600087803b15801561048557600080fd5b505af1158015610499573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bd9190612142565b50505b5050505050505050565b6104d2610d59565b6001600160a01b03166104e3610738565b6001600160a01b0316146105095760405162461bcd60e51b815260040161033490612582565b61051382826111a2565b5050565b61051f610d59565b6001600160a01b0316610530610738565b6001600160a01b0316146105565760405162461bcd60e51b815260040161033490612582565b806001600160a01b0381161580159061057c575061057c816001600160a01b0316611226565b6105985760405162461bcd60e51b815260040161033490612397565b606580546001600160a01b0319166001600160a01b0384169081179091556040517f5ce0e6b7fd36339ee97339831b6c72694ecee88c62aab49919d9cabe0a732e4190600090a25050565b6105eb610d59565b6001600160a01b03166105fc610738565b6001600160a01b0316146106225760405162461bcd60e51b815260040161033490612582565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b600054610100900460ff16806106855750610685611262565b80610693575060005460ff16155b6106af5760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff161580156106da576000805460ff1961ff0019909116610100171660011790555b6106e2611273565b80156106f4576000805461ff00191690555b50565b6106ff611ccc565b50600090815260696020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b6033546001600160a01b031690565b61074f610d59565b6001600160a01b0316610760610738565b6001600160a01b0316146107865760405162461bcd60e51b815260040161033490612582565b6001600160a01b03811660008181526067602052604080822080546001600160a01b0319169055517f87e1027e3dc61d1977f39f0dfe911b66a943946b4ceb39210dee01495621de529190a250565b6107dd610d59565b6001600160a01b03166107ee610738565b6001600160a01b0316146108145760405162461bcd60e51b815260040161033490612582565b816001600160a01b0381161580159061083a575061083a816001600160a01b0316611226565b6108565760405162461bcd60e51b815260040161033490612397565b6001600160a01b03821661087c5760405162461bcd60e51b81526004016103349061230b565b6001600160a01b0382811660008181526067602052604080822080546001600160a01b0319169488169485179055517f3b76c6366ef8a1f8d2dbb75e4be27be1e0749716fff3e6bc327da9c6158deada9190a3505050565b6108dc610d59565b6001600160a01b03166108ed610738565b6001600160a01b0316146109135760405162461bcd60e51b815260040161033490612582565b806001600160a01b038116158015906109395750610939816001600160a01b0316611226565b6109555760405162461bcd60e51b815260040161033490612397565b50606680546001600160a01b0319166001600160a01b0392909216919091179055565b610980610d59565b6001600160a01b0316610991610738565b6001600160a01b0316146109b75760405162461bcd60e51b815260040161033490612582565b6109c3848484846112f1565b50505050565b6065546001600160a01b031633146109f35760405162461bcd60e51b8152600401610334906125b7565b60006109fe83611158565b90506001600160a01b038116156104c057604051631434318f60e21b81526001600160a01b038216906350d0c63c90610a3f908b908b908790600401612275565b602060405180830381600087803b158015610a5957600080fd5b505af1158015610a6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a919190612142565b505050505050505050565b6065546001600160a01b03163314610ac65760405162461bcd60e51b8152600401610334906125b7565b6000610ad183611158565b90506001600160a01b03811615610a91576040516323632fb160e11b81526001600160a01b038216906346c65f6290610b16908a908a908a908a908990600401612224565b600060405180830381600087803b158015610b3057600080fd5b505af1158015610b44573d6000803e3d6000fd5b50505050505050505050505050565b6066546001600160a01b031681565b6065546001600160a01b03163314610b8c5760405162461bcd60e51b8152600401610334906125b7565b6103848787858585611450565b6000610ba482611158565b92915050565b610bb2610d59565b6001600160a01b0316610bc3610738565b6001600160a01b031614610be95760405162461bcd60e51b815260040161033490612582565b6001600160a01b038116610c0f5760405162461bcd60e51b81526004016103349061232e565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6065546001600160a01b03163314610c955760405162461bcd60e51b8152600401610334906125b7565b6000610ca085611158565b90506001600160a01b03811615610a91576000610cc784610cc18588611541565b90611176565b604051631434318f60e21b81529091506001600160a01b038316906350d0c63c90610cfa908d908d908690600401612275565b602060405180830381600087803b158015610d1457600080fd5b505af1158015610d28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4c9190612142565b5050505050505050505050565b3390565b6001600160a01b038316610d835760405162461bcd60e51b815260040161033490612374565b6040516370a0823160e01b815281906001600160a01b038416906370a0823190610db190309060040161219b565b60206040518083038186803b158015610dc957600080fd5b505afa158015610ddd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e019190612142565b1061034857610e1a6001600160a01b0383168483611569565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b83604051610e5d919061267c565b60405180910390a3505050565b6066546001600160a01b03848116911614610e8457610ff6565b6000610e996001600160a01b038716866115bf565b90506000610ea785856115f3565b9050600081118015610ece57506000828152606860205260409020610ecc90826116d5565b155b15610fa6576000828152606860205260409020610eeb90826116e1565b506000610ef7836116ed565b600084815260696020526040902060010154909150610f5157604080516060810182528281524360208083019182526000838501818152888252606990925293909320915182555160018201559051600290910155610fa4565b60008381526069602052604090206001810154908290554303610f90610f7882600261176d565b60008681526069602052604090206001015490611176565b600085815260696020526040902060010155505b505b846001600160a01b0316876001600160a01b03167f186ebbe503be539e070ca73b33a78f4266d96003e62b888dc31f88a39ddc9c878887604051610feb929190612685565b60405180910390a350505b5050505050565b6001600160a01b0383166110235760405162461bcd60e51b815260040161033490612374565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e9061105190859060040161267c565b60206040518083038186803b15801561106957600080fd5b505afa15801561107d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a19190611d50565b6001600160a01b03161415610348576040516323b872dd60e01b81526001600160a01b038316906323b872dd906110e0903090879086906004016121af565b600060405180830381600087803b1580156110fa57600080fd5b505af115801561110e573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b039081166000908152606760205260409020541690565b60008282018381101561119b5760405162461bcd60e51b8152600401610334906123ba565b9392505050565b6001600160a01b0382166111c85760405162461bcd60e51b815260040161033490612374565b804710610513576111e26001600160a01b0383168261179f565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd8260405161121a919061267c565b60405180910390a25050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061125a57508115155b949350505050565b600061126d3061183b565b15905090565b600054610100900460ff168061128c575061128c611262565b8061129a575060005460ff16155b6112b65760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff161580156112e1576000805460ff1961ff0019909116610100171660011790555b6112e9611841565b6106e26118c2565b6001600160a01b0384166113175760405162461bcd60e51b815260040161033490612374565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e90611345903090879060040161220b565b60206040518083038186803b15801561135d57600080fd5b505afa158015611371573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113959190612142565b106109c357604051637921219560e11b81526001600160a01b0384169063f242432a906113cc9030908890879087906004016121d3565b600060405180830381600087803b1580156113e657600080fd5b505af11580156113fa573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b84604051611442919061267c565b60405180910390a450505050565b6066546001600160a01b0384811691161461146a57610ff6565b600061147f6001600160a01b038716866115bf565b600081815260696020526040812091925061149a86866115f3565b60008481526068602052604090209091506114b5908261199c565b5060008381526068602052604081206114cd906119a8565b11156114e3576114dc836116ed565b82556114ea565b4360028301555b856001600160a01b0316886001600160a01b03167ff3cfcfc091fdd683cf6c013de9806af93f3af27b256a57cb776331291cef4085898860405161152f929190612685565b60405180910390a35050505050505050565b6000828211156115635760405162461bcd60e51b8152600401610334906123f1565b50900390565b6103488363a9059cbb60e01b848460405160240161158892919061220b565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526119b3565b600082826040516020016115d492919061215a565b60408051601f1981840301815291905280516020909101209392505050565b60008063adf8252d60e01b905060006060856001600160a01b03168386604051602401611620919061267c565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161165e919061217c565b6000604051808303816000865af19150503d806000811461169b576040519150601f19603f3d011682016040523d82523d6000602084013e6116a0565b606091505b509150915081156116c957808060200190518101906116bf9190612142565b9350505050610ba4565b60009350505050610ba4565b600061119b8383611a42565b600061119b8383611a5a565b60008181526068602052604081208190611706906119a8565b905060006032815b83811015611743576000868152606860205260409020611739906117329083611aa4565b8490611176565b925060010161170e565b6001841115611763576117606117598386611ab0565b8490611541565b92505b5090949350505050565b600080821161178e5760405162461bcd60e51b8152600401610334906124bc565b81838161179757fe5b049392505050565b804710156117bf5760405162461bcd60e51b815260040161033490612485565b6000826001600160a01b0316826040516117d890612198565b60006040518083038185875af1925050503d8060008114611815576040519150601f19603f3d011682016040523d82523d6000602084013e61181a565b606091505b50509050806103485760405162461bcd60e51b815260040161033490612428565b3b151590565b600054610100900460ff168061185a575061185a611262565b80611868575060005460ff16155b6118845760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff161580156106e2576000805460ff1961ff00199091166101001716600117905580156106f4576000805461ff001916905550565b600054610100900460ff16806118db57506118db611262565b806118e9575060005460ff16155b6119055760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff16158015611930576000805460ff1961ff0019909116610100171660011790555b600061193a610d59565b603380546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35080156106f4576000805461ff001916905550565b600061119b8383611aea565b6000610ba482611bb0565b6060611a08826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611bb49092919063ffffffff16565b8051909150156103485780806020019051810190611a26919061210a565b6103485760405162461bcd60e51b815260040161033490612611565b60009081526001919091016020526040902054151590565b6000611a668383611a42565b611a9c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ba4565b506000610ba4565b600061119b8383611bc3565b600082611abf57506000610ba4565b82820282848281611acc57fe5b041461119b5760405162461bcd60e51b815260040161033490612541565b60008181526001830160205260408120548015611ba65783546000198083019190810190600090879083908110611b1d57fe5b9060005260206000200154905080876000018481548110611b3a57fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080611b6a57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610ba4565b6000915050610ba4565b5490565b606061125a8484600085611c08565b81546000908210611be65760405162461bcd60e51b8152600401610334906122c9565b826000018281548110611bf557fe5b9060005260206000200154905092915050565b6060611c138561183b565b611c2f5760405162461bcd60e51b8152600401610334906125da565b60006060866001600160a01b03168587604051611c4c919061217c565b60006040518083038185875af1925050503d8060008114611c89576040519150601f19603f3d011682016040523d82523d6000602084013e611c8e565b606091505b50915091508115611ca257915061125a9050565b805115611cb25780518082602001fd5b8360405162461bcd60e51b81526004016103349190612296565b60405180606001604052806000815260200160008152602001600081525090565b60008083601f840112611cfe578182fd5b50813567ffffffffffffffff811115611d15578182fd5b602083019150836020828501011115611d2d57600080fd5b9250929050565b600060208284031215611d45578081fd5b813561119b816126bf565b600060208284031215611d61578081fd5b815161119b816126bf565b600080600060608486031215611d80578182fd5b8335611d8b816126bf565b92506020840135611d9b816126bf565b929592945050506040919091013590565b60008060008060808587031215611dc1578081fd5b8435611dcc816126bf565b93506020850135611ddc816126bf565b93969395505050506040820135916060013590565b60008060408385031215611e03578182fd5b8235611e0e816126bf565b946020939093013593505050565b60008060408385031215611e2e578182fd5b8235611e39816126bf565b91506020830135611e49816126bf565b809150509250929050565b60008060008060008060008060e0898b031215611e6f578384fd5b8835611e7a816126bf565b97506020890135611e8a816126bf565b96506040890135611e9a816126bf565b955060608901359450608089013567ffffffffffffffff811115611ebc578485fd5b611ec88b828c01611ced565b90955093505060a0890135611edc816126bf565b8092505060c089013590509295985092959890939650565b600080600080600080600060e0888a031215611f0e578283fd5b8735611f19816126bf565b9650602088013595506040880135611f30816126bf565b94506060880135611f40816126bf565b93506080880135925060a0880135611f57816126bf565b8092505060c0880135905092959891949750929550565b600080600080600080600060c0888a031215611f88578283fd5b8735611f93816126bf565b965060208801359550604088013567ffffffffffffffff811115611fb5578384fd5b611fc18a828b01611ced565b9096509450506060880135611fd5816126bf565b92506080880135611fe5816126bf565b8092505060a0880135905092959891949750929550565b600080600080600080600060c0888a031215612016578081fd5b8735612021816126bf565b965060208801359550604088013567ffffffffffffffff811115612043578182fd5b61204f8a828b01611ced565b9096509450506060880135612063816126bf565b969995985093969295946080840135945060a09093013592915050565b60008060008060008060008060e0898b03121561209b578182fd5b88356120a6816126bf565b975060208901359650604089013567ffffffffffffffff8111156120c8578283fd5b6120d48b828c01611ced565b90975095505060608901356120e8816126bf565b979a96995094979396956080850135955060a08501359460c001359350915050565b60006020828403121561211b578081fd5b8151801515811461119b578182fd5b60006020828403121561213b578081fd5b5035919050565b600060208284031215612153578081fd5b5051919050565b60609290921b6bffffffffffffffffffffffff19168252601482015260340190565b6000825161218e818460208701612693565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03861681526020810185905260806040820181905281018390526000838560a08401378060a0858401015260a0601f19601f86011683010190508260608301529695505050505050565b6001600160a01b039390931683526020830191909152604082015260600190565b60006020825282518060208401526122b5816040850160208701612693565b601f01601f19169190910160400192915050565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b602080825260099082015268554e493a452d34303360b81b604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b602080825260099082015268554e493a452d34313760b81b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252600990820152680aa9c92748a5a6260760bb1b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b81518152602080830151908201526040918201519181019190915260600190565b90815260200190565b918252602082015260400190565b60005b838110156126ae578181015183820152602001612696565b838111156109c35750506000910152565b6001600160a01b03811681146106f457600080fdfea264697066735822122055c84894697dd3e92642a98fce78fc85de39452936a89059494ec186a3b80f2d64736f6c634300060c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061014d5760003560e01c80638da5cb5b116100c3578063b9e09b4b1161007c578063b9e09b4b1461028e578063bbf1da84146102a1578063bea38be0146102a9578063c5d1d706146102bc578063f2fde38b146102cf578063fbf5ca14146102e25761014d565b80638da5cb5b14610227578063945233e21461022f57806395469dfc146102425780639a87c0de14610255578063a0edb48b14610268578063aa29542d1461027b5761014d565b8063522f681511610115578063522f6815146101be5780636e5559fd146101d1578063715018a6146101e45780638129fc1c146101ec578063836c478d146101f45780638b9309b2146102145761014d565b80631593dee1146101525780632bdbb77f1461016757806330219ef41461017a5780634025feb21461019857806341db85d6146101ab575b600080fd5b610165610160366004611d6c565b6102f5565b005b610165610175366004611ffc565b61034d565b61018261038d565b60405161018f919061219b565b60405180910390f35b6101656101a6366004611d6c565b61039c565b6101656101b9366004611ffc565b6103e6565b6101656101cc366004611df1565b6104ca565b6101656101df366004611d34565b610517565b6101656105e3565b61016561066c565b61020761020236600461212a565b6106f7565b60405161018f919061265b565b610165610222366004611ef4565b610384565b610182610738565b61016561023d366004611d34565b610747565b610165610250366004611e1c565b6107d5565b610165610263366004611d34565b6108d4565b610165610276366004611dac565b610978565b610165610289366004611f6e565b6109c9565b61016561029c366004611e54565b610a9c565b610182610b53565b6101656102b7366004611ffc565b610b62565b6101826102ca366004611d34565b610b99565b6101656102dd366004611d34565b610baa565b6101656102f0366004612080565b610c6b565b6102fd610d59565b6001600160a01b031661030e610738565b6001600160a01b03161461033d5760405162461bcd60e51b815260040161033490612582565b60405180910390fd5b610348838383610d5d565b505050565b6065546001600160a01b031633146103775760405162461bcd60e51b8152600401610334906125b7565b6103848787858585610e6a565b50505050505050565b6065546001600160a01b031681565b6103a4610d59565b6001600160a01b03166103b5610738565b6001600160a01b0316146103db5760405162461bcd60e51b815260040161033490612582565b610348838383610ffd565b6065546001600160a01b031633146104105760405162461bcd60e51b8152600401610334906125b7565b600061041b84611158565b90506001600160a01b038116156104c05760006104388385611176565b604051631434318f60e21b81529091506001600160a01b038316906350d0c63c9061046b908c908c908690600401612275565b602060405180830381600087803b15801561048557600080fd5b505af1158015610499573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bd9190612142565b50505b5050505050505050565b6104d2610d59565b6001600160a01b03166104e3610738565b6001600160a01b0316146105095760405162461bcd60e51b815260040161033490612582565b61051382826111a2565b5050565b61051f610d59565b6001600160a01b0316610530610738565b6001600160a01b0316146105565760405162461bcd60e51b815260040161033490612582565b806001600160a01b0381161580159061057c575061057c816001600160a01b0316611226565b6105985760405162461bcd60e51b815260040161033490612397565b606580546001600160a01b0319166001600160a01b0384169081179091556040517f5ce0e6b7fd36339ee97339831b6c72694ecee88c62aab49919d9cabe0a732e4190600090a25050565b6105eb610d59565b6001600160a01b03166105fc610738565b6001600160a01b0316146106225760405162461bcd60e51b815260040161033490612582565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b600054610100900460ff16806106855750610685611262565b80610693575060005460ff16155b6106af5760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff161580156106da576000805460ff1961ff0019909116610100171660011790555b6106e2611273565b80156106f4576000805461ff00191690555b50565b6106ff611ccc565b50600090815260696020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b6033546001600160a01b031690565b61074f610d59565b6001600160a01b0316610760610738565b6001600160a01b0316146107865760405162461bcd60e51b815260040161033490612582565b6001600160a01b03811660008181526067602052604080822080546001600160a01b0319169055517f87e1027e3dc61d1977f39f0dfe911b66a943946b4ceb39210dee01495621de529190a250565b6107dd610d59565b6001600160a01b03166107ee610738565b6001600160a01b0316146108145760405162461bcd60e51b815260040161033490612582565b816001600160a01b0381161580159061083a575061083a816001600160a01b0316611226565b6108565760405162461bcd60e51b815260040161033490612397565b6001600160a01b03821661087c5760405162461bcd60e51b81526004016103349061230b565b6001600160a01b0382811660008181526067602052604080822080546001600160a01b0319169488169485179055517f3b76c6366ef8a1f8d2dbb75e4be27be1e0749716fff3e6bc327da9c6158deada9190a3505050565b6108dc610d59565b6001600160a01b03166108ed610738565b6001600160a01b0316146109135760405162461bcd60e51b815260040161033490612582565b806001600160a01b038116158015906109395750610939816001600160a01b0316611226565b6109555760405162461bcd60e51b815260040161033490612397565b50606680546001600160a01b0319166001600160a01b0392909216919091179055565b610980610d59565b6001600160a01b0316610991610738565b6001600160a01b0316146109b75760405162461bcd60e51b815260040161033490612582565b6109c3848484846112f1565b50505050565b6065546001600160a01b031633146109f35760405162461bcd60e51b8152600401610334906125b7565b60006109fe83611158565b90506001600160a01b038116156104c057604051631434318f60e21b81526001600160a01b038216906350d0c63c90610a3f908b908b908790600401612275565b602060405180830381600087803b158015610a5957600080fd5b505af1158015610a6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a919190612142565b505050505050505050565b6065546001600160a01b03163314610ac65760405162461bcd60e51b8152600401610334906125b7565b6000610ad183611158565b90506001600160a01b03811615610a91576040516323632fb160e11b81526001600160a01b038216906346c65f6290610b16908a908a908a908a908990600401612224565b600060405180830381600087803b158015610b3057600080fd5b505af1158015610b44573d6000803e3d6000fd5b50505050505050505050505050565b6066546001600160a01b031681565b6065546001600160a01b03163314610b8c5760405162461bcd60e51b8152600401610334906125b7565b6103848787858585611450565b6000610ba482611158565b92915050565b610bb2610d59565b6001600160a01b0316610bc3610738565b6001600160a01b031614610be95760405162461bcd60e51b815260040161033490612582565b6001600160a01b038116610c0f5760405162461bcd60e51b81526004016103349061232e565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6065546001600160a01b03163314610c955760405162461bcd60e51b8152600401610334906125b7565b6000610ca085611158565b90506001600160a01b03811615610a91576000610cc784610cc18588611541565b90611176565b604051631434318f60e21b81529091506001600160a01b038316906350d0c63c90610cfa908d908d908690600401612275565b602060405180830381600087803b158015610d1457600080fd5b505af1158015610d28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4c9190612142565b5050505050505050505050565b3390565b6001600160a01b038316610d835760405162461bcd60e51b815260040161033490612374565b6040516370a0823160e01b815281906001600160a01b038416906370a0823190610db190309060040161219b565b60206040518083038186803b158015610dc957600080fd5b505afa158015610ddd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e019190612142565b1061034857610e1a6001600160a01b0383168483611569565b816001600160a01b0316836001600160a01b03167f6c9d637297625e945b296ff73a71fcfbd0a9e062652b6491a921c4c60194176b83604051610e5d919061267c565b60405180910390a3505050565b6066546001600160a01b03848116911614610e8457610ff6565b6000610e996001600160a01b038716866115bf565b90506000610ea785856115f3565b9050600081118015610ece57506000828152606860205260409020610ecc90826116d5565b155b15610fa6576000828152606860205260409020610eeb90826116e1565b506000610ef7836116ed565b600084815260696020526040902060010154909150610f5157604080516060810182528281524360208083019182526000838501818152888252606990925293909320915182555160018201559051600290910155610fa4565b60008381526069602052604090206001810154908290554303610f90610f7882600261176d565b60008681526069602052604090206001015490611176565b600085815260696020526040902060010155505b505b846001600160a01b0316876001600160a01b03167f186ebbe503be539e070ca73b33a78f4266d96003e62b888dc31f88a39ddc9c878887604051610feb929190612685565b60405180910390a350505b5050505050565b6001600160a01b0383166110235760405162461bcd60e51b815260040161033490612374565b6040516331a9108f60e11b815230906001600160a01b03841690636352211e9061105190859060040161267c565b60206040518083038186803b15801561106957600080fd5b505afa15801561107d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a19190611d50565b6001600160a01b03161415610348576040516323b872dd60e01b81526001600160a01b038316906323b872dd906110e0903090879086906004016121af565b600060405180830381600087803b1580156110fa57600080fd5b505af115801561110e573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167ffefe036cac4ee3a4aca074a81cbcc4376e1484693289078dbec149c890101d5b60405160405180910390a4505050565b6001600160a01b039081166000908152606760205260409020541690565b60008282018381101561119b5760405162461bcd60e51b8152600401610334906123ba565b9392505050565b6001600160a01b0382166111c85760405162461bcd60e51b815260040161033490612374565b804710610513576111e26001600160a01b0383168261179f565b816001600160a01b03167eddb683bb45cd5d0ad8a200c6fae7152b1c236ee90a4a37db692407f5cc38bd8260405161121a919061267c565b60405180910390a25050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061125a57508115155b949350505050565b600061126d3061183b565b15905090565b600054610100900460ff168061128c575061128c611262565b8061129a575060005460ff16155b6112b65760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff161580156112e1576000805460ff1961ff0019909116610100171660011790555b6112e9611841565b6106e26118c2565b6001600160a01b0384166113175760405162461bcd60e51b815260040161033490612374565b604051627eeac760e11b815281906001600160a01b0385169062fdd58e90611345903090879060040161220b565b60206040518083038186803b15801561135d57600080fd5b505afa158015611371573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113959190612142565b106109c357604051637921219560e11b81526001600160a01b0384169063f242432a906113cc9030908890879087906004016121d3565b600060405180830381600087803b1580156113e657600080fd5b505af11580156113fa573d6000803e3d6000fd5b5050505081836001600160a01b0316856001600160a01b03167f620337bf89eea2b9ae2657beead83b5fa620452817118348aff96e201d52598b84604051611442919061267c565b60405180910390a450505050565b6066546001600160a01b0384811691161461146a57610ff6565b600061147f6001600160a01b038716866115bf565b600081815260696020526040812091925061149a86866115f3565b60008481526068602052604090209091506114b5908261199c565b5060008381526068602052604081206114cd906119a8565b11156114e3576114dc836116ed565b82556114ea565b4360028301555b856001600160a01b0316886001600160a01b03167ff3cfcfc091fdd683cf6c013de9806af93f3af27b256a57cb776331291cef4085898860405161152f929190612685565b60405180910390a35050505050505050565b6000828211156115635760405162461bcd60e51b8152600401610334906123f1565b50900390565b6103488363a9059cbb60e01b848460405160240161158892919061220b565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526119b3565b600082826040516020016115d492919061215a565b60408051601f1981840301815291905280516020909101209392505050565b60008063adf8252d60e01b905060006060856001600160a01b03168386604051602401611620919061267c565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161165e919061217c565b6000604051808303816000865af19150503d806000811461169b576040519150601f19603f3d011682016040523d82523d6000602084013e6116a0565b606091505b509150915081156116c957808060200190518101906116bf9190612142565b9350505050610ba4565b60009350505050610ba4565b600061119b8383611a42565b600061119b8383611a5a565b60008181526068602052604081208190611706906119a8565b905060006032815b83811015611743576000868152606860205260409020611739906117329083611aa4565b8490611176565b925060010161170e565b6001841115611763576117606117598386611ab0565b8490611541565b92505b5090949350505050565b600080821161178e5760405162461bcd60e51b8152600401610334906124bc565b81838161179757fe5b049392505050565b804710156117bf5760405162461bcd60e51b815260040161033490612485565b6000826001600160a01b0316826040516117d890612198565b60006040518083038185875af1925050503d8060008114611815576040519150601f19603f3d011682016040523d82523d6000602084013e61181a565b606091505b50509050806103485760405162461bcd60e51b815260040161033490612428565b3b151590565b600054610100900460ff168061185a575061185a611262565b80611868575060005460ff16155b6118845760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff161580156106e2576000805460ff1961ff00199091166101001716600117905580156106f4576000805461ff001916905550565b600054610100900460ff16806118db57506118db611262565b806118e9575060005460ff16155b6119055760405162461bcd60e51b8152600401610334906124f3565b600054610100900460ff16158015611930576000805460ff1961ff0019909116610100171660011790555b600061193a610d59565b603380546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35080156106f4576000805461ff001916905550565b600061119b8383611aea565b6000610ba482611bb0565b6060611a08826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611bb49092919063ffffffff16565b8051909150156103485780806020019051810190611a26919061210a565b6103485760405162461bcd60e51b815260040161033490612611565b60009081526001919091016020526040902054151590565b6000611a668383611a42565b611a9c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ba4565b506000610ba4565b600061119b8383611bc3565b600082611abf57506000610ba4565b82820282848281611acc57fe5b041461119b5760405162461bcd60e51b815260040161033490612541565b60008181526001830160205260408120548015611ba65783546000198083019190810190600090879083908110611b1d57fe5b9060005260206000200154905080876000018481548110611b3a57fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080611b6a57fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610ba4565b6000915050610ba4565b5490565b606061125a8484600085611c08565b81546000908210611be65760405162461bcd60e51b8152600401610334906122c9565b826000018281548110611bf557fe5b9060005260206000200154905092915050565b6060611c138561183b565b611c2f5760405162461bcd60e51b8152600401610334906125da565b60006060866001600160a01b03168587604051611c4c919061217c565b60006040518083038185875af1925050503d8060008114611c89576040519150601f19603f3d011682016040523d82523d6000602084013e611c8e565b606091505b50915091508115611ca257915061125a9050565b805115611cb25780518082602001fd5b8360405162461bcd60e51b81526004016103349190612296565b60405180606001604052806000815260200160008152602001600081525090565b60008083601f840112611cfe578182fd5b50813567ffffffffffffffff811115611d15578182fd5b602083019150836020828501011115611d2d57600080fd5b9250929050565b600060208284031215611d45578081fd5b813561119b816126bf565b600060208284031215611d61578081fd5b815161119b816126bf565b600080600060608486031215611d80578182fd5b8335611d8b816126bf565b92506020840135611d9b816126bf565b929592945050506040919091013590565b60008060008060808587031215611dc1578081fd5b8435611dcc816126bf565b93506020850135611ddc816126bf565b93969395505050506040820135916060013590565b60008060408385031215611e03578182fd5b8235611e0e816126bf565b946020939093013593505050565b60008060408385031215611e2e578182fd5b8235611e39816126bf565b91506020830135611e49816126bf565b809150509250929050565b60008060008060008060008060e0898b031215611e6f578384fd5b8835611e7a816126bf565b97506020890135611e8a816126bf565b96506040890135611e9a816126bf565b955060608901359450608089013567ffffffffffffffff811115611ebc578485fd5b611ec88b828c01611ced565b90955093505060a0890135611edc816126bf565b8092505060c089013590509295985092959890939650565b600080600080600080600060e0888a031215611f0e578283fd5b8735611f19816126bf565b9650602088013595506040880135611f30816126bf565b94506060880135611f40816126bf565b93506080880135925060a0880135611f57816126bf565b8092505060c0880135905092959891949750929550565b600080600080600080600060c0888a031215611f88578283fd5b8735611f93816126bf565b965060208801359550604088013567ffffffffffffffff811115611fb5578384fd5b611fc18a828b01611ced565b9096509450506060880135611fd5816126bf565b92506080880135611fe5816126bf565b8092505060a0880135905092959891949750929550565b600080600080600080600060c0888a031215612016578081fd5b8735612021816126bf565b965060208801359550604088013567ffffffffffffffff811115612043578182fd5b61204f8a828b01611ced565b9096509450506060880135612063816126bf565b969995985093969295946080840135945060a09093013592915050565b60008060008060008060008060e0898b03121561209b578182fd5b88356120a6816126bf565b975060208901359650604089013567ffffffffffffffff8111156120c8578283fd5b6120d48b828c01611ced565b90975095505060608901356120e8816126bf565b979a96995094979396956080850135955060a08501359460c001359350915050565b60006020828403121561211b578081fd5b8151801515811461119b578182fd5b60006020828403121561213b578081fd5b5035919050565b600060208284031215612153578081fd5b5051919050565b60609290921b6bffffffffffffffffffffffff19168252601482015260340190565b6000825161218e818460208701612693565b9190910192915050565b90565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260009082015260c00190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03861681526020810185905260806040820181905281018390526000838560a08401378060a0858401015260a0601f19601f86011683010190508260608301529695505050505050565b6001600160a01b039390931683526020830191909152604082015260600190565b60006020825282518060208401526122b5816040850160208701612693565b601f01601f19169190910160400192915050565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b602080825260099082015268554e493a452d34303360b81b604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252600990820152684248503a452d34303360b81b604082015260600190565b602080825260099082015268554e493a452d34313760b81b604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252600990820152680aa9c92748a5a6260760bb1b604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b81518152602080830151908201526040918201519181019190915260600190565b90815260200190565b918252602082015260400190565b60005b838110156126ae578181015183820152602001612696565b838111156109c35750506000910152565b6001600160a01b03811681146106f457600080fdfea264697066735822122055c84894697dd3e92642a98fce78fc85de39452936a89059494ec186a3b80f2d64736f6c634300060c0033", + "devdoc": { + "details": "Upgradeable Contract", + "kind": "dev", + "methods": { + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Charged Particles Universe Contract with Rewards Program", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 680, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 683, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 3177, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 111, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "t_address" + }, + { + "astId": 230, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 16752, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_chargedParticles", + "offset": 0, + "slot": "101", + "type": "t_address" + }, + { + "astId": 16754, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_multiplierNft", + "offset": 0, + "slot": "102", + "type": "t_address" + }, + { + "astId": 16758, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_assetRewardPrograms", + "offset": 0, + "slot": "103", + "type": "t_mapping(t_address,t_address)" + }, + { + "astId": 16762, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_multiplierNftsSet", + "offset": 0, + "slot": "104", + "type": "t_mapping(t_uint256,t_struct(UintSet)8991_storage)" + }, + { + "astId": 16766, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_nftStake", + "offset": 0, + "slot": "105", + "type": "t_mapping(t_uint256,t_struct(NftStake)29442_storage)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_address)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_uint256,t_struct(NftStake)29442_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct IUniverseRP.NftStake)", + "numberOfBytes": "32", + "value": "t_struct(NftStake)29442_storage" + }, + "t_mapping(t_uint256,t_struct(UintSet)8991_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct EnumerableSet.UintSet)", + "numberOfBytes": "32", + "value": "t_struct(UintSet)8991_storage" + }, + "t_struct(NftStake)29442_storage": { + "encoding": "inplace", + "label": "struct IUniverseRP.NftStake", + "members": [ + { + "astId": 29437, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "multiplier", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 29439, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "depositBlockNumber", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 29441, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "releaseBlockNumber", + "offset": 0, + "slot": "2", + "type": "t_uint256" + } + ], + "numberOfBytes": "96" + }, + "t_struct(Set)8702_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 8697, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 8701, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_struct(UintSet)8991_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.UintSet", + "members": [ + { + "astId": 8990, + "contract": "contracts/v1/UniverseRP.sol:UniverseRP", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)8702_storage" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/deployments/polygon/UniverseRP_Proxy.json b/deployments/polygon/UniverseRP_Proxy.json new file mode 100644 index 0000000..c29668f --- /dev/null +++ b/deployments/polygon/UniverseRP_Proxy.json @@ -0,0 +1,264 @@ +{ + "address": "0x60d85948075c106b7605B2F549d0861e55608F19", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x507c836b98c9c0f8a8e78c51fecb2c4bab8c0873ee6299e4276beca7c94bc695", + "receipt": { + "to": null, + "from": "0xb8D175F16742395F530e0b3bC1d30BD06B78CdA9", + "contractAddress": "0x60d85948075c106b7605B2F549d0861e55608F19", + "transactionIndex": 27, + "gasUsed": "769446", + "logsBloom": "0x00000000000000000000000000000000400000000000000000800000000000402000000000000000000000000000000000008000000000000000000000000000000080000000000100000000000002800001000000400000000100000000000000000000020000000000400000000800000000800000000080000000000000400000000000000000000000020000000000000000000000000000000000800000220000000000000000000000000000000000000004000000000000000000004000000020000000000001000000000000000000000400000000100000000020000000000000000000000000000000000000010000000000000000000002100000", + "blockHash": "0x9ce9e7f299ae68bd8a7cbb5707bd3c833b14e6f61eaa177257e35c285efff24d", + "transactionHash": "0x507c836b98c9c0f8a8e78c51fecb2c4bab8c0873ee6299e4276beca7c94bc695", + "logs": [ + { + "transactionIndex": 27, + "blockNumber": 46700950, + "transactionHash": "0x507c836b98c9c0f8a8e78c51fecb2c4bab8c0873ee6299e4276beca7c94bc695", + "address": "0x60d85948075c106b7605B2F549d0861e55608F19", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000001aa013d7a31557ae1a60578394a8acc785935d06" + ], + "data": "0x", + "logIndex": 131, + "blockHash": "0x9ce9e7f299ae68bd8a7cbb5707bd3c833b14e6f61eaa177257e35c285efff24d" + }, + { + "transactionIndex": 27, + "blockNumber": 46700950, + "transactionHash": "0x507c836b98c9c0f8a8e78c51fecb2c4bab8c0873ee6299e4276beca7c94bc695", + "address": "0x60d85948075c106b7605B2F549d0861e55608F19", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000b8d175f16742395f530e0b3bc1d30bd06b78cda9" + ], + "data": "0x", + "logIndex": 132, + "blockHash": "0x9ce9e7f299ae68bd8a7cbb5707bd3c833b14e6f61eaa177257e35c285efff24d" + }, + { + "transactionIndex": 27, + "blockNumber": 46700950, + "transactionHash": "0x507c836b98c9c0f8a8e78c51fecb2c4bab8c0873ee6299e4276beca7c94bc695", + "address": "0x60d85948075c106b7605B2F549d0861e55608F19", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fd6b09036bf046f2b32e1d7345833bf21db6733", + "logIndex": 133, + "blockHash": "0x9ce9e7f299ae68bd8a7cbb5707bd3c833b14e6f61eaa177257e35c285efff24d" + }, + { + "transactionIndex": 27, + "blockNumber": 46700950, + "transactionHash": "0x507c836b98c9c0f8a8e78c51fecb2c4bab8c0873ee6299e4276beca7c94bc695", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000b8d175f16742395f530e0b3bc1d30bd06b78cda9", + "0x0000000000000000000000007c7379531b2aee82e4ca06d4175d13b9cbeafd49" + ], + "data": "0x000000000000000000000000000000000000000000000000006b5f699062507c00000000000000000000000000000000000000000000001a320f02b4e531a2a0000000000000000000000000000000000000000000024af6263b5650da18070300000000000000000000000000000000000000000000001a31a3a34b54cf5224000000000000000000000000000000000000000000024af626a6b5ba6a7a577f", + "logIndex": 134, + "blockHash": "0x9ce9e7f299ae68bd8a7cbb5707bd3c833b14e6f61eaa177257e35c285efff24d" + } + ], + "blockNumber": 46700950, + "cumulativeGasUsed": "6150147", + "status": 1, + "byzantium": true + }, + "args": [ + "0x1aA013d7A31557Ae1A60578394a8ACC785935D06", + "0x0fD6B09036BF046f2B32E1D7345833bf21db6733", + "0x8129fc1c" + ], + "numDeployments": 1, + "solcInputHash": "0e89febeebc7444140de8e67c9067d2c", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x93b4e21c931252739a1ec13ea31d3d35a5c068be3163ccab83e4d70c40355f03\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.implementation\\\")) - 1));\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0x6309f9f39dc6f4f45a24f296543867aa358e32946cd6b2874627a996d606b3a0\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view virtual returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(Address.isContract(IBeacon(newBeacon).implementation()), \\\"ERC1967: beacon implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x17668652127feebed0ce8d9431ef95ccc8c4292f03e3b8cf06c6ca16af396633\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internall call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overriden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xd5d1fd16e9faff7fcb3a52e02a8d49156f42a38a03f07b5f1810c21c2149a8ab\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin.\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(\\n address _logic,\\n address admin_,\\n bytes memory _data\\n ) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x140055a64cf579d622e04f5a198595832bf2cb193cd0005f4f2d4d61ca906253\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\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 * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev 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\":\"0x3777e696b62134e6177440dbe6e6601c0c156a443f57167194b67e75527439de\",\"license\":\"MIT\"},\"solc_0.8/openzeppelin/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfe1b7a9aa2a530a9e705b220e26cd584e2fbdc9602a3a1066032b12816b46aca\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051620011b2380380620011b2833981016040819052620000269162000519565b82816200005560017f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbd620005f9565b6000805160206200116b833981519152146200007557620000756200061f565b6200008382826000620000e7565b50620000b3905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005f9565b6000805160206200114b83398151915214620000d357620000d36200061f565b620000de8262000124565b50505062000688565b620000f2836200017f565b600082511180620001005750805b156200011f576200011d8383620001c160201b620002ff1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6200014f620001f0565b604080516001600160a01b03928316815291841660208301520160405180910390a16200017c8162000229565b50565b6200018a81620002de565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6060620001e983836040518060600160405280602781526020016200118b6027913962000381565b9392505050565b60006200021a6000805160206200114b83398151915260001b6200046760201b620002731760201c565b546001600160a01b0316919050565b6001600160a01b038116620002945760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002bd6000805160206200114b83398151915260001b6200046760201b620002731760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002f4816200046a60201b6200032b1760201c565b620003585760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016200028b565b80620002bd6000805160206200116b83398151915260001b6200046760201b620002731760201c565b60606001600160a01b0384163b620003eb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016200028b565b600080856001600160a01b03168560405162000408919062000635565b600060405180830381855af49150503d806000811462000445576040519150601f19603f3d011682016040523d82523d6000602084013e6200044a565b606091505b5090925090506200045d82828662000479565b9695505050505050565b90565b6001600160a01b03163b151590565b606083156200048a575081620001e9565b8251156200049b5782518084602001fd5b8160405162461bcd60e51b81526004016200028b919062000653565b80516001600160a01b0381168114620004cf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101562000507578181015183820152602001620004ed565b838111156200011d5750506000910152565b6000806000606084860312156200052f57600080fd5b6200053a84620004b7565b92506200054a60208501620004b7565b60408501519092506001600160401b03808211156200056857600080fd5b818601915086601f8301126200057d57600080fd5b815181811115620005925762000592620004d4565b604051601f8201601f19908116603f01168101908382118183101715620005bd57620005bd620004d4565b81604052828152896020848701011115620005d757600080fd5b620005ea836020830160208801620004ea565b80955050505050509250925092565b6000828210156200061a57634e487b7160e01b600052601160045260246000fd5b500390565b634e487b7160e01b600052600160045260246000fd5b6000825162000649818460208701620004ea565b9190910192915050565b602081526000825180602084015262000674816040850160208701620004ea565b601f01601f19169190910160400192915050565b610ab380620006986000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461091f565b610135565b61006b6100a336600461093a565b610196565b3480156100b457600080fd5b506100bd610221565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461091f565b610276565b34801561011257600080fd5b506100bd6102ba565b610123610347565b61013361012e610435565b61043f565b565b61013d610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816040518060200160405280600081525060006104a3565b50565b61018b61011b565b61019e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610219576102148383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506104a3915050565b505050565b61021461011b565b600061022b610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610435565b905090565b61027361011b565b90565b61027e610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561018e5761018b816104ce565b60006102c4610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561026b57610266610463565b60606103248383604051806060016040528060278152602001610a576027913961052f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b61034f610463565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b6000610266610657565b3660008037600080366000845af43d6000803e80801561045e573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6104ac8361067f565b6000825111806104b95750805b15610214576104c883836102ff565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104f7610463565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161018b816106cc565b606073ffffffffffffffffffffffffffffffffffffffff84163b6105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161042c565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105fd91906109e9565b600060405180830381855af49150503d8060008114610638576040519150601f19603f3d011682016040523d82523d6000602084013e61063d565b606091505b509150915061064d8282866107d8565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610487565b6106888161082b565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff811661076f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161042c565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b606083156107e7575081610324565b8251156107f75782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c9190610a05565b73ffffffffffffffffffffffffffffffffffffffff81163b6108cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161042c565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610792565b803573ffffffffffffffffffffffffffffffffffffffff8116811461091a57600080fd5b919050565b60006020828403121561093157600080fd5b610324826108f6565b60008060006040848603121561094f57600080fd5b610958846108f6565b9250602084013567ffffffffffffffff8082111561097557600080fd5b818601915086601f83011261098957600080fd5b81358181111561099857600080fd5b8760208285010111156109aa57600080fd5b6020830194508093505050509250925092565b60005b838110156109d85781810151838201526020016109c0565b838111156104c85750506000910152565b600082516109fb8184602087016109bd565b9190910192915050565b6020815260008251806020840152610a248160408501602087016109bd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b29caa54336b3ee836679675e9732ec5e526fb3f803cca2fe336cc3555aba62264736f6c634300080a0033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/polygon/solcInputs/0e89febeebc7444140de8e67c9067d2c.json b/deployments/polygon/solcInputs/0e89febeebc7444140de8e67c9067d2c.json new file mode 100644 index 0000000..6eb5ed9 --- /dev/null +++ b/deployments/polygon/solcInputs/0e89febeebc7444140de8e67c9067d2c.json @@ -0,0 +1,80 @@ +{ + "language": "Solidity", + "sources": { + "solc_0.8/openzeppelin/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 (address initialOwner) {\n _transferOwnership(initialOwner);\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" + }, + "solc_0.8/openzeppelin/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" + }, + "solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"../../access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n\n constructor (address initialOwner) Ownable(initialOwner) {}\n\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(\n TransparentUpgradeableProxy proxy,\n address implementation,\n bytes memory data\n ) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(\n address _logic,\n address admin_,\n bytes memory _data\n ) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _changeAdmin(admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n _changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internall call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overriden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n" + }, + "solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view virtual returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(Address.isContract(IBeacon(newBeacon).implementation()), \"ERC1967: beacon implementation is not a contract\");\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "solc_0.8/openzeppelin/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\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 * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev 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" + }, + "solc_0.8/openzeppelin/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n assembly {\n r.slot := slot\n }\n }\n}\n" + }, + "solc_0.8/proxy/OptimizedTransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract OptimizedTransparentUpgradeableProxy is ERC1967Proxy {\n address internal immutable _ADMIN;\n\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(\n address _logic,\n address admin_,\n bytes memory _data\n ) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _ADMIN = admin_;\n\n // still store it to work with EIP-1967\n bytes32 slot = _ADMIN_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, admin_)\n }\n emit AdminChanged(address(0), admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n\n function _getAdmin() internal view virtual override returns (address) {\n return _ADMIN;\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/utils/UUPSUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../ERC1967/ERC1967Upgrade.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n *\n * _Available since v4.1._\n */\nabstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade {\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\n address private immutable __self = address(this);\n\n /**\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n * fail.\n */\n modifier onlyProxy() {\n require(address(this) != __self, \"Function must be called through delegatecall\");\n require(_getImplementation() == __self, \"Function must be called through active proxy\");\n _;\n }\n\n /**\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\n * callable on the implementing contract but not through proxies.\n */\n modifier notDelegated() {\n require(address(this) == __self, \"UUPSUpgradeable: must not be called through delegatecall\");\n _;\n }\n\n /**\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\n * implementation. It is used to validate that the this implementation remains valid after an upgrade.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\n */\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\n return _IMPLEMENTATION_SLOT;\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n */\n function upgradeTo(address newImplementation) external virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n * encoded in `data`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n */\n function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, data, true);\n }\n\n /**\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n * {upgradeTo} and {upgradeToAndCall}.\n *\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\n *\n * ```solidity\n * function _authorizeUpgrade(address) internal override onlyOwner {}\n * ```\n */\n function _authorizeUpgrade(address newImplementation) internal virtual;\n}\n" + }, + "solc_0.8/openzeppelin/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * 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 !Address.isContract(address(this));\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/beacon/UpgradeableBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/UpgradeableBeacon.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IBeacon.sol\";\nimport \"../../access/Ownable.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their\n * implementation contract, which is where they will delegate all function calls.\n *\n * An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon.\n */\ncontract UpgradeableBeacon is IBeacon, Ownable {\n address private _implementation;\n\n /**\n * @dev Emitted when the implementation returned by the beacon is changed.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Sets the address of the initial implementation, and the deployer account as the owner who can upgrade the\n * beacon.\n */\n\n constructor(address implementation_, address initialOwner) Ownable(initialOwner) {\n _setImplementation(implementation_);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function implementation() public view virtual override returns (address) {\n return _implementation;\n }\n\n /**\n * @dev Upgrades the beacon to a new implementation.\n *\n * Emits an {Upgraded} event.\n *\n * Requirements:\n *\n * - msg.sender must be the owner of the contract.\n * - `newImplementation` must be a contract.\n */\n function upgradeTo(address newImplementation) public virtual onlyOwner {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Sets the implementation contract address for this beacon\n *\n * Requirements:\n *\n * - `newImplementation` must be a contract.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"UpgradeableBeacon: implementation is not a contract\");\n _implementation = newImplementation;\n }\n}\n" + }, + "solc_0.8/openzeppelin/proxy/beacon/BeaconProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/BeaconProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IBeacon.sol\";\nimport \"../Proxy.sol\";\nimport \"../ERC1967/ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements a proxy that gets the implementation address for each call from a {UpgradeableBeacon}.\n *\n * The beacon address is stored in storage slot `uint256(keccak256('eip1967.proxy.beacon')) - 1`, so that it doesn't\n * conflict with the storage layout of the implementation behind the proxy.\n *\n * _Available since v3.4._\n */\ncontract BeaconProxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the proxy with `beacon`.\n *\n * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This\n * will typically be an encoded function call, and allows initializating the storage of the proxy like a Solidity\n * constructor.\n *\n * Requirements:\n *\n * - `beacon` must be a contract with the interface {IBeacon}.\n */\n constructor(address beacon, bytes memory data) payable {\n assert(_BEACON_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.beacon\")) - 1));\n _upgradeBeaconToAndCall(beacon, data, false);\n }\n\n /**\n * @dev Returns the current beacon address.\n */\n function _beacon() internal view virtual returns (address) {\n return _getBeacon();\n }\n\n /**\n * @dev Returns the current implementation address of the associated beacon.\n */\n function _implementation() internal view virtual override returns (address) {\n return IBeacon(_getBeacon()).implementation();\n }\n\n /**\n * @dev Changes the proxy to use a new beacon. Deprecated: see {_upgradeBeaconToAndCall}.\n *\n * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon.\n *\n * Requirements:\n *\n * - `beacon` must be a contract.\n * - The implementation returned by `beacon` must be a contract.\n */\n function _setBeacon(address beacon, bytes memory data) internal virtual {\n _upgradeBeaconToAndCall(beacon, data, false);\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "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/deployments/polygon/solcInputs/3690d415d9dd47a6d97f03bb58afbf9e.json b/deployments/polygon/solcInputs/3690d415d9dd47a6d97f03bb58afbf9e.json new file mode 100644 index 0000000..3ae43d6 --- /dev/null +++ b/deployments/polygon/solcInputs/3690d415d9dd47a6d97f03bb58afbf9e.json @@ -0,0 +1,455 @@ +{ + "language": "Solidity", + "sources": { + "@opengsn/gsn/contracts/BaseRelayRecipient.sol": { + "content": "// SPDX-License-Identifier:MIT\n// solhint-disable no-inline-assembly\npragma solidity ^0.6.2;\n\nimport \"./interfaces/IRelayRecipient.sol\";\n\n/**\n * A base contract to be inherited by any contract that want to receive relayed transactions\n * A subclass must use \"_msgSender()\" instead of \"msg.sender\"\n */\nabstract contract BaseRelayRecipient is IRelayRecipient {\n\n /*\n * Forwarder singleton we accept calls from\n */\n address public trustedForwarder;\n\n function isTrustedForwarder(address forwarder) public override view returns(bool) {\n return forwarder == trustedForwarder;\n }\n\n /**\n * return the sender of this call.\n * if the call came through our trusted forwarder, return the original sender.\n * otherwise, return `msg.sender`.\n * should be used in the contract anywhere instead of msg.sender\n */\n function _msgSender() internal override virtual view returns (address payable ret) {\n if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // so we trust that the last bytes of msg.data are the verified sender address.\n // extract sender address from the end of msg.data\n assembly {\n ret := shr(96,calldataload(sub(calldatasize(),20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n /**\n * return the msg.data of this call.\n * if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes\n * of the msg.data - so this method will strip those 20 bytes off.\n * otherwise, return `msg.data`\n * should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly\n * signing or hashing the\n */\n function _msgData() internal override virtual view returns (bytes memory ret) {\n if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // we copy the msg.data , except the last 20 bytes (and update the total length)\n assembly {\n let ptr := mload(0x40)\n // copy only size-20 bytes\n let size := sub(calldatasize(),20)\n // structure RLP data as \n mstore(ptr, 0x20)\n mstore(add(ptr,32), size)\n calldatacopy(add(ptr,64), 0, size)\n return(ptr, add(size,64))\n }\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "@opengsn/gsn/contracts/interfaces/IRelayRecipient.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.6.2;\n\n/**\n * a contract must implement this interface in order to support relayed transaction.\n * It is better to inherit the BaseRelayRecipient as its implementation.\n */\nabstract contract IRelayRecipient {\n\n /**\n * return if the forwarder is trusted to forward relayed transactions to us.\n * the forwarder is required to verify the sender's signature, and verify\n * the call is not a replay.\n */\n function isTrustedForwarder(address forwarder) public virtual view returns(bool);\n\n /**\n * return the sender of this call.\n * if the call came through our trusted forwarder, then the real sender is appended as the last 20 bytes\n * of the msg.data.\n * otherwise, return `msg.sender`\n * should be used in the contract anywhere instead of msg.sender\n */\n function _msgSender() internal virtual view returns (address payable);\n\n /**\n * return the msg.data of this call.\n * if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes\n * of the msg.data - so this method will strip those 20 bytes off.\n * otherwise, return `msg.data`\n * should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly\n * signing or hashing the\n */\n function _msgData() internal virtual view returns (bytes memory);\n\n function versionRecipient() external virtual view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\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 initializer {\n __Context_init_unchained();\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal initializer {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), 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 emit OwnershipTransferred(_owner, address(0));\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n function __ERC165_init() internal initializer {\n __ERC165_init_unchained();\n }\n\n function __ERC165_init_unchained() internal initializer {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMathUpgradeable {\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 uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\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 if (b > a) return (false, 0);\n return (true, a - b);\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 // 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 * @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 if (b == 0) return (false, 0);\n return (true, a / b);\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 if (b == 0) return (false, 0);\n return (true, a % b);\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 uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n return c;\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 require(b <= a, \"SafeMath: subtraction overflow\");\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 if (a == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n return c;\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. 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(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: division by zero\");\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 require(b > 0, \"SafeMath: modulo by zero\");\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n return a - b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a / b;\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.4.24 <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 {UpgradeableProxy-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 */\nabstract contract Initializable {\n\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 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 /// @dev Returns true if and only if the function is running in the constructor\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\n\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 )\n external\n 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 )\n external\n returns(bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC20Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../proxy/Initializable.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 guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable {\n using SafeMathUpgradeable for uint256;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal initializer {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer {\n _name = name_;\n _symbol = symbol_;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal virtual {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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(address sender, address recipient, uint256 amount) 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/ERC20/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.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 SafeERC20Upgradeable {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) 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(IERC20Upgradeable token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\n require((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(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\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(IERC20Upgradeable 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) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721MetadataUpgradeable.sol\";\nimport \"./IERC721EnumerableUpgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"../../introspection/ERC165Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/EnumerableSetUpgradeable.sol\";\nimport \"../../utils/EnumerableMapUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../proxy/Initializable.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable, IERC721EnumerableUpgradeable {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet;\n using EnumerableMapUpgradeable for EnumerableMapUpgradeable.UintToAddressMap;\n using StringsUpgradeable for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSetUpgradeable.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMapUpgradeable.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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 initializer {\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 initializer {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\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 _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\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 _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\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(_msgSender() == owner || ERC721Upgradeable.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 require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) 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(address from, address to, uint256 tokenId, bytes memory _data) 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 _tokenOwners.contains(tokenId);\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 || ERC721Upgradeable.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\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 _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(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); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(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(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721ReceiverUpgradeable(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); // internal owner\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(address from, address to, uint256 tokenId) internal virtual { }\n uint256[41] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721EnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 /**\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/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 /**\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\npragma solidity >=0.6.0 <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(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) 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 // solhint-disable-next-line avoid-low-level-calls\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(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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 // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/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 GSN 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 initializer {\n __Context_init_unchained();\n }\n\n function __Context_init_unchained() internal initializer {\n }\n function _msgSender() internal view virtual returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/EnumerableMapUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMapUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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 EnumerableSetUpgradeable {\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\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\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] = toDeleteIndex + 1; // All indexes are 1-based\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 require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\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 // 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 // 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" + }, + "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/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 initializer {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal initializer {\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 make 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/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n /**\n * @dev Converts a `uint256` to its ASCII `string` 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 uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = bytes1(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../GSN/Context.sol\";\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 */\ncontract 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 () internal {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), msgSender);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view 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 emit OwnershipTransferred(_owner, address(0));\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n" + }, + "@openzeppelin/contracts/cryptography/MerkleProof.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev These functions deal with verification of Merkle trees (hash trees),\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(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {\n bytes32 computedHash = leaf;\n\n for (uint256 i = 0; i < proof.length; i++) {\n bytes32 proofElement = proof[i];\n\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\n // Check if the computed hash (root) is equal to the provided root\n return computedHash == root;\n }\n}\n" + }, + "@openzeppelin/contracts/GSN/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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 GSN 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 payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\ncontract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () internal {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n" + }, + "@openzeppelin/contracts/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\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 uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\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 sub(a, b, \"SafeMath: subtraction overflow\");\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 * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\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 // 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) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts 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 mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\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 SafeMath for uint256;\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 * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri) public {\n _setURI(uri);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\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) external view 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 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(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\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 require(accounts[i] != address(0), \"ERC1155: batch balance query for the zero address\");\n batchBalances[i] = _balances[ids[i]][accounts[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 require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view 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 )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, 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 )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\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 _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(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 `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` 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(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, 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(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) 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 (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\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 `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, 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(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != 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, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\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 )\n internal virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).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 )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).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/token/ERC1155/ERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() public {\n _registerInterface(\n ERC1155Receiver(0).onERC1155Received.selector ^\n ERC1155Receiver(0).onERC1155BatchReceived.selector\n );\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\nimport \"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\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 )\n external\n 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 )\n external\n returns(bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.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 guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 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 {\n using SafeMath for uint256;\n using Address for address;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name, string memory symbol) public {\n _name = name;\n _symbol = symbol;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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/token/ERC20/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.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 SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\n require((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(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\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) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n\n // If there is no base URI, return the token URI.\n if (bytes(_baseURI).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(_baseURI, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(_baseURI, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_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 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 require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) 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(address from, address to, uint256 tokenId, bytes memory _data) 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 returns (bool) {\n return _tokenOwners.contains(tokenId);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = 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 d*\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\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 _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(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 = ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(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(address from, address to, uint256 tokenId) internal virtual {\n require(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 _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\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(address from, address to, uint256 tokenId) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\nimport \"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 /**\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/token/ERC721/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 /**\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/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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(address operator, address from, uint256 tokenId, bytes calldata data)\n external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 in 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 // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n return _functionCallWithValue(target, data, value, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\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 // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../math/SafeMath.sol\";\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented or decremented by one. 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 * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}\n * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never\n * directly accessed.\n */\nlibrary Counters {\n using SafeMath for uint256;\n\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 // The {SafeMath} overflow check can be skipped here, see the comment at the top\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableMap.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n return _get(map, key, \"EnumerableMap: nonexistent key\");\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(value)));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint256(value)));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint256(_get(map._inner, bytes32(key))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint256(_get(map._inner, bytes32(key), errorMessage)));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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.0.0, only sets of type `address` (`AddressSet`) and `uint256`\n * (`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\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\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] = toDeleteIndex + 1; // All indexes are 1-based\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 require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\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(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(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(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(uint256(_at(set._inner, index)));\n }\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" + }, + "@openzeppelin/contracts/utils/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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 */\ncontract 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 () internal {\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 make 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/utils/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value < 2**128, \"SafeCast: value doesn\\'t fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value < 2**64, \"SafeCast: value doesn\\'t fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value < 2**32, \"SafeCast: value doesn\\'t fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value < 2**16, \"SafeCast: value doesn\\'t fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value < 2**8, \"SafeCast: value doesn\\'t fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= -2**127 && value < 2**127, \"SafeCast: value doesn\\'t fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= -2**63 && value < 2**63, \"SafeCast: value doesn\\'t fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= -2**31 && value < 2**31, \"SafeCast: value doesn\\'t fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= -2**15 && value < 2**15, \"SafeCast: value doesn\\'t fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= -2**7 && value < 2**7, \"SafeCast: value doesn\\'t fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n require(value < 2**255, \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` 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 uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = byte(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n" + }, + "contracts/v1/ChargedManagers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Wallet-Managers Contract\n */\ncontract ChargedManagers is\n IChargedManagers,\n Initializable,\n OwnableUpgradeable,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n\n IChargedSettings internal _chargedSettings;\n IChargedState internal _chargedState;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // Wallet/Basket Managers (by Unique Manager ID)\n mapping (string => IWalletManager) internal _ftWalletManager;\n mapping (string => IBasketManager) internal _nftBasketManager;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n /// @notice Checks if an Account is the Owner of an NFT Contract\n /// When Custom Contracts are registered, only the \"owner\" or operator of the Contract\n /// is allowed to register them and define custom rules for how their tokens are \"Charged\".\n /// Otherwise, any token can be \"Charged\" according to the default rules of Charged Particles.\n /// @param contractAddress The Address to the External NFT Contract to check\n /// @param account The Account to check if it is the Owner of the specified Contract\n /// @return True if the account is the Owner of the _contract\n function isContractOwner(address contractAddress, address account) external view override virtual returns (bool) {\n return contractAddress.isContractOwner(account);\n }\n\n function isWalletManagerEnabled(string calldata walletManagerId) external virtual override view returns (bool) {\n return _isWalletManagerEnabled(walletManagerId);\n }\n\n function getWalletManager(string calldata walletManagerId) external virtual override view returns (IWalletManager) {\n return _ftWalletManager[walletManagerId];\n }\n\n function isNftBasketEnabled(string calldata basketId) external virtual override view returns (bool) {\n return _isNftBasketEnabled(basketId);\n }\n\n function getBasketManager(string calldata basketId) external virtual override view returns (IBasketManager) {\n return _nftBasketManager[basketId];\n }\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param sender The sender address to validate against\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external virtual override {\n _validateDeposit(sender, contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param sender The sender address to validate against\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external virtual override {\n _validateNftDeposit(sender, contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateDischarge(sender, contractAddress, tokenId);\n }\n\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateRelease(sender, contractAddress, tokenId);\n }\n\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateBreakBond(sender, contractAddress, tokenId);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"state\"))) {\n _chargedState = IChargedState(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n /// @dev Register Contracts as wallet managers with a unique liquidity provider ID\n function registerWalletManager(string calldata walletManagerId, address walletManager) external virtual onlyOwner {\n // Validate wallet manager\n IWalletManager newWalletMgr = IWalletManager(walletManager);\n require(newWalletMgr.isPaused() != true, \"CP:E-418\");\n\n // Register LP ID\n _ftWalletManager[walletManagerId] = newWalletMgr;\n emit WalletManagerRegistered(walletManagerId, walletManager);\n }\n\n /// @dev Register Contracts as basket managers with a unique basket ID\n function registerBasketManager(string calldata basketId, address basketManager) external virtual onlyOwner {\n // Validate basket manager\n IBasketManager newBasketMgr = IBasketManager(basketManager);\n require(newBasketMgr.isPaused() != true, \"CP:E-418\");\n\n // Register Basket ID\n _nftBasketManager[basketId] = newBasketMgr;\n emit BasketManagerRegistered(basketId, basketManager);\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev See {ChargedParticles-isWalletManagerEnabled}.\n function _isWalletManagerEnabled(string calldata walletManagerId) internal view virtual returns (bool) {\n return (address(_ftWalletManager[walletManagerId]) != address(0x0) && !_ftWalletManager[walletManagerId].isPaused());\n }\n\n /// @dev See {ChargedParticles-isNftBasketEnabled}.\n function _isNftBasketEnabled(string calldata basketId) internal view virtual returns (bool) {\n return (address(_nftBasketManager[basketId]) != address(0x0) && !_nftBasketManager[basketId].isPaused());\n }\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n internal\n virtual\n {\n if (_chargedState.isEnergizeRestricted(contractAddress, tokenId)) {\n bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender);\n require(isNFTOwnerOrOperator, \"CP:E-105\");\n }\n\n ( string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n ) = _chargedSettings.getAssetRequirements(contractAddress, assetToken);\n\n require(energizeEnabled, \"CP:E-417\");\n\n require(!invalidAsset, \"CP:E-424\");\n\n // Valid Wallet Manager?\n if (bytes(requiredWalletManager).length > 0) {\n require(keccak256(abi.encodePacked(requiredWalletManager)) == keccak256(abi.encodePacked(walletManagerId)), \"CP:E-419\");\n }\n\n // Valid Asset?\n if (restrictedAssets) {\n require(validAsset, \"CP:E-424\");\n }\n\n _validateDepositAmount(\n contractAddress,\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n depositCap,\n depositMin,\n depositMax\n );\n }\n\n /// @dev Validates a Deposit-Amount according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDepositAmount(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax\n )\n internal\n virtual\n {\n uint256 existingBalance = _ftWalletManager[walletManagerId].getPrincipal(contractAddress, tokenId, assetToken);\n uint256 newBalance = assetAmount.add(existingBalance);\n\n // Validate Deposit Cap\n if (depositCap > 0) {\n require(newBalance <= depositCap, \"CP:E-408\");\n }\n\n // Valid Amount for Deposit?\n if (depositMin > 0) {\n require(newBalance >= depositMin, \"CP:E-410\");\n }\n if (depositMax > 0) {\n require(newBalance <= depositMax, \"CP:E-410\");\n }\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n {\n // Prevent Ouroboros NFTs\n require(contractAddress.getTokenUUID(tokenId) != nftTokenAddress.getTokenUUID(nftTokenId), \"CP:E-433\");\n\n if (_chargedState.isCovalentBondRestricted(contractAddress, tokenId)) {\n bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender);\n require(isNFTOwnerOrOperator, \"CP:E-105\");\n }\n\n ( string memory requiredBasketManager,\n bool basketEnabled,\n uint256 maxNfts\n ) = _chargedSettings.getNftAssetRequirements(contractAddress, nftTokenAddress);\n\n require(basketEnabled, \"CP:E-417\");\n\n // Valid Basket Manager?\n if (bytes(requiredBasketManager).length > 0) {\n require(keccak256(abi.encodePacked(requiredBasketManager)) == keccak256(abi.encodePacked(basketManagerId)), \"CP:E-419\");\n }\n\n if (maxNfts > 0) {\n uint256 tokenCount = _nftBasketManager[basketManagerId].getTokenTotalCount(contractAddress, tokenId);\n require(maxNfts >= (tokenCount + nftTokenAmount), \"CP:E-427\");\n }\n }\n\n function _validateDischarge(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getDischargeState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateRelease(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getReleaseState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateBreakBond(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getBreakBondState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateState(\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n internal\n view\n virtual\n {\n if (!allowFromAll) {\n require(isApproved, \"CP:E-105\");\n }\n if (timelock > 0) {\n require(block.number >= timelock, \"CP:E-302\");\n }\n if (tempLockExpiry > 0) {\n require(block.number >= tempLockExpiry, \"CP:E-303\");\n }\n }\n}\n" + }, + "contracts/v1/ChargedParticles.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\n\nimport \"./interfaces/IUniverse.sol\";\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/IWalletManager.sol\";\nimport \"./interfaces/IBasketManager.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/RelayRecipient.sol\";\n\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles V2 Contract\n * @dev Upgradeable Contract\n */\ncontract ChargedParticles is\n IChargedParticles,\n Initializable,\n OwnableUpgradeable,\n ReentrancyGuardUpgradeable,\n RelayRecipient,\n IERC721ReceiverUpgradeable,\n BlackholePrevention,\n IERC1155ReceiverUpgradeable\n{\n using SafeMathUpgradeable for uint256;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using Bitwise for uint32;\n using AddressUpgradeable for address;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n //\n // Particle Terminology\n //\n // Particle - Non-fungible Token (NFT)\n // Mass - Underlying Asset of a Token (ex; DAI)\n // Charge - Accrued Interest on the Underlying Asset of a Token\n // Charged Particle - Any NFT that has a Mass and a Positive Charge\n // Neutral Particle - Any NFT that has a Mass and No Charge\n // Energize / Recharge - Deposit of an Underlying Asset into an NFT\n // Discharge - Withdraw the Accrued Interest of an NFT leaving the Particle with its initial Mass\n // Release - Withdraw the Underlying Asset & Accrued Interest of an NFT leaving the Particle with No Mass or Charge\n //\n // Proton - NFTs minted from the Charged Particle Accelerator\n // - A proton is a subatomic particle, symbol p or p⁺, with a positive electric charge of +1e elementary\n // charge and a mass slightly less than that of a neutron.\n // Ion - Platform Governance Token\n // - A charged subatomic particle. An atom or group of atoms that carries a positive or negative electric charge\n // as a result of having lost or gained one or more electrons.\n //\n\n // Linked Contracts\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n address internal _lepton;\n uint256 internal depositFee;\n ITokenInfoProxy internal _tokenInfoProxy;\n IChargedManagers internal _chargedManagers;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n __ReentrancyGuard_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getStateAddress() external view virtual override returns (address stateAddress) {\n return address(_chargedState);\n }\n\n function getSettingsAddress() external view virtual override returns (address settingsAddress) {\n return address(_chargedSettings);\n }\n\n function getManagersAddress() external view virtual override returns (address managersAddress) {\n return address(_chargedManagers);\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external virtual override returns (bytes4) {\n return IERC721ReceiverUpgradeable(0).onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external virtual override returns (bytes4) {\n return IERC1155ReceiverUpgradeable(0).onERC1155Received.selector;\n }\n\n // Unimplemented\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external virtual override returns (bytes4) {\n return \"\"; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector;\n }\n\n function supportsInterface(bytes4 /* interfaceId */) external view virtual override returns (bool) {\n return false;\n }\n\n /// @notice Calculates the amount of Fees to be paid for a specific deposit amount\n /// @param assetAmount The Amount of Assets to calculate Fees on\n /// @return protocolFee The amount of deposit fees for the protocol\n function getFeesForDeposit(\n uint256 assetAmount\n )\n external\n override\n view\n returns (uint256 protocolFee)\n {\n protocolFee = _getFeesForDeposit(assetAmount);\n }\n\n /// @notice Gets the Amount of Asset Tokens that have been Deposited into the Particle\n /// representing the Mass of the Particle.\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Asset balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The Amount of underlying Assets held within the Token\n function baseParticleMass(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _baseParticleMass(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the amount of Interest that the Particle has generated representing\n /// the Charge of the Particle\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Interest balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The amount of interest the Token has generated (in Asset Token)\n function currentParticleCharge(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _currentParticleCharge(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the amount of LP Tokens that the Particle has generated representing\n /// the Kinetics of the Particle\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Kinetics balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The amount of LP tokens that have been generated\n function currentParticleKinetics(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _currentParticleKinetics(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the total amount of ERC721 Tokens that the Particle holds\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param basketManagerId The ID of the BasketManager to check the token balance of\n /// @return The total amount of ERC721 tokens that are held within the Particle\n function currentParticleCovalentBonds(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId\n )\n external\n view\n virtual\n override\n basketEnabled(basketManagerId)\n returns (uint256)\n {\n return _currentParticleCovalentBonds(contractAddress, tokenId, basketManagerId);\n }\n\n\n /***********************************|\n | Energize Particles |\n |__________________________________*/\n\n /// @notice Fund Particle with Asset Token\n /// Must be called by the account providing the Asset\n /// Account must Approve THIS contract as Operator of Asset\n ///\n /// NOTE: DO NOT Energize an ERC20 Token, as anyone who holds any amount\n /// of the same ERC20 token could discharge or release the funds.\n /// All holders of the ERC20 token would essentially be owners of the Charged Particle.\n ///\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param walletManagerId The Asset-Pair to Energize the Token with\n /// @param assetToken The Address of the Asset Token being used\n /// @param assetAmount The Amount of Asset Token to Energize the Token with\n /// @return yieldTokensAmount The amount of Yield-bearing Tokens added to the escrow for the Token\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 yieldTokensAmount)\n {\n _validateDeposit(contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n\n // Transfer ERC20 Token from Caller to Contract (reverts on fail)\n uint256 feeAmount = _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n yieldTokensAmount = _depositIntoWalletManager(contractAddress, tokenId, walletManagerId, assetToken, assetAmount, feeAmount);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onEnergize(_msgSender(), referrer, contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n }\n\n\n /***********************************|\n | Discharge Particles |\n |__________________________________*/\n\n /// @notice Allows the owner or operator of the Token to collect or transfer the interest generated\n /// from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @return creatorAmount Amount of Asset Token discharged to the Creator\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateDischarge(contractAddress, tokenId);\n\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).discharge(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount);\n }\n }\n\n /// @notice Allows the owner or operator of the Token to collect or transfer a specific amount of the interest\n /// generated from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @param assetAmount The specific amount of Asset Token to Discharge from the Token\n /// @return creatorAmount Amount of Asset Token discharged to the Creator\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateDischarge(contractAddress, tokenId);\n\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).dischargeAmount(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n assetAmount,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount);\n }\n }\n\n /// @notice Allows the Creator of the Token to collect or transfer a their portion of the interest (if any)\n /// generated from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @param assetAmount The specific amount of Asset Token to Discharge from the Particle\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 receiverAmount)\n {\n address sender = _msgSender();\n address tokenCreator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId);\n require(sender == tokenCreator, \"CP:E-104\");\n\n receiverAmount = _chargedManagers.getWalletManager(walletManagerId).dischargeAmountForCreator(\n receiver,\n contractAddress,\n tokenId,\n sender,\n assetToken,\n assetAmount\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischargeForCreator(contractAddress, tokenId, walletManagerId, sender, assetToken, receiverAmount);\n }\n }\n\n\n /***********************************|\n | Release Particles |\n |__________________________________*/\n\n /// @notice Releases the Full amount of Asset + Interest held within the Particle by LP of the Assets\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Release\n /// @param tokenId The ID of the Token to Release\n /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token\n /// @param assetToken The Address of the Asset Token being released\n /// @return creatorAmount Amount of Asset Token released to the Creator\n /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount)\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateRelease(contractAddress, tokenId);\n\n // Release Particle to Receiver\n uint256 principalAmount;\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).release(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n }\n\n\n /// @notice Releases a partial amount of Asset + Interest held within the Particle by LP of the Assets\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Release\n /// @param tokenId The ID of the Token to Release\n /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token\n /// @param assetToken The Address of the Asset Token being released\n /// @param assetAmount The specific amount of Asset Token to Release from the Particle\n /// @return creatorAmount Amount of Asset Token released to the Creator\n /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount)\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateRelease(contractAddress, tokenId);\n\n // Release Particle to Receiver\n uint256 principalAmount;\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).releaseAmount(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n assetAmount,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n }\n\n\n /***********************************|\n | Covalent Bonding |\n |__________________________________*/\n\n /// @notice Deposit other NFT Assets into the Particle\n /// Must be called by the account providing the Asset\n /// Account must Approve THIS contract as Operator of Asset\n ///\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n basketEnabled(basketManagerId)\n nonReentrant\n returns (bool success)\n {\n _validateNftDeposit(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Transfer ERC721 Token from Caller to Contract (reverts on fail)\n _collectNftToken(_msgSender(), nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n success = _depositIntoBasketManager(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onCovalentBond(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n }\n\n /// @notice Release NFT Assets from the Particle\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Withdraw (ERC1155-specific)\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n basketEnabled(basketManagerId)\n nonReentrant\n returns (bool success)\n {\n _validateBreakBond(contractAddress, tokenId);\n\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked(\"generic\"))) {\n basketMgr.prepareTransferAmount(nftTokenAmount);\n }\n\n // Release Particle to Receiver\n success = basketMgr.removeFromBasket(\n receiver,\n contractAddress,\n tokenId,\n nftTokenAddress,\n nftTokenId\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onCovalentBreak(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"universe\"))) {\n _universe = IUniverse(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"state\"))) {\n _chargedState = IChargedState(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"managers\"))) {\n _chargedManagers = IChargedManagers(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"leptons\"))) {\n _lepton = controller;\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"forwarder\"))) {\n trustedForwarder = controller;\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n\n /***********************************|\n | Protocol Fees |\n |__________________________________*/\n\n /// @dev Setup the Base Deposit Fee for the Protocol\n function setDepositFee(uint256 fee) external onlyOwner {\n require(fee < PERCENTAGE_SCALE, \"CP:E-421\");\n depositFee = fee;\n emit DepositFeeSet(fee);\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n internal\n virtual\n {\n _chargedManagers.validateDeposit(_msgSender(), contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _validateNftDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n {\n _chargedManagers.validateNftDeposit(_msgSender(), contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function _validateDischarge(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateDischarge(_msgSender(), contractAddress, tokenId);\n }\n\n function _validateRelease(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateRelease(_msgSender(), contractAddress, tokenId);\n }\n\n function _validateBreakBond(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateBreakBond(_msgSender(), contractAddress, tokenId);\n }\n\n /// @dev Deposit Asset Tokens into an NFT via the Wallet Manager\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n /// @param feeAmount The Amount of Protocol Fees charged\n function _depositIntoWalletManager(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 feeAmount\n )\n internal\n virtual\n returns (uint256)\n {\n // Get Wallet-Manager for LP\n IWalletManager lpWalletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n address wallet = lpWalletMgr.getWalletAddressById(contractAddress, tokenId, creator, annuityPct);\n IERC20Upgradeable(assetToken).transfer(wallet, assetAmount);\n\n emit ProtocolFeesCollected(assetToken, assetAmount, feeAmount);\n\n return lpWalletMgr.energize(contractAddress, tokenId, assetToken, assetAmount);\n }\n\n /// @dev Deposit NFT Tokens into the Basket Manager\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @param basketManagerId The Wallet Manager of the Assets to Deposit\n /// @param nftTokenAddress The Address of the Asset Token to Deposit\n /// @param nftTokenId The specific amount of Asset Token to Deposit\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _depositIntoBasketManager(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n returns (bool)\n {\n // Deposit NFT Token directly into Smart Wallet (reverts on fail) and Update BasketManager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId);\n\n if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked(\"generic\"))) {\n basketMgr.prepareTransferAmount(nftTokenAmount);\n }\n\n if (_isERC1155(nftTokenAddress)) {\n if (nftTokenAmount == 0) { nftTokenAmount = 1; }\n IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(address(this), wallet, nftTokenId, nftTokenAmount, \"\");\n } else {\n IERC721Upgradeable(nftTokenAddress).transferFrom(address(this), wallet, nftTokenId);\n }\n return basketMgr.addToBasket(contractAddress, tokenId, nftTokenAddress, nftTokenId);\n }\n\n /**\n * @dev Calculates the amount of Fees to be paid for a specific deposit amount\n * Fees are calculated in Interest-Token as they are the type collected for Fees\n * @param assetAmount The Amount of Assets to calculate Fees on\n * @return protocolFee The amount of fees reserved for the protocol\n */\n function _getFeesForDeposit(\n uint256 assetAmount\n )\n internal\n view\n returns (uint256 protocolFee)\n {\n if (depositFee > 0) {\n protocolFee = assetAmount.mul(depositFee).div(PERCENTAGE_SCALE);\n }\n }\n\n /// @dev Collects the Required ERC20 Token(s) from the users wallet\n /// Be sure to Approve this Contract to transfer your Token(s)\n /// @param from The owner address to collect the tokens from\n /// @param tokenAddress The addres of the token to transfer\n /// @param tokenAmount The amount of tokens to collect\n function _collectAssetToken(address from, address tokenAddress, uint256 tokenAmount) internal virtual returns (uint256 protocolFee) {\n protocolFee = _getFeesForDeposit(tokenAmount);\n IERC20Upgradeable(tokenAddress).safeTransferFrom(from, address(this), tokenAmount.add(protocolFee));\n }\n\n /// @dev Collects the Required ERC721 Token(s) from the users wallet\n /// Be sure to Approve this Contract to transfer your Token(s)\n /// @param from The owner address to collect the tokens from\n /// @param nftTokenAddress The address of the NFT token to transfer\n /// @param nftTokenId The ID of the NFT token to transfer\n /// @param nftTokenAmount The amount of Tokens to Transfer (ERC1155-specific)\n function _collectNftToken(address from, address nftTokenAddress, uint256 nftTokenId, uint256 nftTokenAmount) internal virtual {\n if (_isERC1155(nftTokenAddress)) {\n IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId, nftTokenAmount, \"\");\n } else {\n IERC721Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId);\n }\n }\n\n /// @dev Checks if an NFT token contract supports the ERC1155 standard interface\n function _isERC1155(address nftTokenAddress) internal view virtual returns (bool) {\n bytes4 _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n return IERC165Upgradeable(nftTokenAddress).supportsInterface(_INTERFACE_ID_ERC1155);\n }\n\n /// @dev See {ChargedParticles-baseParticleMass}.\n function _baseParticleMass(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n return _chargedManagers.getWalletManager(walletManagerId).getPrincipal(contractAddress, tokenId, assetToken);\n }\n\n /// @dev See {ChargedParticles-currentParticleCharge}.\n function _currentParticleCharge(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n (, uint256 ownerInterest) = _chargedManagers.getWalletManager(walletManagerId).getInterest(contractAddress, tokenId, assetToken);\n return ownerInterest;\n }\n\n /// @dev See {ChargedParticles-currentParticleKinetics}.\n function _currentParticleKinetics(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n return _chargedManagers.getWalletManager(walletManagerId).getRewards(contractAddress, tokenId, assetToken);\n }\n\n /// @dev See {ChargedParticles-currentParticleCovalentBonds}.\n function _currentParticleCovalentBonds(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId\n )\n internal\n view\n virtual\n returns (uint256)\n {\n return _chargedManagers.getBasketManager(basketManagerId).getTokenTotalCount(contractAddress, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier managerEnabled(string calldata walletManagerId) {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"CP:E-419\");\n _;\n }\n\n modifier basketEnabled(string calldata basketManagerId) {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"CP:E-419\");\n _;\n }\n}\n" + }, + "contracts/v1/ChargedSettings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/RelayRecipient.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\nimport \"./lib/TokenInfoProxy.sol\";\n\n/**\n * @notice Charged Particles Settings Contract\n */\ncontract ChargedSettings is\n IChargedSettings,\n Initializable,\n OwnableUpgradeable,\n RelayRecipient,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using Bitwise for uint32;\n\n uint256 constant internal MAX_ANNUITIES = 1e4; // 10000 (100%)\n\n // NftSettings - actionPerms\n uint32 constant internal PERM_CHARGE_NFT = 1; // NFT Contracts that can have assets Deposited into them (Charged)\n uint32 constant internal PERM_BASKET_NFT = 2; // NFT Contracts that can have other NFTs Deposited into them\n uint32 constant internal PERM_TIMELOCK_ANY_NFT = 4; // NFT Contracts that can timelock any NFT on behalf of users (primarily used for Front-run Protection)\n uint32 constant internal PERM_TIMELOCK_OWN_NFT = 8; // NFT Contracts that can timelock their own NFTs on behalf of their users\n uint32 constant internal PERM_RESTRICTED_ASSETS = 16; // NFT Contracts that have restricted deposits to specific assets\n\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // Current Settings for External NFT Token Contracts;\n // - Any user can add any ERC721 or ERC1155 token as a Charged Particle without Limits,\n // unless the Owner of the ERC721 or ERC1155 token contract registers the token\n // and sets the Custom Settings for their token(s)\n mapping (address => uint32) internal _nftActionPerms;\n\n mapping (address => string) internal _nftRequiredWalletManager;\n mapping (address => string) internal _nftRequiredBasketManager;\n\n // ERC20\n mapping (address => mapping(address => bool)) internal _nftAllowedAssetTokens;\n mapping (address => mapping (address => uint256)) internal _nftDepositMin;\n mapping (address => mapping (address => uint256)) internal _nftDepositMax;\n\n // ERC721 / ERC1155\n mapping (address => mapping (address => uint256)) internal _nftMaxNfts; // NFT Token Address => Max\n\n // Optional Configs for individual NFTs set by NFT Creator (by Token UUID)\n mapping (uint256 => uint256) internal _creatorAnnuityPercent;\n mapping (uint256 => address) internal _creatorAnnuityRedirect;\n\n mapping (address => uint256) internal _depositCap;\n uint256 internal _tempLockExpiryBlocks;\n\n // Blacklist for non-compliant tokens\n mapping (address => bool) internal _invalidAssets;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n /// @dev Gets the amount of creator annuities reserved for the creator for the specified NFT\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @return creator The address of the creator\n /// @return annuityPct The percentage amount of annuities reserved for the creator\n function getCreatorAnnuities(\n address contractAddress,\n uint256 tokenId\n )\n external\n override\n virtual\n returns (address creator, uint256 annuityPct)\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n creator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId);\n annuityPct = _creatorAnnuityPercent[tokenUuid];\n }\n\n function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId)\n external\n view\n override\n virtual\n returns (address)\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _creatorAnnuityRedirect[tokenUuid];\n }\n\n function getTempLockExpiryBlocks() external view override virtual returns (uint256) {\n return _tempLockExpiryBlocks;\n }\n\n function getTimelockApprovals(address operator)\n external\n view\n override\n virtual\n returns (bool timelockAny, bool timelockOwn)\n {\n timelockAny = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_ANY_NFT);\n timelockOwn = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_OWN_NFT);\n }\n\n function getAssetRequirements(address contractAddress, address assetToken)\n external\n view\n override\n virtual\n returns (\n string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n )\n {\n requiredWalletManager = _nftRequiredWalletManager[contractAddress];\n energizeEnabled = _nftActionPerms[contractAddress].hasBit(PERM_CHARGE_NFT);\n restrictedAssets = _nftActionPerms[contractAddress].hasBit(PERM_RESTRICTED_ASSETS);\n validAsset = _nftAllowedAssetTokens[contractAddress][assetToken];\n depositCap = _depositCap[assetToken];\n depositMin = _nftDepositMin[contractAddress][assetToken];\n depositMax = _nftDepositMax[contractAddress][assetToken];\n invalidAsset = _invalidAssets[assetToken];\n }\n\n function getNftAssetRequirements(address contractAddress, address nftTokenAddress)\n external\n view\n override\n virtual\n returns (string memory requiredBasketManager, bool basketEnabled, uint256 maxNfts)\n {\n requiredBasketManager = _nftRequiredBasketManager[contractAddress];\n basketEnabled = _nftActionPerms[contractAddress].hasBit(PERM_BASKET_NFT);\n maxNfts = _nftMaxNfts[contractAddress][nftTokenAddress];\n }\n\n\n /***********************************|\n | Only NFT Creator |\n |__________________________________*/\n\n /// @notice Sets the Custom Configuration for Creators of Proton-based NFTs\n /// @param contractAddress The Address to the Proton-based NFT to configure\n /// @param tokenId The token ID of the Proton-based NFT to configure\n /// @param creator The creator of the Proton-based NFT\n /// @param annuityPercent The percentage of interest-annuities to reserve for the creator\n function setCreatorAnnuities(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent\n )\n external\n virtual\n override\n {\n require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), \"CP:E-104\");\n _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent);\n }\n\n /// @notice Sets a Custom Receiver Address for the Creator Annuities\n /// @param contractAddress The Address to the Proton-based NFT to configure\n /// @param tokenId The token ID of the Proton-based NFT to configure\n /// @param receiver The receiver of the Creator interest-annuities\n function setCreatorAnnuitiesRedirect(\n address contractAddress,\n uint256 tokenId,\n address receiver\n )\n external\n virtual\n override\n {\n require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), \"CP:E-104\");\n _setCreatorAnnuitiesRedirect(contractAddress, tokenId, receiver);\n }\n\n\n /***********************************|\n | Register Contract Settings |\n |(For External Contract Integration)|\n |__________________________________*/\n\n /// @notice Sets a Required Wallet-Manager for External NFT Contracts (otherwise set to \"none\" to allow any Wallet-Manager)\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param walletManager If set, will only allow deposits from this specific Wallet-Manager\n function setRequiredWalletManager(\n address contractAddress,\n string calldata walletManager\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (keccak256(bytes(walletManager)) == keccak256(bytes(\"none\"))) {\n _nftRequiredWalletManager[contractAddress] = \"\";\n } else {\n _nftRequiredWalletManager[contractAddress] = walletManager;\n }\n\n emit RequiredWalletManagerSet(\n contractAddress,\n walletManager\n );\n }\n\n /// @notice Sets a Required Basket-Manager for External NFT Contracts (otherwise set to \"none\" to allow any Basket-Manager)\n /// @param contractAddress The Address to the External Contract to configure\n /// @param basketManager If set, will only allow deposits from this specific Basket-Manager\n function setRequiredBasketManager(\n address contractAddress,\n string calldata basketManager\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (keccak256(bytes(basketManager)) == keccak256(bytes(\"none\"))) {\n _nftRequiredBasketManager[contractAddress] = \"\";\n } else {\n _nftRequiredBasketManager[contractAddress] = basketManager;\n }\n\n emit RequiredBasketManagerSet(\n contractAddress,\n basketManager\n );\n }\n\n /// @notice Enables or Disables Asset-Token Restrictions for External NFT Contracts\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param restrictionsEnabled If set, will only allow deposits from Allowed Asset Tokens\n function setAssetTokenRestrictions(\n address contractAddress,\n bool restrictionsEnabled\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (restrictionsEnabled) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_RESTRICTED_ASSETS);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_RESTRICTED_ASSETS);\n }\n\n emit AssetTokenRestrictionsSet(\n contractAddress,\n restrictionsEnabled\n );\n }\n\n /// @notice Enables or Disables Allowed Asset Tokens for External NFT Contracts\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param assetToken The Address of the Asset Token to Allow or Disallow\n /// @param isAllowed True if the Asset Token is allowed\n function setAllowedAssetToken(\n address contractAddress,\n address assetToken,\n bool isAllowed\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftAllowedAssetTokens[contractAddress][assetToken] = isAllowed;\n\n emit AllowedAssetTokenSet(\n contractAddress,\n assetToken,\n isAllowed\n );\n }\n\n /// @notice Sets the Custom Configuration for External Contracts\n /// @param contractAddress The Address to the External Contract to configure\n /// @param assetToken The address of the Asset Token to set Limits for\n /// @param depositMin If set, will define the minimum amount of Asset tokens the NFT may hold, otherwise any amount\n /// @param depositMax If set, will define the maximum amount of Asset tokens the NFT may hold, otherwise any amount\n function setAssetTokenLimits(\n address contractAddress,\n address assetToken,\n uint256 depositMin,\n uint256 depositMax\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftDepositMin[contractAddress][assetToken] = depositMin;\n _nftDepositMax[contractAddress][assetToken] = depositMax;\n\n emit AssetTokenLimitsSet(\n contractAddress,\n assetToken,\n depositMin,\n depositMax\n );\n }\n\n /// @notice Sets the Max Number of NFTs that can be held by a Charged Particle NFT\n /// @param contractAddress The Address to the External Contract to configure\n /// @param nftTokenAddress The address of the NFT Token to set a Max for\n /// @param maxNfts The maximum numbers of NFTs that can be held by a given NFT (0 = unlimited)\n function setMaxNfts(\n address contractAddress,\n address nftTokenAddress,\n uint256 maxNfts\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftMaxNfts[contractAddress][nftTokenAddress] = maxNfts;\n\n emit MaxNftsSet(\n contractAddress,\n nftTokenAddress,\n maxNfts\n );\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n function setAssetInvalidity(address assetToken, bool invalidity) external virtual override onlyOwner {\n _invalidAssets[assetToken] = invalidity;\n emit AssetInvaliditySet(assetToken, invalidity);\n }\n\n function setDepositCap(address assetToken, uint256 cap) external virtual onlyOwner {\n _depositCap[assetToken] = cap;\n emit DepositCapSet(assetToken, cap);\n }\n\n function setTempLockExpiryBlocks(uint256 numBlocks) external virtual onlyOwner {\n _tempLockExpiryBlocks = numBlocks;\n emit TempLockExpirySet(numBlocks);\n }\n\n function enableNftContracts(address[] calldata contracts) external override virtual onlyOwner {\n uint count = contracts.length;\n for (uint i = 0; i < count; i++) {\n address tokenContract = contracts[i];\n _setPermsForCharge(tokenContract, true);\n _setPermsForBasket(tokenContract, true);\n _setPermsForTimelockSelf(tokenContract, true);\n }\n }\n\n function migrateToken(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent,\n address annuityReceiver\n )\n external\n onlyOwner\n {\n _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent);\n if (annuityReceiver != address(0)) {\n _setCreatorAnnuitiesRedirect(contractAddress, tokenId, annuityReceiver);\n }\n }\n\n /// @dev Update the list of NFT contracts that can be Charged\n function setPermsForCharge(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForCharge(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can hold other NFTs\n function setPermsForBasket(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForBasket(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection\n function setPermsForTimelockAny(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForTimelockAny(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock their own tokens\n function setPermsForTimelockSelf(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForTimelockSelf(contractAddress, state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Update the list of NFT contracts that can be Charged\n function _setPermsForCharge(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_CHARGE_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_CHARGE_NFT);\n }\n emit PermsSetForCharge(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can hold other NFTs\n function _setPermsForBasket(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_BASKET_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_BASKET_NFT);\n }\n emit PermsSetForBasket(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection\n function _setPermsForTimelockAny(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_ANY_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_ANY_NFT);\n }\n emit PermsSetForTimelockAny(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock their own tokens\n function _setPermsForTimelockSelf(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_OWN_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_OWN_NFT);\n }\n emit PermsSetForTimelockSelf(contractAddress, state);\n }\n\n /// @dev see setCreatorAnnuities()\n function _setCreatorAnnuities(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent\n )\n internal\n virtual\n {\n require(annuityPercent <= MAX_ANNUITIES, \"CP:E-421\");\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Update Configs for External Token Creator\n _creatorAnnuityPercent[tokenUuid] = annuityPercent;\n\n emit TokenCreatorConfigsSet(\n contractAddress,\n tokenId,\n creator,\n annuityPercent\n );\n }\n\n /// @dev see setCreatorAnnuitiesRedirect()\n function _setCreatorAnnuitiesRedirect(\n address contractAddress,\n uint256 tokenId,\n address receiver\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _creatorAnnuityRedirect[tokenUuid] = receiver;\n emit TokenCreatorAnnuitiesRedirected(contractAddress, tokenId, receiver);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyValidExternalContract(address contractAddress) {\n require(contractAddress.isContract(), \"CP:E-420\");\n _;\n }\n\n modifier onlyContractOwnerOrAdmin(address contractAddress, address sender) {\n require(sender == owner() || contractAddress.isContractOwner(sender), \"CP:E-103\");\n _;\n }\n}\n" + }, + "contracts/v1/ChargedState.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedState.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/RelayRecipient.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Settings Contract\n */\ncontract ChargedState is\n IChargedState,\n Initializable,\n OwnableUpgradeable,\n RelayRecipient,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using Bitwise for uint32;\n\n // NftState - actionPerms\n uint32 constant internal PERM_RESTRICT_ENERGIZE_FROM_ALL = 1; // NFTs that have Restrictions on Energize\n uint32 constant internal PERM_ALLOW_DISCHARGE_FROM_ALL = 2; // NFTs that allow Discharge by anyone\n uint32 constant internal PERM_ALLOW_RELEASE_FROM_ALL = 4; // NFTs that allow Release by anyone\n uint32 constant internal PERM_RESTRICT_BOND_FROM_ALL = 8; // NFTs that have Restrictions on Covalent Bonds\n uint32 constant internal PERM_ALLOW_BREAK_BOND_FROM_ALL = 16; // NFTs that allow Breaking Covalent Bonds by anyone\n\n IChargedSettings internal _chargedSettings;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // NftTimelocks\n /// @dev discharge unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftDischargeTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftDischargeTimelockLockedBy;\n\n /// @dev release unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftReleaseTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftReleaseTimelockLockedBy;\n\n /// @dev release unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftBreakBondTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftBreakBondTimelockLockedBy;\n\n // NftState\n /// @dev maps nft by tokenId to actionPermissions uint32 which is a composite of all possible NftState - actionPerms\n mapping (uint256 => uint32) internal _nftActionPerms;\n\n /// @dev maps nft by tokenId to its tempLockExpiry\n mapping (uint256 => uint256) internal _nftTempLockExpiry;\n\n /// @dev maps tokenId to user address to operator address for approving various actions\n mapping (uint256 => mapping(address => address)) internal _nftDischargeApproval;\n mapping (uint256 => mapping(address => address)) internal _nftReleaseApproval;\n mapping (uint256 => mapping(address => address)) internal _nftBreakBondApproval;\n mapping (uint256 => mapping(address => address)) internal _nftTimelockApproval;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftDischargeTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftDischargeTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftReleaseTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftReleaseTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftBreakBondTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftBreakBondTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n\n /// @notice Checks if an operator is allowed to Discharge a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForDischarge(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Release a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForRelease(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Break Covalent Bonds on a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForBreakBond(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Timelock a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForTimelock(contractAddress, tokenId, operator);\n }\n\n\n function isEnergizeRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n }\n\n\n function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_BOND_FROM_ALL);\n }\n\n\n function getDischargeState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n isApproved = _isApprovedForDischarge(contractAddress, tokenId, sender);\n timelock = _nftDischargeTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n function getReleaseState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_RELEASE_FROM_ALL);\n isApproved = _isApprovedForRelease(contractAddress, tokenId, sender);\n timelock = _nftReleaseTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n function getBreakBondState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n isApproved = _isApprovedForBreakBond(contractAddress, tokenId, sender);\n timelock = _nftBreakBondTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n\n /***********************************|\n | Only NFT Owner/Operator |\n |__________________________________*/\n\n /// @notice Sets an Operator as Approved to Discharge a specific Token\n /// This allows an operator to withdraw the interest-portion only\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setDischargeApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Release a specific Token\n /// This allows an operator to withdraw the principal + interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setReleaseApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token\n /// This allows an operator to withdraw Basket NFTs\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setBreakBondApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Timelock a specific Token\n /// This allows an operator to timelock the principal or interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setTimelockApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Discharge/Release/Timelock a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setApprovalForAll(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @dev Updates Restrictions on Energizing an NFT\n function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForRestrictCharge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowDischarge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowRelease(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Restrictions on Covalent Bonds on an NFT\n function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForRestrictBond(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone\n function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowBreakBond(contractAddress, tokenId, state);\n }\n\n /// @notice Sets a Timelock on the ability to Discharge the Interest of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setDischargeTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftDischargeTimelockLockedBy[tokenUuid] == sender) {\n delete _nftDischargeTimelockUnlockBlock[tokenUuid];\n delete _nftDischargeTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftDischargeTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftDischargeTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftDischargeTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenDischargeTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n /// @notice Sets a Timelock on the ability to Release the Assets of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setReleaseTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftReleaseTimelockLockedBy[tokenUuid] == sender) {\n delete _nftReleaseTimelockUnlockBlock[tokenUuid];\n delete _nftReleaseTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftReleaseTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftReleaseTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftReleaseTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenReleaseTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n /// @notice Sets a Timelock on the ability to Break the Covalent Bond of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setBreakBondTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftBreakBondTimelockLockedBy[tokenUuid] == sender) {\n delete _nftBreakBondTimelockUnlockBlock[tokenUuid];\n delete _nftBreakBondTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftBreakBondTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftBreakBondTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftBreakBondTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenBreakBondTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n\n /***********************************|\n | Only NFT Contract |\n |__________________________________*/\n\n /// @notice Sets a Temporary-Lock on the ability to Release/Discharge the Assets of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param isLocked The locked state; contracts are expected to disable this lock before expiry\n function setTemporaryLock(\n address contractAddress,\n uint256 tokenId,\n bool isLocked\n )\n external\n override\n virtual\n {\n require(msg.sender == contractAddress, \"CP:E-112\");\n\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n uint256 unlockBlock;\n if (isLocked && _nftTempLockExpiry[tokenUuid] == 0) {\n unlockBlock = block.number.add(_chargedSettings.getTempLockExpiryBlocks());\n _nftTempLockExpiry[tokenUuid] = unlockBlock;\n }\n if (!isLocked) {\n _nftTempLockExpiry[tokenUuid] = 0;\n }\n\n emit TokenTempLock(contractAddress, tokenId, unlockBlock);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n function migrateToken(\n address contractAddress,\n uint256 tokenId,\n uint256 releaseTimelockExpiry,\n address releaseTimelockLockedBy,\n uint256 tempLockExpiry\n )\n external\n onlyOwner\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (releaseTimelockExpiry > block.number && releaseTimelockLockedBy != address(0)) {\n _nftReleaseTimelockUnlockBlock[tokenUuid] = releaseTimelockExpiry;\n _nftReleaseTimelockLockedBy[tokenUuid] = releaseTimelockLockedBy;\n emit TokenReleaseTimelock(contractAddress, tokenId, releaseTimelockLockedBy, releaseTimelockExpiry);\n }\n\n if (tempLockExpiry > 0) {\n _nftTempLockExpiry[tokenUuid] = tempLockExpiry;\n emit TokenTempLock(contractAddress, tokenId, tempLockExpiry);\n }\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev See {ChargedParticles-isApprovedForDischarge}.\n function _isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftDischargeApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForRelease}.\n function _isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftReleaseApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForBreakBond}.\n function _isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftBreakBondApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForTimelock}.\n function _isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n (bool timelockAny, bool timelockOwn) = _chargedSettings.getTimelockApprovals(operator);\n if (timelockAny || (timelockOwn && contractAddress == operator)) { return true; }\n\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return tokenOwner == operator || _nftTimelockApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @notice Sets an Operator as Approved to Discharge a specific Token\n /// This allows an operator to withdraw the interest-portion only\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setDischargeApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftDischargeApproval[tokenUuid][tokenOwner] = operator;\n emit DischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Release a specific Token\n /// This allows an operator to withdraw the principal + interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setReleaseApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftReleaseApproval[tokenUuid][tokenOwner] = operator;\n emit ReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token\n /// This allows an operator to withdraw Basket NFTs\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setBreakBondApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftBreakBondApproval[tokenUuid][tokenOwner] = operator;\n emit BreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Timelock a specific Token\n /// This allows an operator to timelock the principal or interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setTimelockApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftTimelockApproval[tokenUuid][tokenOwner] = operator;\n emit TimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @dev Updates Restrictions on Energizing an NFT\n function _setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n }\n emit PermsSetForRestrictCharge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function _setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n }\n emit PermsSetForAllowDischarge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function _setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_RELEASE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_RELEASE_FROM_ALL);\n }\n emit PermsSetForAllowRelease(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Restrictions on Covalent Bonds on an NFT\n function _setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_BOND_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_BOND_FROM_ALL);\n }\n emit PermsSetForRestrictBond(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone\n function _setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n }\n emit PermsSetForAllowBreakBond(contractAddress, tokenId, state);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) {\n require(_tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender), \"CP:E-105\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/CommunityVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract CommunityVault is Ownable, BlackholePrevention {\n\n IERC20 private immutable _ionx;\n\n constructor (address ionx) public {\n _ionx = IERC20(ionx);\n }\n\n event SetAllowance(address indexed caller, address indexed spender, uint256 amount);\n\n function setAllowance(address spender, uint amount) public onlyOwner {\n _ionx.approve(spender, amount);\n\n emit SetAllowance(msg.sender, spender, amount);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens other than IONX, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n require(tokenAddress != address(_ionx), \"CommunityVault: cannot withdraw IONX\");\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n}" + }, + "contracts/v1/incentives/MerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_) public {\n token = token_;\n merkleRoot = merkleRoot_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), 'MerkleDistributor: Drop already claimed.');\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), 'MerkleDistributor: Invalid proof.');\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), 'MerkleDistributor: Transfer failed.');\n\n emit Claimed(index, account, amount);\n }\n}\n" + }, + "contracts/v1/incentives/MerkleDistributor2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor2 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"MerkleDistributor2: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"MerkleDistributor2: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor2: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"MerkleDistributor2: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"MerkleDistributor2: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"MerkleDistributor2: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/MerkleDistributor3.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor3 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"MerkleDistributor3: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"MerkleDistributor3: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor3: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"MerkleDistributor3: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"MerkleDistributor3: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"MerkleDistributor3: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/RewardProgram.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// RewardProgram.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/IRewardProgram.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/introspection/IERC165.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"../interfaces/IUniverseRP.sol\";\nimport \"../interfaces/IChargedManagers.sol\";\nimport \"../interfaces/IWalletManager.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IERC20Detailed.sol\";\n\ncontract RewardProgram is\n IRewardProgram,\n BlackholePrevention,\n IERC165,\n ReentrancyGuard,\n IERC721Receiver,\n IERC1155Receiver\n{\n using SafeMath for uint256;\n using TokenInfo for address;\n using SafeERC20 for IERC20;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n\n address private _owner;\n IUniverseRP private _universe;\n IChargedManagers private _chargedManagers;\n ProgramRewardData private _programData;\n mapping(uint256 => AssetStake) private _assetStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public {}\n\n function initialize(\n address stakingToken,\n address rewardToken,\n uint256 baseMultiplier,\n address chargedManagers,\n address universe,\n address owner\n ) external override {\n require(_owner == address(0x0), \"Already initialized\");\n _owner = owner;\n\n // Prepare Reward Program\n _programData.stakingToken = stakingToken;\n _programData.rewardToken = rewardToken;\n _programData.baseMultiplier = baseMultiplier; // Basis Points\n\n // Connect to Charged Particles\n _chargedManagers = IChargedManagers(chargedManagers);\n _universe = IUniverseRP(universe);\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getProgramData() external view override returns (ProgramRewardData memory) {\n return _programData;\n }\n\n function getAssetStake(uint256 parentNftUuid) external view override returns (AssetStake memory) {\n return _assetStake[parentNftUuid];\n }\n\n function getFundBalance() external view override returns (uint256) {\n return _getFundBalance();\n }\n\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) public view override returns (uint256) {\n return _calculateRewardsEarned(parentNftUuid, interestAmount);\n }\n\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n return _assetStake[parentNftUuid].claimableRewards;\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\n return \"\";\n }\n\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(IERC165)\n returns (bool)\n {\n // default interface support\n if (\n interfaceId == type(IERC721Receiver).interfaceId ||\n interfaceId == type(IERC1155Receiver).interfaceId ||\n interfaceId == type(IERC165).interfaceId\n ) {\n return true;\n }\n }\n\n function owner() public view returns (address) {\n return _owner;\n }\n\n\n /***********************************|\n | Only Universe |\n |__________________________________*/\n\n function registerAssetDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n uint256 principalAmount\n )\n external\n override\n onlyUniverse\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n if (assetStake.start == 0) {\n assetStake.start = block.number;\n assetStake.walletManagerId = walletManagerId;\n }\n emit AssetDeposit(contractAddress, tokenId, walletManagerId, principalAmount);\n }\n\n function registerAssetRelease(\n address contractAddress,\n uint256 tokenId,\n uint256 interestAmount\n )\n external\n override\n onlyUniverse\n nonReentrant\n returns (uint256 rewards)\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n // Update Claimable Rewards\n uint256 newRewards = _calculateRewardsEarned(parentNftUuid, interestAmount);\n assetStake.claimableRewards = assetStake.claimableRewards.add(newRewards);\n\n // Reset Stake if Principal Balance falls to Zero\n IWalletManager walletMgr = _chargedManagers.getWalletManager(assetStake.walletManagerId);\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\n if (principal == 0) {\n assetStake.start = 0;\n }\n\n // Issue Rewards to NFT Owner\n rewards = _claimRewards(contractAddress, tokenId);\n\n emit AssetRelease(contractAddress, tokenId, interestAmount);\n }\n\n\n /***********************************|\n | Reward Calculation |\n |__________________________________*/\n\n function _calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) internal view returns (uint256 totalReward) {\n uint256 baseReward = _calculateBaseReward(interestAmount);\n uint256 leptonMultipliedReward = _calculateMultipliedReward(parentNftUuid, baseReward);\n totalReward = _convertDecimals(leptonMultipliedReward);\n }\n\n function _calculateBaseReward(uint256 amount) internal view returns(uint256 baseReward) {\n baseReward = amount.mul(_programData.baseMultiplier).div(PERCENTAGE_SCALE);\n }\n\n function _calculateMultipliedReward(uint256 parentNftUuid, uint256 baseReward) internal view returns(uint256) {\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n if (assetStake.start == 0) { return baseReward; }\n\n IUniverseRP.NftStake memory nftStake = _universe.getNftStake(parentNftUuid);\n uint256 multiplierBP = nftStake.multiplier;\n\n uint256 assetDepositLength = block.number.sub(assetStake.start);\n uint256 nftDepositLength = 0;\n if (nftStake.releaseBlockNumber > 0) {\n nftDepositLength = nftStake.releaseBlockNumber.sub(nftStake.depositBlockNumber);\n } else {\n nftDepositLength = block.number.sub(nftStake.depositBlockNumber);\n }\n\n if (multiplierBP == 0 || nftDepositLength == 0 || assetDepositLength == 0) {\n return baseReward;\n }\n\n if (nftDepositLength > assetDepositLength) {\n nftDepositLength = assetDepositLength;\n }\n\n // Percentage of the total program that the Multiplier Nft was deposited for\n uint256 nftRewardRatioBP = nftDepositLength.mul(PERCENTAGE_SCALE).div(assetDepositLength);\n\n // Amount of reward that the Multiplier Nft is responsible for\n uint256 amountGeneratedDuringNftDeposit = baseReward.mul(nftRewardRatioBP).div(PERCENTAGE_SCALE);\n\n // Amount of Multiplied Reward from NFT\n uint256 multipliedReward = amountGeneratedDuringNftDeposit.mul(multiplierBP.mul(LEPTON_MULTIPLIER_SCALE)).div(PERCENTAGE_SCALE);\n\n // Amount of Base Reward without Multiplied NFT Rewards\n uint256 amountGeneratedWithoutNftDeposit = baseReward.sub(amountGeneratedDuringNftDeposit);\n\n // Amount of Base Rewards + Multiplied NFT Rewards\n return amountGeneratedWithoutNftDeposit.add(multipliedReward);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function fundProgram(uint256 amount) external onlyOwner {\n require(_programData.rewardToken != address(0), \"RP:E-405\");\n IERC20(_programData.rewardToken).safeTransferFrom(msg.sender, address(this), amount);\n emit RewardProgramFunded(amount);\n }\n\n function setStakingToken(address newStakingToken) external onlyOwner {\n _programData.stakingToken = newStakingToken;\n }\n\n function setRewardToken(address newRewardToken) external onlyOwner {\n _programData.rewardToken = newRewardToken;\n }\n\n function setBaseMultiplier(uint256 newMultiplier) external onlyOwner {\n _programData.baseMultiplier = newMultiplier; // Basis Points\n }\n\n function setChargedManagers(address manager) external onlyOwner {\n _chargedManagers = IChargedManagers(manager);\n }\n\n function setUniverse(address universe) external onlyOwner {\n _universe = IUniverseRP(universe);\n }\n\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external override onlyOwner {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n\n // Initiate Asset Stake\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\n if (principal > 0) {\n _assetStake[parentNftUuid] = AssetStake(block.number, 0, walletManagerId);\n emit AssetRegistered(contractAddress, tokenId, walletManagerId, principal);\n }\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _claimRewards(\n address contractAddress,\n uint256 tokenId\n )\n internal\n returns (uint256 totalReward)\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n // Rewards Receiver\n address receiver = IERC721(contractAddress).ownerOf(tokenId);\n\n // Ensure Reward Pool has Sufficient Balance\n totalReward = assetStake.claimableRewards;\n uint256 fundBalance = _getFundBalance();\n uint256 unavailReward = totalReward > fundBalance ? totalReward.sub(fundBalance) : 0;\n\n // Determine amount of Rewards to Transfer\n if (unavailReward > 0) {\n totalReward = totalReward.sub(unavailReward);\n emit RewardProgramOutOfFunds();\n }\n\n // Update Asset Stake\n assetStake.claimableRewards = unavailReward;\n\n if (totalReward > 0) {\n // Transfer Available Rewards to Receiver\n IERC20(_programData.rewardToken).safeTransfer(receiver, totalReward);\n }\n\n emit RewardsClaimed(contractAddress, tokenId, receiver, totalReward, unavailReward);\n }\n\n function _convertDecimals(uint256 reward) internal view returns (uint256) {\n uint8 stakingTokenDecimals = IERC20Detailed(_programData.stakingToken).decimals();\n return reward.mul(10**(18 - uint256(stakingTokenDecimals)));\n }\n\n function _getFundBalance() internal view returns (uint256) {\n return IERC20Detailed(_programData.rewardToken).balanceOf(address(this));\n }\n\n\n modifier onlyOwner() {\n require(_owner == msg.sender, \"Caller is not the owner\");\n _;\n }\n\n modifier onlyUniverse() {\n require(msg.sender == address(_universe), \"RP:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/RewardProgramFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// RewardProgramFactory.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport \"./RewardProgram.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract RewardProgramFactory is BlackholePrevention, Ownable {\n event RewardProgramCreated(address indexed rewardProgram);\n\n address public _template;\n\n constructor () public {\n _template = address(new RewardProgram());\n }\n\n // function _msgSender() internal view override returns (address payable) {\n // return msg.sender;\n // }\n\n function createRewardProgram(\n address stakingToken,\n address rewardToken,\n uint256 baseMultiplier,\n address chargedManagers,\n address universe\n )\n external\n onlyOwner\n returns (address)\n {\n address newRewardProgram = _createClone(_template);\n RewardProgram rewardProgram = RewardProgram(newRewardProgram);\n rewardProgram.initialize(stakingToken, rewardToken, baseMultiplier, chargedManagers, universe, _msgSender());\n emit RewardProgramCreated(newRewardProgram);\n return newRewardProgram;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n}\n" + }, + "contracts/v1/incentives/Staking.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/Staking2.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking2 is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/Staking3.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking3 is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/YieldFarm.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/incentives/YieldFarm2.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm2 is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/incentives/YieldFarm3.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm3 is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/interfaces/IAaveBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IAaveBridge.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n\ninterface IAaveBridge {\n function getReserveInterestToken(address assetToken) external view returns (address aTokenAddress);\n function isReserveActive(address assetToken) external view returns (bool);\n\n function getTotalBalance(address account, address assetToken) external view returns (uint256);\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(address receiver, address assetToken, uint256 assetAmount) external;\n}\n" + }, + "contracts/v1/interfaces/IBaseProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IBaseProton is IERC721 {\n event PausedStateSet(bool isPaused);\n event SalePriceSet(uint256 indexed tokenId, uint256 salePrice);\n event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct);\n event FeesWithdrawn(address indexed receiver, uint256 amount);\n event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties);\n event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view returns (address);\n function getSalePrice(uint256 tokenId) external view returns (uint256);\n function getLastSellPrice(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyalties(address account) external view returns (uint256);\n function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address);\n\n function buyProton(uint256 tokenId, uint256 gasLimit) external payable returns (bool);\n function claimCreatorRoyalties() external returns (uint256);\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n ) external returns (uint256 newTokenId);\n\n function createProtons(\n address creator,\n address receiver,\n string[] calldata tokenMetaUris\n ) external returns (bool);\n\n function createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n ) external returns (bool);\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice) external;\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external;\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external;\n}" + }, + "contracts/v1/interfaces/IBasketManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Particle Basket Manager interface\n * @dev The basket-manager for underlying assets attached to Charged Particles\n * @dev Manages the link between NFTs and their respective Smart-Baskets\n */\ninterface IBasketManager {\n\n event ControllerSet(address indexed controller);\n event ExecutorSet(address indexed executor);\n event PausedStateSet(bool isPaused);\n event NewSmartBasket(address indexed contractAddress, uint256 indexed tokenId, address indexed smartBasket);\n event BasketAdd(address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\n event BasketRemove(address indexed receiver, address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\n event BasketRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\n event RewardProgramSet(address indexed rewardProgram);\n\n function isPaused() external view returns (bool);\n\n function getTokenTotalCount(address contractAddress, uint256 tokenId) external view returns (uint256);\n function getTokenCountByType(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (uint256);\n\n function prepareTransferAmount(uint256 nftTokenAmount) external;\n function addToBasket(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function getBasketAddressById(address contractAddress, uint256 tokenId) external returns (address);\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/IChargedManagers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IWalletManager.sol\";\nimport \"./IBasketManager.sol\";\n\n/**\n * @notice Interface for Charged Wallet-Managers\n */\ninterface IChargedManagers {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function isContractOwner(address contractAddress, address account) external view returns (bool);\n\n // ERC20\n function isWalletManagerEnabled(string calldata walletManagerId) external view returns (bool);\n function getWalletManager(string calldata walletManagerId) external view returns (IWalletManager);\n\n // ERC721\n function isNftBasketEnabled(string calldata basketId) external view returns (bool);\n function getBasketManager(string calldata basketId) external view returns (IBasketManager);\n\n // Validation\n function validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external;\n function validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external;\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external;\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event WalletManagerRegistered(string indexed walletManagerId, address indexed walletManager);\n event BasketManagerRegistered(string indexed basketId, address indexed basketManager);\n}\n" + }, + "contracts/v1/interfaces/IChargedParticles.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Charged Particles\n */\ninterface IChargedParticles {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getStateAddress() external view returns (address stateAddress);\n function getSettingsAddress() external view returns (address settingsAddress);\n function getManagersAddress() external view returns (address managersAddress);\n\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\n\n /***********************************|\n | Particle Mechanics |\n |__________________________________*/\n\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n ) external returns (uint256 yieldTokensAmount);\n\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 receiverAmount);\n\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositFeeSet(uint256 depositFee);\n event ProtocolFeesCollected(address indexed assetToken, uint256 depositAmount, uint256 feesCollected);\n}\n" + }, + "contracts/v1/interfaces/IChargedSettings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IWalletManager.sol\";\nimport \"./IBasketManager.sol\";\n\n/**\n * @notice Interface for Charged Settings\n */\ninterface IChargedSettings {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n // function isContractOwner(address contractAddress, address account) external view returns (bool);\n function getCreatorAnnuities(address contractAddress, uint256 tokenId) external returns (address creator, uint256 annuityPct);\n function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId) external view returns (address);\n function getTempLockExpiryBlocks() external view returns (uint256);\n function getTimelockApprovals(address operator) external view returns (bool timelockAny, bool timelockOwn);\n function getAssetRequirements(\n address contractAddress,\n address assetToken\n ) external view returns (\n string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n );\n function getNftAssetRequirements(\n address contractAddress,\n address nftTokenAddress\n ) external view returns (\n string memory requiredBasketManager,\n bool basketEnabled,\n uint256 maxNfts\n );\n\n /***********************************|\n | Only NFT Creator |\n |__________________________________*/\n\n function setCreatorAnnuities(address contractAddress, uint256 tokenId, address creator, uint256 annuityPercent) external;\n function setCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId, address receiver) external;\n\n\n /***********************************|\n | Only NFT Contract Owner |\n |__________________________________*/\n\n function setRequiredWalletManager(address contractAddress, string calldata walletManager) external;\n function setRequiredBasketManager(address contractAddress, string calldata basketManager) external;\n function setAssetTokenRestrictions(address contractAddress, bool restrictionsEnabled) external;\n function setAllowedAssetToken(address contractAddress, address assetToken, bool isAllowed) external;\n function setAssetTokenLimits(address contractAddress, address assetToken, uint256 depositMin, uint256 depositMax) external;\n function setMaxNfts(address contractAddress, address nftTokenAddress, uint256 maxNfts) external;\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAssetInvalidity(address assetToken, bool invalidity) external;\n function enableNftContracts(address[] calldata contracts) external;\n function setPermsForCharge(address contractAddress, bool state) external;\n function setPermsForBasket(address contractAddress, bool state) external;\n function setPermsForTimelockAny(address contractAddress, bool state) external;\n function setPermsForTimelockSelf(address contractAddress, bool state) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositCapSet(address assetToken, uint256 depositCap);\n event TempLockExpirySet(uint256 expiryBlocks);\n\n event RequiredWalletManagerSet(address indexed contractAddress, string walletManager);\n event RequiredBasketManagerSet(address indexed contractAddress, string basketManager);\n event AssetTokenRestrictionsSet(address indexed contractAddress, bool restrictionsEnabled);\n event AllowedAssetTokenSet(address indexed contractAddress, address assetToken, bool isAllowed);\n event AssetTokenLimitsSet(address indexed contractAddress, address assetToken, uint256 assetDepositMin, uint256 assetDepositMax);\n event MaxNftsSet(address indexed contractAddress, address indexed nftTokenAddress, uint256 maxNfts);\n event AssetInvaliditySet(address indexed assetToken, bool invalidity);\n\n event TokenCreatorConfigsSet(address indexed contractAddress, uint256 indexed tokenId, address indexed creatorAddress, uint256 annuityPercent);\n event TokenCreatorAnnuitiesRedirected(address indexed contractAddress, uint256 indexed tokenId, address indexed redirectAddress);\n\n event PermsSetForCharge(address indexed contractAddress, bool state);\n event PermsSetForBasket(address indexed contractAddress, bool state);\n event PermsSetForTimelockAny(address indexed contractAddress, bool state);\n event PermsSetForTimelockSelf(address indexed contractAddress, bool state);\n}\n" + }, + "contracts/v1/interfaces/IChargedState.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IChargedSettings.sol\";\n\n/**\n * @notice Interface for Charged State\n */\ninterface IChargedState {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n\n function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n\n function isEnergizeRestricted(address contractAddress, uint256 tokenId) external view returns (bool);\n function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external view returns (bool);\n\n function getDischargeState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n function getReleaseState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n function getBreakBondState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n\n /***********************************|\n | Only NFT Owner/Operator |\n |__________________________________*/\n\n function setDischargeApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setReleaseApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setBreakBondApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setTimelockApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setApprovalForAll(address contractAddress, uint256 tokenId, address operator) external;\n\n function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) external;\n\n function setDischargeTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n function setReleaseTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n function setBreakBondTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n /***********************************|\n | Only NFT Contract |\n |__________________________________*/\n\n function setTemporaryLock(\n address contractAddress,\n uint256 tokenId,\n bool isLocked\n ) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n\n event DischargeApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event ReleaseApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event BreakBondApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event TimelockApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n\n event TokenDischargeTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenReleaseTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenBreakBondTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenTempLock(address indexed contractAddress, uint256 indexed tokenId, uint256 unlockBlock);\n\n event PermsSetForRestrictCharge(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowDischarge(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowRelease(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForRestrictBond(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowBreakBond(address indexed contractAddress, uint256 indexed tokenId, bool state);\n}\n" + }, + "contracts/v1/interfaces/IDai.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\ninterface IDai is IERC20Upgradeable {\n // --- Approve by signature ---\n function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external;\n function transferFrom(address src, address dst, uint wad) external override returns (bool);\n}" + }, + "contracts/v1/interfaces/IERC20Detailed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Detailed {\n function decimals() external view returns (uint8);\n function symbol() external view returns (string memory);\n function name() external view returns (string memory);\n\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(address sender, address recipient, uint256 amount) 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" + }, + "contracts/v1/interfaces/IERC721Chargeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IERC721Chargeable.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\n\ninterface IERC721Chargeable is IERC165Upgradeable {\n function owner() external view returns (address);\n function creatorOf(uint256 tokenId) external view returns (address);\n function balanceOf(address tokenOwner) external view returns (uint256 balance);\n function ownerOf(uint256 tokenId) external view returns (address tokenOwner);\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n function transferFrom(address from, address to, uint256 tokenId) external;\n function approve(address to, uint256 tokenId) external;\n function getApproved(uint256 tokenId) external view returns (address operator);\n function setApprovalForAll(address operator, bool _approved) external;\n function isApprovedForAll(address tokenOwner, address operator) external view returns (bool);\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "contracts/v1/interfaces/ILepton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ILepton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Lepton Interface\n * @dev ...\n */\ninterface ILepton {\n\n struct Classification {\n string tokenUri;\n uint256 price;\n uint128 _upperBounds;\n uint32 supply;\n uint32 multiplier;\n uint32 bonus;\n }\n\n function mintLepton() external payable returns (uint256 newTokenId);\n function batchMintLepton(uint256 count) external payable;\n function getNextType() external view returns (uint256);\n function getNextPrice() external view returns (uint256);\n function getMultiplier(uint256 tokenId) external view returns (uint256);\n function getBonus(uint256 tokenId) external view returns (uint256);\n\n\n event MaxMintPerTxSet(uint256 maxAmount);\n event LeptonTypeAdded(string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\n event LeptonTypeUpdated(uint256 leptonIndex, string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\n event LeptonMinted(address indexed receiver, uint256 indexed tokenId, uint256 price, uint32 multiplier);\n event LeptonBatchMinted(address indexed receiver, uint256 indexed tokenId, uint256 count, uint256 price, uint32 multiplier);\n event PausedStateSet(bool isPaused);\n}\n" + }, + "contracts/v1/interfaces/IMerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.6.0;\n\n// Allows anyone to claim a token if they exist in a merkle root.\ninterface IMerkleDistributor {\n // Returns the address of the token distributed by this contract.\n function token() external view returns (address);\n // Returns the merkle root of the merkle tree containing account balances available to claim.\n function merkleRoot() external view returns (bytes32);\n // Returns true if the index has been marked claimed.\n function isClaimed(uint256 index) external view returns (bool);\n // Claim the given amount of the token to the given address. Reverts if the inputs are invalid.\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external;\n\n // This event is triggered whenever a call to #claim succeeds.\n event Claimed(uint256 index, address account, uint256 amount);\n}" + }, + "contracts/v1/interfaces/IParticleSplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IParticleSplitter.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Particle Splitter\n */\ninterface IParticleSplitter {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function executeForWallet(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address externalAddress,\n bytes memory encodedParams\n ) external payable returns (bytes memory);\n\n function executeForBasket(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address externalAddress,\n bytes memory encodedParams\n ) external payable returns (bytes memory);\n\n function withdrawWalletRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n ) external returns (uint256 amountWithdrawn);\n\n function withdrawBasketRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n ) external returns (uint256 amountWithdrawn);\n\n function refreshWalletPrincipal(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external;\n\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event ChargedManagersSet(address indexed chargedManagers);\n event TokenInfoProxySet(address indexed tokenInfoProxy);\n\n event ExecuteForWallet(\n address indexed contractAddress,\n uint256 tokenId,\n string walletManagerId,\n address indexed externalAddress,\n bytes encodedParams,\n uint256 ethValue\n );\n event ExecuteForBasket(\n address indexed contractAddress,\n uint256 tokenId,\n string basketManagerId,\n address indexed externalAddress,\n bytes encodedParams,\n uint256 ethValue\n );\n event PrincipalRefreshed(\n address contractAddress,\n uint256 tokenId,\n string walletManagerId,\n address assetToken\n );\n event PermsSetForExternal(\n address indexed contractAddress,\n bool state\n );\n}\n" + }, + "contracts/v1/interfaces/IProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IProton is IERC721 {\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n event PausedStateSet(bool isPaused);\n event SalePriceSet(uint256 indexed tokenId, uint256 salePrice);\n event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct);\n event FeesWithdrawn(address indexed receiver, uint256 amount);\n event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties);\n event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view returns (address);\n function getSalePrice(uint256 tokenId) external view returns (uint256);\n function getLastSellPrice(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyalties(address account) external view returns (uint256);\n function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address);\n\n function buyProton(uint256 tokenId) external payable returns (bool);\n function claimCreatorRoyalties() external returns (uint256);\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n ) external returns (uint256 newTokenId);\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n ) external returns (uint256 newTokenId);\n\n function batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n ) external;\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice) external;\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external;\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external;\n}" + }, + "contracts/v1/interfaces/IProtonB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IProtonB is IERC721 {\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n ) external returns (uint256 newTokenId);\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n}" + }, + "contracts/v1/interfaces/IRewardNft.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IRewardNft.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Reward-NFT Interface\n * @dev ...\n */\ninterface IRewardNft {\n function getMultiplier(uint256 tokenId) external view returns (uint256);\n function getBonus(uint256 tokenId) external view returns (uint256);\n}\n" + }, + "contracts/v1/interfaces/IRewardProgram.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IRewardProgram.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\ninterface IRewardProgram {\n /* admin events */\n event RewardProgramFunded(uint256 amount);\n event RewardProgramOutOfFunds();\n\n /* user events */\n event RewardsClaimed(address indexed contractAddress, uint256 tokenId, address indexed receiver, uint256 rewarded, uint256 remaining);\n\n event AssetRegistered(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\n event AssetDeposit(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\n event AssetRelease(address indexed contractAddress, uint256 tokenId, uint256 interestAmount);\n\n /* data types */\n struct ProgramRewardData {\n address stakingToken;\n address rewardToken;\n uint256 baseMultiplier; // Basis Points\n }\n\n struct AssetStake {\n uint256 start;\n uint256 claimableRewards;\n string walletManagerId;\n }\n\n function initialize(address stakingToken, address rewardToken, uint256 baseMultiplier, address chargedManagers, address universe, address owner) external;\n\n /* user functions */\n function getProgramData() external view returns (ProgramRewardData memory programData);\n function getAssetStake(uint256 uuid) external view returns (AssetStake memory);\n function getFundBalance() external view returns (uint256);\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) external view returns (uint256);\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external;\n function registerAssetDeposit(address contractAddress, uint256 tokenId, string calldata walletManagerId, uint256 principalAmount) external;\n function registerAssetRelease(address contractAddress, uint256 tokenId, uint256 interestAmount) external returns (uint256 rewards);\n}" + }, + "contracts/v1/interfaces/ISmartBasket.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartBasket.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Basket\n * @dev Manages holding and transferring NFTs within an NFT (if any),\n */\ninterface ISmartBasket {\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function addToBasket(address contractAddress, uint256 tokenId) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId) external returns (bool);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartBasketB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartBasketB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Basket \"B\"\n * @dev Manages holding and transferring NFTs within an NFT (if any),\n */\ninterface ISmartBasketB {\n function getNestedNftCount() external view returns (uint256);\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool);\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Wallet\n * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any),\n */\ninterface ISmartWallet {\n function getAssetTokenCount() external view returns (uint256);\n function getAssetTokenByIndex(uint256 index) external view returns (address);\n\n function setNftCreator(address creator, uint256 annuityPct) external;\n\n function isReserveActive(address assetToken) external view returns (bool);\n function getReserveInterestToken(address assetToken) external view returns (address);\n\n function getPrincipal(address assetToken) external returns (uint256);\n function getInterest(address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getTotal(address assetToken) external returns (uint256);\n function getRewards(address assetToken) external returns (uint256);\n\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(address receiver, address creatorRedirect, address assetToken) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function withdrawAmount(address receiver, address creatorRedirect, address assetToken, uint256 assetAmount) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function withdrawAmountForCreator(address receiver, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address assetToken) external;\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Wallet\n * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any),\n */\ninterface ISmartWalletB {\n function getAssetTokenCount() external view returns (uint256);\n function getAssetTokenByIndex(uint256 index) external view returns (address);\n\n function isReserveActive(address assetToken) external view returns (bool);\n function getReserveInterestToken(address assetToken) external view returns (address);\n\n function getPrincipal(address assetToken) external returns (uint256);\n function getInterest(address assetToken, uint256 creatorPct) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getTotal(address assetToken) external returns (uint256);\n function getRewards(address assetToken) external returns (uint256);\n\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken\n ) external returns (\n uint256 creatorAmount,\n uint256 receiverAmount\n );\n function withdrawAmount(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n ) external returns (\n uint256 creatorAmount,\n uint256 receiverAmount\n );\n function withdrawAmountForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n ) external returns (\n uint256 receiverAmount\n );\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address assetToken) external;\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/IStaking.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\ninterface IStaking {\n function manualEpochInit(address[] memory tokens, uint128 epochId) external;\n function getCurrentEpoch() external view returns (uint128);\n function getEpochId(uint timestamp) external view returns (uint); // get epoch id\n function getEpochUserBalance(address user, address token, uint128 epoch) external view returns(uint);\n function getEpochPoolSize(address token, uint128 epoch) external view returns (uint);\n function epoch1Start() external view returns (uint);\n function epochDuration() external view returns (uint);\n}" + }, + "contracts/v1/interfaces/ITokenInfoProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfoProxy.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\n\ninterface ITokenInfoProxy {\n\n event ContractFunctionSignatureSet(address indexed contractAddress, string fnName, bytes4 fnSig);\n\n struct FnSignatures {\n bytes4 ownerOf;\n bytes4 creatorOf;\n }\n\n function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external;\n function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external;\n\n function getTokenUUID(address contractAddress, uint256 tokenId) external pure returns (uint256);\n function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external returns (bool);\n function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external returns (bool);\n function getTokenOwner(address contractAddress, uint256 tokenId) external returns (address);\n function getTokenCreator(address contractAddress, uint256 tokenId) external returns (address);\n}\n" + }, + "contracts/v1/interfaces/IUniverse.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IUniverse.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Universal Controller interface\n * @dev ...\n */\ninterface IUniverse {\n\n event ChargedParticlesSet(address indexed chargedParticles);\n event PhotonSet(address indexed photonToken, uint256 maxSupply);\n event ProtonTokenSet(address indexed protonToken);\n event LeptonTokenSet(address indexed leptonToken);\n event QuarkTokenSet(address indexed quarkToken);\n event BosonTokenSet(address indexed bosonToken);\n event EsaMultiplierSet(address indexed assetToken, uint256 multiplier);\n event ElectrostaticAttraction(address indexed account, address photonSource, uint256 energy, uint256 multiplier);\n event ElectrostaticDischarge(address indexed account, address photonSource, uint256 energy);\n\n function onEnergize(\n address sender,\n address referrer,\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 assetEnergy\n ) external;\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n ) external;\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address creator,\n address assetToken,\n uint256 receiverEnergy\n ) external;\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 principalEnergy,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n ) external;\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n ) external;\n}\n" + }, + "contracts/v1/interfaces/IUniverseRP.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IUniverseRP.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport \"./IUniverse.sol\";\n\n/**\n * @title Universal Controller interface for Rewards Program\n * @dev ...\n */\ninterface IUniverseRP is IUniverse {\n event RewardProgramSet(address indexed assetToken, address indexed rewardProgram);\n event RewardProgramRemoved(address indexed assetToken);\n event NftDeposit(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\n event NftRelease(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\n\n struct NftStake {\n uint256 multiplier; // in Basis Points\n uint256 depositBlockNumber;\n uint256 releaseBlockNumber;\n }\n\n function getRewardProgram(address asset) external view returns (address);\n function getNftStake(uint256 uuid) external view returns (NftStake memory);\n}\n" + }, + "contracts/v1/interfaces/IWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Particle Wallet Manager interface\n * @dev The wallet-manager for underlying assets attached to Charged Particles\n * @dev Manages the link between NFTs and their respective Smart-Wallets\n */\ninterface IWalletManager {\n\n event ControllerSet(address indexed controller);\n event ExecutorSet(address indexed executor);\n event PausedStateSet(bool isPaused);\n event NewSmartWallet(address indexed contractAddress, uint256 indexed tokenId, address indexed smartWallet, address creator, uint256 annuityPct);\n event WalletEnergized(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 assetAmount, uint256 yieldTokensAmount);\n event WalletDischarged(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 creatorAmount, uint256 receiverAmount);\n event WalletDischargedForCreator(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, address creator, uint256 receiverAmount);\n event WalletReleased(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address assetToken, uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n event WalletRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\n\n function isPaused() external view returns (bool);\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view returns (bool);\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view returns (address);\n\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\n function getInterest(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken) external returns (uint256);\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount) external returns (uint256 yieldTokensAmount);\n function discharge(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function dischargeAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function dischargeAmountForCreator(address receiver, address contractAddress, uint256 tokenId, address creator, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\n function release(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n function releaseAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken) external;\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct) external returns (address);\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\n}\n" + }, + "contracts/v1/lib/BaseProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IBaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n/// @title Base Proton Contract for Charged Particles compatible ERC721 NFTs\n/// @dev MUST NOT be Upgradeable, as Upgradeable NFTs are incompatible with Charged Particles.\ncontract BaseProton is \n IBaseProton, \n ERC721, \n Ownable, \n RelayRecipient, \n ReentrancyGuard, \n BlackholePrevention \n{\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n event Received(address, uint);\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n /// @dev Sequential Token IDs storage\n Counters.Counter internal _tokenIds;\n\n /// @dev NFT Token Creator settings\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct;\n mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect;\n mapping (address => uint256) internal _tokenCreatorClaimableRoyalties;\n\n /// @dev NFT Token Sale settings\n mapping (uint256 => uint256) internal _tokenSalePrice;\n mapping (uint256 => uint256) internal _tokenLastSellPrice;\n\n /// @dev Whether of not the Contract is Paused\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n /// @dev Inherit from ERC721 standard\n constructor(string memory _name, string memory _symbol) public ERC721(_name, _symbol) {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n receive() external payable virtual {\n emit Received(msg.sender, msg.value);\n }\n\n /// Returns the Creator address of an NFT by Token ID\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The address of the Creator account\n function creatorOf(uint256 tokenId) external view virtual override returns (address) {\n return _tokenCreator[tokenId];\n }\n\n /// Returns the Sale Price of an NFT by Token ID\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The sale price of the NFT\n function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenSalePrice[tokenId];\n }\n\n /// Returns the Last Sale Price of an NFT by Token ID\n /// @notice This is used to determine any increase in sale price used in royalties calculations\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The last sale price of the NFT\n function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenLastSellPrice[tokenId];\n }\n\n /// Returns the Claimable Royalties for the NFT Creator\n /// @param account The address of the Creator account to lookup\n /// @return The amount of earned royalties for the creator account\n function getCreatorRoyalties(address account) external view virtual override returns (uint256) {\n return _tokenCreatorClaimableRoyalties[account];\n }\n\n /// Returns the Percentage of Royalties reserved for the NFT Creator\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The percentage of royalties reserved for the creator\n function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenCreatorRoyaltiesPct[tokenId];\n }\n\n /// Returns the Receiving address of the Creator Royalties (or Creator if not set)\n /// @dev Returns the creator address if a receiving address has not been configured\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The Receiving address of the Creator Royalties\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) {\n return _creatorRoyaltiesReceiver(tokenId);\n }\n\n /// Allows an NFT Creator to Claim any Royalties that have been earned from NFT sales\n /// @dev Must be called by the royalties receiver account (not neccessarily the creator)\n /// @return The amout of creator royalties claimed\n function claimCreatorRoyalties()\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256)\n {\n return _claimCreatorRoyalties(_msgSender());\n }\n\n\n /***********************************|\n | Create Single Protons |\n |__________________________________*/\n\n /// Creates a Basic NFT with no Royalties and no initial Sale Price\n /// @dev Royalties and Sale Price can be configured later\n /// @param creator The address of the NFT Creator (can be different from the caller)\n /// @param receiver The receiving address of the NFT (can be different from the caller)\n /// @param tokenMetaUri The unique metadata URI for the NFT\n /// @return newTokenId The newly minted NFT Token ID\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n\n /***********************************|\n | Create Multiple Protons |\n |__________________________________*/\n\n function createProtons(\n address creator,\n address receiver,\n string[] calldata tokenMetaUris\n )\n external\n virtual\n override\n whenNotPaused\n returns (bool)\n {\n _createProtons(\n creator,\n receiver,\n 0, // royaltiesPercent\n tokenMetaUris\n );\n return true;\n }\n\n function createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n external\n virtual\n override\n whenNotPaused\n returns (bool)\n {\n _createProtonsForSale(\n creator,\n receiver,\n royaltiesPercent,\n tokenMetaUris,\n salePrices\n );\n return true;\n }\n\n\n /***********************************|\n | Buy Protons |\n |__________________________________*/\n\n function buyProton(uint256 tokenId, uint256 gasLimit)\n external\n payable\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (bool)\n {\n _buyProton(tokenId, gasLimit);\n return true;\n }\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice)\n external\n virtual\n override\n whenNotPaused\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setSalePrice(tokenId, salePrice);\n }\n\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setRoyaltiesPct(tokenId, royaltiesPct);\n }\n\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n {\n _tokenCreatorRoyaltiesRedirect[tokenId] = receiver;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual {\n _tokenSalePrice[tokenId] = salePrice;\n emit SalePriceSet(tokenId, salePrice);\n }\n\n function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual {\n require(royaltiesPct <= PERCENTAGE_SCALE, \"PRT:E-421\");\n _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct;\n emit CreatorRoyaltiesSet(tokenId, royaltiesPct);\n }\n\n function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) {\n address receiver = _tokenCreatorRoyaltiesRedirect[tokenId];\n if (receiver == address(0x0)) {\n receiver = _tokenCreator[tokenId];\n }\n return receiver;\n }\n\n function _createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n _tokenIds.increment();\n\n newTokenId = _tokenIds.current();\n _safeMint(receiver, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUri);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n }\n\n function _createProtons(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris\n )\n internal\n virtual\n {\n uint256 count = tokenMetaUris.length;\n for (uint256 i; i < count; i++) {\n _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, 0);\n }\n }\n\n function _createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n internal\n virtual\n {\n require(tokenMetaUris.length == salePrices.length, \"PRT:E-202\");\n\n uint256 count = tokenMetaUris.length;\n for (uint256 i; i < count; i++) {\n _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, salePrices[i]);\n }\n }\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n contractAddress = address(this);\n tokenId = _tokenId;\n salePrice = _tokenSalePrice[_tokenId];\n require(salePrice > 0, \"PRT:E-416\");\n require(msg.value >= salePrice, \"PRT:E-414\");\n\n uint256 ownerAmount = salePrice;\n creatorAmount;\n oldOwner = ownerOf(_tokenId);\n newOwner = _msgSender();\n\n // Creator Royalties\n royaltiesReceiver = _creatorRoyaltiesReceiver(_tokenId);\n uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[_tokenId];\n uint256 lastSellPrice = _tokenLastSellPrice[_tokenId];\n if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) {\n creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE);\n ownerAmount = ownerAmount.sub(creatorAmount);\n }\n _tokenLastSellPrice[_tokenId] = salePrice;\n\n // Reserve Royalties for Creator\n if (creatorAmount > 0) {\n _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount);\n }\n\n // Transfer Token\n _transfer(oldOwner, newOwner, _tokenId);\n\n // Transfer Payment\n if (ownerAmount > 0) {\n payable(oldOwner).sendValue(ownerAmount, _gasLimit);\n }\n\n emit ProtonSold(_tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n\n _refundOverpayment(salePrice, _gasLimit);\n }\n\n /**\n * @dev Pays out the Creator Royalties of the calling account\n * @param receiver The receiver of the claimable royalties\n * @return The amount of Creator Royalties claimed\n */\n function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) {\n uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver];\n require(claimableAmount > 0, \"PRT:E-411\");\n\n delete _tokenCreatorClaimableRoyalties[receiver];\n payable(receiver).sendValue(claimableAmount, 0);\n\n emit RoyaltiesClaimed(receiver, claimableAmount);\n }\n\n /**\n * @dev Collects the Required Asset Token from the users wallet\n * @param from The owner address to collect the Assets from\n * @param assetAmount The Amount of Asset Tokens to Collect\n */\n function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual {\n uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from);\n require(assetAmount <= _userAssetBalance, \"PRT:E-411\");\n // Be sure to Approve this Contract to transfer your Asset Token\n require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), \"PRT:E-401\");\n }\n\n function _refundOverpayment(uint256 threshold, uint256 gasLimit) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage, gasLimit);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n _tokenSalePrice[tokenId] = 0;\n super._transfer(from, to, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"PRT:E-101\");\n _;\n }\n\n modifier onlyTokenOwnerOrApproved(uint256 tokenId) {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"PRT:E-105\");\n _;\n }\n\n modifier onlyTokenCreator(uint256 tokenId) {\n require(_tokenCreator[tokenId] == _msgSender(), \"PRT:E-104\");\n _;\n }\n}" + }, + "contracts/v1/lib/Bitwise.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Bitwise.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nlibrary Bitwise {\n function negate(uint32 a) internal pure returns (uint32) {\n return a ^ maxInt();\n }\n\n function shiftLeft(uint32 a, uint32 n) internal pure returns (uint32) {\n return a * uint32(2) ** n;\n }\n\n function shiftRight(uint32 a, uint32 n) internal pure returns (uint32) {\n return a / uint32(2) ** n;\n }\n\n function maxInt() internal pure returns (uint32) {\n return uint32(-1);\n }\n\n // Get bit value at position\n function hasBit(uint32 a, uint32 n) internal pure returns (bool) {\n return a & shiftLeft(0x01, n) != 0;\n }\n\n // Set bit value at position\n function setBit(uint32 a, uint32 n) internal pure returns (uint32) {\n return a | shiftLeft(0x01, n);\n }\n\n // Set the bit into state \"false\"\n function clearBit(uint32 a, uint32 n) internal pure returns (uint32) {\n uint32 mask = negate(shiftLeft(0x01, n));\n return a & mask;\n }\n}\n" + }, + "contracts/v1/lib/BlackholePrevention.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\n\n/**\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\n * the Owner/DAO to pull them out on behalf of a user\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\n */\ncontract BlackholePrevention {\n using Address for address payable;\n using SafeERC20 for IERC20;\n\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\n\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (address(this).balance >= amount) {\n receiver.sendValue(amount);\n emit WithdrawStuckEther(receiver, amount);\n }\n }\n\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\n IERC20(tokenAddress).safeTransfer(receiver, amount);\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\n }\n }\n\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\n }\n }\n\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \"\");\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\n }\n }\n}\n" + }, + "contracts/v1/lib/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/GSN/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableMap.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n /**\n * @dev Emitted when `tokenId` token is transfered from `from` to `to`.\n */\n event TransferBatch(address indexed from, address indexed to, uint256 startTokenId, uint256 count);\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721:E-403\");\n\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721:E-405\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"ERC721:E-405\");\n return _tokenURIs[tokenId];\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721:E-111\");\n\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \"ERC721:E-105\");\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view override returns (address) {\n require(_exists(tokenId), \"ERC721:E-405\");\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 require(operator != _msgSender(), \"ERC721:E-111\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721:E-402\");\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 returns (bool) {\n return _tokenOwners.contains(tokenId);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721:E-405\");\n address owner = ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721:E-402\");\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 _safeMintBatch(address to, uint256 startTokenId, uint256 count, bytes memory _data) internal virtual {\n _mintBatch(to, startTokenId, count);\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \"ERC721:E-402\");\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:E-403\");\n require(!_exists(tokenId), \"ERC721:E-407\");\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\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 _mintBatch(address to, uint256 startTokenId, uint256 count) internal virtual {\n require(to != address(0), \"ERC721:E-403\");\n require(!_exists(startTokenId), \"ERC721:E-407\");\n\n for (uint i = 0; i < count; i++) {\n uint256 tokenId = startTokenId.add(i);\n _holderTokens[to].add(tokenId);\n _tokenOwners.set(tokenId, to);\n }\n\n emit TransferBatch(address(0), to, startTokenId, count);\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(address from, address to, uint256 tokenId) internal virtual {\n require(ownerOf(tokenId) == from, \"ERC721:E-102\");\n require(to != address(0), \"ERC721:E-403\");\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721:E-405\");\n _tokenURIs[tokenId] = _tokenURI;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721:E-402\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\n }\n}\n" + }, + "contracts/v1/lib/ERC721Basic.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/GSN/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Basic is Context, ERC165, IERC721, IERC721Metadata {\n using SafeMath for uint256;\n using Address for address;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 internal constant _ERC721_RECEIVED = 0x150b7a02;\n\n // mapping from token ids to their owners\n mapping (uint256 => address) internal _tokenOwners;\n\n // mapping from owner to token balance\n mapping (address => uint256) internal _ownerBalance;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) internal _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) internal _operatorApprovals;\n\n // Token name\n string internal _name;\n\n // Token symbol\n string internal _symbol;\n\n // Token Count\n uint256 internal _tokenCount;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 internal constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 internal constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721:E-403\");\n return _ownerBalance[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners[tokenId];\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view 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 return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721:E-111\");\n\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \"ERC721:E-105\");\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view override returns (address) {\n require(_exists(tokenId), \"ERC721:E-405\");\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721:E-111\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721:E-402\");\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 returns (bool) {\n return _tokenOwners[tokenId] != address(0x0);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721:E-405\");\n address owner = ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\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(address to, bytes memory _data) internal virtual returns (uint256) {\n uint256 tokenId = _mint(to);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721:E-402\");\n return 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 _safeMintBatch(address to, uint256 count, bytes memory _data) internal virtual {\n uint256 startTokenId = _mintBatch(to, count);\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \"ERC721:E-402\");\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) internal virtual returns (uint256) {\n require(to != address(0), \"ERC721:E-403\");\n\n _tokenCount = _tokenCount.add(1);\n uint256 tokenId = _tokenCount;\n require(!_exists(tokenId), \"ERC721:E-407\");\n\n _tokenOwners[tokenId] = to;\n _ownerBalance[to] = _ownerBalance[to].add(1);\n\n emit Transfer(address(0), to, tokenId);\n return tokenId;\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 _mintBatch(address to, uint256 count) internal virtual returns (uint256) {\n require(to != address(0), \"ERC721:E-403\");\n\n uint256 startTokenId = _tokenCount.add(1);\n for (uint i = 1; i <= count; i++) {\n uint256 tokenId = _tokenCount.add(i);\n _tokenOwners[tokenId] = to;\n emit Transfer(address(0), to, tokenId);\n }\n\n _tokenCount = _tokenCount.add(count);\n _ownerBalance[to] = _ownerBalance[to].add(count);\n return startTokenId;\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(address from, address to, uint256 tokenId) internal virtual {\n require(ownerOf(tokenId) == from, \"ERC721:E-102\");\n require(to != address(0), \"ERC721:E-403\");\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _tokenOwners[tokenId] = to;\n _ownerBalance[from] = _ownerBalance[from].sub(1);\n _ownerBalance[to] = _ownerBalance[to].add(1);\n\n emit Transfer(from, to, tokenId);\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(address from, address to, uint256 tokenId, bytes memory _data)\n internal returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721:E-402\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) internal {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\n }\n}\n" + }, + "contracts/v1/lib/IERC5192.sol": { + "content": "// SPDX-License-Identifier: CC0-1.0\npragma solidity ^0.6.0;\n\ninterface IERC5192 {\n /// @notice Emitted when the locking status is changed to locked.\n /// @dev If a token is minted and the status is locked, this event should be emitted.\n /// @param tokenId The identifier for a token.\n event Locked(uint256 tokenId);\n\n /// @notice Emitted when the locking status is changed to unlocked.\n /// @dev If a token is minted and the status is unlocked, this event should be emitted.\n /// @param tokenId The identifier for a token.\n event Unlocked(uint256 tokenId);\n\n /// @notice Returns the locking status of an Soulbound Token\n /// @dev SBTs assigned to zero address are considered invalid, and queries\n /// about them do throw.\n /// @param tokenId The identifier for an SBT.\n function locked(uint256 tokenId) external view returns (bool);\n}\n" + }, + "contracts/v1/lib/NftTokenType.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// NftTokenType.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/introspection/IERC165.sol\";\n\nlibrary NftTokenType {\n bytes4 constant internal INTERFACE_SIGNATURE_ERC721 = 0x80ac58cd;\n bytes4 constant internal INTERFACE_SIGNATURE_ERC1155 = 0xd9b67a26;\n\n uint256 constant internal TYPE_MASK = uint256(uint128(~0)) << 128;\n uint256 constant internal TYPE_NFT_BIT = 1 << 255;\n\n function isERC721(address contractAddress) internal view returns (bool) {\n return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC721);\n }\n\n function isERC1155(address contractAddress) internal view returns (bool) {\n return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC1155);\n }\n\n function getTokenType(address contractAddress, uint256 tokenId) internal view returns (uint256) {\n IERC165 tokenInterface = IERC165(contractAddress);\n bool is1155 = tokenInterface.supportsInterface(INTERFACE_SIGNATURE_ERC1155);\n\n if (!is1155 || (tokenId & TYPE_NFT_BIT != TYPE_NFT_BIT)) { return 0; }\n\n return tokenId & TYPE_MASK;\n }\n}\n" + }, + "contracts/v1/lib/ReentrancyGuard.sol": { + "content": "pragma solidity 0.6.12;\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 () public {\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 _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\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 /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}" + }, + "contracts/v1/lib/RelayRecipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0;\n\nimport \"@opengsn/gsn/contracts/BaseRelayRecipient.sol\";\n\ncontract RelayRecipient is BaseRelayRecipient {\n function versionRecipient() external override view returns (string memory) {\n return \"1.0.0-beta.1/charged-particles.relay.recipient\";\n }\n}\n" + }, + "contracts/v1/lib/SmartWalletBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// SmartWalletBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../interfaces/ISmartWallet.sol\";\nimport \"./BlackholePrevention.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract SmartWalletBase is ISmartWallet, BlackholePrevention {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n address internal _walletManager;\n\n address internal nftCreator;\n uint256 internal nftCreatorAnnuityPct;\n uint256 internal nftCreatorAmountDischarged;\n\n EnumerableSet.AddressSet internal _assetTokens;\n\n // Asset Token => Principal Balance\n mapping (address => uint256) internal _assetPrincipalBalance;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initializeBase() public {\n require(_walletManager == address(0x0), \"SWB:E-002\");\n _walletManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getAssetTokenCount() external view virtual override returns (uint256) {\n return _assetTokens.length();\n }\n\n function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) {\n if (index >= _assetTokens.length()) {\n return address(0);\n }\n return _assetTokens.at(index);\n }\n\n function setNftCreator(address creator, uint256 annuityPct) external virtual override onlyWalletManager {\n nftCreator = creator;\n nftCreatorAnnuityPct = annuityPct;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyWalletManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n function refreshPrincipal(address assetToken)\n external\n virtual\n override\n onlyWalletManager\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getPrincipal(address assetToken) internal view virtual returns (uint256) {\n return _assetPrincipalBalance[assetToken];\n }\n\n function _trackAssetToken(address assetToken) internal virtual {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n }\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the wallet manager\n modifier onlyWalletManager() {\n require(_walletManager == msg.sender, \"SWB:E-109\");\n _;\n }\n}" + }, + "contracts/v1/lib/SmartWalletBaseB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// SmartWalletBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../interfaces/ISmartWalletB.sol\";\nimport \"./BlackholePrevention.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract SmartWalletBaseB is ISmartWalletB, BlackholePrevention {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n address internal _walletManager;\n\n EnumerableSet.AddressSet internal _assetTokens;\n\n // Asset Token => Principal Balance\n mapping (address => uint256) internal _assetPrincipalBalance;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initializeBase() public {\n require(_walletManager == address(0x0), \"SWB:E-002\");\n _walletManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getAssetTokenCount() external view virtual override returns (uint256) {\n return _assetTokens.length();\n }\n\n function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) {\n if (index >= _assetTokens.length()) {\n return address(0);\n }\n return _assetTokens.at(index);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyWalletManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getPrincipal(address assetToken) internal view virtual returns (uint256) {\n return _assetPrincipalBalance[assetToken];\n }\n\n function _trackAssetToken(address assetToken) internal virtual {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n }\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the wallet manager\n modifier onlyWalletManager() {\n require(_walletManager == msg.sender, \"SWB:E-109\");\n _;\n }\n}" + }, + "contracts/v1/lib/Soul.sol": { + "content": "// SPDX-License-Identifier: CC0-1.0\npragma solidity ^0.6.12;\n\nimport \"./IERC5192.sol\";\n\ncontract Soul is IERC5192 {\n \n mapping (uint256 => bool) public lockedTokens;\n\n function _lockToken(uint256 tokenId) internal {\n lockedTokens[tokenId] = true;\n emit Locked(tokenId);\n }\n\n function _unlockToken(uint256 tokenId) internal {\n lockedTokens[tokenId] = false;\n emit Unlocked(tokenId);\n }\n\n function locked(uint256 tokenId)\n external\n view\n override(IERC5192)\n returns (bool)\n {\n return lockedTokens[tokenId];\n }\n}\n" + }, + "contracts/v1/lib/TokenInfo.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfo.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"../interfaces/IERC721Chargeable.sol\";\n\nlibrary TokenInfo {\n function getTokenUUID(address contractAddress, uint256 tokenId) internal pure virtual returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n function getTokenOwner(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n return tokenInterface.ownerOf(tokenId);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n function getTokenCreator(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n return tokenInterface.creatorOf(tokenId);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Owner of an External NFT contract\n /// @param contractAddress The Address to the Contract of the NFT to check\n /// @param account The Address of the Account to check\n /// @return True if the account owns the contract\n function isContractOwner(address contractAddress, address account) internal view virtual returns (bool) {\n address contractOwner = IERC721Chargeable(contractAddress).owner();\n return contractOwner != address(0x0) && contractOwner == account;\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Creator of a Proton-based NFT\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the Proton-based NFT\n function isTokenCreator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenCreator = tokenInterface.creatorOf(tokenId);\n return (sender == tokenCreator);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the Proton-based NFT or the Contract itself\n function isTokenContractOrCreator(address contractAddress, uint256 tokenId, address creator, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenCreator = tokenInterface.creatorOf(tokenId);\n if (sender == contractAddress && creator == tokenCreator) { return true; }\n return (sender == tokenCreator);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Owner or Operator of an External NFT\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the Owner or Operator of the External NFT\n function isErc721OwnerOrOperator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenOwner = tokenInterface.ownerOf(tokenId);\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\n }\n\n /**\n * @dev Returns true if `account` is a contract.\n * @dev Taken from OpenZeppelin library\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\n // for accounts without code, i.e. `keccak256('')`\n bytes32 codehash;\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n // solhint-disable-next-line no-inline-assembly\n assembly { codehash := extcodehash(account) }\n return (codehash != accountHash && codehash != 0x0);\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 * @dev Taken from OpenZeppelin library\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, uint256 gasLimit) internal {\n require(address(this).balance >= amount, \"TokenInfo: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = (gasLimit > 0)\n ? recipient.call{ value: amount, gas: gasLimit }(\"\")\n : recipient.call{ value: amount }(\"\");\n require(success, \"TokenInfo: unable to send value, recipient may have reverted\");\n }\n}\n" + }, + "contracts/v1/lib/TokenInfoProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfoProxy.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../interfaces/ITokenInfoProxy.sol\";\nimport \"../interfaces/IERC721Chargeable.sol\";\n\n\ncontract TokenInfoProxy is ITokenInfoProxy, Ownable {\n using Address for address;\n\n mapping (address => FnSignatures) internal _remappedFnSigs;\n\n function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner {\n _remappedFnSigs[contractAddress].ownerOf = fnSig;\n emit ContractFunctionSignatureSet(contractAddress, \"ownerOf\", fnSig);\n }\n\n function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner {\n _remappedFnSigs[contractAddress].creatorOf = fnSig;\n emit ContractFunctionSignatureSet(contractAddress, \"creatorOf\", fnSig);\n }\n\n\n function getTokenUUID(address contractAddress, uint256 tokenId) external pure virtual override returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n function getTokenOwner(address contractAddress, uint256 tokenId) external virtual override returns (address) {\n return _getTokenOwner(contractAddress, tokenId);\n }\n\n function getTokenCreator(address contractAddress, uint256 tokenId) external virtual override returns (address) {\n return _getTokenCreator(contractAddress, tokenId);\n }\n\n function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenOwner = _getTokenOwner(contractAddress, tokenId);\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\n }\n\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the NFT or the Contract itself\n function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) {\n address tokenCreator = _getTokenCreator(contractAddress, tokenId);\n return (sender == tokenCreator || sender == contractAddress);\n }\n\n\n\n function _getTokenCreator(address contractAddress, uint256 tokenId) internal returns (address) {\n bytes4 fnSig = IERC721Chargeable.creatorOf.selector;\n if (_remappedFnSigs[contractAddress].creatorOf != bytes4(0)) {\n fnSig = _remappedFnSigs[contractAddress].creatorOf;\n }\n\n // solhint-disable-next-line\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n if (success) {\n return abi.decode(returnData, (address));\n } else {\n return address(0x0);\n }\n }\n\n function _getTokenOwner(address contractAddress, uint256 tokenId) internal returns (address) {\n bytes4 fnSig = IERC721Chargeable.ownerOf.selector;\n if (_remappedFnSigs[contractAddress].ownerOf != bytes4(0)) {\n fnSig = _remappedFnSigs[contractAddress].ownerOf;\n }\n\n // solhint-disable-next-line\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n if (success) {\n return abi.decode(returnData, (address));\n } else {\n return address(0x0);\n }\n }\n}\n" + }, + "contracts/v1/lib/WalletManagerBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// WalletManagerBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IWalletManager.sol\";\nimport \"../interfaces/ISmartWallet.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"./BlackholePrevention.sol\";\n\n\n/**\n * @notice Wallet-Manager Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract WalletManagerBase is Ownable, BlackholePrevention, IWalletManager {\n using TokenInfo for address;\n\n // The Controller Contract Address\n address internal _controller;\n\n // The Executor Contract Address\n address internal _executor;\n\n // Template Contract for creating Token Smart-Wallet Bridges\n address internal _walletTemplate;\n\n // TokenID => Token Smart-Wallet Address\n mapping (uint256 => address) internal _wallets;\n\n // State of Wallet Manager\n bool internal _paused;\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Wallet Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n /**\n * @dev Connects to the ExecForAccount Controller\n */\n function setExecutor(address executor) external onlyOwner {\n _executor = executor;\n emit ExecutorSet(executor);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartWallet(wallet).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartWallet(wallet).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartWallet(wallet).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Executor contract\n modifier onlyExecutor() {\n require(_executor == msg.sender, \"WMB:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Controller or Executor contract\n modifier onlyControllerOrExecutor() {\n require(_executor == msg.sender || _controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"WMB:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/ParticleSplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ParticleSplitter.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"./interfaces/IParticleSplitter.sol\";\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IWalletManager.sol\";\nimport \"./interfaces/IBasketManager.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Contract\n * @dev Upgradeable Contract\n */\ncontract ParticleSplitter is IParticleSplitter, Ownable, ReentrancyGuard, BlackholePrevention\n{\n IChargedManagers internal _chargedManagers;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n mapping (address => bool) internal _externalAddressesAllowed;\n\n\n /***********************************|\n | Execute for Account |\n |__________________________________*/\n\n /// @notice Executes an arbitrary command on an NFT Wallet\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Wallet Manager controlling the NFT Wallet to execute on\n /// @param externalAddress The Address of the External Contract to execute on\n /// @param encodedParams The encoded function call to execute\n function executeForWallet(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address externalAddress,\n bytes memory encodedParams\n )\n external\n payable\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (bytes memory)\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n require(_externalAddressesAllowed[externalAddress], \"PS:E-117\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Wallet Manager\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n // Get Address of Wallet to send any ETH into\n if (msg.value > 0) {\n address wallet = walletMgr.getWalletAddressById(contractAddress, tokenId, address(0), 0);\n payable(wallet).sendValue(msg.value);\n }\n\n emit ExecuteForWallet(contractAddress, tokenId, walletManagerId, externalAddress, encodedParams, msg.value);\n\n // Execute command for NFT Wallet\n return walletMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams);\n }\n\n /// @notice Executes an arbitrary command on an NFT Basket\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param basketManagerId The Basket Manager controlling the NFT Wallet to execute on\n /// @param externalAddress The Address of the External Contract to execute on\n /// @param encodedParams The encoded function call to execute\n function executeForBasket(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address externalAddress,\n bytes memory encodedParams\n )\n external\n payable\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (bytes memory)\n {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"PS:E-419\");\n require(_externalAddressesAllowed[externalAddress], \"PS:E-117\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Basket Manager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n\n // Get Address of Wallet to send any ETH into\n if (msg.value > 0) {\n address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId);\n payable(wallet).sendValue(msg.value);\n }\n\n emit ExecuteForBasket(contractAddress, tokenId, basketManagerId, externalAddress, encodedParams, msg.value);\n\n // Execute command for NFT Wallet\n return basketMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams);\n }\n\n function withdrawWalletRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (uint256 amountWithdrawn)\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Wallet Manager\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n // Withdraw Rewards for NFT Wallet\n return walletMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount);\n }\n\n function withdrawBasketRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (uint256 amountWithdrawn)\n {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"PS:E-419\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Basket Manager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n\n // Withdraw Rewards for NFT Basket\n return basketMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount);\n }\n\n function refreshWalletPrincipal(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n walletMgr.refreshPrincipal(contractAddress, tokenId, assetToken);\n\n emit PrincipalRefreshed(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedManagers Interface\n */\n function setChargedManagers(address chargedManagers) external virtual onlyOwner {\n _chargedManagers = IChargedManagers(chargedManagers);\n emit ChargedManagersSet(chargedManagers);\n }\n\n /**\n * @dev Setup the ChargedManagers Interface\n */\n function setTokenInfoProxy(address tokenInfoProxy) external virtual onlyOwner {\n _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy);\n emit TokenInfoProxySet(tokenInfoProxy);\n }\n\n /**\n * @dev Allows/Disallows execute from on specific contracts\n */\n function setExternalContracts(address[] calldata contracts, bool state) external onlyOwner {\n uint count = contracts.length;\n for (uint i; i < count; i++) {\n address externalContract = contracts[i];\n _externalAddressesAllowed[externalContract] = state;\n emit PermsSetForExternal(externalContract, state);\n }\n }\n\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyTokenOwner(address contractAddress, uint256 tokenId) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(msg.sender == tokenOwner, \"PS:E-102\");\n _;\n }\n}\n" + }, + "contracts/v1/test/Dai.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"../interfaces/IDai.sol\";\n\ncontract Dai is IDai {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (uint256 chainId_) public {\n string memory version = \"1\";\n\n _name = \"Dai Stablecoin\";\n _symbol = \"DAI\";\n _decimals = 18;\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(_name)),\n keccak256(bytes(version)),\n chainId_,\n address(this)\n )\n );\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view 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(msg.sender, 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(msg.sender, 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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(msg.sender, spender, _allowances[msg.sender][spender].add(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 _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20:E-403\");\n require(recipient != address(0), \"ERC20:E-403\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20:E-403\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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:E-403\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20:E-403\");\n require(spender != address(0), \"ERC20:E-403\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n\n mapping (address => uint) public nonces;\n\n // --- EIP712 niceties ---\n bytes32 public DOMAIN_SEPARATOR;\n // bytes32 public constant PERMIT_TYPEHASH = keccak256(\"Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)\");\n bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;\n\n // --- Approve by signature ---\n function permit(\n address holder, address spender, uint256 nonce, uint256 expiry,\n bool allowed, uint8 v, bytes32 r, bytes32 s) external override\n {\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n holder,\n spender,\n nonce,\n expiry,\n allowed\n )\n )\n )\n );\n\n require(holder != address(0), \"Dai/invalid-address-0\");\n require(holder == ecrecover(digest, v, r, s), \"Dai/invalid-permit\");\n require(expiry == 0 || now <= expiry, \"Dai/permit-expired\");\n require(nonce == nonces[holder]++, \"Dai/invalid-nonce\");\n uint wad = allowed ? uint(-1) : 0;\n _allowances[holder][spender] = wad;\n emit Approval(holder, spender, wad);\n }\n\n function mint(address to, uint256 amount) external {\n _mint(to, amount);\n }\n}" + }, + "contracts/v1/test/ERC20Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.7.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/**\n * @dev Extension of {ERC20} that adds a set of accounts with the {MinterRole},\n * which have permission to mint (create) new tokens as they see fit.\n *\n * At construction, the deployer of the contract is the only minter.\n */\ncontract ERC20Mintable is ERC20Upgradeable {\n\n constructor(string memory _name, string memory _symbol) public {\n __ERC20_init(_name, _symbol);\n }\n\n /**\n * @dev See {ERC20-_mint}.\n *\n * Requirements:\n *\n * - the caller must have the {MinterRole}.\n */\n function mint(address account, uint256 amount) public returns (bool) {\n _mint(account, amount);\n return true;\n }\n\n function burn(address account, uint256 amount) public returns (bool) {\n _burn(account, amount);\n return true;\n }\n}" + }, + "contracts/v1/test/ERC721Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.7.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\n\n/**\n * @dev Extension of {ERC721} for Minting/Burning\n */\ncontract ERC721Mintable is ERC721Upgradeable {\n\n constructor () public {\n __ERC721_init(\"ERC 721\", \"NFT\");\n }\n\n /**\n * @dev See {ERC721-_mint}.\n */\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n\n /**\n * @dev See {ERC721-_burn}.\n */\n function burn(uint256 tokenId) public {\n _burn(tokenId);\n }\n}\n" + }, + "contracts/v1/tokens/ExternalERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ExternalERC721.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\n\ncontract ExternalERC721 is ERC721 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n\n constructor() public ERC721(\"Charged Particles - ExternalERC721\", \"ExNFT\") {}\n\n function mintNft(address receiver, string memory tokenUri) external returns (uint256 newTokenId) {\n return _mintNft(receiver, tokenUri);\n }\n\n function _mintNft(address receiver, string memory tokenUri) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n\n _safeMint(receiver, newTokenId, \"\");\n\n _setTokenURI(newTokenId, tokenUri);\n }\n}\n" + }, + "contracts/v1/tokens/FungibleERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// FungibleERC1155.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract FungibleERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n\n constructor() public ERC1155(\"https://staging.app.charged.fi/erc1155/metadata.json\") {}\n\n function mintNft(address receiver, uint256 amount) external returns (uint256 newTokenId) {\n return _mintNft(receiver, amount);\n }\n\n function _mintNft(address receiver, uint256 amount) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n _mint(receiver, newTokenId, amount, \"\");\n }\n}\n" + }, + "contracts/v1/tokens/Ionx.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Ionx.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"erc20permit/contracts/ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\n\ncontract Ionx is ERC20Permit, Ownable, BlackholePrevention {\n using SafeMath for uint256;\n\n /// @notice An event thats emitted when the minter address is changed\n event MinterChanged(address minter, address newMinter);\n\n /// @notice Total number of tokens in circulation\n uint256 constant public INITIAL_SUPPLY = 1e8 ether;\n\n /// @notice Minimum time between mints\n uint32 public constant INFLATION_EPOCH = 1 days * 365;\n\n /// @notice Cap on the percentage of totalSupply that can be minted at each mint\n uint8 public constant INFLATION_CAP = 2;\n\n /// @notice Address which may mint new tokens\n address public minter;\n\n /// @notice The timestamp after which minting may occur\n uint256 public mintingAllowedAfter;\n\n\n constructor() public ERC20Permit(\"Charged Particles - IONX\", \"IONX\") {}\n\n\n /**\n * @notice Change the minter address\n * @param newMinter The address of the new minter\n */\n function setMinter(address newMinter) external onlyOwner {\n emit MinterChanged(minter, newMinter);\n minter = newMinter;\n }\n\n /**\n * @notice Mint new tokens\n * @param receiver The address of the destination account\n * @param amount The number of tokens to be minted\n */\n function mint(address receiver, uint256 amount) external onlyMinter {\n require(block.timestamp >= mintingAllowedAfter, \"Ionx:E-114\");\n require(receiver != address(0), \"Ionx:E-403\");\n\n uint256 amountToMint = amount;\n uint256 _totalSupply = totalSupply();\n\n // From Inflationary Supply\n if (_totalSupply >= INITIAL_SUPPLY) {\n mintingAllowedAfter = mintingAllowedAfter.add(INFLATION_EPOCH);\n amountToMint = _totalSupply.mul(INFLATION_CAP).div(100);\n }\n\n // From Initial Supply\n else {\n if (_totalSupply.add(amountToMint) > INITIAL_SUPPLY) {\n amountToMint = INITIAL_SUPPLY.sub(_totalSupply);\n }\n if (_totalSupply.add(amountToMint) == INITIAL_SUPPLY) {\n mintingAllowedAfter = block.timestamp.add(INFLATION_EPOCH);\n }\n }\n\n // transfer the amount to the recipient\n _mint(receiver, amountToMint);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n modifier onlyMinter() {\n require(msg.sender == minter, \"Ionx:E-113\");\n _;\n }\n}\n" + }, + "contracts/v1/tokens/Lepton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Lepton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/ILepton.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\n\ncontract Lepton is ILepton, ERC721, Ownable, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenIds;\n Classification[] internal _leptonTypes;\n mapping (uint256 => Classification) internal _leptonData;\n\n uint256 internal _typeIndex;\n uint256 internal _maxSupply;\n uint256 internal _maxMintPerTx;\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721(\"Charged Particles - Lepton\", \"LEPTON\") {\n _paused = true;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function mintLepton() external payable virtual override nonReentrant whenNotPaused returns (uint256 newTokenId) {\n newTokenId = _mintLepton(msg.sender);\n }\n\n function batchMintLepton(uint256 count) external payable virtual override nonReentrant whenNotPaused {\n _batchMintLepton(msg.sender, count);\n }\n\n function getNextType() external view virtual override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _typeIndex;\n }\n\n function getNextPrice() external view virtual override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _leptonTypes[_typeIndex].price;\n }\n\n function getMultiplier(uint256 tokenId) external view virtual override returns (uint256) {\n return _leptonData[tokenId].multiplier;\n }\n\n function getBonus(uint256 tokenId) external view virtual override returns (uint256) {\n return _leptonData[tokenId].bonus;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function addLeptonType(\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n virtual\n onlyOwner\n {\n _maxSupply = _maxSupply.add(uint256(supply));\n\n Classification memory lepton = Classification({\n tokenUri: tokenUri,\n price: price,\n supply: supply,\n multiplier: multiplier,\n bonus: bonus,\n _upperBounds: uint128(_maxSupply)\n });\n _leptonTypes.push(lepton);\n\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function updateLeptonType(\n uint256 leptonIndex,\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n virtual\n onlyOwner\n {\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\n _leptonTypes[leptonIndex].price = price;\n _leptonTypes[leptonIndex].supply = supply;\n _leptonTypes[leptonIndex].multiplier = multiplier;\n _leptonTypes[leptonIndex].bonus = bonus;\n\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function setMaxMintPerTx(uint256 maxAmount) external virtual onlyOwner {\n _maxMintPerTx = maxAmount;\n emit MaxMintPerTxSet(maxAmount);\n }\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _mintLepton(address receiver) internal virtual returns (uint256 newTokenId) {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n require(msg.value >= lepton.price, \"LPT:E-414\");\n\n _tokenIds.increment();\n newTokenId = _tokenIds.current();\n\n _leptonData[newTokenId] = lepton;\n _safeMint(receiver, newTokenId, \"\");\n _setTokenURI(newTokenId, lepton.tokenUri);\n\n // Distribute Next Type\n if (newTokenId == lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n emit LeptonMinted(receiver, newTokenId, lepton.price, lepton.multiplier);\n\n _refundOverpayment(lepton.price);\n }\n\n\n function _batchMintLepton(address receiver, uint256 count) internal virtual {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \"LPT:E-429\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n\n uint256 startTokenId = _tokenIds.current();\n uint256 endTokenId = startTokenId.add(count);\n if (endTokenId > lepton._upperBounds) {\n count = count.sub(endTokenId.sub(lepton._upperBounds));\n }\n\n uint256 salePrice = lepton.price.mul(count);\n require(msg.value >= salePrice, \"LPT:E-414\");\n\n _safeMintBatch(receiver, startTokenId.add(1), count, \"\");\n\n for (uint i = 0; i < count; i++) {\n _tokenIds.increment();\n startTokenId = _tokenIds.current();\n\n _leptonData[startTokenId] = lepton;\n _setTokenURI(startTokenId, lepton.tokenUri);\n }\n\n // Distribute Next Type\n if (startTokenId >= lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n emit LeptonBatchMinted(receiver, startTokenId, count, lepton.price, lepton.multiplier);\n\n _refundOverpayment(salePrice);\n }\n\n function _refundOverpayment(uint256 threshold) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"LPT:E-101\");\n _;\n }\n}" + }, + "contracts/v1/tokens/Lepton2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Lepton2.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"../lib/ERC721Basic.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\n\nimport \"../interfaces/ILepton.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Lepton2 is ILepton, ERC721Basic, Ownable, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n\n Classification[] internal _leptonTypes;\n\n uint256 internal _typeIndex;\n uint256 internal _maxSupply;\n uint256 internal _maxMintPerTx;\n uint256 internal _migratedCount;\n\n bool internal _paused;\n bool internal _migrationComplete;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721Basic(\"Charged Particles - Lepton2\", \"LEPTON2\") {\n _paused = true;\n _migrationComplete = false;\n _migratedCount = 0;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function mintLepton() external payable override nonReentrant whenNotPaused returns (uint256 newTokenId) {\n newTokenId = _mintLepton(msg.sender);\n }\n\n function batchMintLepton(uint256 count) external payable override nonReentrant whenNotPaused {\n _batchMintLepton(msg.sender, count);\n }\n\n function totalSupply() public view returns (uint256) {\n return _tokenCount;\n }\n\n function maxSupply() external view returns (uint256) {\n return _maxSupply;\n }\n\n function getNextType() external view override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _typeIndex;\n }\n\n function getNextPrice() external view override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _leptonTypes[_typeIndex].price;\n }\n\n function getMultiplier(uint256 tokenId) external view override returns (uint256) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).multiplier;\n }\n\n function getBonus(uint256 tokenId) external view override returns (uint256) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).bonus;\n }\n\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).tokenUri;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function addLeptonType(\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n onlyOwner\n {\n _maxSupply = _maxSupply.add(uint256(supply));\n\n Classification memory lepton = Classification({\n tokenUri: tokenUri,\n price: price,\n supply: supply,\n multiplier: multiplier,\n bonus: bonus,\n _upperBounds: uint128(_maxSupply)\n });\n _leptonTypes.push(lepton);\n\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function updateLeptonType(\n uint256 leptonIndex,\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n onlyOwner\n {\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\n _leptonTypes[leptonIndex].price = price;\n _leptonTypes[leptonIndex].supply = supply;\n _leptonTypes[leptonIndex].multiplier = multiplier;\n _leptonTypes[leptonIndex].bonus = bonus;\n\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function setMaxMintPerTx(uint256 maxAmount) external onlyOwner {\n _maxMintPerTx = maxAmount;\n emit MaxMintPerTxSet(maxAmount);\n }\n\n function setPausedState(bool state) external onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function migrateAccounts(address oldLeptonContract, uint256 count) external onlyOwner whenNotMigrated {\n uint256 oldSupply = IERC721Enumerable(oldLeptonContract).totalSupply();\n require(oldSupply == 0 || oldSupply > _migratedCount, \"LPT:E-004\");\n\n if (oldSupply > 0) {\n uint256 endTokenId = _migratedCount.add(count);\n if (endTokenId > oldSupply) {\n count = count.sub(endTokenId.sub(oldSupply));\n }\n\n for (uint256 i = 1; i <= count; i++) {\n uint256 tokenId = _migratedCount.add(i);\n address tokenOwner = IERC721(oldLeptonContract).ownerOf(tokenId);\n _mint(tokenOwner);\n }\n _migratedCount = _migratedCount.add(count);\n }\n\n if (oldSupply == _migratedCount) {\n _finalizeMigration();\n }\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getLepton(uint256 tokenId) internal view returns (Classification memory) {\n uint256 types = _leptonTypes.length;\n for (uint256 i = 0; i < types; i++) {\n Classification memory lepton = _leptonTypes[i];\n if (tokenId <= lepton._upperBounds) {\n return lepton;\n }\n }\n }\n\n function _mintLepton(address receiver) internal returns (uint256 newTokenId) {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n require(msg.value >= lepton.price, \"LPT:E-414\");\n\n newTokenId = _safeMint(receiver, \"\");\n\n // Determine Next Type\n if (newTokenId == lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n _refundOverpayment(lepton.price);\n }\n\n function _batchMintLepton(address receiver, uint256 count) internal {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \"LPT:E-429\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n\n uint256 endTokenId = _tokenCount.add(count);\n if (endTokenId > lepton._upperBounds) {\n count = count.sub(endTokenId.sub(lepton._upperBounds));\n }\n\n uint256 salePrice = lepton.price.mul(count);\n require(msg.value >= salePrice, \"LPT:E-414\");\n\n _safeMintBatch(receiver, count, \"\");\n\n // Determine Next Type\n if (endTokenId >= lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n _refundOverpayment(salePrice);\n }\n\n function _refundOverpayment(uint256 threshold) internal {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n function _finalizeMigration() internal {\n // Determine Next Type\n _typeIndex = 0;\n for (uint256 i = 0; i < _leptonTypes.length; i++) {\n Classification memory lepton = _leptonTypes[i];\n if (_migratedCount >= lepton._upperBounds) {\n _typeIndex = i + 1;\n }\n }\n _migrationComplete = true;\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotMigrated() {\n require(!_migrationComplete, \"LPT:E-004\");\n _;\n }\n\n modifier whenNotPaused() {\n require(!_paused, \"LPT:E-101\");\n _;\n }\n}" + }, + "contracts/v1/tokens/NonFungibleERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// NonFungibleERC1155.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract NonFungibleERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => address) internal _tokenOwner;\n\n constructor() public ERC1155(\"https://staging.app.charged.fi/erc1155/metadata.json\") {}\n\n function creatorOf(uint256 tokenId) external view returns (address) {\n return _tokenCreator[tokenId];\n }\n\n function ownerOf(uint256 tokenId) external view returns (address) {\n return _tokenOwner[tokenId];\n }\n\n function mintNft(address receiver) external returns (uint256 newTokenId) {\n return _mintNft(msg.sender, receiver);\n }\n\n function _mintNft(address creator, address receiver) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n\n _mint(receiver, newTokenId, 1, \"\");\n _tokenCreator[newTokenId] = creator;\n _tokenOwner[newTokenId] = receiver;\n }\n}\n" + }, + "contracts/v1/tokens/Proton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IProton.sol\";\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ncontract Proton is IProton, ERC721, Ownable, RelayRecipient, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n using Counters for Counters.Counter;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n uint256 constant internal MAX_ROYALTIES = 8e3; // 8000 (80%)\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n Counters.Counter internal _tokenIds;\n\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct;\n mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect;\n mapping (address => uint256) internal _tokenCreatorClaimableRoyalties;\n\n mapping (uint256 => uint256) internal _tokenSalePrice;\n mapping (uint256 => uint256) internal _tokenLastSellPrice;\n\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721(\"Charged Particles - Proton\", \"PROTON\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view virtual override returns (address) {\n return _tokenCreator[tokenId];\n }\n\n function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenSalePrice[tokenId];\n }\n\n function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenLastSellPrice[tokenId];\n }\n\n function getCreatorRoyalties(address account) external view virtual override returns (uint256) {\n return _tokenCreatorClaimableRoyalties[account];\n }\n\n function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenCreatorRoyaltiesPct[tokenId];\n }\n\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) {\n return _creatorRoyaltiesReceiver(tokenId);\n }\n\n function claimCreatorRoyalties()\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256)\n {\n return _claimCreatorRoyalties(_msgSender());\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // annuityPercent,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n royaltiesPercent,\n salePrice\n );\n }\n\n function batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n external\n virtual\n override\n whenNotPaused\n {\n _batchProtonsForSale(\n creator,\n annuityPercent,\n royaltiesPercent,\n tokenMetaUris,\n salePrices\n );\n }\n\n function buyProton(uint256 tokenId)\n external\n payable\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (bool)\n {\n return _buyProton(tokenId);\n }\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice)\n external\n virtual\n override\n whenNotPaused\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setSalePrice(tokenId, salePrice);\n }\n\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setRoyaltiesPct(tokenId, royaltiesPct);\n }\n\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n {\n _tokenCreatorRoyaltiesRedirect[tokenId] = receiver;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual {\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n\n _tokenSalePrice[tokenId] = salePrice;\n emit SalePriceSet(tokenId, salePrice);\n }\n\n function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual {\n require(royaltiesPct <= MAX_ROYALTIES, \"PRT:E-421\");\n _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct;\n emit CreatorRoyaltiesSet(tokenId, royaltiesPct);\n }\n\n function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) {\n address receiver = _tokenCreatorRoyaltiesRedirect[tokenId];\n if (receiver == address(0x0)) {\n receiver = _tokenCreator[tokenId];\n }\n return receiver;\n }\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, annuityPercent, 0, 0);\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n _tokenIds.increment();\n\n newTokenId = _tokenIds.current();\n _safeMint(receiver, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUri);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function _batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n internal\n virtual\n {\n require(tokenMetaUris.length == salePrices.length, \"PRT:E-202\");\n address self = address(this);\n\n uint256 count = tokenMetaUris.length;\n for (uint256 i = 0; i < count; i++) {\n _tokenIds.increment();\n uint256 newTokenId = _tokenIds.current();\n\n _safeMint(creator, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUris[i]);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n uint256 salePrice = salePrices[i];\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n self,\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n function _buyProton(uint256 tokenId)\n internal\n virtual\n returns (bool)\n {\n uint256 salePrice = _tokenSalePrice[tokenId];\n require(salePrice > 0, \"PRT:E-416\");\n require(msg.value >= salePrice, \"PRT:E-414\");\n\n uint256 ownerAmount = salePrice;\n uint256 creatorAmount;\n address oldOwner = ownerOf(tokenId);\n address newOwner = _msgSender();\n\n // Creator Royalties\n address royaltiesReceiver = _creatorRoyaltiesReceiver(tokenId);\n uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[tokenId];\n uint256 lastSellPrice = _tokenLastSellPrice[tokenId];\n if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) {\n creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE);\n ownerAmount = ownerAmount.sub(creatorAmount);\n }\n _tokenLastSellPrice[tokenId] = salePrice;\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(address(this), tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n\n // Reserve Royalties for Creator\n if (creatorAmount > 0) {\n _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount);\n }\n\n // Transfer Token\n _transfer(oldOwner, newOwner, tokenId);\n\n // Transfer Payment\n payable(oldOwner).sendValue(ownerAmount);\n\n emit ProtonSold(tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n\n _refundOverpayment(salePrice);\n return true;\n }\n\n /**\n * @dev Pays out the Creator Royalties of the calling account\n * @param receiver The receiver of the claimable royalties\n * @return The amount of Creator Royalties claimed\n */\n function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) {\n uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver];\n require(claimableAmount > 0, \"PRT:E-411\");\n\n delete _tokenCreatorClaimableRoyalties[receiver];\n payable(receiver).sendValue(claimableAmount);\n\n emit RoyaltiesClaimed(receiver, claimableAmount);\n }\n\n /**\n * @dev Collects the Required Asset Token from the users wallet\n * @param from The owner address to collect the Assets from\n * @param assetAmount The Amount of Asset Tokens to Collect\n */\n function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual {\n uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from);\n require(assetAmount <= _userAssetBalance, \"PRT:E-411\");\n // Be sure to Approve this Contract to transfer your Asset Token\n require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), \"PRT:E-401\");\n }\n\n function _refundOverpayment(uint256 threshold) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n _tokenSalePrice[tokenId] = 0;\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n super._transfer(from, to, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"PRT:E-101\");\n _;\n }\n\n modifier onlyTokenOwnerOrApproved(uint256 tokenId) {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"PRT:E-105\");\n _;\n }\n\n modifier onlyTokenCreator(uint256 tokenId) {\n require(_tokenCreator[tokenId] == _msgSender(), \"PRT:E-104\");\n _;\n }\n}" + }, + "contracts/v1/tokens/ProtonB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\nimport \"../interfaces/IProtonB.sol\";\n\nimport \"../lib/BaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ncontract ProtonB is BaseProton, IProtonB {\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public BaseProton(\"Charged Particles - ProtonB\", \"PROTON.B\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n external\n virtual\n override\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n royaltiesPercent,\n salePrice\n );\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n /// @dev for backwards compatibility with v1\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0);\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n\n /***********************************|\n | Function Overrides |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override {\n super._setSalePrice(tokenId, salePrice);\n\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n }\n\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n override\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n }\n\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n // Unlock NFT\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n\n super._transfer(from, to, tokenId);\n }\n}" + }, + "contracts/v1/tokens/ProtonC.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\nimport \"../lib/Soul.sol\";\n\n\ncontract ProtonC is BaseProton, Soul {\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public BaseProton(\"Charged Particles - ProtonC\", \"PROTON.C\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createBondedToken(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent\n )\n external\n virtual\n payable\n returns (uint256 newTokenId)\n {\n uint256 tokenId = createProtonForSale(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n royaltiesPercent,\n 0\n );\n lockToken(tokenId);\n\n return tokenId;\n }\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n public \n virtual\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n royaltiesPercent,\n salePrice\n );\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n nonReentrant\n whenNotPaused\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n /// @dev for backwards compatibility with v1\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n whenNotPaused\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function burn(uint256 tokenId) public {\n requireTokenOwner(tokenId); \n _burn(tokenId);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n function requireTokenOwner(uint256 tokenId) public view {\n require(ownerOf(tokenId) == msg.sender, \"Only token owner\");\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0);\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n function _burn(uint256 tokenId) internal {\n _unlockToken(tokenId);\n _transfer(ownerOf(tokenId), address(0x000000000000000000000000000000000000dEaD), tokenId);\n }\n\n /***********************************|\n | Soul bounded |\n |__________________________________*/\n\n function lockToken(uint256 tokenId) public {\n requireTokenOwner(tokenId);\n _lockToken(tokenId);\n }\n\n /***********************************|\n | Function Overrides |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override {\n super._setSalePrice(tokenId, salePrice);\n\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n }\n\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n override\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n require(lockedTokens[tokenId] == false, \"BondedToken: Token is locked\");\n\n // Unlock NFT\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n\n super._transfer(from, to, tokenId);\n }\n}" + }, + "contracts/v1/Universe.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\n\nimport \"./interfaces/IUniverse.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n\n/**\n * @notice Charged Particles Universe Contract\n * @dev Upgradeable Contract\n */\ncontract Universe is IUniverse, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n // The ChargedParticles Contract Address\n address public chargedParticles;\n address public proton;\n address public lepton;\n address public quark;\n address public boson;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // Positive Charge\n uint256 internal photonMaxSupply;\n uint256 internal totalPhotonDischarged;\n\n // Source of Positive Charge\n IERC20Upgradeable public photonSource;\n\n // Asset Token => Electrostatic Attraction Multiplier\n mapping (address => uint256) internal esaMultiplier;\n\n // Account => Electrostatic Attraction Levels\n mapping (address => uint256) internal esaLevel;\n\n // Energizing Account => Referral Source\n mapping (address => address) internal referralSource;\n\n // NFT Token UUID => Bonded Lepton Mass\n mapping (uint256 => uint256) internal bondedLeptonMass;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getStaticCharge(address /* account */) external pure virtual returns (uint256 positiveEnergy) {\n return 0;\n }\n\n function conductElectrostaticDischarge(address /* account */, uint256 /* amount */) external pure virtual returns (uint256 positiveEnergy) {\n return 0;\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n onlyProton\n {\n // no-op\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(controller)\n {\n chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setPhoton(\n address token,\n uint256 maxSupply\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n photonSource = IERC20Upgradeable(token);\n photonMaxSupply = maxSupply;\n emit PhotonSet(token, maxSupply);\n }\n\n function setProtonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n proton = token;\n emit ProtonTokenSet(token);\n }\n\n function setLeptonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n lepton = token;\n emit LeptonTokenSet(token);\n }\n\n function setQuarkToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n quark = token;\n emit QuarkTokenSet(token);\n }\n\n function setBosonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n boson = token;\n emit BosonTokenSet(token);\n }\n\n function setEsaMultiplier(\n address assetToken,\n uint256 multiplier\n )\n external\n virtual\n onlyOwner\n {\n esaMultiplier[assetToken] = multiplier;\n emit EsaMultiplierSet(assetToken, multiplier);\n }\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _electrostaticAttraction(uint256 tokenUuid, address receiver, address assetToken, uint256 baseAmount) internal virtual {\n }\n\n function _conductElectrostaticDischarge(address /* account */, uint256 /* energy */) internal virtual pure returns (uint256) {\n return 0;\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Proton NFT contract\n modifier onlyProton() {\n require(proton == msg.sender, \"UNI:E-110\");\n _;\n }\n}\n" + }, + "contracts/v1/UniverseRP.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"./interfaces/IUniverseRP.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./interfaces/IRewardNft.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\nimport \"./interfaces/IRewardProgram.sol\";\n\n/**\n * @notice Charged Particles Universe Contract with Rewards Program\n * @dev Upgradeable Contract\n */\ncontract UniverseRP is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // The ChargedParticles Contract Address\n address public _chargedParticles;\n\n // The Lepton NFT Contract Address\n address public _multiplierNft;\n\n // Asset Token => Reward Program\n mapping (address => address) internal _assetRewardPrograms;\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\n\n // Token UUID => NFT Staking Data\n mapping (uint256 => NftStake) private _nftStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n function getRewardProgram(address asset) external view override returns (address) {\n return _getRewardProgram(asset);\n }\n\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\n return _nftStake[uuid];\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetDeposit(\n contractAddress,\n tokenId,\n walletManagerId,\n assetAmount\n );\n }\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\n }\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n // \"receiverEnergy\" includes the \"principalAmount\"\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n onlyOwner\n onlyValidContractAddress(controller)\n {\n _chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setMultiplierNft(address nftTokenAddress)\n external\n onlyOwner\n onlyValidContractAddress(nftTokenAddress)\n {\n _multiplierNft = nftTokenAddress;\n }\n\n function setRewardProgram(\n address rewardProgam,\n address assetToken\n )\n external\n onlyOwner\n onlyValidContractAddress(rewardProgam)\n {\n require(assetToken != address(0x0), \"UNI:E-403\");\n _assetRewardPrograms[assetToken] = rewardProgam;\n emit RewardProgramSet(assetToken, rewardProgam);\n }\n\n function removeRewardProgram(address assetToken) external onlyOwner {\n delete _assetRewardPrograms[assetToken];\n emit RewardProgramRemoved(assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getRewardProgram(address assetToken) internal view returns (address) {\n return _assetRewardPrograms[assetToken];\n }\n\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != depositNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n uint256 multiplier = _getNftMultiplier(depositNftAddress, depositNftTokenId);\n\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\n // Add to Multipliers Set\n _multiplierNftsSet[parentNftUuid].add(multiplier);\n\n // Update NFT Stake\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\n } else {\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\n }\n }\n\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\n }\n\n function _registerNftRelease(\n address contractAddress,\n uint256 tokenId,\n address releaseNftAddress,\n uint256 releaseNftTokenId,\n uint256 /* nftTokenAmount */\n )\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != releaseNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n NftStake storage nftStake = _nftStake[parentNftUuid];\n\n // Remove from Multipliers Set\n uint256 multiplier = _getNftMultiplier(releaseNftAddress, releaseNftTokenId);\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\n\n // Determine New Multiplier or Mark as Released\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\n } else {\n nftStake.releaseBlockNumber = block.number;\n }\n\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\n }\n\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\n uint256 multiplier = 0;\n uint256 loss = 50;\n uint256 i = 0;\n\n for (; i < len; i++) {\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\n }\n if (len > 1) {\n multiplier = multiplier.sub(loss.mul(len));\n }\n return multiplier;\n }\n\n function _getNftMultiplier(address contractAddress, uint256 tokenId) internal returns (uint256) {\n bytes4 fnSig = IRewardNft.getMultiplier.selector;\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n\n if (success) {\n return abi.decode(returnData, (uint256));\n } else {\n return 0;\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(_chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/UniveserRPPolygon.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"./interfaces/IUniverseRP.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./interfaces/IRewardNft.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\nimport \"./interfaces/IRewardProgram.sol\";\n\n/**\n * @notice Charged Particles Universe Contract with Rewards Program\n * @dev Upgradeable Contract\n */\ncontract UniverseRPPolygon is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // The ChargedParticles Contract Address\n address public _chargedParticles;\n\n // The Lepton NFT Contract Address\n address public _multiplierNft;\n\n // Asset Token => Reward Program\n mapping (address => address) internal _assetRewardPrograms;\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\n\n // Token UUID => NFT Staking Data\n mapping (uint256 => NftStake) private _nftStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n function getRewardProgram(address asset) external view override returns (address) {\n return _getRewardProgram(asset);\n }\n\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\n return _nftStake[uuid];\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetDeposit(\n contractAddress,\n tokenId,\n walletManagerId,\n assetAmount\n );\n }\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\n }\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n // \"receiverEnergy\" includes the \"principalAmount\"\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n onlyOwner\n onlyValidContractAddress(controller)\n {\n _chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setMultiplierNft(address nftTokenAddress)\n external\n onlyOwner\n onlyValidContractAddress(nftTokenAddress)\n {\n _multiplierNft = nftTokenAddress;\n }\n\n function setRewardProgram(\n address rewardProgam,\n address assetToken\n )\n external\n onlyOwner\n onlyValidContractAddress(rewardProgam)\n {\n require(assetToken != address(0x0), \"UNI:E-403\");\n _assetRewardPrograms[assetToken] = rewardProgam;\n emit RewardProgramSet(assetToken, rewardProgam);\n }\n\n function removeRewardProgram(address assetToken) external onlyOwner {\n delete _assetRewardPrograms[assetToken];\n emit RewardProgramRemoved(assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getRewardProgram(address assetToken) internal view returns (address) {\n return _assetRewardPrograms[assetToken];\n }\n\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != depositNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n uint256 multiplier = _getNftMultiplier(depositNftTokenId);\n\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\n // Add to Multipliers Set\n _multiplierNftsSet[parentNftUuid].add(multiplier);\n\n // Update NFT Stake\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\n } else {\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\n }\n }\n\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\n }\n\n function _registerNftRelease(\n address contractAddress,\n uint256 tokenId,\n address releaseNftAddress,\n uint256 releaseNftTokenId,\n uint256 /* nftTokenAmount */\n )\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != releaseNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n NftStake storage nftStake = _nftStake[parentNftUuid];\n\n // Remove from Multipliers Set\n uint256 multiplier = _getNftMultiplier(releaseNftTokenId);\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\n\n // Determine New Multiplier or Mark as Released\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\n } else {\n nftStake.releaseBlockNumber = block.number;\n }\n\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\n }\n\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\n uint256 multiplier = 0;\n uint256 loss = 50;\n uint256 i = 0;\n\n for (; i < len; i++) {\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\n }\n if (len > 1) {\n multiplier = multiplier.sub(loss.mul(len));\n }\n return multiplier;\n }\n\n function _getNftMultiplier(uint256 tokenId) internal pure returns (uint256) {\n if (tokenId >= 1 && tokenId <= 721) {\n return 110;\n } else if (tokenId > 721 && tokenId <= 1122) {\n return 130;\n } else if (tokenId > 1122 && tokenId <= 1423) {\n return 150;\n } else if (tokenId > 1423 && tokenId <= 1624) {\n return 180;\n } else if (tokenId > 1624 && tokenId <= 1712) {\n return 230;\n } else if (tokenId > 1712 && tokenId <= 1733) {\n return 510;\n } else {\n return 1;\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(_chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/vesting/VestingClaim7.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract VestingClaim7 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"VestingClaim7: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"VestingClaim7: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"VestingClaim7: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"VestingClaim7: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"VestingClaim7: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"VestingClaim7: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveSmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\nimport \"../../interfaces/IAaveBridge.sol\";\nimport \"../../lib/SmartWalletBase.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet for Aave Assets\n * @dev Non-upgradeable Contract\n */\ncontract AaveSmartWallet is SmartWalletBase {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 constant internal RAY = 1e27;\n\n IAaveBridge internal _bridge;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(\n address aaveBridge\n )\n public\n {\n SmartWalletBase.initializeBase();\n _bridge = IAaveBridge(aaveBridge);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _bridge.isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address) {\n return _bridge.getReserveInterestToken(assetToken);\n }\n\n function getPrincipal(address assetToken) external override returns (uint256) {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address assetToken) external override returns (uint256 creatorInterest, uint256 ownerInterest) {\n return _getInterest(assetToken);\n }\n\n function getTotal(address assetToken) external override returns (uint256) {\n return _getTotal(assetToken);\n }\n\n function getRewards(address rewardToken) external override returns (uint256) {\n return IERC20(rewardToken).balanceOf(address(this));\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _deposit(assetToken, assetAmount, referralCode);\n }\n\n\n function withdraw(\n address receiver,\n address creatorRedirect,\n address assetToken\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (, uint256 ownerInterest) = _getInterest(assetToken);\n return _withdraw(receiver, creatorRedirect, assetToken, walletPrincipal.add(ownerInterest));\n }\n\n function withdrawAmount(\n address receiver,\n address creatorRedirect,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return _withdraw(receiver, creatorRedirect, assetToken, assetAmount);\n }\n\n function withdrawAmountForCreator(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return _withdrawForCreator(receiver, assetToken, assetAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _withdrawRewards(receiver, rewardsToken, rewardsAmount);\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n internal\n returns (uint256)\n {\n _trackAssetToken(assetToken);\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n\n // Deposit Assets into Aave (reverts on fail)\n _sendToken(address(_bridge), assetToken, assetAmount);\n uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function _withdraw(\n address receiver,\n address creatorRedirect,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken);\n\n // Withdraw from Interest only\n if (assetAmount < ownerInterest) {\n if (creatorInterest > 0) {\n uint256 ratio = assetAmount.mul(RAY).div(ownerInterest);\n creatorAmount = creatorInterest.add(nftCreatorAmountDischarged).mul(ratio).div(RAY);\n\n if (creatorAmount <= nftCreatorAmountDischarged) {\n nftCreatorAmountDischarged = nftCreatorAmountDischarged.sub(creatorAmount);\n creatorAmount = 0;\n }\n\n else {\n creatorAmount = creatorAmount.sub(nftCreatorAmountDischarged);\n nftCreatorAmountDischarged = 0;\n }\n }\n receiverAmount = assetAmount;\n }\n\n // Withdraw from Interest + Principal\n else {\n uint256 fromPrincipal = assetAmount.sub(ownerInterest);\n if (fromPrincipal > walletPrincipal) {\n fromPrincipal = walletPrincipal.sub(ownerInterest);\n }\n\n creatorAmount = creatorInterest;\n receiverAmount = ownerInterest.add(fromPrincipal);\n nftCreatorAmountDischarged = 0;\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal);\n }\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount));\n\n // Withdraw Assets for Creator\n if (creatorAmount > 0) {\n address receivesForCreator = (creatorRedirect != address(0x0)) ? creatorRedirect : nftCreator;\n _bridge.withdraw(receivesForCreator, assetToken, creatorAmount);\n }\n\n // Withdraw Assets for Receiver\n _bridge.withdraw(receiver, assetToken, receiverAmount);\n }\n\n function _withdrawForCreator(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 receiverAmount)\n {\n (uint256 creatorInterest,) = _getInterest(assetToken);\n if (creatorInterest == 0) { return 0; }\n if (assetAmount > creatorInterest) {\n assetAmount = creatorInterest;\n }\n\n nftCreatorAmountDischarged = nftCreatorAmountDischarged.add(assetAmount);\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, assetAmount);\n\n // Withdraw Assets for Receiver on behalf of Creator\n _bridge.withdraw(receiver, assetToken, assetAmount);\n }\n\n function _withdrawRewards(\n address receiver,\n address rewardsTokenAddress,\n uint256 rewardsAmount\n )\n internal\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"ASW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function _getTotal(address assetToken) internal view returns (uint256) {\n return _bridge.getTotalBalance(address(this), assetToken);\n }\n\n function _getInterest(address assetToken) internal view returns (uint256 creatorInterest, uint256 ownerInterest) {\n uint256 total = _getTotal(assetToken);\n uint256 principal = _getPrincipal(assetToken);\n uint256 interest = total.sub(principal);\n\n // Creator Royalties\n if (nftCreatorAnnuityPct > 0) {\n\n // Interest too small to calculate percentage;\n if (interest <= PERCENTAGE_SCALE) {\n // creatorInterest = interest.div(2); // split evenly?\n creatorInterest = 0; // All to owner\n }\n\n // Calculate percentage for Creator\n else {\n creatorInterest = interest\n .add(nftCreatorAmountDischarged)\n .mul(nftCreatorAnnuityPct)\n .div(PERCENTAGE_SCALE)\n .sub(nftCreatorAmountDischarged);\n }\n }\n\n // Owner Portion\n ownerInterest = interest.sub(creatorInterest);\n }\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveSmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\nimport \"../../interfaces/IAaveBridge.sol\";\nimport \"../../lib/SmartWalletBaseB.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet for Aave Assets\n * @dev Non-upgradeable Contract\n */\ncontract AaveSmartWalletB is SmartWalletBaseB {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 constant internal RAY = 1e27;\n\n IAaveBridge internal _bridge;\n\n uint256 internal _nftCreatorAmountDischarged;\n\n mapping (address => address) internal _assetATokens;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(\n address aaveBridge\n )\n public\n {\n SmartWalletBaseB.initializeBase();\n _bridge = IAaveBridge(aaveBridge);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _bridge.isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address) {\n return _bridge.getReserveInterestToken(assetToken);\n }\n\n function getPrincipal(address assetToken) external override returns (uint256) {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address assetToken, uint256 creatorPct) external override returns (uint256 creatorInterest, uint256 ownerInterest) {\n return _getInterest(assetToken, creatorPct);\n }\n\n function getTotal(address assetToken) external override returns (uint256) {\n return _getTotal(assetToken);\n }\n\n function getRewards(address rewardToken) external override returns (uint256) {\n return IERC20(rewardToken).balanceOf(address(this));\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _deposit(assetToken, assetAmount, referralCode);\n }\n\n\n function withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (, uint256 ownerInterest) = _getInterest(assetToken, creatorPct);\n return _withdraw(receiver, creator, creatorPct, assetToken, walletPrincipal.add(ownerInterest));\n }\n\n function withdrawAmount(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return _withdraw(receiver, creator, creatorPct, assetToken, assetAmount);\n }\n\n function withdrawAmountForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return _withdrawForCreator(receiver, creatorPct, assetToken, assetAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _withdrawRewards(receiver, rewardsToken, rewardsAmount);\n }\n\n function refreshPrincipal(address assetToken) external virtual override onlyWalletManager {\n uint256 aTokenBalance = IERC20(_assetATokens[assetToken]).balanceOf(address(this));\n if (_assetPrincipalBalance[assetToken] > aTokenBalance) {\n _assetPrincipalBalance[assetToken] = aTokenBalance;\n }\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n internal\n returns (uint256)\n {\n _trackAssetToken(assetToken);\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n\n // Deposit Assets into Aave (reverts on fail)\n _sendToken(address(_bridge), assetToken, assetAmount);\n uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function _withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken, creatorPct);\n\n // Withdraw from Interest only\n if (assetAmount < ownerInterest) {\n if (creatorInterest > 0) {\n uint256 ratio = assetAmount.mul(RAY).div(ownerInterest);\n creatorAmount = creatorInterest.add(_nftCreatorAmountDischarged).mul(ratio).div(RAY);\n\n if (creatorAmount <= _nftCreatorAmountDischarged) {\n _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.sub(creatorAmount);\n creatorAmount = 0;\n }\n else {\n creatorAmount = creatorAmount.sub(_nftCreatorAmountDischarged);\n _nftCreatorAmountDischarged = 0;\n }\n }\n receiverAmount = assetAmount;\n }\n\n // Withdraw from Interest + Principal\n else {\n uint256 fromPrincipal = assetAmount.sub(ownerInterest);\n if (fromPrincipal > walletPrincipal) {\n fromPrincipal = walletPrincipal.sub(ownerInterest);\n }\n\n creatorAmount = creatorInterest;\n receiverAmount = ownerInterest.add(fromPrincipal);\n _nftCreatorAmountDischarged = 0;\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal);\n }\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount));\n\n // Withdraw Assets for Creator\n if (creatorAmount > 0) {\n if (creator != address(0)) {\n _bridge.withdraw(creator, assetToken, creatorAmount);\n } else {\n receiverAmount = receiverAmount.add(creatorAmount);\n creatorAmount = 0;\n }\n }\n\n // Withdraw Assets for Receiver\n _bridge.withdraw(receiver, assetToken, receiverAmount);\n }\n\n function _withdrawForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 receiverAmount)\n {\n (uint256 creatorInterest,) = _getInterest(assetToken, creatorPct);\n if (creatorInterest == 0) { return 0; }\n if (assetAmount > creatorInterest) {\n assetAmount = creatorInterest;\n }\n\n _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.add(assetAmount);\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, assetAmount);\n\n // Withdraw Assets for Receiver on behalf of Creator\n _bridge.withdraw(receiver, assetToken, assetAmount);\n }\n\n function _withdrawRewards(\n address receiver,\n address rewardsTokenAddress,\n uint256 rewardsAmount\n )\n internal\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"ASW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function _getTotal(address assetToken) internal view returns (uint256) {\n return _bridge.getTotalBalance(address(this), assetToken);\n }\n\n function _getInterest(address assetToken, uint256 creatorPct) internal view returns (uint256 creatorInterest, uint256 ownerInterest) {\n uint256 total = _getTotal(assetToken);\n uint256 principal = _getPrincipal(assetToken);\n uint256 interest = total.sub(principal);\n\n // Creator Royalties\n if (creatorPct > 0) {\n\n // Interest too small to calculate percentage;\n if (interest <= PERCENTAGE_SCALE) {\n // creatorInterest = interest.div(2); // split evenly?\n creatorInterest = 0; // All to owner\n }\n\n // Calculate percentage for Creator\n else {\n creatorInterest = interest\n .add(_nftCreatorAmountDischarged)\n .mul(creatorPct)\n .div(PERCENTAGE_SCALE)\n .sub(_nftCreatorAmountDischarged);\n }\n }\n\n // Owner Portion\n ownerInterest = interest.sub(creatorInterest);\n }\n\n function _trackAssetToken(address assetToken) internal override {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _assetATokens[assetToken] = aTokenAddress;\n }\n }\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../lib/WalletManagerBase.sol\";\n\nimport \"./AaveSmartWallet.sol\";\n\n/**\n * @notice Wallet Manager for Aave\n * @dev Non-upgradeable Contract\n */\ncontract AaveWalletManager is WalletManagerBase {\n using SafeMath for uint256;\n\n event AaveBridgeSet(address indexed aaveBridge);\n event ValidRewardsTokenSet(address indexed rewardsToken, bool state);\n\n address internal _aaveBridge;\n uint256 internal _referralCode;\n\n mapping (address => bool) public rewardsTokenWhitelist;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new AaveSmartWallet());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return AaveSmartWallet(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return AaveSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return AaveSmartWallet(_wallets[uuid]).getInterest(assetToken);\n }\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getTotal(assetToken);\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getRewards(_rewardToken);\n }\n\n\n /***********************************|\n | Only Controller |\n |__________________________________*/\n\n function energize(\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = AaveSmartWallet(wallet).deposit(assetToken, assetAmount, _referralCode);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(ownerInterest > 0, \"AWM:E-412\");\n\n // Discharge the full amount of interest\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, ownerInterest);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(assetAmount > 0 && ownerInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmountForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address creator,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (uint256 creatorInterest,) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(assetAmount > 0 && creatorInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n receiverAmount = AaveSmartWallet(wallet).withdrawAmountForCreator(receiver, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount);\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = AaveSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0;\n\n // Release from interest first + principal if needed\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n require(rewardsTokenWhitelist[rewardsToken], \"AWM:E-423\");\n\n // Withdraw Rewards to Receiver\n amount = AaveSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 tokenId,\n address externalAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return AaveSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n // no-op\n }\n\n function getWalletAddressById(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPct\n )\n external\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n\n if (creator != address(0x0)) {\n AaveSmartWallet(wallet).setNftCreator(creator, annuityPct);\n }\n\n emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAaveBridge(address aaveBridge) external onlyOwner {\n require(aaveBridge != address(0x0), \"AWM:E-403\");\n _aaveBridge = aaveBridge;\n emit AaveBridgeSet(aaveBridge);\n }\n\n // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool\n function setReferralCode(uint256 referralCode) external onlyOwner {\n _referralCode = referralCode;\n }\n\n function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner {\n rewardsTokenWhitelist[rewardsToken] = state;\n emit ValidRewardsTokenSet(rewardsToken, state);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n AaveSmartWallet(newWallet).initialize(_aaveBridge);\n return newWallet;\n }\n}" + }, + "contracts/v1/yield/aave/AaveWalletManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../lib/WalletManagerBase.sol\";\nimport \"../../interfaces/IChargedSettings.sol\";\nimport \"./AaveSmartWalletB.sol\";\n\n/**\n * @notice Wallet Manager for Aave\n * @dev Non-upgradeable Contract\n */\ncontract AaveWalletManagerB is WalletManagerBase {\n using SafeMath for uint256;\n\n event AaveBridgeSet(address indexed aaveBridge);\n event ChargedSettingsSet(address indexed settings);\n event ValidRewardsTokenSet(address indexed rewardsToken, bool state);\n\n IChargedSettings internal _chargedSettings;\n\n address internal _aaveBridge;\n uint256 internal _referralCode;\n\n mapping (address => bool) public _rewardsTokenWhitelist;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new AaveSmartWalletB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return AaveSmartWalletB(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return AaveSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n return AaveSmartWalletB(_wallets[uuid]).getInterest(assetToken, annuityPct);\n }\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getTotal(assetToken);\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getRewards(_rewardToken);\n }\n\n\n /***********************************|\n | Only Controller |\n |__________________________________*/\n\n function energize(\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = AaveSmartWalletB(wallet).deposit(assetToken, assetAmount, _referralCode);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(ownerInterest > 0, \"AWM:E-412\");\n\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Discharge the full amount of interest\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, ownerInterest);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(assetAmount > 0 && ownerInterest >= assetAmount, \"AWM:E-412\");\n\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Discharge a portion of the interest\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmountForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address creator,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (uint256 creatorInterest,) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(assetAmount > 0 && creatorInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n receiverAmount = AaveSmartWalletB(wallet).withdrawAmountForCreator(receiver, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount);\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Release Principal + Interest\n principalAmount = AaveSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdraw(receiver, creator, annuityPct, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0;\n\n // Release from interest first + principal if needed\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n require(_rewardsTokenWhitelist[rewardsToken], \"AWM:E-423\");\n\n // Withdraw Rewards to Receiver\n amount = AaveSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 tokenId,\n address externalAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return AaveSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n AaveSmartWalletB(wallet).refreshPrincipal(assetToken);\n }\n\n function getWalletAddressById(\n address contractAddress,\n uint256 tokenId,\n address /* creator */,\n uint256 /* annuityPct */\n )\n external\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAaveBridge(address aaveBridge) external onlyOwner {\n require(aaveBridge != address(0x0), \"AWM:E-403\");\n _aaveBridge = aaveBridge;\n emit AaveBridgeSet(aaveBridge);\n }\n\n function setChargedSettings(address settings) external onlyOwner {\n require(settings != address(0x0), \"AWM:E-403\");\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool\n function setReferralCode(uint256 referralCode) external onlyOwner {\n _referralCode = referralCode;\n }\n\n function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner {\n _rewardsTokenWhitelist[rewardsToken] = state;\n emit ValidRewardsTokenSet(rewardsToken, state);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n AaveSmartWalletB(newWallet).initialize(_aaveBridge);\n return newWallet;\n }\n}" + }, + "contracts/v1/yield/aave/v2/AaveBridgeV2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveBridgeV2.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/SafeCast.sol\";\n\nimport \"./IATokenV2.sol\";\nimport \"./ILendingPoolV2.sol\";\nimport \"./ILendingPoolAddressesProviderV2.sol\";\n\nimport \"../../../interfaces/IAaveBridge.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\n\ncontract AaveBridgeV2 is Ownable, IAaveBridge, BlackholePrevention {\n using SafeMath for uint256;\n using SafeCast for uint256;\n using SafeERC20 for IERC20;\n using ReserveLogic for ReserveLogic.ReserveData;\n\n ILendingPoolAddressesProviderV2 public provider;\n ILendingPoolV2 public lendingPool;\n\n constructor (address lendingPoolProvider) public {\n provider = ILendingPoolAddressesProviderV2(lendingPoolProvider);\n lendingPool = ILendingPoolV2(provider.getLendingPool());\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address aTokenAddress) {\n return _getReserveInterestToken(assetToken);\n }\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _isReserveActive(assetToken);\n }\n\n function getTotalBalance(address account, address assetToken) external view override returns (uint256) {\n address aTokenAddress = _getReserveInterestToken(assetToken);\n if (aTokenAddress == address(0x0)) { return 0; }\n return IATokenV2(aTokenAddress).balanceOf(account);\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n returns (uint256)\n {\n address self = address(this);\n address aTokenAddress = _getReserveInterestToken(assetToken);\n require(_isReserveActive(assetToken), \"ABV2:E-424\");\n\n IERC20 token = IERC20(assetToken);\n IATokenV2 aToken = IATokenV2(aTokenAddress);\n\n if (token.allowance(address(this), address(lendingPool)) < assetAmount) {\n token.approve(address(lendingPool), uint256(-1));\n }\n\n // Deposit Assets into Aave\n uint256 preBalance = aToken.balanceOf(self);\n lendingPool.deposit(assetToken, assetAmount, self, referralCode.toUint16());\n uint256 postBalance = aToken.balanceOf(self);\n uint256 aTokensAmount = postBalance.sub(preBalance);\n\n // Transfer back the Interest Tokens\n _sendToken(msg.sender, aTokenAddress, aTokensAmount);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function withdraw(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n {\n address self = address(this);\n require(_isReserveActive(assetToken), \"ABV2:E-424\");\n\n // Redeem aTokens for Asset Tokens\n lendingPool.withdraw(assetToken, assetAmount, self);\n\n // Transfer back the Asset Tokens\n _sendToken(receiver, assetToken, assetAmount);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n\n function _getReserveInterestToken(address assetToken) internal view returns (address aTokenAddress) {\n ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken);\n return config.aTokenAddress;\n }\n\n function _isReserveActive(address assetToken) internal view returns (bool) {\n ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken);\n uint256 isActiveFlag = 2 ** 56; // bit 56: reserve is active\n return (config.configuration.data & isActiveFlag) == isActiveFlag;\n }\n}\n" + }, + "contracts/v1/yield/aave/v2/IATokenV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\n\ninterface IATokenV2 {\n function balanceOf(address account) external view returns (uint256);\n}\n" + }, + "contracts/v1/yield/aave/v2/ILendingPoolAddressesProviderV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\n\ninterface ILendingPoolAddressesProviderV2 {\n function getLendingPool() external view returns (address);\n}" + }, + "contracts/v1/yield/aave/v2/ILendingPoolV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport \"./ILendingPoolAddressesProviderV2.sol\";\n\nlibrary ReserveConfiguration {\n struct Map {\n uint256 data;\n }\n}\n\nlibrary ReserveLogic {\n struct ReserveData {\n ReserveConfiguration.Map configuration;\n uint128 liquidityIndex;\n uint128 variableBorrowIndex;\n uint128 currentLiquidityRate;\n uint128 currentVariableBorrowRate;\n uint128 currentStableBorrowRate;\n uint40 lastUpdateTimestamp;\n address aTokenAddress;\n address stableDebtTokenAddress;\n address variableDebtTokenAddress;\n address interestRateStrategyAddress;\n uint8 id;\n }\n}\n\ninterface ILendingPoolV2 {\n function deposit(address reserve, uint256 amount, address onBehalfOf, uint16 referralCode) external;\n function withdraw(address reserve, uint256 amount, address to) external;\n function getReserveData(address asset) external view returns (ReserveLogic.ReserveData memory);\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericSmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"../../../lib/SmartWalletBase.sol\";\n\n\n/**\n * @notice Generic ERC20-Token Smart-Wallet Bridge\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartWallet is SmartWalletBase {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize()\n public\n {\n SmartWalletBase.initializeBase();\n }\n\n function isReserveActive(address assetToken)\n external\n override\n view\n returns (bool)\n {\n return _getPrincipal(assetToken) == 0;\n }\n\n function getReserveInterestToken(address assetToken)\n external\n override\n view\n returns (address)\n {\n return assetToken;\n }\n\n function getPrincipal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address /* assetToken */)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n return (0, 0);\n }\n\n function getTotal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getRewards(address assetToken)\n external\n override\n returns (uint256)\n {\n return IERC20(assetToken).balanceOf(address(this));\n }\n\n function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n // Track Principal\n _trackAssetToken(assetToken);\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n }\n\n function withdraw(address receiver, address /* creatorRedirect */, address assetToken)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmount(address receiver, address /* creatorRedirect */, address assetToken, uint256 assetAmount)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n if (receiverAmount >= assetAmount) {\n receiverAmount = assetAmount;\n }\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmountForCreator(\n address /* receiver */,\n address /* assetToken */,\n uint256 /* assetID */\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericSmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWalletB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"../../../lib/SmartWalletBaseB.sol\";\n\n\n/**\n * @notice Generic ERC20-Token Smart-Wallet Bridge\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartWalletB is SmartWalletBaseB {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize()\n public\n {\n SmartWalletBaseB.initializeBase();\n }\n\n function isReserveActive(address assetToken)\n external\n override\n view\n returns (bool)\n {\n return _getPrincipal(assetToken) == 0;\n }\n\n function getReserveInterestToken(address assetToken)\n external\n override\n view\n returns (address)\n {\n return assetToken;\n }\n\n function getPrincipal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address /* assetToken */, uint256 /* creatorPct */)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n return (0, 0);\n }\n\n function getTotal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getRewards(address assetToken)\n external\n override\n returns (uint256)\n {\n return IERC20(assetToken).balanceOf(address(this));\n }\n\n function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n // Track Principal\n _trackAssetToken(assetToken);\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n }\n\n function withdraw(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmount(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken, uint256 assetAmount)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n if (receiverAmount >= assetAmount) {\n receiverAmount = assetAmount;\n }\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmountForCreator(\n address /* receiver */,\n uint256 /* creatorPct */,\n address /* assetToken */,\n uint256 /* assetID */\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function refreshPrincipal(address assetToken) external virtual override onlyWalletManager {\n _assetPrincipalBalance[assetToken] = IERC20(assetToken).balanceOf(address(this));\n }\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../../lib/WalletManagerBase.sol\";\nimport \"./GenericSmartWallet.sol\";\n\n/**\n * @notice Generic ERC20 Wallet Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericWalletManager is WalletManagerBase {\n using SafeMath for uint256;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new GenericSmartWallet());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return GenericSmartWallet(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return GenericSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getTotal(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return GenericSmartWallet(_wallets[uuid]).getInterest(assetToken);\n }\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getRewards(rewardToken);\n }\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount)\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = GenericSmartWallet(wallet).deposit(assetToken, assetAmount, 0);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmountForCreator(\n address /* receiver */,\n address /* contractAddress */,\n uint256 /* tokenId */,\n address /* creator */,\n address /* assetToken */,\n uint256 /* assetAmount */\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release from interest first + principal if needed\n principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n external\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return GenericSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n // no-op\n }\n\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct)\n external\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n\n if (creator != address(0x0)) {\n GenericSmartWallet(wallet).setNftCreator(creator, annuityPct);\n }\n\n emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n GenericSmartWallet(newWallet).initialize();\n return newWallet;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericWalletManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericWalletManagerB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../../lib/WalletManagerBase.sol\";\nimport \"./GenericSmartWalletB.sol\";\n\n/**\n * @notice Generic ERC20 Wallet Manager B\n * @dev Non-upgradeable Contract\n */\ncontract GenericWalletManagerB is WalletManagerBase {\n using SafeMath for uint256;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new GenericSmartWalletB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return GenericSmartWalletB(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return GenericSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getTotal(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return GenericSmartWalletB(_wallets[uuid]).getInterest(assetToken, 0);\n }\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getRewards(rewardToken);\n }\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount)\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = GenericSmartWalletB(wallet).deposit(assetToken, assetAmount, 0);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmountForCreator(\n address /* receiver */,\n address /* contractAddress */,\n uint256 /* tokenId */,\n address /* creator */,\n address /* assetToken */,\n uint256 /* assetAmount */\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdraw(receiver, creatorRedirect, 0, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release from interest first + principal if needed\n principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdrawAmount(receiver, creatorRedirect, 0, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyControllerOrExecutor\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n external\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return GenericSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n GenericSmartWalletB(wallet).refreshPrincipal(assetToken);\n }\n\n function getWalletAddressById(address contractAddress, uint256 tokenId, address /* creator */, uint256 /* annuityPct */)\n external\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n GenericSmartWalletB(newWallet).initialize();\n return newWallet;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericBasketManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"../../../interfaces/IBasketManager.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"./GenericSmartBasket.sol\";\n\n/**\n * @notice Generic ERC721 Basket Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericBasketManager is Ownable, BlackholePrevention, IBasketManager {\n using Counters for Counters.Counter;\n using TokenInfo for address;\n\n // The Controller Contract Address\n address internal _controller;\n\n // Template Contract for creating Token Smart-Baskets\n address internal _basketTemplate;\n\n // TokenID => Token Smart-Basket Address\n mapping (uint256 => address) internal _baskets;\n\n mapping (uint256 => Counters.Counter) internal _totalTokens;\n\n // State of Basket Manager\n bool internal _paused;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _basketTemplate = address(new GenericSmartBasket());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n function getTokenTotalCount(\n address contractAddress,\n uint256 tokenId\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n return _totalTokens[uuid].current();\n }\n\n function getTokenCountByType(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n external\n override\n returns (uint256)\n {\n address basket = getBasketAddressById(contractAddress, tokenId);\n return GenericSmartBasket(basket).getTokenCountByType(basketTokenAddress, basketTokenId);\n }\n\n function prepareTransferAmount(uint256 /* nftTokenAmount */) external override onlyController {\n // no-op\n }\n\n function addToBasket(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n whenNotPaused\n returns (bool added)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n added = GenericSmartBasket(basket).addToBasket(basketTokenAddress, basketTokenId);\n\n // Log Event\n if (added) {\n _totalTokens[uuid].increment();\n emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, 1);\n }\n }\n\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n returns (bool removed)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n removed = GenericSmartBasket(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId);\n\n // Log Event\n if (removed) {\n _totalTokens[uuid].decrement();\n emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, 1);\n }\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyController\n returns (uint256 amount)\n {\n // no-op\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n public\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n return GenericSmartBasket(basket).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function getBasketAddressById(address contractAddress, uint256 tokenId)\n public\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n // Create Smart-Basket if none exists\n if (basket == address(0x0)) {\n basket = _createBasket();\n _baskets[uuid] = basket;\n\n emit NewSmartBasket(contractAddress, tokenId, basket);\n }\n\n return basket;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Basket Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartBasket(basket).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n function _createBasket()\n internal\n returns (address)\n {\n address newBasket = _createClone(_basketTemplate);\n GenericSmartBasket(newBasket).initialize();\n return newBasket;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"GBM:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"GBM:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericBasketManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport \"../../../interfaces/IBasketManager.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../interfaces/ITokenInfoProxy.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"../../../lib/NftTokenType.sol\";\nimport \"./GenericSmartBasketB.sol\";\n\n/**\n * @notice Generic ERC721 Basket Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericBasketManagerB is Ownable, BlackholePrevention, IBasketManager {\n using Counters for Counters.Counter;\n using TokenInfo for address;\n using NftTokenType for address;\n\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // The Controller Contract Address\n address internal _controller;\n\n // The Executor Contract Address\n address internal _executor;\n\n // Template Contract for creating Token Smart-Baskets\n address internal _basketTemplate;\n\n // TokenID => Token Smart-Basket Address\n mapping (uint256 => address) internal _baskets;\n\n // Prepared Amount\n uint256 internal _preparedAmount;\n\n // State of Basket Manager\n bool internal _paused;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _basketTemplate = address(new GenericSmartBasketB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n function getTokenTotalCount(\n address contractAddress,\n uint256 tokenId\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n if (basket == address(0)) { return 0; }\n return GenericSmartBasketB(basket).getNestedNftCount();\n }\n\n function getTokenCountByType(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n if (basket == address(0)) { return 0; }\n return GenericSmartBasketB(basket).getTokenCountByType(basketTokenAddress, basketTokenId);\n }\n\n function prepareTransferAmount(uint256 nftTokenAmount) external override onlyController {\n _preparedAmount = nftTokenAmount;\n }\n\n function addToBasket(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n whenNotPaused\n returns (bool added)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n uint256 nftTokenAmount = 1;\n if (_preparedAmount > 0) {\n nftTokenAmount = _preparedAmount;\n _preparedAmount = 0;\n }\n\n added = GenericSmartBasketB(basket).addToBasket(basketTokenAddress, basketTokenId, nftTokenAmount);\n if (added) {\n emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount);\n }\n }\n\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n returns (bool removed)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n uint256 nftTokenAmount = 1;\n if (_preparedAmount > 0) {\n nftTokenAmount = _preparedAmount;\n _preparedAmount = 0;\n }\n\n removed = GenericSmartBasketB(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId, nftTokenAmount);\n if (removed) {\n emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount);\n }\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyControllerOrExecutor\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartBasketB(basket).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit BasketRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n public\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n return GenericSmartBasketB(basket).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function getBasketAddressById(address contractAddress, uint256 tokenId)\n public\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n // Create Smart-Basket if none exists\n if (basket == address(0x0)) {\n basket = _createBasket();\n _baskets[uuid] = basket;\n\n emit NewSmartBasket(contractAddress, tokenId, basket);\n }\n\n return basket;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Basket Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n /**\n * @dev Connects to the ExecForAccount Controller\n */\n function setExecutor(address executor) external onlyOwner {\n _executor = executor;\n emit ExecutorSet(executor);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setTokenInfoProxy(address tokenInfoProxy) external onlyOwner {\n _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartBasket(basket).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createBasket()\n internal\n returns (address)\n {\n address newBasket = _createClone(_basketTemplate);\n GenericSmartBasketB(newBasket).initialize(_tokenInfoProxy);\n return newBasket;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"GBM:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Controller or Executor contract\n modifier onlyControllerOrExecutor() {\n require(_executor == msg.sender || _controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"GBM:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericSmartBasket.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/NftTokenType.sol\";\n\n\n/**\n * @notice Generic ERC721-Token Smart-Basket\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartBasket is ISmartBasket, BlackholePrevention, IERC721Receiver {\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableSet for EnumerableSet.AddressSet;\n using NftTokenType for address;\n\n address internal _basketManager;\n\n // NFT contract address => Token Ids in Basket\n mapping (address => mapping(uint256 => EnumerableSet.UintSet)) internal _nftContractTokens;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public {\n require(_basketManager == address(0x0), \"GSB:E-002\");\n _basketManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n return _nftContractTokens[contractAddress][nftType].length();\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver(0).onERC721Received.selector;\n }\n\n function addToBasket(address contractAddress, uint256 tokenId)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n require(!_nftContractTokens[contractAddress][nftType].contains(tokenId), \"GSB:E-425\");\n\n bool added = _nftContractTokens[contractAddress][nftType].add(tokenId);\n if (added) {\n // NFT should have been Transferred into here via Charged-Particles\n added = (IERC721(contractAddress).ownerOf(tokenId) == address(this));\n }\n return added;\n }\n\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n require(_nftContractTokens[contractAddress][nftType].contains(tokenId), \"GSB:E-426\");\n\n bool removed = _nftContractTokens[contractAddress][nftType].remove(tokenId);\n if (removed) {\n IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId);\n }\n return removed;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyBasketManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the basket manager\n modifier onlyBasketManager() {\n require(_basketManager == msg.sender, \"GSB:E-109\");\n _;\n }\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericSmartBasketB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155Receiver.sol\";\nimport \"../../../interfaces/ISmartBasketB.sol\";\nimport \"../../../interfaces/ITokenInfoProxy.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"../../../lib/NftTokenType.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\n\n/**\n * @notice Generic ERC721-Token Smart-Basket\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartBasketB is ISmartBasketB, BlackholePrevention, IERC721Receiver, ERC1155Receiver {\n using TokenInfo for address;\n using NftTokenType for address;\n\n address internal _basketManager;\n\n // NFT TokenUUID => ERC1155 Balance\n mapping (uint256 => uint256) internal _nftContractTokenBalance;\n uint256 internal _nestedNftCount;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(ITokenInfoProxy /* tokenInfoProxy */) public {\n require(_basketManager == address(0x0), \"GSB:E-002\");\n _basketManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getNestedNftCount() external view override returns (uint256) {\n return _nestedNftCount;\n }\n\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n return _nftContractTokenBalance[contractAddress.getTokenUUID(tokenId)];\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver(0).onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\n return IERC1155Receiver(0).onERC1155Received.selector;\n }\n\n // Unimplemented\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\n return \"\"; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector;\n }\n\n function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n _nftContractTokenBalance[uuid] += nftTokenAmount;\n _nestedNftCount += nftTokenAmount;\n return true;\n }\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n uint256 nftTokenAmount\n )\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n _nftContractTokenBalance[uuid] -= nftTokenAmount;\n _nestedNftCount -= nftTokenAmount;\n\n if (contractAddress.isERC1155()) {\n IERC1155(contractAddress).safeTransferFrom(address(this), receiver, tokenId, nftTokenAmount, \"\");\n } else {\n IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId);\n }\n return true;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyBasketManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSB:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyBasketManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the basket manager\n modifier onlyBasketManager() {\n require(_basketManager == msg.sender, \"GSB:E-109\");\n _;\n }\n}\n" + }, + "erc20permit/contracts/ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"./IERC2612.sol\";\n\n/**\n * @author Georgios Konstantopoulos\n * @dev Extension of {ERC20} that allows token holders to use their tokens\n * without sending any transactions by setting {IERC20-allowance} with a\n * signature using the {permit} method, and then spend them via\n * {IERC20-transferFrom}.\n *\n * The {permit} signature mechanism conforms to the {IERC2612} interface.\n */\nabstract contract ERC20Permit is ERC20, IERC2612 {\n mapping (address => uint256) public override nonces;\n\n bytes32 public immutable PERMIT_TYPEHASH = keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public immutable DOMAIN_SEPARATOR;\n\n constructor(string memory name_, string memory symbol_) internal ERC20(name_, symbol_) {\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name_)),\n keccak256(bytes(\"1\")),\n chainId,\n address(this)\n )\n );\n }\n\n /**\n * @dev See {IERC2612-permit}.\n *\n * In cases where the free option is not a concern, deadline can simply be\n * set to uint(-1), so it should be seen as an optional parameter\n */\n function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {\n require(deadline >= block.timestamp, \"ERC20Permit: expired deadline\");\n\n bytes32 hashStruct = keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n amount,\n nonces[owner]++,\n deadline\n )\n );\n\n bytes32 hash = keccak256(\n abi.encodePacked(\n '\\x19\\x01',\n DOMAIN_SEPARATOR,\n hashStruct\n )\n );\n\n address signer = ecrecover(hash, v, r, s);\n require(\n signer != address(0) && signer == owner,\n \"ERC20Permit: invalid signature\"\n );\n\n _approve(owner, spender, amount);\n }\n}\n" + }, + "erc20permit/contracts/IERC2612.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC2612 standard as defined in the EIP.\n *\n * Adds the {permit} method, which can be used to change one's\n * {IERC20-allowance} without having to send a transaction, by signing a\n * message. This allows users to spend tokens without having to hold Ether.\n *\n * See https://eips.ethereum.org/EIPS/eip-2612.\n */\ninterface IERC2612 {\n /**\n * @dev Sets `amount` 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 * - `owner` cannot be the zero address.\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(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n /**\n * @dev Returns the current ERC2612 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" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "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/deployments/polygon/solcInputs/39876b9d6995fafd8c4442fb1a03f418.json b/deployments/polygon/solcInputs/39876b9d6995fafd8c4442fb1a03f418.json new file mode 100644 index 0000000..891dec4 --- /dev/null +++ b/deployments/polygon/solcInputs/39876b9d6995fafd8c4442fb1a03f418.json @@ -0,0 +1,452 @@ +{ + "language": "Solidity", + "sources": { + "@opengsn/gsn/contracts/BaseRelayRecipient.sol": { + "content": "// SPDX-License-Identifier:MIT\n// solhint-disable no-inline-assembly\npragma solidity ^0.6.2;\n\nimport \"./interfaces/IRelayRecipient.sol\";\n\n/**\n * A base contract to be inherited by any contract that want to receive relayed transactions\n * A subclass must use \"_msgSender()\" instead of \"msg.sender\"\n */\nabstract contract BaseRelayRecipient is IRelayRecipient {\n\n /*\n * Forwarder singleton we accept calls from\n */\n address public trustedForwarder;\n\n function isTrustedForwarder(address forwarder) public override view returns(bool) {\n return forwarder == trustedForwarder;\n }\n\n /**\n * return the sender of this call.\n * if the call came through our trusted forwarder, return the original sender.\n * otherwise, return `msg.sender`.\n * should be used in the contract anywhere instead of msg.sender\n */\n function _msgSender() internal override virtual view returns (address payable ret) {\n if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // so we trust that the last bytes of msg.data are the verified sender address.\n // extract sender address from the end of msg.data\n assembly {\n ret := shr(96,calldataload(sub(calldatasize(),20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n /**\n * return the msg.data of this call.\n * if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes\n * of the msg.data - so this method will strip those 20 bytes off.\n * otherwise, return `msg.data`\n * should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly\n * signing or hashing the\n */\n function _msgData() internal override virtual view returns (bytes memory ret) {\n if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // we copy the msg.data , except the last 20 bytes (and update the total length)\n assembly {\n let ptr := mload(0x40)\n // copy only size-20 bytes\n let size := sub(calldatasize(),20)\n // structure RLP data as \n mstore(ptr, 0x20)\n mstore(add(ptr,32), size)\n calldatacopy(add(ptr,64), 0, size)\n return(ptr, add(size,64))\n }\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "@opengsn/gsn/contracts/interfaces/IRelayRecipient.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.6.2;\n\n/**\n * a contract must implement this interface in order to support relayed transaction.\n * It is better to inherit the BaseRelayRecipient as its implementation.\n */\nabstract contract IRelayRecipient {\n\n /**\n * return if the forwarder is trusted to forward relayed transactions to us.\n * the forwarder is required to verify the sender's signature, and verify\n * the call is not a replay.\n */\n function isTrustedForwarder(address forwarder) public virtual view returns(bool);\n\n /**\n * return the sender of this call.\n * if the call came through our trusted forwarder, then the real sender is appended as the last 20 bytes\n * of the msg.data.\n * otherwise, return `msg.sender`\n * should be used in the contract anywhere instead of msg.sender\n */\n function _msgSender() internal virtual view returns (address payable);\n\n /**\n * return the msg.data of this call.\n * if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes\n * of the msg.data - so this method will strip those 20 bytes off.\n * otherwise, return `msg.data`\n * should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly\n * signing or hashing the\n */\n function _msgData() internal virtual view returns (bytes memory);\n\n function versionRecipient() external virtual view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\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 initializer {\n __Context_init_unchained();\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal initializer {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), 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 emit OwnershipTransferred(_owner, address(0));\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n function __ERC165_init() internal initializer {\n __ERC165_init_unchained();\n }\n\n function __ERC165_init_unchained() internal initializer {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMathUpgradeable {\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 uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\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 if (b > a) return (false, 0);\n return (true, a - b);\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 // 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 * @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 if (b == 0) return (false, 0);\n return (true, a / b);\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 if (b == 0) return (false, 0);\n return (true, a % b);\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 uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n return c;\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 require(b <= a, \"SafeMath: subtraction overflow\");\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 if (a == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n return c;\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. 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(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: division by zero\");\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 require(b > 0, \"SafeMath: modulo by zero\");\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n return a - b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a / b;\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.4.24 <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 {UpgradeableProxy-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 */\nabstract contract Initializable {\n\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 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 /// @dev Returns true if and only if the function is running in the constructor\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\n\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 )\n external\n 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 )\n external\n returns(bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC20Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../proxy/Initializable.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 guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable {\n using SafeMathUpgradeable for uint256;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal initializer {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer {\n _name = name_;\n _symbol = symbol_;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal virtual {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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(address sender, address recipient, uint256 amount) 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/ERC20/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.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 SafeERC20Upgradeable {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) 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(IERC20Upgradeable token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\n require((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(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\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(IERC20Upgradeable 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) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721MetadataUpgradeable.sol\";\nimport \"./IERC721EnumerableUpgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"../../introspection/ERC165Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/EnumerableSetUpgradeable.sol\";\nimport \"../../utils/EnumerableMapUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../proxy/Initializable.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable, IERC721EnumerableUpgradeable {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet;\n using EnumerableMapUpgradeable for EnumerableMapUpgradeable.UintToAddressMap;\n using StringsUpgradeable for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSetUpgradeable.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMapUpgradeable.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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 initializer {\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 initializer {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\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 _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\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 _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\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(_msgSender() == owner || ERC721Upgradeable.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 require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) 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(address from, address to, uint256 tokenId, bytes memory _data) 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 _tokenOwners.contains(tokenId);\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 || ERC721Upgradeable.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\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 _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(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); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(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(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721ReceiverUpgradeable(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); // internal owner\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(address from, address to, uint256 tokenId) internal virtual { }\n uint256[41] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721EnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 /**\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/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 /**\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\npragma solidity >=0.6.0 <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(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) 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 // solhint-disable-next-line avoid-low-level-calls\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(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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 // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/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 GSN 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 initializer {\n __Context_init_unchained();\n }\n\n function __Context_init_unchained() internal initializer {\n }\n function _msgSender() internal view virtual returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/EnumerableMapUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMapUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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 EnumerableSetUpgradeable {\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\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\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] = toDeleteIndex + 1; // All indexes are 1-based\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 require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\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 // 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 // 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" + }, + "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/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 initializer {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal initializer {\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 make 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/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n /**\n * @dev Converts a `uint256` to its ASCII `string` 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 uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = bytes1(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../GSN/Context.sol\";\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 */\ncontract 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 () internal {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), msgSender);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view 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 emit OwnershipTransferred(_owner, address(0));\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n" + }, + "@openzeppelin/contracts/cryptography/MerkleProof.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev These functions deal with verification of Merkle trees (hash trees),\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(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {\n bytes32 computedHash = leaf;\n\n for (uint256 i = 0; i < proof.length; i++) {\n bytes32 proofElement = proof[i];\n\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\n // Check if the computed hash (root) is equal to the provided root\n return computedHash == root;\n }\n}\n" + }, + "@openzeppelin/contracts/GSN/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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 GSN 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 payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\ncontract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () internal {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n" + }, + "@openzeppelin/contracts/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\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 uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\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 sub(a, b, \"SafeMath: subtraction overflow\");\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 * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\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 // 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) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts 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 mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\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 SafeMath for uint256;\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 * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri) public {\n _setURI(uri);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\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) external view 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 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(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\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 require(accounts[i] != address(0), \"ERC1155: batch balance query for the zero address\");\n batchBalances[i] = _balances[ids[i]][accounts[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 require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view 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 )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, 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 )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\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 _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(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 `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` 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(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, 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(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) 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 (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\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 `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, 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(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != 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, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\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 )\n internal virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).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 )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).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/token/ERC1155/ERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() public {\n _registerInterface(\n ERC1155Receiver(0).onERC1155Received.selector ^\n ERC1155Receiver(0).onERC1155BatchReceived.selector\n );\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\nimport \"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\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 )\n external\n 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 )\n external\n returns(bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.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 guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 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 {\n using SafeMath for uint256;\n using Address for address;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name, string memory symbol) public {\n _name = name;\n _symbol = symbol;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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/token/ERC20/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.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 SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\n require((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(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\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) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n\n // If there is no base URI, return the token URI.\n if (bytes(_baseURI).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(_baseURI, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(_baseURI, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_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 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 require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) 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(address from, address to, uint256 tokenId, bytes memory _data) 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 returns (bool) {\n return _tokenOwners.contains(tokenId);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = 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 d*\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\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 _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(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 = ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(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(address from, address to, uint256 tokenId) internal virtual {\n require(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 _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\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(address from, address to, uint256 tokenId) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\nimport \"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 /**\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/token/ERC721/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 /**\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/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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(address operator, address from, uint256 tokenId, bytes calldata data)\n external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 in 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 // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n return _functionCallWithValue(target, data, value, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\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 // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../math/SafeMath.sol\";\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented or decremented by one. 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 * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}\n * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never\n * directly accessed.\n */\nlibrary Counters {\n using SafeMath for uint256;\n\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 // The {SafeMath} overflow check can be skipped here, see the comment at the top\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableMap.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n return _get(map, key, \"EnumerableMap: nonexistent key\");\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(value)));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint256(value)));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint256(_get(map._inner, bytes32(key))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint256(_get(map._inner, bytes32(key), errorMessage)));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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.0.0, only sets of type `address` (`AddressSet`) and `uint256`\n * (`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\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\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] = toDeleteIndex + 1; // All indexes are 1-based\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 require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\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(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(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(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(uint256(_at(set._inner, index)));\n }\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" + }, + "@openzeppelin/contracts/utils/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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 */\ncontract 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 () internal {\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 make 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/utils/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value < 2**128, \"SafeCast: value doesn\\'t fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value < 2**64, \"SafeCast: value doesn\\'t fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value < 2**32, \"SafeCast: value doesn\\'t fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value < 2**16, \"SafeCast: value doesn\\'t fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value < 2**8, \"SafeCast: value doesn\\'t fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= -2**127 && value < 2**127, \"SafeCast: value doesn\\'t fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= -2**63 && value < 2**63, \"SafeCast: value doesn\\'t fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= -2**31 && value < 2**31, \"SafeCast: value doesn\\'t fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= -2**15 && value < 2**15, \"SafeCast: value doesn\\'t fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= -2**7 && value < 2**7, \"SafeCast: value doesn\\'t fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n require(value < 2**255, \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` 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 uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = byte(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n" + }, + "contracts/v1/ChargedManagers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Wallet-Managers Contract\n */\ncontract ChargedManagers is\n IChargedManagers,\n Initializable,\n OwnableUpgradeable,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n\n IChargedSettings internal _chargedSettings;\n IChargedState internal _chargedState;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // Wallet/Basket Managers (by Unique Manager ID)\n mapping (string => IWalletManager) internal _ftWalletManager;\n mapping (string => IBasketManager) internal _nftBasketManager;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n /// @notice Checks if an Account is the Owner of an NFT Contract\n /// When Custom Contracts are registered, only the \"owner\" or operator of the Contract\n /// is allowed to register them and define custom rules for how their tokens are \"Charged\".\n /// Otherwise, any token can be \"Charged\" according to the default rules of Charged Particles.\n /// @param contractAddress The Address to the External NFT Contract to check\n /// @param account The Account to check if it is the Owner of the specified Contract\n /// @return True if the account is the Owner of the _contract\n function isContractOwner(address contractAddress, address account) external view override virtual returns (bool) {\n return contractAddress.isContractOwner(account);\n }\n\n function isWalletManagerEnabled(string calldata walletManagerId) external virtual override view returns (bool) {\n return _isWalletManagerEnabled(walletManagerId);\n }\n\n function getWalletManager(string calldata walletManagerId) external virtual override view returns (IWalletManager) {\n return _ftWalletManager[walletManagerId];\n }\n\n function isNftBasketEnabled(string calldata basketId) external virtual override view returns (bool) {\n return _isNftBasketEnabled(basketId);\n }\n\n function getBasketManager(string calldata basketId) external virtual override view returns (IBasketManager) {\n return _nftBasketManager[basketId];\n }\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param sender The sender address to validate against\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external virtual override {\n _validateDeposit(sender, contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param sender The sender address to validate against\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external virtual override {\n _validateNftDeposit(sender, contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateDischarge(sender, contractAddress, tokenId);\n }\n\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateRelease(sender, contractAddress, tokenId);\n }\n\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateBreakBond(sender, contractAddress, tokenId);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"state\"))) {\n _chargedState = IChargedState(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n /// @dev Register Contracts as wallet managers with a unique liquidity provider ID\n function registerWalletManager(string calldata walletManagerId, address walletManager) external virtual onlyOwner {\n // Validate wallet manager\n IWalletManager newWalletMgr = IWalletManager(walletManager);\n require(newWalletMgr.isPaused() != true, \"CP:E-418\");\n\n // Register LP ID\n _ftWalletManager[walletManagerId] = newWalletMgr;\n emit WalletManagerRegistered(walletManagerId, walletManager);\n }\n\n /// @dev Register Contracts as basket managers with a unique basket ID\n function registerBasketManager(string calldata basketId, address basketManager) external virtual onlyOwner {\n // Validate basket manager\n IBasketManager newBasketMgr = IBasketManager(basketManager);\n require(newBasketMgr.isPaused() != true, \"CP:E-418\");\n\n // Register Basket ID\n _nftBasketManager[basketId] = newBasketMgr;\n emit BasketManagerRegistered(basketId, basketManager);\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev See {ChargedParticles-isWalletManagerEnabled}.\n function _isWalletManagerEnabled(string calldata walletManagerId) internal view virtual returns (bool) {\n return (address(_ftWalletManager[walletManagerId]) != address(0x0) && !_ftWalletManager[walletManagerId].isPaused());\n }\n\n /// @dev See {ChargedParticles-isNftBasketEnabled}.\n function _isNftBasketEnabled(string calldata basketId) internal view virtual returns (bool) {\n return (address(_nftBasketManager[basketId]) != address(0x0) && !_nftBasketManager[basketId].isPaused());\n }\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n internal\n virtual\n {\n if (_chargedState.isEnergizeRestricted(contractAddress, tokenId)) {\n bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender);\n require(isNFTOwnerOrOperator, \"CP:E-105\");\n }\n\n ( string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n ) = _chargedSettings.getAssetRequirements(contractAddress, assetToken);\n\n require(energizeEnabled, \"CP:E-417\");\n\n require(!invalidAsset, \"CP:E-424\");\n\n // Valid Wallet Manager?\n if (bytes(requiredWalletManager).length > 0) {\n require(keccak256(abi.encodePacked(requiredWalletManager)) == keccak256(abi.encodePacked(walletManagerId)), \"CP:E-419\");\n }\n\n // Valid Asset?\n if (restrictedAssets) {\n require(validAsset, \"CP:E-424\");\n }\n\n _validateDepositAmount(\n contractAddress,\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n depositCap,\n depositMin,\n depositMax\n );\n }\n\n /// @dev Validates a Deposit-Amount according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDepositAmount(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax\n )\n internal\n virtual\n {\n uint256 existingBalance = _ftWalletManager[walletManagerId].getPrincipal(contractAddress, tokenId, assetToken);\n uint256 newBalance = assetAmount.add(existingBalance);\n\n // Validate Deposit Cap\n if (depositCap > 0) {\n require(newBalance <= depositCap, \"CP:E-408\");\n }\n\n // Valid Amount for Deposit?\n if (depositMin > 0) {\n require(newBalance >= depositMin, \"CP:E-410\");\n }\n if (depositMax > 0) {\n require(newBalance <= depositMax, \"CP:E-410\");\n }\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n {\n // Prevent Ouroboros NFTs\n require(contractAddress.getTokenUUID(tokenId) != nftTokenAddress.getTokenUUID(nftTokenId), \"CP:E-433\");\n\n if (_chargedState.isCovalentBondRestricted(contractAddress, tokenId)) {\n bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender);\n require(isNFTOwnerOrOperator, \"CP:E-105\");\n }\n\n ( string memory requiredBasketManager,\n bool basketEnabled,\n uint256 maxNfts\n ) = _chargedSettings.getNftAssetRequirements(contractAddress, nftTokenAddress);\n\n require(basketEnabled, \"CP:E-417\");\n\n // Valid Basket Manager?\n if (bytes(requiredBasketManager).length > 0) {\n require(keccak256(abi.encodePacked(requiredBasketManager)) == keccak256(abi.encodePacked(basketManagerId)), \"CP:E-419\");\n }\n\n if (maxNfts > 0) {\n uint256 tokenCount = _nftBasketManager[basketManagerId].getTokenTotalCount(contractAddress, tokenId);\n require(maxNfts >= (tokenCount + nftTokenAmount), \"CP:E-427\");\n }\n }\n\n function _validateDischarge(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getDischargeState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateRelease(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getReleaseState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateBreakBond(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getBreakBondState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateState(\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n internal\n view\n virtual\n {\n if (!allowFromAll) {\n require(isApproved, \"CP:E-105\");\n }\n if (timelock > 0) {\n require(block.number >= timelock, \"CP:E-302\");\n }\n if (tempLockExpiry > 0) {\n require(block.number >= tempLockExpiry, \"CP:E-303\");\n }\n }\n}\n" + }, + "contracts/v1/ChargedParticles.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\n\nimport \"./interfaces/IUniverse.sol\";\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/IWalletManager.sol\";\nimport \"./interfaces/IBasketManager.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/RelayRecipient.sol\";\n\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles V2 Contract\n * @dev Upgradeable Contract\n */\ncontract ChargedParticles is\n IChargedParticles,\n Initializable,\n OwnableUpgradeable,\n ReentrancyGuardUpgradeable,\n RelayRecipient,\n IERC721ReceiverUpgradeable,\n BlackholePrevention,\n IERC1155ReceiverUpgradeable\n{\n using SafeMathUpgradeable for uint256;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using Bitwise for uint32;\n using AddressUpgradeable for address;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n //\n // Particle Terminology\n //\n // Particle - Non-fungible Token (NFT)\n // Mass - Underlying Asset of a Token (ex; DAI)\n // Charge - Accrued Interest on the Underlying Asset of a Token\n // Charged Particle - Any NFT that has a Mass and a Positive Charge\n // Neutral Particle - Any NFT that has a Mass and No Charge\n // Energize / Recharge - Deposit of an Underlying Asset into an NFT\n // Discharge - Withdraw the Accrued Interest of an NFT leaving the Particle with its initial Mass\n // Release - Withdraw the Underlying Asset & Accrued Interest of an NFT leaving the Particle with No Mass or Charge\n //\n // Proton - NFTs minted from the Charged Particle Accelerator\n // - A proton is a subatomic particle, symbol p or p⁺, with a positive electric charge of +1e elementary\n // charge and a mass slightly less than that of a neutron.\n // Ion - Platform Governance Token\n // - A charged subatomic particle. An atom or group of atoms that carries a positive or negative electric charge\n // as a result of having lost or gained one or more electrons.\n //\n\n // Linked Contracts\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n address internal _lepton;\n uint256 internal depositFee;\n ITokenInfoProxy internal _tokenInfoProxy;\n IChargedManagers internal _chargedManagers;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n __ReentrancyGuard_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getStateAddress() external view virtual override returns (address stateAddress) {\n return address(_chargedState);\n }\n\n function getSettingsAddress() external view virtual override returns (address settingsAddress) {\n return address(_chargedSettings);\n }\n\n function getManagersAddress() external view virtual override returns (address managersAddress) {\n return address(_chargedManagers);\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external virtual override returns (bytes4) {\n return IERC721ReceiverUpgradeable(0).onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external virtual override returns (bytes4) {\n return IERC1155ReceiverUpgradeable(0).onERC1155Received.selector;\n }\n\n // Unimplemented\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external virtual override returns (bytes4) {\n return \"\"; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector;\n }\n\n function supportsInterface(bytes4 /* interfaceId */) external view virtual override returns (bool) {\n return false;\n }\n\n /// @notice Calculates the amount of Fees to be paid for a specific deposit amount\n /// @param assetAmount The Amount of Assets to calculate Fees on\n /// @return protocolFee The amount of deposit fees for the protocol\n function getFeesForDeposit(\n uint256 assetAmount\n )\n external\n override\n view\n returns (uint256 protocolFee)\n {\n protocolFee = _getFeesForDeposit(assetAmount);\n }\n\n /// @notice Gets the Amount of Asset Tokens that have been Deposited into the Particle\n /// representing the Mass of the Particle.\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Asset balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The Amount of underlying Assets held within the Token\n function baseParticleMass(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _baseParticleMass(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the amount of Interest that the Particle has generated representing\n /// the Charge of the Particle\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Interest balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The amount of interest the Token has generated (in Asset Token)\n function currentParticleCharge(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _currentParticleCharge(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the amount of LP Tokens that the Particle has generated representing\n /// the Kinetics of the Particle\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Kinetics balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The amount of LP tokens that have been generated\n function currentParticleKinetics(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _currentParticleKinetics(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the total amount of ERC721 Tokens that the Particle holds\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param basketManagerId The ID of the BasketManager to check the token balance of\n /// @return The total amount of ERC721 tokens that are held within the Particle\n function currentParticleCovalentBonds(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId\n )\n external\n view\n virtual\n override\n basketEnabled(basketManagerId)\n returns (uint256)\n {\n return _currentParticleCovalentBonds(contractAddress, tokenId, basketManagerId);\n }\n\n\n /***********************************|\n | Energize Particles |\n |__________________________________*/\n\n /// @notice Fund Particle with Asset Token\n /// Must be called by the account providing the Asset\n /// Account must Approve THIS contract as Operator of Asset\n ///\n /// NOTE: DO NOT Energize an ERC20 Token, as anyone who holds any amount\n /// of the same ERC20 token could discharge or release the funds.\n /// All holders of the ERC20 token would essentially be owners of the Charged Particle.\n ///\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param walletManagerId The Asset-Pair to Energize the Token with\n /// @param assetToken The Address of the Asset Token being used\n /// @param assetAmount The Amount of Asset Token to Energize the Token with\n /// @return yieldTokensAmount The amount of Yield-bearing Tokens added to the escrow for the Token\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 yieldTokensAmount)\n {\n _validateDeposit(contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n\n // Transfer ERC20 Token from Caller to Contract (reverts on fail)\n uint256 feeAmount = _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n yieldTokensAmount = _depositIntoWalletManager(contractAddress, tokenId, walletManagerId, assetToken, assetAmount, feeAmount);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onEnergize(_msgSender(), referrer, contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n }\n\n\n /***********************************|\n | Discharge Particles |\n |__________________________________*/\n\n /// @notice Allows the owner or operator of the Token to collect or transfer the interest generated\n /// from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @return creatorAmount Amount of Asset Token discharged to the Creator\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateDischarge(contractAddress, tokenId);\n\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).discharge(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount);\n }\n }\n\n /// @notice Allows the owner or operator of the Token to collect or transfer a specific amount of the interest\n /// generated from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @param assetAmount The specific amount of Asset Token to Discharge from the Token\n /// @return creatorAmount Amount of Asset Token discharged to the Creator\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateDischarge(contractAddress, tokenId);\n\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).dischargeAmount(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n assetAmount,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount);\n }\n }\n\n /// @notice Allows the Creator of the Token to collect or transfer a their portion of the interest (if any)\n /// generated from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @param assetAmount The specific amount of Asset Token to Discharge from the Particle\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 receiverAmount)\n {\n address sender = _msgSender();\n address tokenCreator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId);\n require(sender == tokenCreator, \"CP:E-104\");\n\n receiverAmount = _chargedManagers.getWalletManager(walletManagerId).dischargeAmountForCreator(\n receiver,\n contractAddress,\n tokenId,\n sender,\n assetToken,\n assetAmount\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischargeForCreator(contractAddress, tokenId, walletManagerId, sender, assetToken, receiverAmount);\n }\n }\n\n\n /***********************************|\n | Release Particles |\n |__________________________________*/\n\n /// @notice Releases the Full amount of Asset + Interest held within the Particle by LP of the Assets\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Release\n /// @param tokenId The ID of the Token to Release\n /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token\n /// @param assetToken The Address of the Asset Token being released\n /// @return creatorAmount Amount of Asset Token released to the Creator\n /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount)\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateRelease(contractAddress, tokenId);\n\n // Release Particle to Receiver\n uint256 principalAmount;\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).release(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n }\n\n\n /// @notice Releases a partial amount of Asset + Interest held within the Particle by LP of the Assets\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Release\n /// @param tokenId The ID of the Token to Release\n /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token\n /// @param assetToken The Address of the Asset Token being released\n /// @param assetAmount The specific amount of Asset Token to Release from the Particle\n /// @return creatorAmount Amount of Asset Token released to the Creator\n /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount)\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateRelease(contractAddress, tokenId);\n\n // Release Particle to Receiver\n uint256 principalAmount;\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).releaseAmount(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n assetAmount,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n }\n\n\n /***********************************|\n | Covalent Bonding |\n |__________________________________*/\n\n /// @notice Deposit other NFT Assets into the Particle\n /// Must be called by the account providing the Asset\n /// Account must Approve THIS contract as Operator of Asset\n ///\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n basketEnabled(basketManagerId)\n nonReentrant\n returns (bool success)\n {\n _validateNftDeposit(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Transfer ERC721 Token from Caller to Contract (reverts on fail)\n _collectNftToken(_msgSender(), nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n success = _depositIntoBasketManager(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onCovalentBond(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n }\n\n /// @notice Release NFT Assets from the Particle\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Withdraw (ERC1155-specific)\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n basketEnabled(basketManagerId)\n nonReentrant\n returns (bool success)\n {\n _validateBreakBond(contractAddress, tokenId);\n\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked(\"generic\"))) {\n basketMgr.prepareTransferAmount(nftTokenAmount);\n }\n\n // Release Particle to Receiver\n success = basketMgr.removeFromBasket(\n receiver,\n contractAddress,\n tokenId,\n nftTokenAddress,\n nftTokenId\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onCovalentBreak(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"universe\"))) {\n _universe = IUniverse(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"state\"))) {\n _chargedState = IChargedState(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"managers\"))) {\n _chargedManagers = IChargedManagers(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"leptons\"))) {\n _lepton = controller;\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"forwarder\"))) {\n trustedForwarder = controller;\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n\n /***********************************|\n | Protocol Fees |\n |__________________________________*/\n\n /// @dev Setup the Base Deposit Fee for the Protocol\n function setDepositFee(uint256 fee) external onlyOwner {\n require(fee < PERCENTAGE_SCALE, \"CP:E-421\");\n depositFee = fee;\n emit DepositFeeSet(fee);\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n internal\n virtual\n {\n _chargedManagers.validateDeposit(_msgSender(), contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _validateNftDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n {\n _chargedManagers.validateNftDeposit(_msgSender(), contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function _validateDischarge(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateDischarge(_msgSender(), contractAddress, tokenId);\n }\n\n function _validateRelease(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateRelease(_msgSender(), contractAddress, tokenId);\n }\n\n function _validateBreakBond(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateBreakBond(_msgSender(), contractAddress, tokenId);\n }\n\n /// @dev Deposit Asset Tokens into an NFT via the Wallet Manager\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n /// @param feeAmount The Amount of Protocol Fees charged\n function _depositIntoWalletManager(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 feeAmount\n )\n internal\n virtual\n returns (uint256)\n {\n // Get Wallet-Manager for LP\n IWalletManager lpWalletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n address wallet = lpWalletMgr.getWalletAddressById(contractAddress, tokenId, creator, annuityPct);\n IERC20Upgradeable(assetToken).transfer(wallet, assetAmount);\n\n emit ProtocolFeesCollected(assetToken, assetAmount, feeAmount);\n\n return lpWalletMgr.energize(contractAddress, tokenId, assetToken, assetAmount);\n }\n\n /// @dev Deposit NFT Tokens into the Basket Manager\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @param basketManagerId The Wallet Manager of the Assets to Deposit\n /// @param nftTokenAddress The Address of the Asset Token to Deposit\n /// @param nftTokenId The specific amount of Asset Token to Deposit\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _depositIntoBasketManager(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n returns (bool)\n {\n // Deposit NFT Token directly into Smart Wallet (reverts on fail) and Update BasketManager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId);\n\n if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked(\"generic\"))) {\n basketMgr.prepareTransferAmount(nftTokenAmount);\n }\n\n if (_isERC1155(nftTokenAddress)) {\n if (nftTokenAmount == 0) { nftTokenAmount = 1; }\n IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(address(this), wallet, nftTokenId, nftTokenAmount, \"\");\n } else {\n IERC721Upgradeable(nftTokenAddress).transferFrom(address(this), wallet, nftTokenId);\n }\n return basketMgr.addToBasket(contractAddress, tokenId, nftTokenAddress, nftTokenId);\n }\n\n /**\n * @dev Calculates the amount of Fees to be paid for a specific deposit amount\n * Fees are calculated in Interest-Token as they are the type collected for Fees\n * @param assetAmount The Amount of Assets to calculate Fees on\n * @return protocolFee The amount of fees reserved for the protocol\n */\n function _getFeesForDeposit(\n uint256 assetAmount\n )\n internal\n view\n returns (uint256 protocolFee)\n {\n if (depositFee > 0) {\n protocolFee = assetAmount.mul(depositFee).div(PERCENTAGE_SCALE);\n }\n }\n\n /// @dev Collects the Required ERC20 Token(s) from the users wallet\n /// Be sure to Approve this Contract to transfer your Token(s)\n /// @param from The owner address to collect the tokens from\n /// @param tokenAddress The addres of the token to transfer\n /// @param tokenAmount The amount of tokens to collect\n function _collectAssetToken(address from, address tokenAddress, uint256 tokenAmount) internal virtual returns (uint256 protocolFee) {\n protocolFee = _getFeesForDeposit(tokenAmount);\n IERC20Upgradeable(tokenAddress).safeTransferFrom(from, address(this), tokenAmount.add(protocolFee));\n }\n\n /// @dev Collects the Required ERC721 Token(s) from the users wallet\n /// Be sure to Approve this Contract to transfer your Token(s)\n /// @param from The owner address to collect the tokens from\n /// @param nftTokenAddress The address of the NFT token to transfer\n /// @param nftTokenId The ID of the NFT token to transfer\n /// @param nftTokenAmount The amount of Tokens to Transfer (ERC1155-specific)\n function _collectNftToken(address from, address nftTokenAddress, uint256 nftTokenId, uint256 nftTokenAmount) internal virtual {\n if (_isERC1155(nftTokenAddress)) {\n IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId, nftTokenAmount, \"\");\n } else {\n IERC721Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId);\n }\n }\n\n /// @dev Checks if an NFT token contract supports the ERC1155 standard interface\n function _isERC1155(address nftTokenAddress) internal view virtual returns (bool) {\n bytes4 _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n return IERC165Upgradeable(nftTokenAddress).supportsInterface(_INTERFACE_ID_ERC1155);\n }\n\n /// @dev See {ChargedParticles-baseParticleMass}.\n function _baseParticleMass(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n return _chargedManagers.getWalletManager(walletManagerId).getPrincipal(contractAddress, tokenId, assetToken);\n }\n\n /// @dev See {ChargedParticles-currentParticleCharge}.\n function _currentParticleCharge(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n (, uint256 ownerInterest) = _chargedManagers.getWalletManager(walletManagerId).getInterest(contractAddress, tokenId, assetToken);\n return ownerInterest;\n }\n\n /// @dev See {ChargedParticles-currentParticleKinetics}.\n function _currentParticleKinetics(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n return _chargedManagers.getWalletManager(walletManagerId).getRewards(contractAddress, tokenId, assetToken);\n }\n\n /// @dev See {ChargedParticles-currentParticleCovalentBonds}.\n function _currentParticleCovalentBonds(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId\n )\n internal\n view\n virtual\n returns (uint256)\n {\n return _chargedManagers.getBasketManager(basketManagerId).getTokenTotalCount(contractAddress, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier managerEnabled(string calldata walletManagerId) {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"CP:E-419\");\n _;\n }\n\n modifier basketEnabled(string calldata basketManagerId) {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"CP:E-419\");\n _;\n }\n}\n" + }, + "contracts/v1/ChargedSettings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/RelayRecipient.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\nimport \"./lib/TokenInfoProxy.sol\";\n\n/**\n * @notice Charged Particles Settings Contract\n */\ncontract ChargedSettings is\n IChargedSettings,\n Initializable,\n OwnableUpgradeable,\n RelayRecipient,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using Bitwise for uint32;\n\n uint256 constant internal MAX_ANNUITIES = 1e4; // 10000 (100%)\n\n // NftSettings - actionPerms\n uint32 constant internal PERM_CHARGE_NFT = 1; // NFT Contracts that can have assets Deposited into them (Charged)\n uint32 constant internal PERM_BASKET_NFT = 2; // NFT Contracts that can have other NFTs Deposited into them\n uint32 constant internal PERM_TIMELOCK_ANY_NFT = 4; // NFT Contracts that can timelock any NFT on behalf of users (primarily used for Front-run Protection)\n uint32 constant internal PERM_TIMELOCK_OWN_NFT = 8; // NFT Contracts that can timelock their own NFTs on behalf of their users\n uint32 constant internal PERM_RESTRICTED_ASSETS = 16; // NFT Contracts that have restricted deposits to specific assets\n\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // Current Settings for External NFT Token Contracts;\n // - Any user can add any ERC721 or ERC1155 token as a Charged Particle without Limits,\n // unless the Owner of the ERC721 or ERC1155 token contract registers the token\n // and sets the Custom Settings for their token(s)\n mapping (address => uint32) internal _nftActionPerms;\n\n mapping (address => string) internal _nftRequiredWalletManager;\n mapping (address => string) internal _nftRequiredBasketManager;\n\n // ERC20\n mapping (address => mapping(address => bool)) internal _nftAllowedAssetTokens;\n mapping (address => mapping (address => uint256)) internal _nftDepositMin;\n mapping (address => mapping (address => uint256)) internal _nftDepositMax;\n\n // ERC721 / ERC1155\n mapping (address => mapping (address => uint256)) internal _nftMaxNfts; // NFT Token Address => Max\n\n // Optional Configs for individual NFTs set by NFT Creator (by Token UUID)\n mapping (uint256 => uint256) internal _creatorAnnuityPercent;\n mapping (uint256 => address) internal _creatorAnnuityRedirect;\n\n mapping (address => uint256) internal _depositCap;\n uint256 internal _tempLockExpiryBlocks;\n\n // Blacklist for non-compliant tokens\n mapping (address => bool) internal _invalidAssets;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n /// @dev Gets the amount of creator annuities reserved for the creator for the specified NFT\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @return creator The address of the creator\n /// @return annuityPct The percentage amount of annuities reserved for the creator\n function getCreatorAnnuities(\n address contractAddress,\n uint256 tokenId\n )\n external\n override\n virtual\n returns (address creator, uint256 annuityPct)\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n creator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId);\n annuityPct = _creatorAnnuityPercent[tokenUuid];\n }\n\n function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId)\n external\n view\n override\n virtual\n returns (address)\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _creatorAnnuityRedirect[tokenUuid];\n }\n\n function getTempLockExpiryBlocks() external view override virtual returns (uint256) {\n return _tempLockExpiryBlocks;\n }\n\n function getTimelockApprovals(address operator)\n external\n view\n override\n virtual\n returns (bool timelockAny, bool timelockOwn)\n {\n timelockAny = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_ANY_NFT);\n timelockOwn = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_OWN_NFT);\n }\n\n function getAssetRequirements(address contractAddress, address assetToken)\n external\n view\n override\n virtual\n returns (\n string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n )\n {\n requiredWalletManager = _nftRequiredWalletManager[contractAddress];\n energizeEnabled = _nftActionPerms[contractAddress].hasBit(PERM_CHARGE_NFT);\n restrictedAssets = _nftActionPerms[contractAddress].hasBit(PERM_RESTRICTED_ASSETS);\n validAsset = _nftAllowedAssetTokens[contractAddress][assetToken];\n depositCap = _depositCap[assetToken];\n depositMin = _nftDepositMin[contractAddress][assetToken];\n depositMax = _nftDepositMax[contractAddress][assetToken];\n invalidAsset = _invalidAssets[assetToken];\n }\n\n function getNftAssetRequirements(address contractAddress, address nftTokenAddress)\n external\n view\n override\n virtual\n returns (string memory requiredBasketManager, bool basketEnabled, uint256 maxNfts)\n {\n requiredBasketManager = _nftRequiredBasketManager[contractAddress];\n basketEnabled = _nftActionPerms[contractAddress].hasBit(PERM_BASKET_NFT);\n maxNfts = _nftMaxNfts[contractAddress][nftTokenAddress];\n }\n\n\n /***********************************|\n | Only NFT Creator |\n |__________________________________*/\n\n /// @notice Sets the Custom Configuration for Creators of Proton-based NFTs\n /// @param contractAddress The Address to the Proton-based NFT to configure\n /// @param tokenId The token ID of the Proton-based NFT to configure\n /// @param creator The creator of the Proton-based NFT\n /// @param annuityPercent The percentage of interest-annuities to reserve for the creator\n function setCreatorAnnuities(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent\n )\n external\n virtual\n override\n {\n require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), \"CP:E-104\");\n _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent);\n }\n\n /// @notice Sets a Custom Receiver Address for the Creator Annuities\n /// @param contractAddress The Address to the Proton-based NFT to configure\n /// @param tokenId The token ID of the Proton-based NFT to configure\n /// @param receiver The receiver of the Creator interest-annuities\n function setCreatorAnnuitiesRedirect(\n address contractAddress,\n uint256 tokenId,\n address receiver\n )\n external\n virtual\n override\n {\n require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), \"CP:E-104\");\n _setCreatorAnnuitiesRedirect(contractAddress, tokenId, receiver);\n }\n\n\n /***********************************|\n | Register Contract Settings |\n |(For External Contract Integration)|\n |__________________________________*/\n\n /// @notice Sets a Required Wallet-Manager for External NFT Contracts (otherwise set to \"none\" to allow any Wallet-Manager)\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param walletManager If set, will only allow deposits from this specific Wallet-Manager\n function setRequiredWalletManager(\n address contractAddress,\n string calldata walletManager\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (keccak256(bytes(walletManager)) == keccak256(bytes(\"none\"))) {\n _nftRequiredWalletManager[contractAddress] = \"\";\n } else {\n _nftRequiredWalletManager[contractAddress] = walletManager;\n }\n\n emit RequiredWalletManagerSet(\n contractAddress,\n walletManager\n );\n }\n\n /// @notice Sets a Required Basket-Manager for External NFT Contracts (otherwise set to \"none\" to allow any Basket-Manager)\n /// @param contractAddress The Address to the External Contract to configure\n /// @param basketManager If set, will only allow deposits from this specific Basket-Manager\n function setRequiredBasketManager(\n address contractAddress,\n string calldata basketManager\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (keccak256(bytes(basketManager)) == keccak256(bytes(\"none\"))) {\n _nftRequiredBasketManager[contractAddress] = \"\";\n } else {\n _nftRequiredBasketManager[contractAddress] = basketManager;\n }\n\n emit RequiredBasketManagerSet(\n contractAddress,\n basketManager\n );\n }\n\n /// @notice Enables or Disables Asset-Token Restrictions for External NFT Contracts\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param restrictionsEnabled If set, will only allow deposits from Allowed Asset Tokens\n function setAssetTokenRestrictions(\n address contractAddress,\n bool restrictionsEnabled\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (restrictionsEnabled) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_RESTRICTED_ASSETS);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_RESTRICTED_ASSETS);\n }\n\n emit AssetTokenRestrictionsSet(\n contractAddress,\n restrictionsEnabled\n );\n }\n\n /// @notice Enables or Disables Allowed Asset Tokens for External NFT Contracts\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param assetToken The Address of the Asset Token to Allow or Disallow\n /// @param isAllowed True if the Asset Token is allowed\n function setAllowedAssetToken(\n address contractAddress,\n address assetToken,\n bool isAllowed\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftAllowedAssetTokens[contractAddress][assetToken] = isAllowed;\n\n emit AllowedAssetTokenSet(\n contractAddress,\n assetToken,\n isAllowed\n );\n }\n\n /// @notice Sets the Custom Configuration for External Contracts\n /// @param contractAddress The Address to the External Contract to configure\n /// @param assetToken The address of the Asset Token to set Limits for\n /// @param depositMin If set, will define the minimum amount of Asset tokens the NFT may hold, otherwise any amount\n /// @param depositMax If set, will define the maximum amount of Asset tokens the NFT may hold, otherwise any amount\n function setAssetTokenLimits(\n address contractAddress,\n address assetToken,\n uint256 depositMin,\n uint256 depositMax\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftDepositMin[contractAddress][assetToken] = depositMin;\n _nftDepositMax[contractAddress][assetToken] = depositMax;\n\n emit AssetTokenLimitsSet(\n contractAddress,\n assetToken,\n depositMin,\n depositMax\n );\n }\n\n /// @notice Sets the Max Number of NFTs that can be held by a Charged Particle NFT\n /// @param contractAddress The Address to the External Contract to configure\n /// @param nftTokenAddress The address of the NFT Token to set a Max for\n /// @param maxNfts The maximum numbers of NFTs that can be held by a given NFT (0 = unlimited)\n function setMaxNfts(\n address contractAddress,\n address nftTokenAddress,\n uint256 maxNfts\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftMaxNfts[contractAddress][nftTokenAddress] = maxNfts;\n\n emit MaxNftsSet(\n contractAddress,\n nftTokenAddress,\n maxNfts\n );\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n function setAssetInvalidity(address assetToken, bool invalidity) external virtual override onlyOwner {\n _invalidAssets[assetToken] = invalidity;\n emit AssetInvaliditySet(assetToken, invalidity);\n }\n\n function setDepositCap(address assetToken, uint256 cap) external virtual onlyOwner {\n _depositCap[assetToken] = cap;\n emit DepositCapSet(assetToken, cap);\n }\n\n function setTempLockExpiryBlocks(uint256 numBlocks) external virtual onlyOwner {\n _tempLockExpiryBlocks = numBlocks;\n emit TempLockExpirySet(numBlocks);\n }\n\n function enableNftContracts(address[] calldata contracts) external override virtual onlyOwner {\n uint count = contracts.length;\n for (uint i = 0; i < count; i++) {\n address tokenContract = contracts[i];\n _setPermsForCharge(tokenContract, true);\n _setPermsForBasket(tokenContract, true);\n _setPermsForTimelockSelf(tokenContract, true);\n }\n }\n\n function migrateToken(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent,\n address annuityReceiver\n )\n external\n onlyOwner\n {\n _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent);\n if (annuityReceiver != address(0)) {\n _setCreatorAnnuitiesRedirect(contractAddress, tokenId, annuityReceiver);\n }\n }\n\n /// @dev Update the list of NFT contracts that can be Charged\n function setPermsForCharge(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForCharge(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can hold other NFTs\n function setPermsForBasket(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForBasket(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection\n function setPermsForTimelockAny(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForTimelockAny(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock their own tokens\n function setPermsForTimelockSelf(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForTimelockSelf(contractAddress, state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Update the list of NFT contracts that can be Charged\n function _setPermsForCharge(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_CHARGE_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_CHARGE_NFT);\n }\n emit PermsSetForCharge(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can hold other NFTs\n function _setPermsForBasket(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_BASKET_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_BASKET_NFT);\n }\n emit PermsSetForBasket(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection\n function _setPermsForTimelockAny(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_ANY_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_ANY_NFT);\n }\n emit PermsSetForTimelockAny(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock their own tokens\n function _setPermsForTimelockSelf(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_OWN_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_OWN_NFT);\n }\n emit PermsSetForTimelockSelf(contractAddress, state);\n }\n\n /// @dev see setCreatorAnnuities()\n function _setCreatorAnnuities(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent\n )\n internal\n virtual\n {\n require(annuityPercent <= MAX_ANNUITIES, \"CP:E-421\");\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Update Configs for External Token Creator\n _creatorAnnuityPercent[tokenUuid] = annuityPercent;\n\n emit TokenCreatorConfigsSet(\n contractAddress,\n tokenId,\n creator,\n annuityPercent\n );\n }\n\n /// @dev see setCreatorAnnuitiesRedirect()\n function _setCreatorAnnuitiesRedirect(\n address contractAddress,\n uint256 tokenId,\n address receiver\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _creatorAnnuityRedirect[tokenUuid] = receiver;\n emit TokenCreatorAnnuitiesRedirected(contractAddress, tokenId, receiver);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyValidExternalContract(address contractAddress) {\n require(contractAddress.isContract(), \"CP:E-420\");\n _;\n }\n\n modifier onlyContractOwnerOrAdmin(address contractAddress, address sender) {\n require(sender == owner() || contractAddress.isContractOwner(sender), \"CP:E-103\");\n _;\n }\n}\n" + }, + "contracts/v1/ChargedState.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedState.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/RelayRecipient.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Settings Contract\n */\ncontract ChargedState is\n IChargedState,\n Initializable,\n OwnableUpgradeable,\n RelayRecipient,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using Bitwise for uint32;\n\n // NftState - actionPerms\n uint32 constant internal PERM_RESTRICT_ENERGIZE_FROM_ALL = 1; // NFTs that have Restrictions on Energize\n uint32 constant internal PERM_ALLOW_DISCHARGE_FROM_ALL = 2; // NFTs that allow Discharge by anyone\n uint32 constant internal PERM_ALLOW_RELEASE_FROM_ALL = 4; // NFTs that allow Release by anyone\n uint32 constant internal PERM_RESTRICT_BOND_FROM_ALL = 8; // NFTs that have Restrictions on Covalent Bonds\n uint32 constant internal PERM_ALLOW_BREAK_BOND_FROM_ALL = 16; // NFTs that allow Breaking Covalent Bonds by anyone\n\n IChargedSettings internal _chargedSettings;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // NftTimelocks\n /// @dev discharge unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftDischargeTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftDischargeTimelockLockedBy;\n\n /// @dev release unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftReleaseTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftReleaseTimelockLockedBy;\n\n /// @dev release unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftBreakBondTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftBreakBondTimelockLockedBy;\n\n // NftState\n /// @dev maps nft by tokenId to actionPermissions uint32 which is a composite of all possible NftState - actionPerms\n mapping (uint256 => uint32) internal _nftActionPerms;\n\n /// @dev maps nft by tokenId to its tempLockExpiry\n mapping (uint256 => uint256) internal _nftTempLockExpiry;\n\n /// @dev maps tokenId to user address to operator address for approving various actions\n mapping (uint256 => mapping(address => address)) internal _nftDischargeApproval;\n mapping (uint256 => mapping(address => address)) internal _nftReleaseApproval;\n mapping (uint256 => mapping(address => address)) internal _nftBreakBondApproval;\n mapping (uint256 => mapping(address => address)) internal _nftTimelockApproval;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftDischargeTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftDischargeTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftReleaseTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftReleaseTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftBreakBondTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftBreakBondTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n\n /// @notice Checks if an operator is allowed to Discharge a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForDischarge(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Release a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForRelease(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Break Covalent Bonds on a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForBreakBond(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Timelock a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForTimelock(contractAddress, tokenId, operator);\n }\n\n\n function isEnergizeRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n }\n\n\n function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_BOND_FROM_ALL);\n }\n\n\n function getDischargeState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n isApproved = _isApprovedForDischarge(contractAddress, tokenId, sender);\n timelock = _nftDischargeTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n function getReleaseState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_RELEASE_FROM_ALL);\n isApproved = _isApprovedForRelease(contractAddress, tokenId, sender);\n timelock = _nftReleaseTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n function getBreakBondState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n isApproved = _isApprovedForBreakBond(contractAddress, tokenId, sender);\n timelock = _nftBreakBondTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n\n /***********************************|\n | Only NFT Owner/Operator |\n |__________________________________*/\n\n /// @notice Sets an Operator as Approved to Discharge a specific Token\n /// This allows an operator to withdraw the interest-portion only\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setDischargeApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Release a specific Token\n /// This allows an operator to withdraw the principal + interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setReleaseApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token\n /// This allows an operator to withdraw Basket NFTs\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setBreakBondApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Timelock a specific Token\n /// This allows an operator to timelock the principal or interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setTimelockApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Discharge/Release/Timelock a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setApprovalForAll(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @dev Updates Restrictions on Energizing an NFT\n function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForRestrictCharge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowDischarge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowRelease(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Restrictions on Covalent Bonds on an NFT\n function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForRestrictBond(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone\n function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowBreakBond(contractAddress, tokenId, state);\n }\n\n /// @notice Sets a Timelock on the ability to Discharge the Interest of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setDischargeTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftDischargeTimelockLockedBy[tokenUuid] == sender) {\n delete _nftDischargeTimelockUnlockBlock[tokenUuid];\n delete _nftDischargeTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftDischargeTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftDischargeTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftDischargeTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenDischargeTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n /// @notice Sets a Timelock on the ability to Release the Assets of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setReleaseTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftReleaseTimelockLockedBy[tokenUuid] == sender) {\n delete _nftReleaseTimelockUnlockBlock[tokenUuid];\n delete _nftReleaseTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftReleaseTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftReleaseTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftReleaseTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenReleaseTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n /// @notice Sets a Timelock on the ability to Break the Covalent Bond of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setBreakBondTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftBreakBondTimelockLockedBy[tokenUuid] == sender) {\n delete _nftBreakBondTimelockUnlockBlock[tokenUuid];\n delete _nftBreakBondTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftBreakBondTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftBreakBondTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftBreakBondTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenBreakBondTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n\n /***********************************|\n | Only NFT Contract |\n |__________________________________*/\n\n /// @notice Sets a Temporary-Lock on the ability to Release/Discharge the Assets of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param isLocked The locked state; contracts are expected to disable this lock before expiry\n function setTemporaryLock(\n address contractAddress,\n uint256 tokenId,\n bool isLocked\n )\n external\n override\n virtual\n {\n require(msg.sender == contractAddress, \"CP:E-112\");\n\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n uint256 unlockBlock;\n if (isLocked && _nftTempLockExpiry[tokenUuid] == 0) {\n unlockBlock = block.number.add(_chargedSettings.getTempLockExpiryBlocks());\n _nftTempLockExpiry[tokenUuid] = unlockBlock;\n }\n if (!isLocked) {\n _nftTempLockExpiry[tokenUuid] = 0;\n }\n\n emit TokenTempLock(contractAddress, tokenId, unlockBlock);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n function migrateToken(\n address contractAddress,\n uint256 tokenId,\n uint256 releaseTimelockExpiry,\n address releaseTimelockLockedBy,\n uint256 tempLockExpiry\n )\n external\n onlyOwner\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (releaseTimelockExpiry > block.number && releaseTimelockLockedBy != address(0)) {\n _nftReleaseTimelockUnlockBlock[tokenUuid] = releaseTimelockExpiry;\n _nftReleaseTimelockLockedBy[tokenUuid] = releaseTimelockLockedBy;\n emit TokenReleaseTimelock(contractAddress, tokenId, releaseTimelockLockedBy, releaseTimelockExpiry);\n }\n\n if (tempLockExpiry > 0) {\n _nftTempLockExpiry[tokenUuid] = tempLockExpiry;\n emit TokenTempLock(contractAddress, tokenId, tempLockExpiry);\n }\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev See {ChargedParticles-isApprovedForDischarge}.\n function _isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftDischargeApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForRelease}.\n function _isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftReleaseApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForBreakBond}.\n function _isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftBreakBondApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForTimelock}.\n function _isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n (bool timelockAny, bool timelockOwn) = _chargedSettings.getTimelockApprovals(operator);\n if (timelockAny || (timelockOwn && contractAddress == operator)) { return true; }\n\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return tokenOwner == operator || _nftTimelockApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @notice Sets an Operator as Approved to Discharge a specific Token\n /// This allows an operator to withdraw the interest-portion only\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setDischargeApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftDischargeApproval[tokenUuid][tokenOwner] = operator;\n emit DischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Release a specific Token\n /// This allows an operator to withdraw the principal + interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setReleaseApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftReleaseApproval[tokenUuid][tokenOwner] = operator;\n emit ReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token\n /// This allows an operator to withdraw Basket NFTs\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setBreakBondApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftBreakBondApproval[tokenUuid][tokenOwner] = operator;\n emit BreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Timelock a specific Token\n /// This allows an operator to timelock the principal or interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setTimelockApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftTimelockApproval[tokenUuid][tokenOwner] = operator;\n emit TimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @dev Updates Restrictions on Energizing an NFT\n function _setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n }\n emit PermsSetForRestrictCharge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function _setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n }\n emit PermsSetForAllowDischarge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function _setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_RELEASE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_RELEASE_FROM_ALL);\n }\n emit PermsSetForAllowRelease(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Restrictions on Covalent Bonds on an NFT\n function _setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_BOND_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_BOND_FROM_ALL);\n }\n emit PermsSetForRestrictBond(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone\n function _setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n }\n emit PermsSetForAllowBreakBond(contractAddress, tokenId, state);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) {\n require(_tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender), \"CP:E-105\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/CommunityVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract CommunityVault is Ownable, BlackholePrevention {\n\n IERC20 private immutable _ionx;\n\n constructor (address ionx) public {\n _ionx = IERC20(ionx);\n }\n\n event SetAllowance(address indexed caller, address indexed spender, uint256 amount);\n\n function setAllowance(address spender, uint amount) public onlyOwner {\n _ionx.approve(spender, amount);\n\n emit SetAllowance(msg.sender, spender, amount);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens other than IONX, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n require(tokenAddress != address(_ionx), \"CommunityVault: cannot withdraw IONX\");\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n}" + }, + "contracts/v1/incentives/MerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_) public {\n token = token_;\n merkleRoot = merkleRoot_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), 'MerkleDistributor: Drop already claimed.');\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), 'MerkleDistributor: Invalid proof.');\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), 'MerkleDistributor: Transfer failed.');\n\n emit Claimed(index, account, amount);\n }\n}\n" + }, + "contracts/v1/incentives/MerkleDistributor2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor2 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"MerkleDistributor2: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"MerkleDistributor2: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor2: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"MerkleDistributor2: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"MerkleDistributor2: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"MerkleDistributor2: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/MerkleDistributor3.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor3 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"MerkleDistributor3: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"MerkleDistributor3: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor3: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"MerkleDistributor3: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"MerkleDistributor3: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"MerkleDistributor3: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/RewardProgram.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// RewardProgram.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/IRewardProgram.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/introspection/IERC165.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"../interfaces/IUniverseRP.sol\";\nimport \"../interfaces/IChargedManagers.sol\";\nimport \"../interfaces/IWalletManager.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IERC20Detailed.sol\";\n\ncontract RewardProgram is\n IRewardProgram,\n BlackholePrevention,\n IERC165,\n ReentrancyGuard,\n IERC721Receiver,\n IERC1155Receiver\n{\n using SafeMath for uint256;\n using TokenInfo for address;\n using SafeERC20 for IERC20;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n\n address private _owner;\n IUniverseRP private _universe;\n IChargedManagers private _chargedManagers;\n ProgramRewardData private _programData;\n mapping(uint256 => AssetStake) private _assetStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public {}\n\n function initialize(\n address stakingToken,\n address rewardToken,\n uint256 baseMultiplier,\n address chargedManagers,\n address universe,\n address owner\n ) external override {\n require(_owner == address(0x0), \"Already initialized\");\n _owner = owner;\n\n // Prepare Reward Program\n _programData.stakingToken = stakingToken;\n _programData.rewardToken = rewardToken;\n _programData.baseMultiplier = baseMultiplier; // Basis Points\n\n // Connect to Charged Particles\n _chargedManagers = IChargedManagers(chargedManagers);\n _universe = IUniverseRP(universe);\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getProgramData() external view override returns (ProgramRewardData memory) {\n return _programData;\n }\n\n function getAssetStake(uint256 parentNftUuid) external view override returns (AssetStake memory) {\n return _assetStake[parentNftUuid];\n }\n\n function getFundBalance() external view override returns (uint256) {\n return _getFundBalance();\n }\n\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) public view override returns (uint256) {\n return _calculateRewardsEarned(parentNftUuid, interestAmount);\n }\n\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n return _assetStake[parentNftUuid].claimableRewards;\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\n return \"\";\n }\n\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(IERC165)\n returns (bool)\n {\n // default interface support\n if (\n interfaceId == type(IERC721Receiver).interfaceId ||\n interfaceId == type(IERC1155Receiver).interfaceId ||\n interfaceId == type(IERC165).interfaceId\n ) {\n return true;\n }\n }\n\n function owner() public view returns (address) {\n return _owner;\n }\n\n\n /***********************************|\n | Only Universe |\n |__________________________________*/\n\n function registerAssetDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n uint256 principalAmount\n )\n external\n override\n onlyUniverse\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n if (assetStake.start == 0) {\n assetStake.start = block.number;\n assetStake.walletManagerId = walletManagerId;\n }\n emit AssetDeposit(contractAddress, tokenId, walletManagerId, principalAmount);\n }\n\n function registerAssetRelease(\n address contractAddress,\n uint256 tokenId,\n uint256 interestAmount\n )\n external\n override\n onlyUniverse\n nonReentrant\n returns (uint256 rewards)\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n // Update Claimable Rewards\n uint256 newRewards = _calculateRewardsEarned(parentNftUuid, interestAmount);\n assetStake.claimableRewards = assetStake.claimableRewards.add(newRewards);\n\n // Reset Stake if Principal Balance falls to Zero\n IWalletManager walletMgr = _chargedManagers.getWalletManager(assetStake.walletManagerId);\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\n if (principal == 0) {\n assetStake.start = 0;\n }\n\n // Issue Rewards to NFT Owner\n rewards = _claimRewards(contractAddress, tokenId);\n\n emit AssetRelease(contractAddress, tokenId, interestAmount);\n }\n\n\n /***********************************|\n | Reward Calculation |\n |__________________________________*/\n\n function _calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) internal view returns (uint256 totalReward) {\n uint256 baseReward = _calculateBaseReward(interestAmount);\n uint256 leptonMultipliedReward = _calculateMultipliedReward(parentNftUuid, baseReward);\n totalReward = _convertDecimals(leptonMultipliedReward);\n }\n\n function _calculateBaseReward(uint256 amount) internal view returns(uint256 baseReward) {\n baseReward = amount.mul(_programData.baseMultiplier).div(PERCENTAGE_SCALE);\n }\n\n function _calculateMultipliedReward(uint256 parentNftUuid, uint256 baseReward) internal view returns(uint256) {\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n if (assetStake.start == 0) { return baseReward; }\n\n IUniverseRP.NftStake memory nftStake = _universe.getNftStake(parentNftUuid);\n uint256 multiplierBP = nftStake.multiplier;\n\n uint256 assetDepositLength = block.number.sub(assetStake.start);\n uint256 nftDepositLength = 0;\n if (nftStake.releaseBlockNumber > 0) {\n nftDepositLength = nftStake.releaseBlockNumber.sub(nftStake.depositBlockNumber);\n } else {\n nftDepositLength = block.number.sub(nftStake.depositBlockNumber);\n }\n\n if (multiplierBP == 0 || nftDepositLength == 0 || assetDepositLength == 0) {\n return baseReward;\n }\n\n if (nftDepositLength > assetDepositLength) {\n nftDepositLength = assetDepositLength;\n }\n\n // Percentage of the total program that the Multiplier Nft was deposited for\n uint256 nftRewardRatioBP = nftDepositLength.mul(PERCENTAGE_SCALE).div(assetDepositLength);\n\n // Amount of reward that the Multiplier Nft is responsible for\n uint256 amountGeneratedDuringNftDeposit = baseReward.mul(nftRewardRatioBP).div(PERCENTAGE_SCALE);\n\n // Amount of Multiplied Reward from NFT\n uint256 multipliedReward = amountGeneratedDuringNftDeposit.mul(multiplierBP.mul(LEPTON_MULTIPLIER_SCALE)).div(PERCENTAGE_SCALE);\n\n // Amount of Base Reward without Multiplied NFT Rewards\n uint256 amountGeneratedWithoutNftDeposit = baseReward.sub(amountGeneratedDuringNftDeposit);\n\n // Amount of Base Rewards + Multiplied NFT Rewards\n return amountGeneratedWithoutNftDeposit.add(multipliedReward);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function fundProgram(uint256 amount) external onlyOwner {\n require(_programData.rewardToken != address(0), \"RP:E-405\");\n IERC20(_programData.rewardToken).safeTransferFrom(msg.sender, address(this), amount);\n emit RewardProgramFunded(amount);\n }\n\n function setStakingToken(address newStakingToken) external onlyOwner {\n _programData.stakingToken = newStakingToken;\n }\n\n function setRewardToken(address newRewardToken) external onlyOwner {\n _programData.rewardToken = newRewardToken;\n }\n\n function setBaseMultiplier(uint256 newMultiplier) external onlyOwner {\n _programData.baseMultiplier = newMultiplier; // Basis Points\n }\n\n function setChargedManagers(address manager) external onlyOwner {\n _chargedManagers = IChargedManagers(manager);\n }\n\n function setUniverse(address universe) external onlyOwner {\n _universe = IUniverseRP(universe);\n }\n\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external override onlyOwner {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n\n // Initiate Asset Stake\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\n if (principal > 0) {\n _assetStake[parentNftUuid] = AssetStake(block.number, 0, walletManagerId);\n emit AssetRegistered(contractAddress, tokenId, walletManagerId, principal);\n }\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _claimRewards(\n address contractAddress,\n uint256 tokenId\n )\n internal\n returns (uint256 totalReward)\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n // Rewards Receiver\n address receiver = IERC721(contractAddress).ownerOf(tokenId);\n\n // Ensure Reward Pool has Sufficient Balance\n totalReward = assetStake.claimableRewards;\n uint256 fundBalance = _getFundBalance();\n uint256 unavailReward = totalReward > fundBalance ? totalReward.sub(fundBalance) : 0;\n\n // Determine amount of Rewards to Transfer\n if (unavailReward > 0) {\n totalReward = totalReward.sub(unavailReward);\n emit RewardProgramOutOfFunds();\n }\n\n // Update Asset Stake\n assetStake.claimableRewards = unavailReward;\n\n if (totalReward > 0) {\n // Transfer Available Rewards to Receiver\n IERC20(_programData.rewardToken).safeTransfer(receiver, totalReward);\n }\n\n emit RewardsClaimed(contractAddress, tokenId, receiver, totalReward, unavailReward);\n }\n\n function _convertDecimals(uint256 reward) internal view returns (uint256) {\n uint8 stakingTokenDecimals = IERC20Detailed(_programData.stakingToken).decimals();\n return reward.mul(10**(18 - uint256(stakingTokenDecimals)));\n }\n\n function _getFundBalance() internal view returns (uint256) {\n return IERC20Detailed(_programData.rewardToken).balanceOf(address(this));\n }\n\n\n modifier onlyOwner() {\n require(_owner == msg.sender, \"Caller is not the owner\");\n _;\n }\n\n modifier onlyUniverse() {\n require(msg.sender == address(_universe), \"RP:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/RewardProgramFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// RewardProgramFactory.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport \"./RewardProgram.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract RewardProgramFactory is BlackholePrevention, Ownable {\n event RewardProgramCreated(address indexed rewardProgram);\n\n address public _template;\n\n constructor () public {\n _template = address(new RewardProgram());\n }\n\n // function _msgSender() internal view override returns (address payable) {\n // return msg.sender;\n // }\n\n function createRewardProgram(\n address stakingToken,\n address rewardToken,\n uint256 baseMultiplier,\n address chargedManagers,\n address universe\n )\n external\n onlyOwner\n returns (address)\n {\n address newRewardProgram = _createClone(_template);\n RewardProgram rewardProgram = RewardProgram(newRewardProgram);\n rewardProgram.initialize(stakingToken, rewardToken, baseMultiplier, chargedManagers, universe, _msgSender());\n emit RewardProgramCreated(newRewardProgram);\n return newRewardProgram;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n}\n" + }, + "contracts/v1/incentives/Staking.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/Staking2.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking2 is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/Staking3.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking3 is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/YieldFarm.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/incentives/YieldFarm2.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm2 is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/incentives/YieldFarm3.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm3 is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/interfaces/IAaveBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IAaveBridge.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n\ninterface IAaveBridge {\n function getReserveInterestToken(address assetToken) external view returns (address aTokenAddress);\n function isReserveActive(address assetToken) external view returns (bool);\n\n function getTotalBalance(address account, address assetToken) external view returns (uint256);\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(address receiver, address assetToken, uint256 assetAmount) external;\n}\n" + }, + "contracts/v1/interfaces/IBaseProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IBaseProton is IERC721 {\n event PausedStateSet(bool isPaused);\n event SalePriceSet(uint256 indexed tokenId, uint256 salePrice);\n event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct);\n event FeesWithdrawn(address indexed receiver, uint256 amount);\n event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties);\n event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view returns (address);\n function getSalePrice(uint256 tokenId) external view returns (uint256);\n function getLastSellPrice(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyalties(address account) external view returns (uint256);\n function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address);\n\n function buyProton(uint256 tokenId, uint256 gasLimit) external payable returns (bool);\n function claimCreatorRoyalties() external returns (uint256);\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n ) external returns (uint256 newTokenId);\n\n function createProtons(\n address creator,\n address receiver,\n string[] calldata tokenMetaUris\n ) external returns (bool);\n\n function createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n ) external returns (bool);\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice) external;\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external;\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external;\n}" + }, + "contracts/v1/interfaces/IBasketManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Particle Basket Manager interface\n * @dev The basket-manager for underlying assets attached to Charged Particles\n * @dev Manages the link between NFTs and their respective Smart-Baskets\n */\ninterface IBasketManager {\n\n event ControllerSet(address indexed controller);\n event ExecutorSet(address indexed executor);\n event PausedStateSet(bool isPaused);\n event NewSmartBasket(address indexed contractAddress, uint256 indexed tokenId, address indexed smartBasket);\n event BasketAdd(address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\n event BasketRemove(address indexed receiver, address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\n event BasketRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\n event RewardProgramSet(address indexed rewardProgram);\n\n function isPaused() external view returns (bool);\n\n function getTokenTotalCount(address contractAddress, uint256 tokenId) external view returns (uint256);\n function getTokenCountByType(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (uint256);\n\n function prepareTransferAmount(uint256 nftTokenAmount) external;\n function addToBasket(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function getBasketAddressById(address contractAddress, uint256 tokenId) external returns (address);\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/IChargedManagers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IWalletManager.sol\";\nimport \"./IBasketManager.sol\";\n\n/**\n * @notice Interface for Charged Wallet-Managers\n */\ninterface IChargedManagers {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function isContractOwner(address contractAddress, address account) external view returns (bool);\n\n // ERC20\n function isWalletManagerEnabled(string calldata walletManagerId) external view returns (bool);\n function getWalletManager(string calldata walletManagerId) external view returns (IWalletManager);\n\n // ERC721\n function isNftBasketEnabled(string calldata basketId) external view returns (bool);\n function getBasketManager(string calldata basketId) external view returns (IBasketManager);\n\n // Validation\n function validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external;\n function validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external;\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external;\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event WalletManagerRegistered(string indexed walletManagerId, address indexed walletManager);\n event BasketManagerRegistered(string indexed basketId, address indexed basketManager);\n}\n" + }, + "contracts/v1/interfaces/IChargedParticles.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Charged Particles\n */\ninterface IChargedParticles {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getStateAddress() external view returns (address stateAddress);\n function getSettingsAddress() external view returns (address settingsAddress);\n function getManagersAddress() external view returns (address managersAddress);\n\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\n\n /***********************************|\n | Particle Mechanics |\n |__________________________________*/\n\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n ) external returns (uint256 yieldTokensAmount);\n\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 receiverAmount);\n\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositFeeSet(uint256 depositFee);\n event ProtocolFeesCollected(address indexed assetToken, uint256 depositAmount, uint256 feesCollected);\n}\n" + }, + "contracts/v1/interfaces/IChargedSettings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IWalletManager.sol\";\nimport \"./IBasketManager.sol\";\n\n/**\n * @notice Interface for Charged Settings\n */\ninterface IChargedSettings {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n // function isContractOwner(address contractAddress, address account) external view returns (bool);\n function getCreatorAnnuities(address contractAddress, uint256 tokenId) external returns (address creator, uint256 annuityPct);\n function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId) external view returns (address);\n function getTempLockExpiryBlocks() external view returns (uint256);\n function getTimelockApprovals(address operator) external view returns (bool timelockAny, bool timelockOwn);\n function getAssetRequirements(\n address contractAddress,\n address assetToken\n ) external view returns (\n string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n );\n function getNftAssetRequirements(\n address contractAddress,\n address nftTokenAddress\n ) external view returns (\n string memory requiredBasketManager,\n bool basketEnabled,\n uint256 maxNfts\n );\n\n /***********************************|\n | Only NFT Creator |\n |__________________________________*/\n\n function setCreatorAnnuities(address contractAddress, uint256 tokenId, address creator, uint256 annuityPercent) external;\n function setCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId, address receiver) external;\n\n\n /***********************************|\n | Only NFT Contract Owner |\n |__________________________________*/\n\n function setRequiredWalletManager(address contractAddress, string calldata walletManager) external;\n function setRequiredBasketManager(address contractAddress, string calldata basketManager) external;\n function setAssetTokenRestrictions(address contractAddress, bool restrictionsEnabled) external;\n function setAllowedAssetToken(address contractAddress, address assetToken, bool isAllowed) external;\n function setAssetTokenLimits(address contractAddress, address assetToken, uint256 depositMin, uint256 depositMax) external;\n function setMaxNfts(address contractAddress, address nftTokenAddress, uint256 maxNfts) external;\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAssetInvalidity(address assetToken, bool invalidity) external;\n function enableNftContracts(address[] calldata contracts) external;\n function setPermsForCharge(address contractAddress, bool state) external;\n function setPermsForBasket(address contractAddress, bool state) external;\n function setPermsForTimelockAny(address contractAddress, bool state) external;\n function setPermsForTimelockSelf(address contractAddress, bool state) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositCapSet(address assetToken, uint256 depositCap);\n event TempLockExpirySet(uint256 expiryBlocks);\n\n event RequiredWalletManagerSet(address indexed contractAddress, string walletManager);\n event RequiredBasketManagerSet(address indexed contractAddress, string basketManager);\n event AssetTokenRestrictionsSet(address indexed contractAddress, bool restrictionsEnabled);\n event AllowedAssetTokenSet(address indexed contractAddress, address assetToken, bool isAllowed);\n event AssetTokenLimitsSet(address indexed contractAddress, address assetToken, uint256 assetDepositMin, uint256 assetDepositMax);\n event MaxNftsSet(address indexed contractAddress, address indexed nftTokenAddress, uint256 maxNfts);\n event AssetInvaliditySet(address indexed assetToken, bool invalidity);\n\n event TokenCreatorConfigsSet(address indexed contractAddress, uint256 indexed tokenId, address indexed creatorAddress, uint256 annuityPercent);\n event TokenCreatorAnnuitiesRedirected(address indexed contractAddress, uint256 indexed tokenId, address indexed redirectAddress);\n\n event PermsSetForCharge(address indexed contractAddress, bool state);\n event PermsSetForBasket(address indexed contractAddress, bool state);\n event PermsSetForTimelockAny(address indexed contractAddress, bool state);\n event PermsSetForTimelockSelf(address indexed contractAddress, bool state);\n}\n" + }, + "contracts/v1/interfaces/IChargedState.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IChargedSettings.sol\";\n\n/**\n * @notice Interface for Charged State\n */\ninterface IChargedState {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n\n function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n\n function isEnergizeRestricted(address contractAddress, uint256 tokenId) external view returns (bool);\n function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external view returns (bool);\n\n function getDischargeState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n function getReleaseState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n function getBreakBondState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n\n /***********************************|\n | Only NFT Owner/Operator |\n |__________________________________*/\n\n function setDischargeApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setReleaseApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setBreakBondApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setTimelockApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setApprovalForAll(address contractAddress, uint256 tokenId, address operator) external;\n\n function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) external;\n\n function setDischargeTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n function setReleaseTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n function setBreakBondTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n /***********************************|\n | Only NFT Contract |\n |__________________________________*/\n\n function setTemporaryLock(\n address contractAddress,\n uint256 tokenId,\n bool isLocked\n ) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n\n event DischargeApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event ReleaseApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event BreakBondApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event TimelockApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n\n event TokenDischargeTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenReleaseTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenBreakBondTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenTempLock(address indexed contractAddress, uint256 indexed tokenId, uint256 unlockBlock);\n\n event PermsSetForRestrictCharge(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowDischarge(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowRelease(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForRestrictBond(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowBreakBond(address indexed contractAddress, uint256 indexed tokenId, bool state);\n}\n" + }, + "contracts/v1/interfaces/IDai.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\ninterface IDai is IERC20Upgradeable {\n // --- Approve by signature ---\n function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external;\n function transferFrom(address src, address dst, uint wad) external override returns (bool);\n}" + }, + "contracts/v1/interfaces/IERC20Detailed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Detailed {\n function decimals() external view returns (uint8);\n function symbol() external view returns (string memory);\n function name() external view returns (string memory);\n\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(address sender, address recipient, uint256 amount) 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" + }, + "contracts/v1/interfaces/IERC721Chargeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IERC721Chargeable.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\n\ninterface IERC721Chargeable is IERC165Upgradeable {\n function owner() external view returns (address);\n function creatorOf(uint256 tokenId) external view returns (address);\n function balanceOf(address tokenOwner) external view returns (uint256 balance);\n function ownerOf(uint256 tokenId) external view returns (address tokenOwner);\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n function transferFrom(address from, address to, uint256 tokenId) external;\n function approve(address to, uint256 tokenId) external;\n function getApproved(uint256 tokenId) external view returns (address operator);\n function setApprovalForAll(address operator, bool _approved) external;\n function isApprovedForAll(address tokenOwner, address operator) external view returns (bool);\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "contracts/v1/interfaces/ILepton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ILepton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Lepton Interface\n * @dev ...\n */\ninterface ILepton {\n\n struct Classification {\n string tokenUri;\n uint256 price;\n uint128 _upperBounds;\n uint32 supply;\n uint32 multiplier;\n uint32 bonus;\n }\n\n function mintLepton() external payable returns (uint256 newTokenId);\n function batchMintLepton(uint256 count) external payable;\n function getNextType() external view returns (uint256);\n function getNextPrice() external view returns (uint256);\n function getMultiplier(uint256 tokenId) external view returns (uint256);\n function getBonus(uint256 tokenId) external view returns (uint256);\n\n\n event MaxMintPerTxSet(uint256 maxAmount);\n event LeptonTypeAdded(string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\n event LeptonTypeUpdated(uint256 leptonIndex, string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\n event LeptonMinted(address indexed receiver, uint256 indexed tokenId, uint256 price, uint32 multiplier);\n event LeptonBatchMinted(address indexed receiver, uint256 indexed tokenId, uint256 count, uint256 price, uint32 multiplier);\n event PausedStateSet(bool isPaused);\n}\n" + }, + "contracts/v1/interfaces/IMerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.6.0;\n\n// Allows anyone to claim a token if they exist in a merkle root.\ninterface IMerkleDistributor {\n // Returns the address of the token distributed by this contract.\n function token() external view returns (address);\n // Returns the merkle root of the merkle tree containing account balances available to claim.\n function merkleRoot() external view returns (bytes32);\n // Returns true if the index has been marked claimed.\n function isClaimed(uint256 index) external view returns (bool);\n // Claim the given amount of the token to the given address. Reverts if the inputs are invalid.\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external;\n\n // This event is triggered whenever a call to #claim succeeds.\n event Claimed(uint256 index, address account, uint256 amount);\n}" + }, + "contracts/v1/interfaces/IParticleSplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IParticleSplitter.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Particle Splitter\n */\ninterface IParticleSplitter {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function executeForWallet(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address externalAddress,\n bytes memory encodedParams\n ) external payable returns (bytes memory);\n\n function executeForBasket(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address externalAddress,\n bytes memory encodedParams\n ) external payable returns (bytes memory);\n\n function withdrawWalletRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n ) external returns (uint256 amountWithdrawn);\n\n function withdrawBasketRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n ) external returns (uint256 amountWithdrawn);\n\n function refreshWalletPrincipal(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external;\n\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event ChargedManagersSet(address indexed chargedManagers);\n event TokenInfoProxySet(address indexed tokenInfoProxy);\n\n event ExecuteForWallet(\n address indexed contractAddress,\n uint256 tokenId,\n string walletManagerId,\n address indexed externalAddress,\n bytes encodedParams,\n uint256 ethValue\n );\n event ExecuteForBasket(\n address indexed contractAddress,\n uint256 tokenId,\n string basketManagerId,\n address indexed externalAddress,\n bytes encodedParams,\n uint256 ethValue\n );\n event PrincipalRefreshed(\n address contractAddress,\n uint256 tokenId,\n string walletManagerId,\n address assetToken\n );\n event PermsSetForExternal(\n address indexed contractAddress,\n bool state\n );\n}\n" + }, + "contracts/v1/interfaces/IProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IProton is IERC721 {\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n event PausedStateSet(bool isPaused);\n event SalePriceSet(uint256 indexed tokenId, uint256 salePrice);\n event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct);\n event FeesWithdrawn(address indexed receiver, uint256 amount);\n event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties);\n event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view returns (address);\n function getSalePrice(uint256 tokenId) external view returns (uint256);\n function getLastSellPrice(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyalties(address account) external view returns (uint256);\n function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address);\n\n function buyProton(uint256 tokenId) external payable returns (bool);\n function claimCreatorRoyalties() external returns (uint256);\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n ) external returns (uint256 newTokenId);\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n ) external returns (uint256 newTokenId);\n\n function batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n ) external;\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice) external;\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external;\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external;\n}" + }, + "contracts/v1/interfaces/IProtonB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IProtonB is IERC721 {\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n ) external returns (uint256 newTokenId);\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n}" + }, + "contracts/v1/interfaces/IRewardNft.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IRewardNft.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Reward-NFT Interface\n * @dev ...\n */\ninterface IRewardNft {\n function getMultiplier(uint256 tokenId) external view returns (uint256);\n function getBonus(uint256 tokenId) external view returns (uint256);\n}\n" + }, + "contracts/v1/interfaces/IRewardProgram.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IRewardProgram.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\ninterface IRewardProgram {\n /* admin events */\n event RewardProgramFunded(uint256 amount);\n event RewardProgramOutOfFunds();\n\n /* user events */\n event RewardsClaimed(address indexed contractAddress, uint256 tokenId, address indexed receiver, uint256 rewarded, uint256 remaining);\n\n event AssetRegistered(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\n event AssetDeposit(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\n event AssetRelease(address indexed contractAddress, uint256 tokenId, uint256 interestAmount);\n\n /* data types */\n struct ProgramRewardData {\n address stakingToken;\n address rewardToken;\n uint256 baseMultiplier; // Basis Points\n }\n\n struct AssetStake {\n uint256 start;\n uint256 claimableRewards;\n string walletManagerId;\n }\n\n function initialize(address stakingToken, address rewardToken, uint256 baseMultiplier, address chargedManagers, address universe, address owner) external;\n\n /* user functions */\n function getProgramData() external view returns (ProgramRewardData memory programData);\n function getAssetStake(uint256 uuid) external view returns (AssetStake memory);\n function getFundBalance() external view returns (uint256);\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) external view returns (uint256);\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external;\n function registerAssetDeposit(address contractAddress, uint256 tokenId, string calldata walletManagerId, uint256 principalAmount) external;\n function registerAssetRelease(address contractAddress, uint256 tokenId, uint256 interestAmount) external returns (uint256 rewards);\n}" + }, + "contracts/v1/interfaces/ISmartBasket.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartBasket.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Basket\n * @dev Manages holding and transferring NFTs within an NFT (if any),\n */\ninterface ISmartBasket {\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function addToBasket(address contractAddress, uint256 tokenId) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId) external returns (bool);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartBasketB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartBasketB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Basket \"B\"\n * @dev Manages holding and transferring NFTs within an NFT (if any),\n */\ninterface ISmartBasketB {\n function getNestedNftCount() external view returns (uint256);\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool);\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Wallet\n * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any),\n */\ninterface ISmartWallet {\n function getAssetTokenCount() external view returns (uint256);\n function getAssetTokenByIndex(uint256 index) external view returns (address);\n\n function setNftCreator(address creator, uint256 annuityPct) external;\n\n function isReserveActive(address assetToken) external view returns (bool);\n function getReserveInterestToken(address assetToken) external view returns (address);\n\n function getPrincipal(address assetToken) external returns (uint256);\n function getInterest(address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getTotal(address assetToken) external returns (uint256);\n function getRewards(address assetToken) external returns (uint256);\n\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(address receiver, address creatorRedirect, address assetToken) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function withdrawAmount(address receiver, address creatorRedirect, address assetToken, uint256 assetAmount) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function withdrawAmountForCreator(address receiver, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address assetToken) external;\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Wallet\n * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any),\n */\ninterface ISmartWalletB {\n function getAssetTokenCount() external view returns (uint256);\n function getAssetTokenByIndex(uint256 index) external view returns (address);\n\n function isReserveActive(address assetToken) external view returns (bool);\n function getReserveInterestToken(address assetToken) external view returns (address);\n\n function getPrincipal(address assetToken) external returns (uint256);\n function getInterest(address assetToken, uint256 creatorPct) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getTotal(address assetToken) external returns (uint256);\n function getRewards(address assetToken) external returns (uint256);\n\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken\n ) external returns (\n uint256 creatorAmount,\n uint256 receiverAmount\n );\n function withdrawAmount(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n ) external returns (\n uint256 creatorAmount,\n uint256 receiverAmount\n );\n function withdrawAmountForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n ) external returns (\n uint256 receiverAmount\n );\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address assetToken) external;\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/IStaking.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\ninterface IStaking {\n function manualEpochInit(address[] memory tokens, uint128 epochId) external;\n function getCurrentEpoch() external view returns (uint128);\n function getEpochId(uint timestamp) external view returns (uint); // get epoch id\n function getEpochUserBalance(address user, address token, uint128 epoch) external view returns(uint);\n function getEpochPoolSize(address token, uint128 epoch) external view returns (uint);\n function epoch1Start() external view returns (uint);\n function epochDuration() external view returns (uint);\n}" + }, + "contracts/v1/interfaces/ITokenInfoProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfoProxy.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\n\ninterface ITokenInfoProxy {\n\n event ContractFunctionSignatureSet(address indexed contractAddress, string fnName, bytes4 fnSig);\n\n struct FnSignatures {\n bytes4 ownerOf;\n bytes4 creatorOf;\n }\n\n function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external;\n function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external;\n\n function getTokenUUID(address contractAddress, uint256 tokenId) external pure returns (uint256);\n function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external returns (bool);\n function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external returns (bool);\n function getTokenOwner(address contractAddress, uint256 tokenId) external returns (address);\n function getTokenCreator(address contractAddress, uint256 tokenId) external returns (address);\n}\n" + }, + "contracts/v1/interfaces/IUniverse.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IUniverse.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Universal Controller interface\n * @dev ...\n */\ninterface IUniverse {\n\n event ChargedParticlesSet(address indexed chargedParticles);\n event PhotonSet(address indexed photonToken, uint256 maxSupply);\n event ProtonTokenSet(address indexed protonToken);\n event LeptonTokenSet(address indexed leptonToken);\n event QuarkTokenSet(address indexed quarkToken);\n event BosonTokenSet(address indexed bosonToken);\n event EsaMultiplierSet(address indexed assetToken, uint256 multiplier);\n event ElectrostaticAttraction(address indexed account, address photonSource, uint256 energy, uint256 multiplier);\n event ElectrostaticDischarge(address indexed account, address photonSource, uint256 energy);\n\n function onEnergize(\n address sender,\n address referrer,\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 assetEnergy\n ) external;\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n ) external;\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address creator,\n address assetToken,\n uint256 receiverEnergy\n ) external;\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 principalEnergy,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n ) external;\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n ) external;\n}\n" + }, + "contracts/v1/interfaces/IUniverseRP.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IUniverseRP.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport \"./IUniverse.sol\";\n\n/**\n * @title Universal Controller interface for Rewards Program\n * @dev ...\n */\ninterface IUniverseRP is IUniverse {\n event RewardProgramSet(address indexed assetToken, address indexed rewardProgram);\n event RewardProgramRemoved(address indexed assetToken);\n event NftDeposit(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\n event NftRelease(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\n\n struct NftStake {\n uint256 multiplier; // in Basis Points\n uint256 depositBlockNumber;\n uint256 releaseBlockNumber;\n }\n\n function getRewardProgram(address asset) external view returns (address);\n function getNftStake(uint256 uuid) external view returns (NftStake memory);\n}\n" + }, + "contracts/v1/interfaces/IWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Particle Wallet Manager interface\n * @dev The wallet-manager for underlying assets attached to Charged Particles\n * @dev Manages the link between NFTs and their respective Smart-Wallets\n */\ninterface IWalletManager {\n\n event ControllerSet(address indexed controller);\n event ExecutorSet(address indexed executor);\n event PausedStateSet(bool isPaused);\n event NewSmartWallet(address indexed contractAddress, uint256 indexed tokenId, address indexed smartWallet, address creator, uint256 annuityPct);\n event WalletEnergized(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 assetAmount, uint256 yieldTokensAmount);\n event WalletDischarged(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 creatorAmount, uint256 receiverAmount);\n event WalletDischargedForCreator(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, address creator, uint256 receiverAmount);\n event WalletReleased(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address assetToken, uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n event WalletRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\n\n function isPaused() external view returns (bool);\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view returns (bool);\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view returns (address);\n\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\n function getInterest(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken) external returns (uint256);\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount) external returns (uint256 yieldTokensAmount);\n function discharge(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function dischargeAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function dischargeAmountForCreator(address receiver, address contractAddress, uint256 tokenId, address creator, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\n function release(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n function releaseAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken) external;\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct) external returns (address);\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\n}\n" + }, + "contracts/v1/lib/BaseProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IBaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n/// @title Base Proton Contract for Charged Particles compatible ERC721 NFTs\n/// @dev MUST NOT be Upgradeable, as Upgradeable NFTs are incompatible with Charged Particles.\ncontract BaseProton is \n IBaseProton, \n ERC721, \n Ownable, \n RelayRecipient, \n ReentrancyGuard, \n BlackholePrevention \n{\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n event Received(address, uint);\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n /// @dev Sequential Token IDs storage\n Counters.Counter internal _tokenIds;\n\n /// @dev NFT Token Creator settings\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct;\n mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect;\n mapping (address => uint256) internal _tokenCreatorClaimableRoyalties;\n\n /// @dev NFT Token Sale settings\n mapping (uint256 => uint256) internal _tokenSalePrice;\n mapping (uint256 => uint256) internal _tokenLastSellPrice;\n\n /// @dev Whether of not the Contract is Paused\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n /// @dev Inherit from ERC721 standard\n constructor(string memory _name, string memory _symbol) public ERC721(_name, _symbol) {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n receive() external payable virtual {\n emit Received(msg.sender, msg.value);\n }\n\n /// Returns the Creator address of an NFT by Token ID\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The address of the Creator account\n function creatorOf(uint256 tokenId) external view virtual override returns (address) {\n return _tokenCreator[tokenId];\n }\n\n /// Returns the Sale Price of an NFT by Token ID\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The sale price of the NFT\n function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenSalePrice[tokenId];\n }\n\n /// Returns the Last Sale Price of an NFT by Token ID\n /// @notice This is used to determine any increase in sale price used in royalties calculations\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The last sale price of the NFT\n function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenLastSellPrice[tokenId];\n }\n\n /// Returns the Claimable Royalties for the NFT Creator\n /// @param account The address of the Creator account to lookup\n /// @return The amount of earned royalties for the creator account\n function getCreatorRoyalties(address account) external view virtual override returns (uint256) {\n return _tokenCreatorClaimableRoyalties[account];\n }\n\n /// Returns the Percentage of Royalties reserved for the NFT Creator\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The percentage of royalties reserved for the creator\n function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenCreatorRoyaltiesPct[tokenId];\n }\n\n /// Returns the Receiving address of the Creator Royalties (or Creator if not set)\n /// @dev Returns the creator address if a receiving address has not been configured\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The Receiving address of the Creator Royalties\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) {\n return _creatorRoyaltiesReceiver(tokenId);\n }\n\n /// Allows an NFT Creator to Claim any Royalties that have been earned from NFT sales\n /// @dev Must be called by the royalties receiver account (not neccessarily the creator)\n /// @return The amout of creator royalties claimed\n function claimCreatorRoyalties()\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256)\n {\n return _claimCreatorRoyalties(_msgSender());\n }\n\n\n /***********************************|\n | Create Single Protons |\n |__________________________________*/\n\n /// Creates a Basic NFT with no Royalties and no initial Sale Price\n /// @dev Royalties and Sale Price can be configured later\n /// @param creator The address of the NFT Creator (can be different from the caller)\n /// @param receiver The receiving address of the NFT (can be different from the caller)\n /// @param tokenMetaUri The unique metadata URI for the NFT\n /// @return newTokenId The newly minted NFT Token ID\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n\n /***********************************|\n | Create Multiple Protons |\n |__________________________________*/\n\n function createProtons(\n address creator,\n address receiver,\n string[] calldata tokenMetaUris\n )\n external\n virtual\n override\n whenNotPaused\n returns (bool)\n {\n _createProtons(\n creator,\n receiver,\n 0, // royaltiesPercent\n tokenMetaUris\n );\n return true;\n }\n\n function createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n external\n virtual\n override\n whenNotPaused\n returns (bool)\n {\n _createProtonsForSale(\n creator,\n receiver,\n royaltiesPercent,\n tokenMetaUris,\n salePrices\n );\n return true;\n }\n\n\n /***********************************|\n | Buy Protons |\n |__________________________________*/\n\n function buyProton(uint256 tokenId, uint256 gasLimit)\n external\n payable\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (bool)\n {\n _buyProton(tokenId, gasLimit);\n return true;\n }\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice)\n external\n virtual\n override\n whenNotPaused\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setSalePrice(tokenId, salePrice);\n }\n\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setRoyaltiesPct(tokenId, royaltiesPct);\n }\n\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n {\n _tokenCreatorRoyaltiesRedirect[tokenId] = receiver;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual {\n _tokenSalePrice[tokenId] = salePrice;\n emit SalePriceSet(tokenId, salePrice);\n }\n\n function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual {\n require(royaltiesPct <= PERCENTAGE_SCALE, \"PRT:E-421\");\n _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct;\n emit CreatorRoyaltiesSet(tokenId, royaltiesPct);\n }\n\n function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) {\n address receiver = _tokenCreatorRoyaltiesRedirect[tokenId];\n if (receiver == address(0x0)) {\n receiver = _tokenCreator[tokenId];\n }\n return receiver;\n }\n\n function _createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n _tokenIds.increment();\n\n newTokenId = _tokenIds.current();\n _safeMint(receiver, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUri);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n }\n\n function _createProtons(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris\n )\n internal\n virtual\n {\n uint256 count = tokenMetaUris.length;\n for (uint256 i; i < count; i++) {\n _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, 0);\n }\n }\n\n function _createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n internal\n virtual\n {\n require(tokenMetaUris.length == salePrices.length, \"PRT:E-202\");\n\n uint256 count = tokenMetaUris.length;\n for (uint256 i; i < count; i++) {\n _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, salePrices[i]);\n }\n }\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n contractAddress = address(this);\n tokenId = _tokenId;\n salePrice = _tokenSalePrice[_tokenId];\n require(salePrice > 0, \"PRT:E-416\");\n require(msg.value >= salePrice, \"PRT:E-414\");\n\n uint256 ownerAmount = salePrice;\n creatorAmount;\n oldOwner = ownerOf(_tokenId);\n newOwner = _msgSender();\n\n // Creator Royalties\n royaltiesReceiver = _creatorRoyaltiesReceiver(_tokenId);\n uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[_tokenId];\n uint256 lastSellPrice = _tokenLastSellPrice[_tokenId];\n if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) {\n creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE);\n ownerAmount = ownerAmount.sub(creatorAmount);\n }\n _tokenLastSellPrice[_tokenId] = salePrice;\n\n // Reserve Royalties for Creator\n if (creatorAmount > 0) {\n _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount);\n }\n\n // Transfer Token\n _transfer(oldOwner, newOwner, _tokenId);\n\n // Transfer Payment\n if (ownerAmount > 0) {\n payable(oldOwner).sendValue(ownerAmount, _gasLimit);\n }\n\n emit ProtonSold(_tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n\n _refundOverpayment(salePrice, _gasLimit);\n }\n\n /**\n * @dev Pays out the Creator Royalties of the calling account\n * @param receiver The receiver of the claimable royalties\n * @return The amount of Creator Royalties claimed\n */\n function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) {\n uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver];\n require(claimableAmount > 0, \"PRT:E-411\");\n\n delete _tokenCreatorClaimableRoyalties[receiver];\n payable(receiver).sendValue(claimableAmount, 0);\n\n emit RoyaltiesClaimed(receiver, claimableAmount);\n }\n\n /**\n * @dev Collects the Required Asset Token from the users wallet\n * @param from The owner address to collect the Assets from\n * @param assetAmount The Amount of Asset Tokens to Collect\n */\n function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual {\n uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from);\n require(assetAmount <= _userAssetBalance, \"PRT:E-411\");\n // Be sure to Approve this Contract to transfer your Asset Token\n require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), \"PRT:E-401\");\n }\n\n function _refundOverpayment(uint256 threshold, uint256 gasLimit) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage, gasLimit);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n _tokenSalePrice[tokenId] = 0;\n super._transfer(from, to, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"PRT:E-101\");\n _;\n }\n\n modifier onlyTokenOwnerOrApproved(uint256 tokenId) {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"PRT:E-105\");\n _;\n }\n\n modifier onlyTokenCreator(uint256 tokenId) {\n require(_tokenCreator[tokenId] == _msgSender(), \"PRT:E-104\");\n _;\n }\n}" + }, + "contracts/v1/lib/Bitwise.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Bitwise.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nlibrary Bitwise {\n function negate(uint32 a) internal pure returns (uint32) {\n return a ^ maxInt();\n }\n\n function shiftLeft(uint32 a, uint32 n) internal pure returns (uint32) {\n return a * uint32(2) ** n;\n }\n\n function shiftRight(uint32 a, uint32 n) internal pure returns (uint32) {\n return a / uint32(2) ** n;\n }\n\n function maxInt() internal pure returns (uint32) {\n return uint32(-1);\n }\n\n // Get bit value at position\n function hasBit(uint32 a, uint32 n) internal pure returns (bool) {\n return a & shiftLeft(0x01, n) != 0;\n }\n\n // Set bit value at position\n function setBit(uint32 a, uint32 n) internal pure returns (uint32) {\n return a | shiftLeft(0x01, n);\n }\n\n // Set the bit into state \"false\"\n function clearBit(uint32 a, uint32 n) internal pure returns (uint32) {\n uint32 mask = negate(shiftLeft(0x01, n));\n return a & mask;\n }\n}\n" + }, + "contracts/v1/lib/BlackholePrevention.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\n\n/**\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\n * the Owner/DAO to pull them out on behalf of a user\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\n */\ncontract BlackholePrevention {\n using Address for address payable;\n using SafeERC20 for IERC20;\n\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\n\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (address(this).balance >= amount) {\n receiver.sendValue(amount);\n emit WithdrawStuckEther(receiver, amount);\n }\n }\n\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\n IERC20(tokenAddress).safeTransfer(receiver, amount);\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\n }\n }\n\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\n }\n }\n\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \"\");\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\n }\n }\n}\n" + }, + "contracts/v1/lib/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/GSN/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableMap.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n /**\n * @dev Emitted when `tokenId` token is transfered from `from` to `to`.\n */\n event TransferBatch(address indexed from, address indexed to, uint256 startTokenId, uint256 count);\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721:E-403\");\n\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721:E-405\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"ERC721:E-405\");\n return _tokenURIs[tokenId];\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721:E-111\");\n\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \"ERC721:E-105\");\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view override returns (address) {\n require(_exists(tokenId), \"ERC721:E-405\");\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 require(operator != _msgSender(), \"ERC721:E-111\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721:E-402\");\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 returns (bool) {\n return _tokenOwners.contains(tokenId);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721:E-405\");\n address owner = ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721:E-402\");\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 _safeMintBatch(address to, uint256 startTokenId, uint256 count, bytes memory _data) internal virtual {\n _mintBatch(to, startTokenId, count);\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \"ERC721:E-402\");\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:E-403\");\n require(!_exists(tokenId), \"ERC721:E-407\");\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\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 _mintBatch(address to, uint256 startTokenId, uint256 count) internal virtual {\n require(to != address(0), \"ERC721:E-403\");\n require(!_exists(startTokenId), \"ERC721:E-407\");\n\n for (uint i = 0; i < count; i++) {\n uint256 tokenId = startTokenId.add(i);\n _holderTokens[to].add(tokenId);\n _tokenOwners.set(tokenId, to);\n }\n\n emit TransferBatch(address(0), to, startTokenId, count);\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(address from, address to, uint256 tokenId) internal virtual {\n require(ownerOf(tokenId) == from, \"ERC721:E-102\");\n require(to != address(0), \"ERC721:E-403\");\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721:E-405\");\n _tokenURIs[tokenId] = _tokenURI;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721:E-402\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\n }\n}\n" + }, + "contracts/v1/lib/ERC721Basic.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/GSN/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Basic is Context, ERC165, IERC721, IERC721Metadata {\n using SafeMath for uint256;\n using Address for address;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 internal constant _ERC721_RECEIVED = 0x150b7a02;\n\n // mapping from token ids to their owners\n mapping (uint256 => address) internal _tokenOwners;\n\n // mapping from owner to token balance\n mapping (address => uint256) internal _ownerBalance;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) internal _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) internal _operatorApprovals;\n\n // Token name\n string internal _name;\n\n // Token symbol\n string internal _symbol;\n\n // Token Count\n uint256 internal _tokenCount;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 internal constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 internal constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721:E-403\");\n return _ownerBalance[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners[tokenId];\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view 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 return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721:E-111\");\n\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \"ERC721:E-105\");\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view override returns (address) {\n require(_exists(tokenId), \"ERC721:E-405\");\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721:E-111\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721:E-402\");\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 returns (bool) {\n return _tokenOwners[tokenId] != address(0x0);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721:E-405\");\n address owner = ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\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(address to, bytes memory _data) internal virtual returns (uint256) {\n uint256 tokenId = _mint(to);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721:E-402\");\n return 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 _safeMintBatch(address to, uint256 count, bytes memory _data) internal virtual {\n uint256 startTokenId = _mintBatch(to, count);\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \"ERC721:E-402\");\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) internal virtual returns (uint256) {\n require(to != address(0), \"ERC721:E-403\");\n\n _tokenCount = _tokenCount.add(1);\n uint256 tokenId = _tokenCount;\n require(!_exists(tokenId), \"ERC721:E-407\");\n\n _tokenOwners[tokenId] = to;\n _ownerBalance[to] = _ownerBalance[to].add(1);\n\n emit Transfer(address(0), to, tokenId);\n return tokenId;\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 _mintBatch(address to, uint256 count) internal virtual returns (uint256) {\n require(to != address(0), \"ERC721:E-403\");\n\n uint256 startTokenId = _tokenCount.add(1);\n for (uint i = 1; i <= count; i++) {\n uint256 tokenId = _tokenCount.add(i);\n _tokenOwners[tokenId] = to;\n emit Transfer(address(0), to, tokenId);\n }\n\n _tokenCount = _tokenCount.add(count);\n _ownerBalance[to] = _ownerBalance[to].add(count);\n return startTokenId;\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(address from, address to, uint256 tokenId) internal virtual {\n require(ownerOf(tokenId) == from, \"ERC721:E-102\");\n require(to != address(0), \"ERC721:E-403\");\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _tokenOwners[tokenId] = to;\n _ownerBalance[from] = _ownerBalance[from].sub(1);\n _ownerBalance[to] = _ownerBalance[to].add(1);\n\n emit Transfer(from, to, tokenId);\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(address from, address to, uint256 tokenId, bytes memory _data)\n internal returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721:E-402\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) internal {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\n }\n}\n" + }, + "contracts/v1/lib/IERC5192.sol": { + "content": "// SPDX-License-Identifier: CC0-1.0\npragma solidity ^0.6.0;\n\ninterface IERC5192 {\n /// @notice Emitted when the locking status is changed to locked.\n /// @dev If a token is minted and the status is locked, this event should be emitted.\n /// @param tokenId The identifier for a token.\n event Locked(uint256 tokenId);\n\n /// @notice Emitted when the locking status is changed to unlocked.\n /// @dev If a token is minted and the status is unlocked, this event should be emitted.\n /// @param tokenId The identifier for a token.\n event Unlocked(uint256 tokenId);\n\n /// @notice Returns the locking status of an Soulbound Token\n /// @dev SBTs assigned to zero address are considered invalid, and queries\n /// about them do throw.\n /// @param tokenId The identifier for an SBT.\n function locked(uint256 tokenId) external view returns (bool);\n}\n" + }, + "contracts/v1/lib/NftTokenType.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// NftTokenType.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/introspection/IERC165.sol\";\n\nlibrary NftTokenType {\n bytes4 constant internal INTERFACE_SIGNATURE_ERC721 = 0x80ac58cd;\n bytes4 constant internal INTERFACE_SIGNATURE_ERC1155 = 0xd9b67a26;\n\n uint256 constant internal TYPE_MASK = uint256(uint128(~0)) << 128;\n uint256 constant internal TYPE_NFT_BIT = 1 << 255;\n\n function isERC721(address contractAddress) internal view returns (bool) {\n return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC721);\n }\n\n function isERC1155(address contractAddress) internal view returns (bool) {\n return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC1155);\n }\n\n function getTokenType(address contractAddress, uint256 tokenId) internal view returns (uint256) {\n IERC165 tokenInterface = IERC165(contractAddress);\n bool is1155 = tokenInterface.supportsInterface(INTERFACE_SIGNATURE_ERC1155);\n\n if (!is1155 || (tokenId & TYPE_NFT_BIT != TYPE_NFT_BIT)) { return 0; }\n\n return tokenId & TYPE_MASK;\n }\n}\n" + }, + "contracts/v1/lib/ReentrancyGuard.sol": { + "content": "pragma solidity 0.6.12;\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 () public {\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 _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\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 /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}" + }, + "contracts/v1/lib/RelayRecipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0;\n\nimport \"@opengsn/gsn/contracts/BaseRelayRecipient.sol\";\n\ncontract RelayRecipient is BaseRelayRecipient {\n function versionRecipient() external override view returns (string memory) {\n return \"1.0.0-beta.1/charged-particles.relay.recipient\";\n }\n}\n" + }, + "contracts/v1/lib/SmartWalletBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// SmartWalletBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../interfaces/ISmartWallet.sol\";\nimport \"./BlackholePrevention.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract SmartWalletBase is ISmartWallet, BlackholePrevention {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n address internal _walletManager;\n\n address internal nftCreator;\n uint256 internal nftCreatorAnnuityPct;\n uint256 internal nftCreatorAmountDischarged;\n\n EnumerableSet.AddressSet internal _assetTokens;\n\n // Asset Token => Principal Balance\n mapping (address => uint256) internal _assetPrincipalBalance;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initializeBase() public {\n require(_walletManager == address(0x0), \"SWB:E-002\");\n _walletManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getAssetTokenCount() external view virtual override returns (uint256) {\n return _assetTokens.length();\n }\n\n function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) {\n if (index >= _assetTokens.length()) {\n return address(0);\n }\n return _assetTokens.at(index);\n }\n\n function setNftCreator(address creator, uint256 annuityPct) external virtual override onlyWalletManager {\n nftCreator = creator;\n nftCreatorAnnuityPct = annuityPct;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyWalletManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n function refreshPrincipal(address assetToken)\n external\n virtual\n override\n onlyWalletManager\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getPrincipal(address assetToken) internal view virtual returns (uint256) {\n return _assetPrincipalBalance[assetToken];\n }\n\n function _trackAssetToken(address assetToken) internal virtual {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n }\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the wallet manager\n modifier onlyWalletManager() {\n require(_walletManager == msg.sender, \"SWB:E-109\");\n _;\n }\n}" + }, + "contracts/v1/lib/SmartWalletBaseB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// SmartWalletBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../interfaces/ISmartWalletB.sol\";\nimport \"./BlackholePrevention.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract SmartWalletBaseB is ISmartWalletB, BlackholePrevention {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n address internal _walletManager;\n\n EnumerableSet.AddressSet internal _assetTokens;\n\n // Asset Token => Principal Balance\n mapping (address => uint256) internal _assetPrincipalBalance;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initializeBase() public {\n require(_walletManager == address(0x0), \"SWB:E-002\");\n _walletManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getAssetTokenCount() external view virtual override returns (uint256) {\n return _assetTokens.length();\n }\n\n function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) {\n if (index >= _assetTokens.length()) {\n return address(0);\n }\n return _assetTokens.at(index);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyWalletManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getPrincipal(address assetToken) internal view virtual returns (uint256) {\n return _assetPrincipalBalance[assetToken];\n }\n\n function _trackAssetToken(address assetToken) internal virtual {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n }\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the wallet manager\n modifier onlyWalletManager() {\n require(_walletManager == msg.sender, \"SWB:E-109\");\n _;\n }\n}" + }, + "contracts/v1/lib/Soul.sol": { + "content": "// SPDX-License-Identifier: CC0-1.0\npragma solidity ^0.6.12;\n\nimport \"./IERC5192.sol\";\n\ncontract Soul is IERC5192 {\n \n mapping (uint256 => bool) public lockedTokens;\n\n function _lockToken(uint256 tokenId) internal {\n lockedTokens[tokenId] = true;\n emit Locked(tokenId);\n }\n\n function _unlockToken(uint256 tokenId) internal {\n lockedTokens[tokenId] = false;\n emit Unlocked(tokenId);\n }\n\n function locked(uint256 tokenId)\n external\n view\n override(IERC5192)\n returns (bool)\n {\n return lockedTokens[tokenId];\n }\n}\n" + }, + "contracts/v1/lib/TokenInfo.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfo.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"../interfaces/IERC721Chargeable.sol\";\n\nlibrary TokenInfo {\n function getTokenUUID(address contractAddress, uint256 tokenId) internal pure virtual returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n function getTokenOwner(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n return tokenInterface.ownerOf(tokenId);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n function getTokenCreator(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n return tokenInterface.creatorOf(tokenId);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Owner of an External NFT contract\n /// @param contractAddress The Address to the Contract of the NFT to check\n /// @param account The Address of the Account to check\n /// @return True if the account owns the contract\n function isContractOwner(address contractAddress, address account) internal view virtual returns (bool) {\n address contractOwner = IERC721Chargeable(contractAddress).owner();\n return contractOwner != address(0x0) && contractOwner == account;\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Creator of a Proton-based NFT\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the Proton-based NFT\n function isTokenCreator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenCreator = tokenInterface.creatorOf(tokenId);\n return (sender == tokenCreator);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the Proton-based NFT or the Contract itself\n function isTokenContractOrCreator(address contractAddress, uint256 tokenId, address creator, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenCreator = tokenInterface.creatorOf(tokenId);\n if (sender == contractAddress && creator == tokenCreator) { return true; }\n return (sender == tokenCreator);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Owner or Operator of an External NFT\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the Owner or Operator of the External NFT\n function isErc721OwnerOrOperator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenOwner = tokenInterface.ownerOf(tokenId);\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\n }\n\n /**\n * @dev Returns true if `account` is a contract.\n * @dev Taken from OpenZeppelin library\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\n // for accounts without code, i.e. `keccak256('')`\n bytes32 codehash;\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n // solhint-disable-next-line no-inline-assembly\n assembly { codehash := extcodehash(account) }\n return (codehash != accountHash && codehash != 0x0);\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 * @dev Taken from OpenZeppelin library\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, uint256 gasLimit) internal {\n require(address(this).balance >= amount, \"TokenInfo: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = (gasLimit > 0)\n ? recipient.call{ value: amount, gas: gasLimit }(\"\")\n : recipient.call{ value: amount }(\"\");\n require(success, \"TokenInfo: unable to send value, recipient may have reverted\");\n }\n}\n" + }, + "contracts/v1/lib/TokenInfoProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfoProxy.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../interfaces/ITokenInfoProxy.sol\";\nimport \"../interfaces/IERC721Chargeable.sol\";\n\n\ncontract TokenInfoProxy is ITokenInfoProxy, Ownable {\n using Address for address;\n\n mapping (address => FnSignatures) internal _remappedFnSigs;\n\n function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner {\n _remappedFnSigs[contractAddress].ownerOf = fnSig;\n emit ContractFunctionSignatureSet(contractAddress, \"ownerOf\", fnSig);\n }\n\n function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner {\n _remappedFnSigs[contractAddress].creatorOf = fnSig;\n emit ContractFunctionSignatureSet(contractAddress, \"creatorOf\", fnSig);\n }\n\n\n function getTokenUUID(address contractAddress, uint256 tokenId) external pure virtual override returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n function getTokenOwner(address contractAddress, uint256 tokenId) external virtual override returns (address) {\n return _getTokenOwner(contractAddress, tokenId);\n }\n\n function getTokenCreator(address contractAddress, uint256 tokenId) external virtual override returns (address) {\n return _getTokenCreator(contractAddress, tokenId);\n }\n\n function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenOwner = _getTokenOwner(contractAddress, tokenId);\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\n }\n\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the NFT or the Contract itself\n function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) {\n address tokenCreator = _getTokenCreator(contractAddress, tokenId);\n return (sender == tokenCreator || sender == contractAddress);\n }\n\n\n\n function _getTokenCreator(address contractAddress, uint256 tokenId) internal returns (address) {\n bytes4 fnSig = IERC721Chargeable.creatorOf.selector;\n if (_remappedFnSigs[contractAddress].creatorOf != bytes4(0)) {\n fnSig = _remappedFnSigs[contractAddress].creatorOf;\n }\n\n // solhint-disable-next-line\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n if (success) {\n return abi.decode(returnData, (address));\n } else {\n return address(0x0);\n }\n }\n\n function _getTokenOwner(address contractAddress, uint256 tokenId) internal returns (address) {\n bytes4 fnSig = IERC721Chargeable.ownerOf.selector;\n if (_remappedFnSigs[contractAddress].ownerOf != bytes4(0)) {\n fnSig = _remappedFnSigs[contractAddress].ownerOf;\n }\n\n // solhint-disable-next-line\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n if (success) {\n return abi.decode(returnData, (address));\n } else {\n return address(0x0);\n }\n }\n}\n" + }, + "contracts/v1/lib/WalletManagerBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// WalletManagerBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IWalletManager.sol\";\nimport \"../interfaces/ISmartWallet.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"./BlackholePrevention.sol\";\n\n\n/**\n * @notice Wallet-Manager Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract WalletManagerBase is Ownable, BlackholePrevention, IWalletManager {\n using TokenInfo for address;\n\n // The Controller Contract Address\n address internal _controller;\n\n // The Executor Contract Address\n address internal _executor;\n\n // Template Contract for creating Token Smart-Wallet Bridges\n address internal _walletTemplate;\n\n // TokenID => Token Smart-Wallet Address\n mapping (uint256 => address) internal _wallets;\n\n // State of Wallet Manager\n bool internal _paused;\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Wallet Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n /**\n * @dev Connects to the ExecForAccount Controller\n */\n function setExecutor(address executor) external onlyOwner {\n _executor = executor;\n emit ExecutorSet(executor);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartWallet(wallet).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartWallet(wallet).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartWallet(wallet).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Executor contract\n modifier onlyExecutor() {\n require(_executor == msg.sender, \"WMB:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Controller or Executor contract\n modifier onlyControllerOrExecutor() {\n require(_executor == msg.sender || _controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"WMB:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/ParticleSplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ParticleSplitter.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"./interfaces/IParticleSplitter.sol\";\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IWalletManager.sol\";\nimport \"./interfaces/IBasketManager.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Contract\n * @dev Upgradeable Contract\n */\ncontract ParticleSplitter is IParticleSplitter, Ownable, ReentrancyGuard, BlackholePrevention\n{\n IChargedManagers internal _chargedManagers;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n mapping (address => bool) internal _externalAddressesAllowed;\n\n\n /***********************************|\n | Execute for Account |\n |__________________________________*/\n\n /// @notice Executes an arbitrary command on an NFT Wallet\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Wallet Manager controlling the NFT Wallet to execute on\n /// @param externalAddress The Address of the External Contract to execute on\n /// @param encodedParams The encoded function call to execute\n function executeForWallet(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address externalAddress,\n bytes memory encodedParams\n )\n external\n payable\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (bytes memory)\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n require(_externalAddressesAllowed[externalAddress], \"PS:E-117\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Wallet Manager\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n // Get Address of Wallet to send any ETH into\n if (msg.value > 0) {\n address wallet = walletMgr.getWalletAddressById(contractAddress, tokenId, address(0), 0);\n payable(wallet).sendValue(msg.value);\n }\n\n emit ExecuteForWallet(contractAddress, tokenId, walletManagerId, externalAddress, encodedParams, msg.value);\n\n // Execute command for NFT Wallet\n return walletMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams);\n }\n\n /// @notice Executes an arbitrary command on an NFT Basket\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param basketManagerId The Basket Manager controlling the NFT Wallet to execute on\n /// @param externalAddress The Address of the External Contract to execute on\n /// @param encodedParams The encoded function call to execute\n function executeForBasket(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address externalAddress,\n bytes memory encodedParams\n )\n external\n payable\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (bytes memory)\n {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"PS:E-419\");\n require(_externalAddressesAllowed[externalAddress], \"PS:E-117\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Basket Manager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n\n // Get Address of Wallet to send any ETH into\n if (msg.value > 0) {\n address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId);\n payable(wallet).sendValue(msg.value);\n }\n\n emit ExecuteForBasket(contractAddress, tokenId, basketManagerId, externalAddress, encodedParams, msg.value);\n\n // Execute command for NFT Wallet\n return basketMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams);\n }\n\n function withdrawWalletRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (uint256 amountWithdrawn)\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Wallet Manager\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n // Withdraw Rewards for NFT Wallet\n return walletMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount);\n }\n\n function withdrawBasketRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (uint256 amountWithdrawn)\n {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"PS:E-419\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Basket Manager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n\n // Withdraw Rewards for NFT Basket\n return basketMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount);\n }\n\n function refreshWalletPrincipal(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n walletMgr.refreshPrincipal(contractAddress, tokenId, assetToken);\n\n emit PrincipalRefreshed(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedManagers Interface\n */\n function setChargedManagers(address chargedManagers) external virtual onlyOwner {\n _chargedManagers = IChargedManagers(chargedManagers);\n emit ChargedManagersSet(chargedManagers);\n }\n\n /**\n * @dev Setup the ChargedManagers Interface\n */\n function setTokenInfoProxy(address tokenInfoProxy) external virtual onlyOwner {\n _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy);\n emit TokenInfoProxySet(tokenInfoProxy);\n }\n\n /**\n * @dev Allows/Disallows execute from on specific contracts\n */\n function setExternalContracts(address[] calldata contracts, bool state) external onlyOwner {\n uint count = contracts.length;\n for (uint i; i < count; i++) {\n address externalContract = contracts[i];\n _externalAddressesAllowed[externalContract] = state;\n emit PermsSetForExternal(externalContract, state);\n }\n }\n\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyTokenOwner(address contractAddress, uint256 tokenId) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(msg.sender == tokenOwner, \"PS:E-102\");\n _;\n }\n}\n" + }, + "contracts/v1/test/Dai.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"../interfaces/IDai.sol\";\n\ncontract Dai is IDai {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (uint256 chainId_) public {\n string memory version = \"1\";\n\n _name = \"Dai Stablecoin\";\n _symbol = \"DAI\";\n _decimals = 18;\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(_name)),\n keccak256(bytes(version)),\n chainId_,\n address(this)\n )\n );\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view 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(msg.sender, 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(msg.sender, 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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(msg.sender, spender, _allowances[msg.sender][spender].add(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 _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20:E-403\");\n require(recipient != address(0), \"ERC20:E-403\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20:E-403\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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:E-403\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20:E-403\");\n require(spender != address(0), \"ERC20:E-403\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n\n mapping (address => uint) public nonces;\n\n // --- EIP712 niceties ---\n bytes32 public DOMAIN_SEPARATOR;\n // bytes32 public constant PERMIT_TYPEHASH = keccak256(\"Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)\");\n bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;\n\n // --- Approve by signature ---\n function permit(\n address holder, address spender, uint256 nonce, uint256 expiry,\n bool allowed, uint8 v, bytes32 r, bytes32 s) external override\n {\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n holder,\n spender,\n nonce,\n expiry,\n allowed\n )\n )\n )\n );\n\n require(holder != address(0), \"Dai/invalid-address-0\");\n require(holder == ecrecover(digest, v, r, s), \"Dai/invalid-permit\");\n require(expiry == 0 || now <= expiry, \"Dai/permit-expired\");\n require(nonce == nonces[holder]++, \"Dai/invalid-nonce\");\n uint wad = allowed ? uint(-1) : 0;\n _allowances[holder][spender] = wad;\n emit Approval(holder, spender, wad);\n }\n\n function mint(address to, uint256 amount) external {\n _mint(to, amount);\n }\n}" + }, + "contracts/v1/test/ERC20Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.7.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/**\n * @dev Extension of {ERC20} that adds a set of accounts with the {MinterRole},\n * which have permission to mint (create) new tokens as they see fit.\n *\n * At construction, the deployer of the contract is the only minter.\n */\ncontract ERC20Mintable is ERC20Upgradeable {\n\n constructor(string memory _name, string memory _symbol) public {\n __ERC20_init(_name, _symbol);\n }\n\n /**\n * @dev See {ERC20-_mint}.\n *\n * Requirements:\n *\n * - the caller must have the {MinterRole}.\n */\n function mint(address account, uint256 amount) public returns (bool) {\n _mint(account, amount);\n return true;\n }\n\n function burn(address account, uint256 amount) public returns (bool) {\n _burn(account, amount);\n return true;\n }\n}" + }, + "contracts/v1/test/ERC721Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.7.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\n\n/**\n * @dev Extension of {ERC721} for Minting/Burning\n */\ncontract ERC721Mintable is ERC721Upgradeable {\n\n constructor () public {\n __ERC721_init(\"ERC 721\", \"NFT\");\n }\n\n /**\n * @dev See {ERC721-_mint}.\n */\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n\n /**\n * @dev See {ERC721-_burn}.\n */\n function burn(uint256 tokenId) public {\n _burn(tokenId);\n }\n}\n" + }, + "contracts/v1/tokens/ExternalERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ExternalERC721.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\n\ncontract ExternalERC721 is ERC721 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n\n constructor() public ERC721(\"Charged Particles - ExternalERC721\", \"ExNFT\") {}\n\n function mintNft(address receiver, string memory tokenUri) external returns (uint256 newTokenId) {\n return _mintNft(receiver, tokenUri);\n }\n\n function _mintNft(address receiver, string memory tokenUri) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n\n _safeMint(receiver, newTokenId, \"\");\n\n _setTokenURI(newTokenId, tokenUri);\n }\n}\n" + }, + "contracts/v1/tokens/FungibleERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// FungibleERC1155.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract FungibleERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n\n constructor() public ERC1155(\"https://staging.app.charged.fi/erc1155/metadata.json\") {}\n\n function mintNft(address receiver, uint256 amount) external returns (uint256 newTokenId) {\n return _mintNft(receiver, amount);\n }\n\n function _mintNft(address receiver, uint256 amount) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n _mint(receiver, newTokenId, amount, \"\");\n }\n}\n" + }, + "contracts/v1/tokens/Ionx.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Ionx.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"erc20permit/contracts/ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\n\ncontract Ionx is ERC20Permit, Ownable, BlackholePrevention {\n using SafeMath for uint256;\n\n /// @notice An event thats emitted when the minter address is changed\n event MinterChanged(address minter, address newMinter);\n\n /// @notice Total number of tokens in circulation\n uint256 constant public INITIAL_SUPPLY = 1e8 ether;\n\n /// @notice Minimum time between mints\n uint32 public constant INFLATION_EPOCH = 1 days * 365;\n\n /// @notice Cap on the percentage of totalSupply that can be minted at each mint\n uint8 public constant INFLATION_CAP = 2;\n\n /// @notice Address which may mint new tokens\n address public minter;\n\n /// @notice The timestamp after which minting may occur\n uint256 public mintingAllowedAfter;\n\n\n constructor() public ERC20Permit(\"Charged Particles - IONX\", \"IONX\") {}\n\n\n /**\n * @notice Change the minter address\n * @param newMinter The address of the new minter\n */\n function setMinter(address newMinter) external onlyOwner {\n emit MinterChanged(minter, newMinter);\n minter = newMinter;\n }\n\n /**\n * @notice Mint new tokens\n * @param receiver The address of the destination account\n * @param amount The number of tokens to be minted\n */\n function mint(address receiver, uint256 amount) external onlyMinter {\n require(block.timestamp >= mintingAllowedAfter, \"Ionx:E-114\");\n require(receiver != address(0), \"Ionx:E-403\");\n\n uint256 amountToMint = amount;\n uint256 _totalSupply = totalSupply();\n\n // From Inflationary Supply\n if (_totalSupply >= INITIAL_SUPPLY) {\n mintingAllowedAfter = mintingAllowedAfter.add(INFLATION_EPOCH);\n amountToMint = _totalSupply.mul(INFLATION_CAP).div(100);\n }\n\n // From Initial Supply\n else {\n if (_totalSupply.add(amountToMint) > INITIAL_SUPPLY) {\n amountToMint = INITIAL_SUPPLY.sub(_totalSupply);\n }\n if (_totalSupply.add(amountToMint) == INITIAL_SUPPLY) {\n mintingAllowedAfter = block.timestamp.add(INFLATION_EPOCH);\n }\n }\n\n // transfer the amount to the recipient\n _mint(receiver, amountToMint);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n modifier onlyMinter() {\n require(msg.sender == minter, \"Ionx:E-113\");\n _;\n }\n}\n" + }, + "contracts/v1/tokens/Lepton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Lepton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/ILepton.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\n\ncontract Lepton is ILepton, ERC721, Ownable, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenIds;\n Classification[] internal _leptonTypes;\n mapping (uint256 => Classification) internal _leptonData;\n\n uint256 internal _typeIndex;\n uint256 internal _maxSupply;\n uint256 internal _maxMintPerTx;\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721(\"Charged Particles - Lepton\", \"LEPTON\") {\n _paused = true;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function mintLepton() external payable virtual override nonReentrant whenNotPaused returns (uint256 newTokenId) {\n newTokenId = _mintLepton(msg.sender);\n }\n\n function batchMintLepton(uint256 count) external payable virtual override nonReentrant whenNotPaused {\n _batchMintLepton(msg.sender, count);\n }\n\n function getNextType() external view virtual override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _typeIndex;\n }\n\n function getNextPrice() external view virtual override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _leptonTypes[_typeIndex].price;\n }\n\n function getMultiplier(uint256 tokenId) external view virtual override returns (uint256) {\n return _leptonData[tokenId].multiplier;\n }\n\n function getBonus(uint256 tokenId) external view virtual override returns (uint256) {\n return _leptonData[tokenId].bonus;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function addLeptonType(\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n virtual\n onlyOwner\n {\n _maxSupply = _maxSupply.add(uint256(supply));\n\n Classification memory lepton = Classification({\n tokenUri: tokenUri,\n price: price,\n supply: supply,\n multiplier: multiplier,\n bonus: bonus,\n _upperBounds: uint128(_maxSupply)\n });\n _leptonTypes.push(lepton);\n\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function updateLeptonType(\n uint256 leptonIndex,\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n virtual\n onlyOwner\n {\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\n _leptonTypes[leptonIndex].price = price;\n _leptonTypes[leptonIndex].supply = supply;\n _leptonTypes[leptonIndex].multiplier = multiplier;\n _leptonTypes[leptonIndex].bonus = bonus;\n\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function setMaxMintPerTx(uint256 maxAmount) external virtual onlyOwner {\n _maxMintPerTx = maxAmount;\n emit MaxMintPerTxSet(maxAmount);\n }\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _mintLepton(address receiver) internal virtual returns (uint256 newTokenId) {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n require(msg.value >= lepton.price, \"LPT:E-414\");\n\n _tokenIds.increment();\n newTokenId = _tokenIds.current();\n\n _leptonData[newTokenId] = lepton;\n _safeMint(receiver, newTokenId, \"\");\n _setTokenURI(newTokenId, lepton.tokenUri);\n\n // Distribute Next Type\n if (newTokenId == lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n emit LeptonMinted(receiver, newTokenId, lepton.price, lepton.multiplier);\n\n _refundOverpayment(lepton.price);\n }\n\n\n function _batchMintLepton(address receiver, uint256 count) internal virtual {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \"LPT:E-429\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n\n uint256 startTokenId = _tokenIds.current();\n uint256 endTokenId = startTokenId.add(count);\n if (endTokenId > lepton._upperBounds) {\n count = count.sub(endTokenId.sub(lepton._upperBounds));\n }\n\n uint256 salePrice = lepton.price.mul(count);\n require(msg.value >= salePrice, \"LPT:E-414\");\n\n _safeMintBatch(receiver, startTokenId.add(1), count, \"\");\n\n for (uint i = 0; i < count; i++) {\n _tokenIds.increment();\n startTokenId = _tokenIds.current();\n\n _leptonData[startTokenId] = lepton;\n _setTokenURI(startTokenId, lepton.tokenUri);\n }\n\n // Distribute Next Type\n if (startTokenId >= lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n emit LeptonBatchMinted(receiver, startTokenId, count, lepton.price, lepton.multiplier);\n\n _refundOverpayment(salePrice);\n }\n\n function _refundOverpayment(uint256 threshold) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"LPT:E-101\");\n _;\n }\n}" + }, + "contracts/v1/tokens/Lepton2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Lepton2.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"../lib/ERC721Basic.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\n\nimport \"../interfaces/ILepton.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Lepton2 is ILepton, ERC721Basic, Ownable, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n\n Classification[] internal _leptonTypes;\n\n uint256 internal _typeIndex;\n uint256 internal _maxSupply;\n uint256 internal _maxMintPerTx;\n uint256 internal _migratedCount;\n\n bool internal _paused;\n bool internal _migrationComplete;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721Basic(\"Charged Particles - Lepton2\", \"LEPTON2\") {\n _paused = true;\n _migrationComplete = false;\n _migratedCount = 0;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function mintLepton() external payable override nonReentrant whenNotPaused returns (uint256 newTokenId) {\n newTokenId = _mintLepton(msg.sender);\n }\n\n function batchMintLepton(uint256 count) external payable override nonReentrant whenNotPaused {\n _batchMintLepton(msg.sender, count);\n }\n\n function totalSupply() public view returns (uint256) {\n return _tokenCount;\n }\n\n function maxSupply() external view returns (uint256) {\n return _maxSupply;\n }\n\n function getNextType() external view override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _typeIndex;\n }\n\n function getNextPrice() external view override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _leptonTypes[_typeIndex].price;\n }\n\n function getMultiplier(uint256 tokenId) external view override returns (uint256) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).multiplier;\n }\n\n function getBonus(uint256 tokenId) external view override returns (uint256) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).bonus;\n }\n\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).tokenUri;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function addLeptonType(\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n onlyOwner\n {\n _maxSupply = _maxSupply.add(uint256(supply));\n\n Classification memory lepton = Classification({\n tokenUri: tokenUri,\n price: price,\n supply: supply,\n multiplier: multiplier,\n bonus: bonus,\n _upperBounds: uint128(_maxSupply)\n });\n _leptonTypes.push(lepton);\n\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function updateLeptonType(\n uint256 leptonIndex,\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n onlyOwner\n {\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\n _leptonTypes[leptonIndex].price = price;\n _leptonTypes[leptonIndex].supply = supply;\n _leptonTypes[leptonIndex].multiplier = multiplier;\n _leptonTypes[leptonIndex].bonus = bonus;\n\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function setMaxMintPerTx(uint256 maxAmount) external onlyOwner {\n _maxMintPerTx = maxAmount;\n emit MaxMintPerTxSet(maxAmount);\n }\n\n function setPausedState(bool state) external onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function migrateAccounts(address oldLeptonContract, uint256 count) external onlyOwner whenNotMigrated {\n uint256 oldSupply = IERC721Enumerable(oldLeptonContract).totalSupply();\n require(oldSupply == 0 || oldSupply > _migratedCount, \"LPT:E-004\");\n\n if (oldSupply > 0) {\n uint256 endTokenId = _migratedCount.add(count);\n if (endTokenId > oldSupply) {\n count = count.sub(endTokenId.sub(oldSupply));\n }\n\n for (uint256 i = 1; i <= count; i++) {\n uint256 tokenId = _migratedCount.add(i);\n address tokenOwner = IERC721(oldLeptonContract).ownerOf(tokenId);\n _mint(tokenOwner);\n }\n _migratedCount = _migratedCount.add(count);\n }\n\n if (oldSupply == _migratedCount) {\n _finalizeMigration();\n }\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getLepton(uint256 tokenId) internal view returns (Classification memory) {\n uint256 types = _leptonTypes.length;\n for (uint256 i = 0; i < types; i++) {\n Classification memory lepton = _leptonTypes[i];\n if (tokenId <= lepton._upperBounds) {\n return lepton;\n }\n }\n }\n\n function _mintLepton(address receiver) internal returns (uint256 newTokenId) {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n require(msg.value >= lepton.price, \"LPT:E-414\");\n\n newTokenId = _safeMint(receiver, \"\");\n\n // Determine Next Type\n if (newTokenId == lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n _refundOverpayment(lepton.price);\n }\n\n function _batchMintLepton(address receiver, uint256 count) internal {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \"LPT:E-429\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n\n uint256 endTokenId = _tokenCount.add(count);\n if (endTokenId > lepton._upperBounds) {\n count = count.sub(endTokenId.sub(lepton._upperBounds));\n }\n\n uint256 salePrice = lepton.price.mul(count);\n require(msg.value >= salePrice, \"LPT:E-414\");\n\n _safeMintBatch(receiver, count, \"\");\n\n // Determine Next Type\n if (endTokenId >= lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n _refundOverpayment(salePrice);\n }\n\n function _refundOverpayment(uint256 threshold) internal {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n function _finalizeMigration() internal {\n // Determine Next Type\n _typeIndex = 0;\n for (uint256 i = 0; i < _leptonTypes.length; i++) {\n Classification memory lepton = _leptonTypes[i];\n if (_migratedCount >= lepton._upperBounds) {\n _typeIndex = i + 1;\n }\n }\n _migrationComplete = true;\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotMigrated() {\n require(!_migrationComplete, \"LPT:E-004\");\n _;\n }\n\n modifier whenNotPaused() {\n require(!_paused, \"LPT:E-101\");\n _;\n }\n}" + }, + "contracts/v1/tokens/NonFungibleERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// NonFungibleERC1155.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract NonFungibleERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => address) internal _tokenOwner;\n\n constructor() public ERC1155(\"https://staging.app.charged.fi/erc1155/metadata.json\") {}\n\n function creatorOf(uint256 tokenId) external view returns (address) {\n return _tokenCreator[tokenId];\n }\n\n function ownerOf(uint256 tokenId) external view returns (address) {\n return _tokenOwner[tokenId];\n }\n\n function mintNft(address receiver) external returns (uint256 newTokenId) {\n return _mintNft(msg.sender, receiver);\n }\n\n function _mintNft(address creator, address receiver) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n\n _mint(receiver, newTokenId, 1, \"\");\n _tokenCreator[newTokenId] = creator;\n _tokenOwner[newTokenId] = receiver;\n }\n}\n" + }, + "contracts/v1/tokens/Proton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IProton.sol\";\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ncontract Proton is IProton, ERC721, Ownable, RelayRecipient, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n using Counters for Counters.Counter;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n uint256 constant internal MAX_ROYALTIES = 8e3; // 8000 (80%)\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n Counters.Counter internal _tokenIds;\n\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct;\n mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect;\n mapping (address => uint256) internal _tokenCreatorClaimableRoyalties;\n\n mapping (uint256 => uint256) internal _tokenSalePrice;\n mapping (uint256 => uint256) internal _tokenLastSellPrice;\n\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721(\"Charged Particles - Proton\", \"PROTON\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view virtual override returns (address) {\n return _tokenCreator[tokenId];\n }\n\n function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenSalePrice[tokenId];\n }\n\n function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenLastSellPrice[tokenId];\n }\n\n function getCreatorRoyalties(address account) external view virtual override returns (uint256) {\n return _tokenCreatorClaimableRoyalties[account];\n }\n\n function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenCreatorRoyaltiesPct[tokenId];\n }\n\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) {\n return _creatorRoyaltiesReceiver(tokenId);\n }\n\n function claimCreatorRoyalties()\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256)\n {\n return _claimCreatorRoyalties(_msgSender());\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // annuityPercent,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n royaltiesPercent,\n salePrice\n );\n }\n\n function batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n external\n virtual\n override\n whenNotPaused\n {\n _batchProtonsForSale(\n creator,\n annuityPercent,\n royaltiesPercent,\n tokenMetaUris,\n salePrices\n );\n }\n\n function buyProton(uint256 tokenId)\n external\n payable\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (bool)\n {\n return _buyProton(tokenId);\n }\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice)\n external\n virtual\n override\n whenNotPaused\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setSalePrice(tokenId, salePrice);\n }\n\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setRoyaltiesPct(tokenId, royaltiesPct);\n }\n\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n {\n _tokenCreatorRoyaltiesRedirect[tokenId] = receiver;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual {\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n\n _tokenSalePrice[tokenId] = salePrice;\n emit SalePriceSet(tokenId, salePrice);\n }\n\n function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual {\n require(royaltiesPct <= MAX_ROYALTIES, \"PRT:E-421\");\n _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct;\n emit CreatorRoyaltiesSet(tokenId, royaltiesPct);\n }\n\n function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) {\n address receiver = _tokenCreatorRoyaltiesRedirect[tokenId];\n if (receiver == address(0x0)) {\n receiver = _tokenCreator[tokenId];\n }\n return receiver;\n }\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, annuityPercent, 0, 0);\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n _tokenIds.increment();\n\n newTokenId = _tokenIds.current();\n _safeMint(receiver, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUri);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function _batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n internal\n virtual\n {\n require(tokenMetaUris.length == salePrices.length, \"PRT:E-202\");\n address self = address(this);\n\n uint256 count = tokenMetaUris.length;\n for (uint256 i = 0; i < count; i++) {\n _tokenIds.increment();\n uint256 newTokenId = _tokenIds.current();\n\n _safeMint(creator, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUris[i]);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n uint256 salePrice = salePrices[i];\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n self,\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n function _buyProton(uint256 tokenId)\n internal\n virtual\n returns (bool)\n {\n uint256 salePrice = _tokenSalePrice[tokenId];\n require(salePrice > 0, \"PRT:E-416\");\n require(msg.value >= salePrice, \"PRT:E-414\");\n\n uint256 ownerAmount = salePrice;\n uint256 creatorAmount;\n address oldOwner = ownerOf(tokenId);\n address newOwner = _msgSender();\n\n // Creator Royalties\n address royaltiesReceiver = _creatorRoyaltiesReceiver(tokenId);\n uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[tokenId];\n uint256 lastSellPrice = _tokenLastSellPrice[tokenId];\n if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) {\n creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE);\n ownerAmount = ownerAmount.sub(creatorAmount);\n }\n _tokenLastSellPrice[tokenId] = salePrice;\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(address(this), tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n\n // Reserve Royalties for Creator\n if (creatorAmount > 0) {\n _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount);\n }\n\n // Transfer Token\n _transfer(oldOwner, newOwner, tokenId);\n\n // Transfer Payment\n payable(oldOwner).sendValue(ownerAmount);\n\n emit ProtonSold(tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n\n _refundOverpayment(salePrice);\n return true;\n }\n\n /**\n * @dev Pays out the Creator Royalties of the calling account\n * @param receiver The receiver of the claimable royalties\n * @return The amount of Creator Royalties claimed\n */\n function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) {\n uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver];\n require(claimableAmount > 0, \"PRT:E-411\");\n\n delete _tokenCreatorClaimableRoyalties[receiver];\n payable(receiver).sendValue(claimableAmount);\n\n emit RoyaltiesClaimed(receiver, claimableAmount);\n }\n\n /**\n * @dev Collects the Required Asset Token from the users wallet\n * @param from The owner address to collect the Assets from\n * @param assetAmount The Amount of Asset Tokens to Collect\n */\n function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual {\n uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from);\n require(assetAmount <= _userAssetBalance, \"PRT:E-411\");\n // Be sure to Approve this Contract to transfer your Asset Token\n require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), \"PRT:E-401\");\n }\n\n function _refundOverpayment(uint256 threshold) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n _tokenSalePrice[tokenId] = 0;\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n super._transfer(from, to, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"PRT:E-101\");\n _;\n }\n\n modifier onlyTokenOwnerOrApproved(uint256 tokenId) {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"PRT:E-105\");\n _;\n }\n\n modifier onlyTokenCreator(uint256 tokenId) {\n require(_tokenCreator[tokenId] == _msgSender(), \"PRT:E-104\");\n _;\n }\n}" + }, + "contracts/v1/tokens/ProtonB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\nimport \"../interfaces/IProtonB.sol\";\n\nimport \"../lib/BaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ncontract ProtonB is BaseProton, IProtonB {\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public BaseProton(\"Charged Particles - ProtonB\", \"PROTON.B\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n external\n virtual\n override\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n royaltiesPercent,\n salePrice\n );\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n /// @dev for backwards compatibility with v1\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0);\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n\n /***********************************|\n | Function Overrides |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override {\n super._setSalePrice(tokenId, salePrice);\n\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n }\n\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n override\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n }\n\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n // Unlock NFT\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n\n super._transfer(from, to, tokenId);\n }\n}" + }, + "contracts/v1/tokens/ProtonC.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\nimport \"../lib/Soul.sol\";\n\n\ncontract ProtonC is BaseProton, Soul {\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public BaseProton(\"Charged Particles - ProtonC\", \"PROTON.C\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createBondedToken(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent\n )\n external\n virtual\n payable\n returns (uint256 newTokenId)\n {\n uint256 tokenId = createProtonForSale(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n royaltiesPercent,\n 0\n );\n lockToken(tokenId);\n\n return tokenId;\n }\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n public \n virtual\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n royaltiesPercent,\n salePrice\n );\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n nonReentrant\n whenNotPaused\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n /// @dev for backwards compatibility with v1\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n whenNotPaused\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function burn(uint256 tokenId) public {\n requireTokenOwner(tokenId); \n _burn(tokenId);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n function requireTokenOwner(uint256 tokenId) public view {\n require(ownerOf(tokenId) == msg.sender, \"Only token owner\");\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0);\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n function _burn(uint256 tokenId) internal {\n _unlockToken(tokenId);\n _transfer(ownerOf(tokenId), address(0x000000000000000000000000000000000000dEaD), tokenId);\n }\n\n /***********************************|\n | Soul bounded |\n |__________________________________*/\n\n function lockToken(uint256 tokenId) public {\n requireTokenOwner(tokenId);\n _lockToken(tokenId);\n }\n\n /***********************************|\n | Function Overrides |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override {\n super._setSalePrice(tokenId, salePrice);\n\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n }\n\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n override\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n require(lockedTokens[tokenId] == false, \"BondedToken: Token is locked\");\n\n // Unlock NFT\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n\n super._transfer(from, to, tokenId);\n }\n}" + }, + "contracts/v1/Universe.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\n\nimport \"./interfaces/IUniverse.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n\n/**\n * @notice Charged Particles Universe Contract\n * @dev Upgradeable Contract\n */\ncontract Universe is IUniverse, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n // The ChargedParticles Contract Address\n address public chargedParticles;\n address public proton;\n address public lepton;\n address public quark;\n address public boson;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // Positive Charge\n uint256 internal photonMaxSupply;\n uint256 internal totalPhotonDischarged;\n\n // Source of Positive Charge\n IERC20Upgradeable public photonSource;\n\n // Asset Token => Electrostatic Attraction Multiplier\n mapping (address => uint256) internal esaMultiplier;\n\n // Account => Electrostatic Attraction Levels\n mapping (address => uint256) internal esaLevel;\n\n // Energizing Account => Referral Source\n mapping (address => address) internal referralSource;\n\n // NFT Token UUID => Bonded Lepton Mass\n mapping (uint256 => uint256) internal bondedLeptonMass;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getStaticCharge(address /* account */) external pure virtual returns (uint256 positiveEnergy) {\n return 0;\n }\n\n function conductElectrostaticDischarge(address /* account */, uint256 /* amount */) external pure virtual returns (uint256 positiveEnergy) {\n return 0;\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n onlyProton\n {\n // no-op\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(controller)\n {\n chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setPhoton(\n address token,\n uint256 maxSupply\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n photonSource = IERC20Upgradeable(token);\n photonMaxSupply = maxSupply;\n emit PhotonSet(token, maxSupply);\n }\n\n function setProtonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n proton = token;\n emit ProtonTokenSet(token);\n }\n\n function setLeptonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n lepton = token;\n emit LeptonTokenSet(token);\n }\n\n function setQuarkToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n quark = token;\n emit QuarkTokenSet(token);\n }\n\n function setBosonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n boson = token;\n emit BosonTokenSet(token);\n }\n\n function setEsaMultiplier(\n address assetToken,\n uint256 multiplier\n )\n external\n virtual\n onlyOwner\n {\n esaMultiplier[assetToken] = multiplier;\n emit EsaMultiplierSet(assetToken, multiplier);\n }\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _electrostaticAttraction(uint256 tokenUuid, address receiver, address assetToken, uint256 baseAmount) internal virtual {\n }\n\n function _conductElectrostaticDischarge(address /* account */, uint256 /* energy */) internal virtual pure returns (uint256) {\n return 0;\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Proton NFT contract\n modifier onlyProton() {\n require(proton == msg.sender, \"UNI:E-110\");\n _;\n }\n}\n" + }, + "contracts/v1/UniverseRP.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"./interfaces/IUniverseRP.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./interfaces/IRewardNft.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\nimport \"./interfaces/IRewardProgram.sol\";\n\n/**\n * @notice Charged Particles Universe Contract with Rewards Program\n * @dev Upgradeable Contract\n */\ncontract UniverseRP is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // The ChargedParticles Contract Address\n address public _chargedParticles;\n\n // The Lepton NFT Contract Address\n address public _multiplierNft;\n\n // Asset Token => Reward Program\n mapping (address => address) internal _assetRewardPrograms;\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\n\n // Token UUID => NFT Staking Data\n mapping (uint256 => NftStake) private _nftStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n function getRewardProgram(address asset) external view override returns (address) {\n return _getRewardProgram(asset);\n }\n\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\n return _nftStake[uuid];\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetDeposit(\n contractAddress,\n tokenId,\n walletManagerId,\n assetAmount\n );\n }\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\n }\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n // \"receiverEnergy\" includes the \"principalAmount\"\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n onlyOwner\n onlyValidContractAddress(controller)\n {\n _chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setMultiplierNft(address nftTokenAddress)\n external\n onlyOwner\n onlyValidContractAddress(nftTokenAddress)\n {\n _multiplierNft = nftTokenAddress;\n }\n\n function setRewardProgram(\n address rewardProgam,\n address assetToken\n )\n external\n onlyOwner\n onlyValidContractAddress(rewardProgam)\n {\n require(assetToken != address(0x0), \"UNI:E-403\");\n _assetRewardPrograms[assetToken] = rewardProgam;\n emit RewardProgramSet(assetToken, rewardProgam);\n }\n\n function removeRewardProgram(address assetToken) external onlyOwner {\n delete _assetRewardPrograms[assetToken];\n emit RewardProgramRemoved(assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getRewardProgram(address assetToken) internal view returns (address) {\n return _assetRewardPrograms[assetToken];\n }\n\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != depositNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n uint256 multiplier = _getNftMultiplier(depositNftAddress, depositNftTokenId);\n\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\n // Add to Multipliers Set\n _multiplierNftsSet[parentNftUuid].add(multiplier);\n\n // Update NFT Stake\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\n } else {\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\n }\n }\n\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\n }\n\n function _registerNftRelease(\n address contractAddress,\n uint256 tokenId,\n address releaseNftAddress,\n uint256 releaseNftTokenId,\n uint256 /* nftTokenAmount */\n )\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != releaseNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n NftStake storage nftStake = _nftStake[parentNftUuid];\n\n // Remove from Multipliers Set\n uint256 multiplier = _getNftMultiplier(releaseNftAddress, releaseNftTokenId);\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\n\n // Determine New Multiplier or Mark as Released\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\n } else {\n nftStake.releaseBlockNumber = block.number;\n }\n\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\n }\n\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\n uint256 multiplier = 0;\n uint256 loss = 50;\n uint256 i = 0;\n\n for (; i < len; i++) {\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\n }\n if (len > 1) {\n multiplier = multiplier.sub(loss.mul(len));\n }\n return multiplier;\n }\n\n function _getNftMultiplier(address contractAddress, uint256 tokenId) internal returns (uint256) {\n bytes4 fnSig = IRewardNft.getMultiplier.selector;\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n\n if (success) {\n return abi.decode(returnData, (uint256));\n } else {\n return 0;\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(_chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/vesting/VestingClaim7.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract VestingClaim7 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"VestingClaim7: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"VestingClaim7: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"VestingClaim7: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"VestingClaim7: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"VestingClaim7: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"VestingClaim7: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveSmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\nimport \"../../interfaces/IAaveBridge.sol\";\nimport \"../../lib/SmartWalletBase.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet for Aave Assets\n * @dev Non-upgradeable Contract\n */\ncontract AaveSmartWallet is SmartWalletBase {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 constant internal RAY = 1e27;\n\n IAaveBridge internal _bridge;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(\n address aaveBridge\n )\n public\n {\n SmartWalletBase.initializeBase();\n _bridge = IAaveBridge(aaveBridge);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _bridge.isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address) {\n return _bridge.getReserveInterestToken(assetToken);\n }\n\n function getPrincipal(address assetToken) external override returns (uint256) {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address assetToken) external override returns (uint256 creatorInterest, uint256 ownerInterest) {\n return _getInterest(assetToken);\n }\n\n function getTotal(address assetToken) external override returns (uint256) {\n return _getTotal(assetToken);\n }\n\n function getRewards(address rewardToken) external override returns (uint256) {\n return IERC20(rewardToken).balanceOf(address(this));\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _deposit(assetToken, assetAmount, referralCode);\n }\n\n\n function withdraw(\n address receiver,\n address creatorRedirect,\n address assetToken\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (, uint256 ownerInterest) = _getInterest(assetToken);\n return _withdraw(receiver, creatorRedirect, assetToken, walletPrincipal.add(ownerInterest));\n }\n\n function withdrawAmount(\n address receiver,\n address creatorRedirect,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return _withdraw(receiver, creatorRedirect, assetToken, assetAmount);\n }\n\n function withdrawAmountForCreator(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return _withdrawForCreator(receiver, assetToken, assetAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _withdrawRewards(receiver, rewardsToken, rewardsAmount);\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n internal\n returns (uint256)\n {\n _trackAssetToken(assetToken);\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n\n // Deposit Assets into Aave (reverts on fail)\n _sendToken(address(_bridge), assetToken, assetAmount);\n uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function _withdraw(\n address receiver,\n address creatorRedirect,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken);\n\n // Withdraw from Interest only\n if (assetAmount < ownerInterest) {\n if (creatorInterest > 0) {\n uint256 ratio = assetAmount.mul(RAY).div(ownerInterest);\n creatorAmount = creatorInterest.add(nftCreatorAmountDischarged).mul(ratio).div(RAY);\n\n if (creatorAmount <= nftCreatorAmountDischarged) {\n nftCreatorAmountDischarged = nftCreatorAmountDischarged.sub(creatorAmount);\n creatorAmount = 0;\n }\n\n else {\n creatorAmount = creatorAmount.sub(nftCreatorAmountDischarged);\n nftCreatorAmountDischarged = 0;\n }\n }\n receiverAmount = assetAmount;\n }\n\n // Withdraw from Interest + Principal\n else {\n uint256 fromPrincipal = assetAmount.sub(ownerInterest);\n if (fromPrincipal > walletPrincipal) {\n fromPrincipal = walletPrincipal.sub(ownerInterest);\n }\n\n creatorAmount = creatorInterest;\n receiverAmount = ownerInterest.add(fromPrincipal);\n nftCreatorAmountDischarged = 0;\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal);\n }\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount));\n\n // Withdraw Assets for Creator\n if (creatorAmount > 0) {\n address receivesForCreator = (creatorRedirect != address(0x0)) ? creatorRedirect : nftCreator;\n _bridge.withdraw(receivesForCreator, assetToken, creatorAmount);\n }\n\n // Withdraw Assets for Receiver\n _bridge.withdraw(receiver, assetToken, receiverAmount);\n }\n\n function _withdrawForCreator(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 receiverAmount)\n {\n (uint256 creatorInterest,) = _getInterest(assetToken);\n if (creatorInterest == 0) { return 0; }\n if (assetAmount > creatorInterest) {\n assetAmount = creatorInterest;\n }\n\n nftCreatorAmountDischarged = nftCreatorAmountDischarged.add(assetAmount);\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, assetAmount);\n\n // Withdraw Assets for Receiver on behalf of Creator\n _bridge.withdraw(receiver, assetToken, assetAmount);\n }\n\n function _withdrawRewards(\n address receiver,\n address rewardsTokenAddress,\n uint256 rewardsAmount\n )\n internal\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"ASW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function _getTotal(address assetToken) internal view returns (uint256) {\n return _bridge.getTotalBalance(address(this), assetToken);\n }\n\n function _getInterest(address assetToken) internal view returns (uint256 creatorInterest, uint256 ownerInterest) {\n uint256 total = _getTotal(assetToken);\n uint256 principal = _getPrincipal(assetToken);\n uint256 interest = total.sub(principal);\n\n // Creator Royalties\n if (nftCreatorAnnuityPct > 0) {\n\n // Interest too small to calculate percentage;\n if (interest <= PERCENTAGE_SCALE) {\n // creatorInterest = interest.div(2); // split evenly?\n creatorInterest = 0; // All to owner\n }\n\n // Calculate percentage for Creator\n else {\n creatorInterest = interest\n .add(nftCreatorAmountDischarged)\n .mul(nftCreatorAnnuityPct)\n .div(PERCENTAGE_SCALE)\n .sub(nftCreatorAmountDischarged);\n }\n }\n\n // Owner Portion\n ownerInterest = interest.sub(creatorInterest);\n }\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveSmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\nimport \"../../interfaces/IAaveBridge.sol\";\nimport \"../../lib/SmartWalletBaseB.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet for Aave Assets\n * @dev Non-upgradeable Contract\n */\ncontract AaveSmartWalletB is SmartWalletBaseB {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 constant internal RAY = 1e27;\n\n IAaveBridge internal _bridge;\n\n uint256 internal _nftCreatorAmountDischarged;\n\n mapping (address => address) internal _assetATokens;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(\n address aaveBridge\n )\n public\n {\n SmartWalletBaseB.initializeBase();\n _bridge = IAaveBridge(aaveBridge);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _bridge.isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address) {\n return _bridge.getReserveInterestToken(assetToken);\n }\n\n function getPrincipal(address assetToken) external override returns (uint256) {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address assetToken, uint256 creatorPct) external override returns (uint256 creatorInterest, uint256 ownerInterest) {\n return _getInterest(assetToken, creatorPct);\n }\n\n function getTotal(address assetToken) external override returns (uint256) {\n return _getTotal(assetToken);\n }\n\n function getRewards(address rewardToken) external override returns (uint256) {\n return IERC20(rewardToken).balanceOf(address(this));\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _deposit(assetToken, assetAmount, referralCode);\n }\n\n\n function withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (, uint256 ownerInterest) = _getInterest(assetToken, creatorPct);\n return _withdraw(receiver, creator, creatorPct, assetToken, walletPrincipal.add(ownerInterest));\n }\n\n function withdrawAmount(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return _withdraw(receiver, creator, creatorPct, assetToken, assetAmount);\n }\n\n function withdrawAmountForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return _withdrawForCreator(receiver, creatorPct, assetToken, assetAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _withdrawRewards(receiver, rewardsToken, rewardsAmount);\n }\n\n function refreshPrincipal(address assetToken) external virtual override onlyWalletManager {\n uint256 aTokenBalance = IERC20(_assetATokens[assetToken]).balanceOf(address(this));\n if (_assetPrincipalBalance[assetToken] > aTokenBalance) {\n _assetPrincipalBalance[assetToken] = aTokenBalance;\n }\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n internal\n returns (uint256)\n {\n _trackAssetToken(assetToken);\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n\n // Deposit Assets into Aave (reverts on fail)\n _sendToken(address(_bridge), assetToken, assetAmount);\n uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function _withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken, creatorPct);\n\n // Withdraw from Interest only\n if (assetAmount < ownerInterest) {\n if (creatorInterest > 0) {\n uint256 ratio = assetAmount.mul(RAY).div(ownerInterest);\n creatorAmount = creatorInterest.add(_nftCreatorAmountDischarged).mul(ratio).div(RAY);\n\n if (creatorAmount <= _nftCreatorAmountDischarged) {\n _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.sub(creatorAmount);\n creatorAmount = 0;\n }\n else {\n creatorAmount = creatorAmount.sub(_nftCreatorAmountDischarged);\n _nftCreatorAmountDischarged = 0;\n }\n }\n receiverAmount = assetAmount;\n }\n\n // Withdraw from Interest + Principal\n else {\n uint256 fromPrincipal = assetAmount.sub(ownerInterest);\n if (fromPrincipal > walletPrincipal) {\n fromPrincipal = walletPrincipal.sub(ownerInterest);\n }\n\n creatorAmount = creatorInterest;\n receiverAmount = ownerInterest.add(fromPrincipal);\n _nftCreatorAmountDischarged = 0;\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal);\n }\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount));\n\n // Withdraw Assets for Creator\n if (creatorAmount > 0) {\n if (creator != address(0)) {\n _bridge.withdraw(creator, assetToken, creatorAmount);\n } else {\n receiverAmount = receiverAmount.add(creatorAmount);\n creatorAmount = 0;\n }\n }\n\n // Withdraw Assets for Receiver\n _bridge.withdraw(receiver, assetToken, receiverAmount);\n }\n\n function _withdrawForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 receiverAmount)\n {\n (uint256 creatorInterest,) = _getInterest(assetToken, creatorPct);\n if (creatorInterest == 0) { return 0; }\n if (assetAmount > creatorInterest) {\n assetAmount = creatorInterest;\n }\n\n _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.add(assetAmount);\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, assetAmount);\n\n // Withdraw Assets for Receiver on behalf of Creator\n _bridge.withdraw(receiver, assetToken, assetAmount);\n }\n\n function _withdrawRewards(\n address receiver,\n address rewardsTokenAddress,\n uint256 rewardsAmount\n )\n internal\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"ASW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function _getTotal(address assetToken) internal view returns (uint256) {\n return _bridge.getTotalBalance(address(this), assetToken);\n }\n\n function _getInterest(address assetToken, uint256 creatorPct) internal view returns (uint256 creatorInterest, uint256 ownerInterest) {\n uint256 total = _getTotal(assetToken);\n uint256 principal = _getPrincipal(assetToken);\n uint256 interest = total.sub(principal);\n\n // Creator Royalties\n if (creatorPct > 0) {\n\n // Interest too small to calculate percentage;\n if (interest <= PERCENTAGE_SCALE) {\n // creatorInterest = interest.div(2); // split evenly?\n creatorInterest = 0; // All to owner\n }\n\n // Calculate percentage for Creator\n else {\n creatorInterest = interest\n .add(_nftCreatorAmountDischarged)\n .mul(creatorPct)\n .div(PERCENTAGE_SCALE)\n .sub(_nftCreatorAmountDischarged);\n }\n }\n\n // Owner Portion\n ownerInterest = interest.sub(creatorInterest);\n }\n\n function _trackAssetToken(address assetToken) internal override {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _assetATokens[assetToken] = aTokenAddress;\n }\n }\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../lib/WalletManagerBase.sol\";\n\nimport \"./AaveSmartWallet.sol\";\n\n/**\n * @notice Wallet Manager for Aave\n * @dev Non-upgradeable Contract\n */\ncontract AaveWalletManager is WalletManagerBase {\n using SafeMath for uint256;\n\n event AaveBridgeSet(address indexed aaveBridge);\n event ValidRewardsTokenSet(address indexed rewardsToken, bool state);\n\n address internal _aaveBridge;\n uint256 internal _referralCode;\n\n mapping (address => bool) public rewardsTokenWhitelist;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new AaveSmartWallet());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return AaveSmartWallet(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return AaveSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return AaveSmartWallet(_wallets[uuid]).getInterest(assetToken);\n }\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getTotal(assetToken);\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getRewards(_rewardToken);\n }\n\n\n /***********************************|\n | Only Controller |\n |__________________________________*/\n\n function energize(\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = AaveSmartWallet(wallet).deposit(assetToken, assetAmount, _referralCode);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(ownerInterest > 0, \"AWM:E-412\");\n\n // Discharge the full amount of interest\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, ownerInterest);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(assetAmount > 0 && ownerInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmountForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address creator,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (uint256 creatorInterest,) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(assetAmount > 0 && creatorInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n receiverAmount = AaveSmartWallet(wallet).withdrawAmountForCreator(receiver, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount);\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = AaveSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0;\n\n // Release from interest first + principal if needed\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n require(rewardsTokenWhitelist[rewardsToken], \"AWM:E-423\");\n\n // Withdraw Rewards to Receiver\n amount = AaveSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 tokenId,\n address externalAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return AaveSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n // no-op\n }\n\n function getWalletAddressById(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPct\n )\n external\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n\n if (creator != address(0x0)) {\n AaveSmartWallet(wallet).setNftCreator(creator, annuityPct);\n }\n\n emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAaveBridge(address aaveBridge) external onlyOwner {\n require(aaveBridge != address(0x0), \"AWM:E-403\");\n _aaveBridge = aaveBridge;\n emit AaveBridgeSet(aaveBridge);\n }\n\n // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool\n function setReferralCode(uint256 referralCode) external onlyOwner {\n _referralCode = referralCode;\n }\n\n function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner {\n rewardsTokenWhitelist[rewardsToken] = state;\n emit ValidRewardsTokenSet(rewardsToken, state);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n AaveSmartWallet(newWallet).initialize(_aaveBridge);\n return newWallet;\n }\n}" + }, + "contracts/v1/yield/aave/AaveWalletManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../lib/WalletManagerBase.sol\";\nimport \"../../interfaces/IChargedSettings.sol\";\nimport \"./AaveSmartWalletB.sol\";\n\n/**\n * @notice Wallet Manager for Aave\n * @dev Non-upgradeable Contract\n */\ncontract AaveWalletManagerB is WalletManagerBase {\n using SafeMath for uint256;\n\n event AaveBridgeSet(address indexed aaveBridge);\n event ChargedSettingsSet(address indexed settings);\n event ValidRewardsTokenSet(address indexed rewardsToken, bool state);\n\n IChargedSettings internal _chargedSettings;\n\n address internal _aaveBridge;\n uint256 internal _referralCode;\n\n mapping (address => bool) public _rewardsTokenWhitelist;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new AaveSmartWalletB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return AaveSmartWalletB(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return AaveSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n return AaveSmartWalletB(_wallets[uuid]).getInterest(assetToken, annuityPct);\n }\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getTotal(assetToken);\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getRewards(_rewardToken);\n }\n\n\n /***********************************|\n | Only Controller |\n |__________________________________*/\n\n function energize(\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = AaveSmartWalletB(wallet).deposit(assetToken, assetAmount, _referralCode);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(ownerInterest > 0, \"AWM:E-412\");\n\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Discharge the full amount of interest\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, ownerInterest);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(assetAmount > 0 && ownerInterest >= assetAmount, \"AWM:E-412\");\n\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Discharge a portion of the interest\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmountForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address creator,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (uint256 creatorInterest,) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(assetAmount > 0 && creatorInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n receiverAmount = AaveSmartWalletB(wallet).withdrawAmountForCreator(receiver, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount);\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Release Principal + Interest\n principalAmount = AaveSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdraw(receiver, creator, annuityPct, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0;\n\n // Release from interest first + principal if needed\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n require(_rewardsTokenWhitelist[rewardsToken], \"AWM:E-423\");\n\n // Withdraw Rewards to Receiver\n amount = AaveSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 tokenId,\n address externalAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return AaveSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n AaveSmartWalletB(wallet).refreshPrincipal(assetToken);\n }\n\n function getWalletAddressById(\n address contractAddress,\n uint256 tokenId,\n address /* creator */,\n uint256 /* annuityPct */\n )\n external\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAaveBridge(address aaveBridge) external onlyOwner {\n require(aaveBridge != address(0x0), \"AWM:E-403\");\n _aaveBridge = aaveBridge;\n emit AaveBridgeSet(aaveBridge);\n }\n\n function setChargedSettings(address settings) external onlyOwner {\n require(settings != address(0x0), \"AWM:E-403\");\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool\n function setReferralCode(uint256 referralCode) external onlyOwner {\n _referralCode = referralCode;\n }\n\n function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner {\n _rewardsTokenWhitelist[rewardsToken] = state;\n emit ValidRewardsTokenSet(rewardsToken, state);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n AaveSmartWalletB(newWallet).initialize(_aaveBridge);\n return newWallet;\n }\n}" + }, + "contracts/v1/yield/aave/v2/AaveBridgeV2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveBridgeV2.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/SafeCast.sol\";\n\nimport \"./IATokenV2.sol\";\nimport \"./ILendingPoolV2.sol\";\nimport \"./ILendingPoolAddressesProviderV2.sol\";\n\nimport \"../../../interfaces/IAaveBridge.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\n\ncontract AaveBridgeV2 is Ownable, IAaveBridge, BlackholePrevention {\n using SafeMath for uint256;\n using SafeCast for uint256;\n using SafeERC20 for IERC20;\n using ReserveLogic for ReserveLogic.ReserveData;\n\n ILendingPoolAddressesProviderV2 public provider;\n ILendingPoolV2 public lendingPool;\n\n constructor (address lendingPoolProvider) public {\n provider = ILendingPoolAddressesProviderV2(lendingPoolProvider);\n lendingPool = ILendingPoolV2(provider.getLendingPool());\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address aTokenAddress) {\n return _getReserveInterestToken(assetToken);\n }\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _isReserveActive(assetToken);\n }\n\n function getTotalBalance(address account, address assetToken) external view override returns (uint256) {\n address aTokenAddress = _getReserveInterestToken(assetToken);\n if (aTokenAddress == address(0x0)) { return 0; }\n return IATokenV2(aTokenAddress).balanceOf(account);\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n returns (uint256)\n {\n address self = address(this);\n address aTokenAddress = _getReserveInterestToken(assetToken);\n require(_isReserveActive(assetToken), \"ABV2:E-424\");\n\n IERC20 token = IERC20(assetToken);\n IATokenV2 aToken = IATokenV2(aTokenAddress);\n\n if (token.allowance(address(this), address(lendingPool)) < assetAmount) {\n token.approve(address(lendingPool), uint256(-1));\n }\n\n // Deposit Assets into Aave\n uint256 preBalance = aToken.balanceOf(self);\n lendingPool.deposit(assetToken, assetAmount, self, referralCode.toUint16());\n uint256 postBalance = aToken.balanceOf(self);\n uint256 aTokensAmount = postBalance.sub(preBalance);\n\n // Transfer back the Interest Tokens\n _sendToken(msg.sender, aTokenAddress, aTokensAmount);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function withdraw(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n {\n address self = address(this);\n require(_isReserveActive(assetToken), \"ABV2:E-424\");\n\n // Redeem aTokens for Asset Tokens\n lendingPool.withdraw(assetToken, assetAmount, self);\n\n // Transfer back the Asset Tokens\n _sendToken(receiver, assetToken, assetAmount);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n\n function _getReserveInterestToken(address assetToken) internal view returns (address aTokenAddress) {\n ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken);\n return config.aTokenAddress;\n }\n\n function _isReserveActive(address assetToken) internal view returns (bool) {\n ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken);\n uint256 isActiveFlag = 2 ** 56; // bit 56: reserve is active\n return (config.configuration.data & isActiveFlag) == isActiveFlag;\n }\n}\n" + }, + "contracts/v1/yield/aave/v2/IATokenV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\n\ninterface IATokenV2 {\n function balanceOf(address account) external view returns (uint256);\n}\n" + }, + "contracts/v1/yield/aave/v2/ILendingPoolAddressesProviderV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\n\ninterface ILendingPoolAddressesProviderV2 {\n function getLendingPool() external view returns (address);\n}" + }, + "contracts/v1/yield/aave/v2/ILendingPoolV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport \"./ILendingPoolAddressesProviderV2.sol\";\n\nlibrary ReserveConfiguration {\n struct Map {\n uint256 data;\n }\n}\n\nlibrary ReserveLogic {\n struct ReserveData {\n ReserveConfiguration.Map configuration;\n uint128 liquidityIndex;\n uint128 variableBorrowIndex;\n uint128 currentLiquidityRate;\n uint128 currentVariableBorrowRate;\n uint128 currentStableBorrowRate;\n uint40 lastUpdateTimestamp;\n address aTokenAddress;\n address stableDebtTokenAddress;\n address variableDebtTokenAddress;\n address interestRateStrategyAddress;\n uint8 id;\n }\n}\n\ninterface ILendingPoolV2 {\n function deposit(address reserve, uint256 amount, address onBehalfOf, uint16 referralCode) external;\n function withdraw(address reserve, uint256 amount, address to) external;\n function getReserveData(address asset) external view returns (ReserveLogic.ReserveData memory);\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericSmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"../../../lib/SmartWalletBase.sol\";\n\n\n/**\n * @notice Generic ERC20-Token Smart-Wallet Bridge\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartWallet is SmartWalletBase {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize()\n public\n {\n SmartWalletBase.initializeBase();\n }\n\n function isReserveActive(address assetToken)\n external\n override\n view\n returns (bool)\n {\n return _getPrincipal(assetToken) == 0;\n }\n\n function getReserveInterestToken(address assetToken)\n external\n override\n view\n returns (address)\n {\n return assetToken;\n }\n\n function getPrincipal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address /* assetToken */)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n return (0, 0);\n }\n\n function getTotal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getRewards(address assetToken)\n external\n override\n returns (uint256)\n {\n return IERC20(assetToken).balanceOf(address(this));\n }\n\n function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n // Track Principal\n _trackAssetToken(assetToken);\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n }\n\n function withdraw(address receiver, address /* creatorRedirect */, address assetToken)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmount(address receiver, address /* creatorRedirect */, address assetToken, uint256 assetAmount)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n if (receiverAmount >= assetAmount) {\n receiverAmount = assetAmount;\n }\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmountForCreator(\n address /* receiver */,\n address /* assetToken */,\n uint256 /* assetID */\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericSmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWalletB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"../../../lib/SmartWalletBaseB.sol\";\n\n\n/**\n * @notice Generic ERC20-Token Smart-Wallet Bridge\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartWalletB is SmartWalletBaseB {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize()\n public\n {\n SmartWalletBaseB.initializeBase();\n }\n\n function isReserveActive(address assetToken)\n external\n override\n view\n returns (bool)\n {\n return _getPrincipal(assetToken) == 0;\n }\n\n function getReserveInterestToken(address assetToken)\n external\n override\n view\n returns (address)\n {\n return assetToken;\n }\n\n function getPrincipal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address /* assetToken */, uint256 /* creatorPct */)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n return (0, 0);\n }\n\n function getTotal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getRewards(address assetToken)\n external\n override\n returns (uint256)\n {\n return IERC20(assetToken).balanceOf(address(this));\n }\n\n function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n // Track Principal\n _trackAssetToken(assetToken);\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n }\n\n function withdraw(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmount(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken, uint256 assetAmount)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n if (receiverAmount >= assetAmount) {\n receiverAmount = assetAmount;\n }\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmountForCreator(\n address /* receiver */,\n uint256 /* creatorPct */,\n address /* assetToken */,\n uint256 /* assetID */\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function refreshPrincipal(address assetToken) external virtual override onlyWalletManager {\n _assetPrincipalBalance[assetToken] = IERC20(assetToken).balanceOf(address(this));\n }\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../../lib/WalletManagerBase.sol\";\nimport \"./GenericSmartWallet.sol\";\n\n/**\n * @notice Generic ERC20 Wallet Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericWalletManager is WalletManagerBase {\n using SafeMath for uint256;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new GenericSmartWallet());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return GenericSmartWallet(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return GenericSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getTotal(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return GenericSmartWallet(_wallets[uuid]).getInterest(assetToken);\n }\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getRewards(rewardToken);\n }\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount)\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = GenericSmartWallet(wallet).deposit(assetToken, assetAmount, 0);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmountForCreator(\n address /* receiver */,\n address /* contractAddress */,\n uint256 /* tokenId */,\n address /* creator */,\n address /* assetToken */,\n uint256 /* assetAmount */\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release from interest first + principal if needed\n principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n external\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return GenericSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n // no-op\n }\n\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct)\n external\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n\n if (creator != address(0x0)) {\n GenericSmartWallet(wallet).setNftCreator(creator, annuityPct);\n }\n\n emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n GenericSmartWallet(newWallet).initialize();\n return newWallet;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericWalletManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericWalletManagerB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../../lib/WalletManagerBase.sol\";\nimport \"./GenericSmartWalletB.sol\";\n\n/**\n * @notice Generic ERC20 Wallet Manager B\n * @dev Non-upgradeable Contract\n */\ncontract GenericWalletManagerB is WalletManagerBase {\n using SafeMath for uint256;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new GenericSmartWalletB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return GenericSmartWalletB(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return GenericSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getTotal(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return GenericSmartWalletB(_wallets[uuid]).getInterest(assetToken, 0);\n }\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getRewards(rewardToken);\n }\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount)\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = GenericSmartWalletB(wallet).deposit(assetToken, assetAmount, 0);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmountForCreator(\n address /* receiver */,\n address /* contractAddress */,\n uint256 /* tokenId */,\n address /* creator */,\n address /* assetToken */,\n uint256 /* assetAmount */\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdraw(receiver, creatorRedirect, 0, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release from interest first + principal if needed\n principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdrawAmount(receiver, creatorRedirect, 0, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyControllerOrExecutor\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n external\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return GenericSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n GenericSmartWalletB(wallet).refreshPrincipal(assetToken);\n }\n\n function getWalletAddressById(address contractAddress, uint256 tokenId, address /* creator */, uint256 /* annuityPct */)\n external\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n GenericSmartWalletB(newWallet).initialize();\n return newWallet;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericBasketManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"../../../interfaces/IBasketManager.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"./GenericSmartBasket.sol\";\n\n/**\n * @notice Generic ERC721 Basket Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericBasketManager is Ownable, BlackholePrevention, IBasketManager {\n using Counters for Counters.Counter;\n using TokenInfo for address;\n\n // The Controller Contract Address\n address internal _controller;\n\n // Template Contract for creating Token Smart-Baskets\n address internal _basketTemplate;\n\n // TokenID => Token Smart-Basket Address\n mapping (uint256 => address) internal _baskets;\n\n mapping (uint256 => Counters.Counter) internal _totalTokens;\n\n // State of Basket Manager\n bool internal _paused;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _basketTemplate = address(new GenericSmartBasket());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n function getTokenTotalCount(\n address contractAddress,\n uint256 tokenId\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n return _totalTokens[uuid].current();\n }\n\n function getTokenCountByType(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n external\n override\n returns (uint256)\n {\n address basket = getBasketAddressById(contractAddress, tokenId);\n return GenericSmartBasket(basket).getTokenCountByType(basketTokenAddress, basketTokenId);\n }\n\n function prepareTransferAmount(uint256 /* nftTokenAmount */) external override onlyController {\n // no-op\n }\n\n function addToBasket(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n whenNotPaused\n returns (bool added)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n added = GenericSmartBasket(basket).addToBasket(basketTokenAddress, basketTokenId);\n\n // Log Event\n if (added) {\n _totalTokens[uuid].increment();\n emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, 1);\n }\n }\n\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n returns (bool removed)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n removed = GenericSmartBasket(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId);\n\n // Log Event\n if (removed) {\n _totalTokens[uuid].decrement();\n emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, 1);\n }\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyController\n returns (uint256 amount)\n {\n // no-op\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n public\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n return GenericSmartBasket(basket).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function getBasketAddressById(address contractAddress, uint256 tokenId)\n public\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n // Create Smart-Basket if none exists\n if (basket == address(0x0)) {\n basket = _createBasket();\n _baskets[uuid] = basket;\n\n emit NewSmartBasket(contractAddress, tokenId, basket);\n }\n\n return basket;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Basket Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartBasket(basket).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n function _createBasket()\n internal\n returns (address)\n {\n address newBasket = _createClone(_basketTemplate);\n GenericSmartBasket(newBasket).initialize();\n return newBasket;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"GBM:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"GBM:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericBasketManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport \"../../../interfaces/IBasketManager.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../interfaces/ITokenInfoProxy.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"../../../lib/NftTokenType.sol\";\nimport \"./GenericSmartBasketB.sol\";\n\n/**\n * @notice Generic ERC721 Basket Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericBasketManagerB is Ownable, BlackholePrevention, IBasketManager {\n using Counters for Counters.Counter;\n using TokenInfo for address;\n using NftTokenType for address;\n\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // The Controller Contract Address\n address internal _controller;\n\n // The Executor Contract Address\n address internal _executor;\n\n // Template Contract for creating Token Smart-Baskets\n address internal _basketTemplate;\n\n // TokenID => Token Smart-Basket Address\n mapping (uint256 => address) internal _baskets;\n\n // Prepared Amount\n uint256 internal _preparedAmount;\n\n // State of Basket Manager\n bool internal _paused;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _basketTemplate = address(new GenericSmartBasketB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n function getTokenTotalCount(\n address contractAddress,\n uint256 tokenId\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n if (basket == address(0)) { return 0; }\n return GenericSmartBasketB(basket).getNestedNftCount();\n }\n\n function getTokenCountByType(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n if (basket == address(0)) { return 0; }\n return GenericSmartBasketB(basket).getTokenCountByType(basketTokenAddress, basketTokenId);\n }\n\n function prepareTransferAmount(uint256 nftTokenAmount) external override onlyController {\n _preparedAmount = nftTokenAmount;\n }\n\n function addToBasket(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n whenNotPaused\n returns (bool added)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n uint256 nftTokenAmount = 1;\n if (_preparedAmount > 0) {\n nftTokenAmount = _preparedAmount;\n _preparedAmount = 0;\n }\n\n added = GenericSmartBasketB(basket).addToBasket(basketTokenAddress, basketTokenId, nftTokenAmount);\n if (added) {\n emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount);\n }\n }\n\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n returns (bool removed)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n uint256 nftTokenAmount = 1;\n if (_preparedAmount > 0) {\n nftTokenAmount = _preparedAmount;\n _preparedAmount = 0;\n }\n\n removed = GenericSmartBasketB(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId, nftTokenAmount);\n if (removed) {\n emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount);\n }\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyControllerOrExecutor\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartBasketB(basket).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit BasketRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n public\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n return GenericSmartBasketB(basket).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function getBasketAddressById(address contractAddress, uint256 tokenId)\n public\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n // Create Smart-Basket if none exists\n if (basket == address(0x0)) {\n basket = _createBasket();\n _baskets[uuid] = basket;\n\n emit NewSmartBasket(contractAddress, tokenId, basket);\n }\n\n return basket;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Basket Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n /**\n * @dev Connects to the ExecForAccount Controller\n */\n function setExecutor(address executor) external onlyOwner {\n _executor = executor;\n emit ExecutorSet(executor);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setTokenInfoProxy(address tokenInfoProxy) external onlyOwner {\n _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartBasket(basket).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createBasket()\n internal\n returns (address)\n {\n address newBasket = _createClone(_basketTemplate);\n GenericSmartBasketB(newBasket).initialize(_tokenInfoProxy);\n return newBasket;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"GBM:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Controller or Executor contract\n modifier onlyControllerOrExecutor() {\n require(_executor == msg.sender || _controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"GBM:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericSmartBasket.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/NftTokenType.sol\";\n\n\n/**\n * @notice Generic ERC721-Token Smart-Basket\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartBasket is ISmartBasket, BlackholePrevention, IERC721Receiver {\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableSet for EnumerableSet.AddressSet;\n using NftTokenType for address;\n\n address internal _basketManager;\n\n // NFT contract address => Token Ids in Basket\n mapping (address => mapping(uint256 => EnumerableSet.UintSet)) internal _nftContractTokens;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public {\n require(_basketManager == address(0x0), \"GSB:E-002\");\n _basketManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n return _nftContractTokens[contractAddress][nftType].length();\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver(0).onERC721Received.selector;\n }\n\n function addToBasket(address contractAddress, uint256 tokenId)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n require(!_nftContractTokens[contractAddress][nftType].contains(tokenId), \"GSB:E-425\");\n\n bool added = _nftContractTokens[contractAddress][nftType].add(tokenId);\n if (added) {\n // NFT should have been Transferred into here via Charged-Particles\n added = (IERC721(contractAddress).ownerOf(tokenId) == address(this));\n }\n return added;\n }\n\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n require(_nftContractTokens[contractAddress][nftType].contains(tokenId), \"GSB:E-426\");\n\n bool removed = _nftContractTokens[contractAddress][nftType].remove(tokenId);\n if (removed) {\n IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId);\n }\n return removed;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyBasketManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the basket manager\n modifier onlyBasketManager() {\n require(_basketManager == msg.sender, \"GSB:E-109\");\n _;\n }\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericSmartBasketB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155Receiver.sol\";\nimport \"../../../interfaces/ISmartBasketB.sol\";\nimport \"../../../interfaces/ITokenInfoProxy.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"../../../lib/NftTokenType.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\n\n/**\n * @notice Generic ERC721-Token Smart-Basket\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartBasketB is ISmartBasketB, BlackholePrevention, IERC721Receiver, ERC1155Receiver {\n using TokenInfo for address;\n using NftTokenType for address;\n\n address internal _basketManager;\n\n // NFT TokenUUID => ERC1155 Balance\n mapping (uint256 => uint256) internal _nftContractTokenBalance;\n uint256 internal _nestedNftCount;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(ITokenInfoProxy /* tokenInfoProxy */) public {\n require(_basketManager == address(0x0), \"GSB:E-002\");\n _basketManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getNestedNftCount() external view override returns (uint256) {\n return _nestedNftCount;\n }\n\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n return _nftContractTokenBalance[contractAddress.getTokenUUID(tokenId)];\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver(0).onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\n return IERC1155Receiver(0).onERC1155Received.selector;\n }\n\n // Unimplemented\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\n return \"\"; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector;\n }\n\n function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n _nftContractTokenBalance[uuid] += nftTokenAmount;\n _nestedNftCount += nftTokenAmount;\n return true;\n }\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n uint256 nftTokenAmount\n )\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n _nftContractTokenBalance[uuid] -= nftTokenAmount;\n _nestedNftCount -= nftTokenAmount;\n\n if (contractAddress.isERC1155()) {\n IERC1155(contractAddress).safeTransferFrom(address(this), receiver, tokenId, nftTokenAmount, \"\");\n } else {\n IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId);\n }\n return true;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyBasketManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSB:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyBasketManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the basket manager\n modifier onlyBasketManager() {\n require(_basketManager == msg.sender, \"GSB:E-109\");\n _;\n }\n}\n" + }, + "erc20permit/contracts/ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"./IERC2612.sol\";\n\n/**\n * @author Georgios Konstantopoulos\n * @dev Extension of {ERC20} that allows token holders to use their tokens\n * without sending any transactions by setting {IERC20-allowance} with a\n * signature using the {permit} method, and then spend them via\n * {IERC20-transferFrom}.\n *\n * The {permit} signature mechanism conforms to the {IERC2612} interface.\n */\nabstract contract ERC20Permit is ERC20, IERC2612 {\n mapping (address => uint256) public override nonces;\n\n bytes32 public immutable PERMIT_TYPEHASH = keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public immutable DOMAIN_SEPARATOR;\n\n constructor(string memory name_, string memory symbol_) internal ERC20(name_, symbol_) {\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name_)),\n keccak256(bytes(\"1\")),\n chainId,\n address(this)\n )\n );\n }\n\n /**\n * @dev See {IERC2612-permit}.\n *\n * In cases where the free option is not a concern, deadline can simply be\n * set to uint(-1), so it should be seen as an optional parameter\n */\n function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {\n require(deadline >= block.timestamp, \"ERC20Permit: expired deadline\");\n\n bytes32 hashStruct = keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n amount,\n nonces[owner]++,\n deadline\n )\n );\n\n bytes32 hash = keccak256(\n abi.encodePacked(\n '\\x19\\x01',\n DOMAIN_SEPARATOR,\n hashStruct\n )\n );\n\n address signer = ecrecover(hash, v, r, s);\n require(\n signer != address(0) && signer == owner,\n \"ERC20Permit: invalid signature\"\n );\n\n _approve(owner, spender, amount);\n }\n}\n" + }, + "erc20permit/contracts/IERC2612.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC2612 standard as defined in the EIP.\n *\n * Adds the {permit} method, which can be used to change one's\n * {IERC20-allowance} without having to send a transaction, by signing a\n * message. This allows users to spend tokens without having to hold Ether.\n *\n * See https://eips.ethereum.org/EIPS/eip-2612.\n */\ninterface IERC2612 {\n /**\n * @dev Sets `amount` 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 * - `owner` cannot be the zero address.\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(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n /**\n * @dev Returns the current ERC2612 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" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "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/deployments/polygon/solcInputs/a3c560866d7e9e0d097f164180bfa9ae.json b/deployments/polygon/solcInputs/a3c560866d7e9e0d097f164180bfa9ae.json new file mode 100644 index 0000000..99c8c72 --- /dev/null +++ b/deployments/polygon/solcInputs/a3c560866d7e9e0d097f164180bfa9ae.json @@ -0,0 +1,458 @@ +{ + "language": "Solidity", + "sources": { + "@opengsn/gsn/contracts/BaseRelayRecipient.sol": { + "content": "// SPDX-License-Identifier:MIT\n// solhint-disable no-inline-assembly\npragma solidity ^0.6.2;\n\nimport \"./interfaces/IRelayRecipient.sol\";\n\n/**\n * A base contract to be inherited by any contract that want to receive relayed transactions\n * A subclass must use \"_msgSender()\" instead of \"msg.sender\"\n */\nabstract contract BaseRelayRecipient is IRelayRecipient {\n\n /*\n * Forwarder singleton we accept calls from\n */\n address public trustedForwarder;\n\n function isTrustedForwarder(address forwarder) public override view returns(bool) {\n return forwarder == trustedForwarder;\n }\n\n /**\n * return the sender of this call.\n * if the call came through our trusted forwarder, return the original sender.\n * otherwise, return `msg.sender`.\n * should be used in the contract anywhere instead of msg.sender\n */\n function _msgSender() internal override virtual view returns (address payable ret) {\n if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // so we trust that the last bytes of msg.data are the verified sender address.\n // extract sender address from the end of msg.data\n assembly {\n ret := shr(96,calldataload(sub(calldatasize(),20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n /**\n * return the msg.data of this call.\n * if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes\n * of the msg.data - so this method will strip those 20 bytes off.\n * otherwise, return `msg.data`\n * should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly\n * signing or hashing the\n */\n function _msgData() internal override virtual view returns (bytes memory ret) {\n if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // we copy the msg.data , except the last 20 bytes (and update the total length)\n assembly {\n let ptr := mload(0x40)\n // copy only size-20 bytes\n let size := sub(calldatasize(),20)\n // structure RLP data as \n mstore(ptr, 0x20)\n mstore(add(ptr,32), size)\n calldatacopy(add(ptr,64), 0, size)\n return(ptr, add(size,64))\n }\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "@opengsn/gsn/contracts/interfaces/IRelayRecipient.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.6.2;\n\n/**\n * a contract must implement this interface in order to support relayed transaction.\n * It is better to inherit the BaseRelayRecipient as its implementation.\n */\nabstract contract IRelayRecipient {\n\n /**\n * return if the forwarder is trusted to forward relayed transactions to us.\n * the forwarder is required to verify the sender's signature, and verify\n * the call is not a replay.\n */\n function isTrustedForwarder(address forwarder) public virtual view returns(bool);\n\n /**\n * return the sender of this call.\n * if the call came through our trusted forwarder, then the real sender is appended as the last 20 bytes\n * of the msg.data.\n * otherwise, return `msg.sender`\n * should be used in the contract anywhere instead of msg.sender\n */\n function _msgSender() internal virtual view returns (address payable);\n\n /**\n * return the msg.data of this call.\n * if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes\n * of the msg.data - so this method will strip those 20 bytes off.\n * otherwise, return `msg.data`\n * should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly\n * signing or hashing the\n */\n function _msgData() internal virtual view returns (bytes memory);\n\n function versionRecipient() external virtual view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\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 initializer {\n __Context_init_unchained();\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal initializer {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), 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 emit OwnershipTransferred(_owner, address(0));\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n function __ERC165_init() internal initializer {\n __ERC165_init_unchained();\n }\n\n function __ERC165_init_unchained() internal initializer {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMathUpgradeable {\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 uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\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 if (b > a) return (false, 0);\n return (true, a - b);\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 // 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 * @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 if (b == 0) return (false, 0);\n return (true, a / b);\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 if (b == 0) return (false, 0);\n return (true, a % b);\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 uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n return c;\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 require(b <= a, \"SafeMath: subtraction overflow\");\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 if (a == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n return c;\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. 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(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: division by zero\");\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 require(b > 0, \"SafeMath: modulo by zero\");\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n return a - b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a / b;\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.4.24 <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 {UpgradeableProxy-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 */\nabstract contract Initializable {\n\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 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 /// @dev Returns true if and only if the function is running in the constructor\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\n\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 )\n external\n 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 )\n external\n returns(bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC20Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../proxy/Initializable.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 guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable {\n using SafeMathUpgradeable for uint256;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal initializer {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer {\n _name = name_;\n _symbol = symbol_;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal virtual {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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(address sender, address recipient, uint256 amount) 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/ERC20/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.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 SafeERC20Upgradeable {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) 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(IERC20Upgradeable token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\n require((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(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\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(IERC20Upgradeable 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) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721MetadataUpgradeable.sol\";\nimport \"./IERC721EnumerableUpgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"../../introspection/ERC165Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/EnumerableSetUpgradeable.sol\";\nimport \"../../utils/EnumerableMapUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../proxy/Initializable.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable, IERC721EnumerableUpgradeable {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet;\n using EnumerableMapUpgradeable for EnumerableMapUpgradeable.UintToAddressMap;\n using StringsUpgradeable for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSetUpgradeable.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMapUpgradeable.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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 initializer {\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 initializer {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\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 _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\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 _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\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(_msgSender() == owner || ERC721Upgradeable.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 require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) 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(address from, address to, uint256 tokenId, bytes memory _data) 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 _tokenOwners.contains(tokenId);\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 || ERC721Upgradeable.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\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 _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(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); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(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(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721ReceiverUpgradeable(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); // internal owner\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(address from, address to, uint256 tokenId) internal virtual { }\n uint256[41] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721EnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 /**\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/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 /**\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\npragma solidity >=0.6.0 <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(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) 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 // solhint-disable-next-line avoid-low-level-calls\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(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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 // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/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 GSN 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 initializer {\n __Context_init_unchained();\n }\n\n function __Context_init_unchained() internal initializer {\n }\n function _msgSender() internal view virtual returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/EnumerableMapUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMapUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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 EnumerableSetUpgradeable {\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\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\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] = toDeleteIndex + 1; // All indexes are 1-based\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 require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\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 // 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 // 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" + }, + "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/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 initializer {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal initializer {\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 make 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/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n /**\n * @dev Converts a `uint256` to its ASCII `string` 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 uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = bytes1(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../GSN/Context.sol\";\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 */\ncontract 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 () internal {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), msgSender);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view 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 emit OwnershipTransferred(_owner, address(0));\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n" + }, + "@openzeppelin/contracts/cryptography/MerkleProof.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev These functions deal with verification of Merkle trees (hash trees),\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(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {\n bytes32 computedHash = leaf;\n\n for (uint256 i = 0; i < proof.length; i++) {\n bytes32 proofElement = proof[i];\n\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\n // Check if the computed hash (root) is equal to the provided root\n return computedHash == root;\n }\n}\n" + }, + "@openzeppelin/contracts/GSN/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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 GSN 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 payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\ncontract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () internal {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n" + }, + "@openzeppelin/contracts/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\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 uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\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 sub(a, b, \"SafeMath: subtraction overflow\");\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 * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\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 // 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) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts 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 mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\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 SafeMath for uint256;\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 * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri) public {\n _setURI(uri);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\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) external view 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 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(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\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 require(accounts[i] != address(0), \"ERC1155: batch balance query for the zero address\");\n batchBalances[i] = _balances[ids[i]][accounts[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 require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view 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 )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, 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 )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\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 _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(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 `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` 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(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, 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(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) 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 (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\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 `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, 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(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != 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, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\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 )\n internal virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).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 )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).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/token/ERC1155/ERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() public {\n _registerInterface(\n ERC1155Receiver(0).onERC1155Received.selector ^\n ERC1155Receiver(0).onERC1155BatchReceived.selector\n );\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\nimport \"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\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 )\n external\n 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 )\n external\n returns(bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.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 guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 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 {\n using SafeMath for uint256;\n using Address for address;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name, string memory symbol) public {\n _name = name;\n _symbol = symbol;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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/token/ERC20/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.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 SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\n require((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(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\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) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n\n // If there is no base URI, return the token URI.\n if (bytes(_baseURI).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(_baseURI, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(_baseURI, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_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 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 require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) 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(address from, address to, uint256 tokenId, bytes memory _data) 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 returns (bool) {\n return _tokenOwners.contains(tokenId);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = 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 d*\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\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 _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(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 = ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(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(address from, address to, uint256 tokenId) internal virtual {\n require(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 _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\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(address from, address to, uint256 tokenId) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\nimport \"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 /**\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/token/ERC721/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 /**\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/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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(address operator, address from, uint256 tokenId, bytes calldata data)\n external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 in 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 // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n return _functionCallWithValue(target, data, value, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\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 // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../math/SafeMath.sol\";\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented or decremented by one. 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 * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}\n * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never\n * directly accessed.\n */\nlibrary Counters {\n using SafeMath for uint256;\n\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 // The {SafeMath} overflow check can be skipped here, see the comment at the top\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableMap.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n return _get(map, key, \"EnumerableMap: nonexistent key\");\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(value)));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint256(value)));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint256(_get(map._inner, bytes32(key))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint256(_get(map._inner, bytes32(key), errorMessage)));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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.0.0, only sets of type `address` (`AddressSet`) and `uint256`\n * (`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\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\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] = toDeleteIndex + 1; // All indexes are 1-based\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 require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\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(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(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(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(uint256(_at(set._inner, index)));\n }\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" + }, + "@openzeppelin/contracts/utils/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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 */\ncontract 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 () internal {\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 make 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/utils/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value < 2**128, \"SafeCast: value doesn\\'t fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value < 2**64, \"SafeCast: value doesn\\'t fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value < 2**32, \"SafeCast: value doesn\\'t fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value < 2**16, \"SafeCast: value doesn\\'t fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value < 2**8, \"SafeCast: value doesn\\'t fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= -2**127 && value < 2**127, \"SafeCast: value doesn\\'t fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= -2**63 && value < 2**63, \"SafeCast: value doesn\\'t fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= -2**31 && value < 2**31, \"SafeCast: value doesn\\'t fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= -2**15 && value < 2**15, \"SafeCast: value doesn\\'t fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= -2**7 && value < 2**7, \"SafeCast: value doesn\\'t fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n require(value < 2**255, \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` 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 uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = byte(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n" + }, + "contracts/v1/ChargedManagers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Wallet-Managers Contract\n */\ncontract ChargedManagers is\n IChargedManagers,\n Initializable,\n OwnableUpgradeable,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n\n IChargedSettings internal _chargedSettings;\n IChargedState internal _chargedState;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // Wallet/Basket Managers (by Unique Manager ID)\n mapping (string => IWalletManager) internal _ftWalletManager;\n mapping (string => IBasketManager) internal _nftBasketManager;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n /// @notice Checks if an Account is the Owner of an NFT Contract\n /// When Custom Contracts are registered, only the \"owner\" or operator of the Contract\n /// is allowed to register them and define custom rules for how their tokens are \"Charged\".\n /// Otherwise, any token can be \"Charged\" according to the default rules of Charged Particles.\n /// @param contractAddress The Address to the External NFT Contract to check\n /// @param account The Account to check if it is the Owner of the specified Contract\n /// @return True if the account is the Owner of the _contract\n function isContractOwner(address contractAddress, address account) external view override virtual returns (bool) {\n return contractAddress.isContractOwner(account);\n }\n\n function isWalletManagerEnabled(string calldata walletManagerId) external virtual override view returns (bool) {\n return _isWalletManagerEnabled(walletManagerId);\n }\n\n function getWalletManager(string calldata walletManagerId) external virtual override view returns (IWalletManager) {\n return _ftWalletManager[walletManagerId];\n }\n\n function isNftBasketEnabled(string calldata basketId) external virtual override view returns (bool) {\n return _isNftBasketEnabled(basketId);\n }\n\n function getBasketManager(string calldata basketId) external virtual override view returns (IBasketManager) {\n return _nftBasketManager[basketId];\n }\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param sender The sender address to validate against\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external virtual override {\n _validateDeposit(sender, contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param sender The sender address to validate against\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external virtual override {\n _validateNftDeposit(sender, contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateDischarge(sender, contractAddress, tokenId);\n }\n\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateRelease(sender, contractAddress, tokenId);\n }\n\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateBreakBond(sender, contractAddress, tokenId);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"state\"))) {\n _chargedState = IChargedState(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n /// @dev Register Contracts as wallet managers with a unique liquidity provider ID\n function registerWalletManager(string calldata walletManagerId, address walletManager) external virtual onlyOwner {\n // Validate wallet manager\n IWalletManager newWalletMgr = IWalletManager(walletManager);\n require(newWalletMgr.isPaused() != true, \"CP:E-418\");\n\n // Register LP ID\n _ftWalletManager[walletManagerId] = newWalletMgr;\n emit WalletManagerRegistered(walletManagerId, walletManager);\n }\n\n /// @dev Register Contracts as basket managers with a unique basket ID\n function registerBasketManager(string calldata basketId, address basketManager) external virtual onlyOwner {\n // Validate basket manager\n IBasketManager newBasketMgr = IBasketManager(basketManager);\n require(newBasketMgr.isPaused() != true, \"CP:E-418\");\n\n // Register Basket ID\n _nftBasketManager[basketId] = newBasketMgr;\n emit BasketManagerRegistered(basketId, basketManager);\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev See {ChargedParticles-isWalletManagerEnabled}.\n function _isWalletManagerEnabled(string calldata walletManagerId) internal view virtual returns (bool) {\n return (address(_ftWalletManager[walletManagerId]) != address(0x0) && !_ftWalletManager[walletManagerId].isPaused());\n }\n\n /// @dev See {ChargedParticles-isNftBasketEnabled}.\n function _isNftBasketEnabled(string calldata basketId) internal view virtual returns (bool) {\n return (address(_nftBasketManager[basketId]) != address(0x0) && !_nftBasketManager[basketId].isPaused());\n }\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n internal\n virtual\n {\n if (_chargedState.isEnergizeRestricted(contractAddress, tokenId)) {\n bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender);\n require(isNFTOwnerOrOperator, \"CP:E-105\");\n }\n\n ( string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n ) = _chargedSettings.getAssetRequirements(contractAddress, assetToken);\n\n require(energizeEnabled, \"CP:E-417\");\n\n require(!invalidAsset, \"CP:E-424\");\n\n // Valid Wallet Manager?\n if (bytes(requiredWalletManager).length > 0) {\n require(keccak256(abi.encodePacked(requiredWalletManager)) == keccak256(abi.encodePacked(walletManagerId)), \"CP:E-419\");\n }\n\n // Valid Asset?\n if (restrictedAssets) {\n require(validAsset, \"CP:E-424\");\n }\n\n _validateDepositAmount(\n contractAddress,\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n depositCap,\n depositMin,\n depositMax\n );\n }\n\n /// @dev Validates a Deposit-Amount according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDepositAmount(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax\n )\n internal\n virtual\n {\n uint256 existingBalance = _ftWalletManager[walletManagerId].getPrincipal(contractAddress, tokenId, assetToken);\n uint256 newBalance = assetAmount.add(existingBalance);\n\n // Validate Deposit Cap\n if (depositCap > 0) {\n require(newBalance <= depositCap, \"CP:E-408\");\n }\n\n // Valid Amount for Deposit?\n if (depositMin > 0) {\n require(newBalance >= depositMin, \"CP:E-410\");\n }\n if (depositMax > 0) {\n require(newBalance <= depositMax, \"CP:E-410\");\n }\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n {\n // Prevent Ouroboros NFTs\n require(contractAddress.getTokenUUID(tokenId) != nftTokenAddress.getTokenUUID(nftTokenId), \"CP:E-433\");\n\n if (_chargedState.isCovalentBondRestricted(contractAddress, tokenId)) {\n bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender);\n require(isNFTOwnerOrOperator, \"CP:E-105\");\n }\n\n ( string memory requiredBasketManager,\n bool basketEnabled,\n uint256 maxNfts\n ) = _chargedSettings.getNftAssetRequirements(contractAddress, nftTokenAddress);\n\n require(basketEnabled, \"CP:E-417\");\n\n // Valid Basket Manager?\n if (bytes(requiredBasketManager).length > 0) {\n require(keccak256(abi.encodePacked(requiredBasketManager)) == keccak256(abi.encodePacked(basketManagerId)), \"CP:E-419\");\n }\n\n if (maxNfts > 0) {\n uint256 tokenCount = _nftBasketManager[basketManagerId].getTokenTotalCount(contractAddress, tokenId);\n require(maxNfts >= (tokenCount + nftTokenAmount), \"CP:E-427\");\n }\n }\n\n function _validateDischarge(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getDischargeState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateRelease(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getReleaseState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateBreakBond(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getBreakBondState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateState(\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n internal\n view\n virtual\n {\n if (!allowFromAll) {\n require(isApproved, \"CP:E-105\");\n }\n if (timelock > 0) {\n require(block.number >= timelock, \"CP:E-302\");\n }\n if (tempLockExpiry > 0) {\n require(block.number >= tempLockExpiry, \"CP:E-303\");\n }\n }\n}\n" + }, + "contracts/v1/ChargedParticles.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\n\nimport \"./interfaces/IUniverse.sol\";\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/IWalletManager.sol\";\nimport \"./interfaces/IBasketManager.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/RelayRecipient.sol\";\n\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles V2 Contract\n * @dev Upgradeable Contract\n */\ncontract ChargedParticles is\n IChargedParticles,\n Initializable,\n OwnableUpgradeable,\n ReentrancyGuardUpgradeable,\n RelayRecipient,\n IERC721ReceiverUpgradeable,\n BlackholePrevention,\n IERC1155ReceiverUpgradeable\n{\n using SafeMathUpgradeable for uint256;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using Bitwise for uint32;\n using AddressUpgradeable for address;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n //\n // Particle Terminology\n //\n // Particle - Non-fungible Token (NFT)\n // Mass - Underlying Asset of a Token (ex; DAI)\n // Charge - Accrued Interest on the Underlying Asset of a Token\n // Charged Particle - Any NFT that has a Mass and a Positive Charge\n // Neutral Particle - Any NFT that has a Mass and No Charge\n // Energize / Recharge - Deposit of an Underlying Asset into an NFT\n // Discharge - Withdraw the Accrued Interest of an NFT leaving the Particle with its initial Mass\n // Release - Withdraw the Underlying Asset & Accrued Interest of an NFT leaving the Particle with No Mass or Charge\n //\n // Proton - NFTs minted from the Charged Particle Accelerator\n // - A proton is a subatomic particle, symbol p or p⁺, with a positive electric charge of +1e elementary\n // charge and a mass slightly less than that of a neutron.\n // Ion - Platform Governance Token\n // - A charged subatomic particle. An atom or group of atoms that carries a positive or negative electric charge\n // as a result of having lost or gained one or more electrons.\n //\n\n // Linked Contracts\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n address internal _lepton;\n uint256 internal depositFee;\n ITokenInfoProxy internal _tokenInfoProxy;\n IChargedManagers internal _chargedManagers;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n __ReentrancyGuard_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getStateAddress() external view virtual override returns (address stateAddress) {\n return address(_chargedState);\n }\n\n function getSettingsAddress() external view virtual override returns (address settingsAddress) {\n return address(_chargedSettings);\n }\n\n function getManagersAddress() external view virtual override returns (address managersAddress) {\n return address(_chargedManagers);\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external virtual override returns (bytes4) {\n return IERC721ReceiverUpgradeable(0).onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external virtual override returns (bytes4) {\n return IERC1155ReceiverUpgradeable(0).onERC1155Received.selector;\n }\n\n // Unimplemented\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external virtual override returns (bytes4) {\n return \"\"; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector;\n }\n\n function supportsInterface(bytes4 /* interfaceId */) external view virtual override returns (bool) {\n return false;\n }\n\n /// @notice Calculates the amount of Fees to be paid for a specific deposit amount\n /// @param assetAmount The Amount of Assets to calculate Fees on\n /// @return protocolFee The amount of deposit fees for the protocol\n function getFeesForDeposit(\n uint256 assetAmount\n )\n external\n override\n view\n returns (uint256 protocolFee)\n {\n protocolFee = _getFeesForDeposit(assetAmount);\n }\n\n /// @notice Gets the Amount of Asset Tokens that have been Deposited into the Particle\n /// representing the Mass of the Particle.\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Asset balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The Amount of underlying Assets held within the Token\n function baseParticleMass(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _baseParticleMass(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the amount of Interest that the Particle has generated representing\n /// the Charge of the Particle\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Interest balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The amount of interest the Token has generated (in Asset Token)\n function currentParticleCharge(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _currentParticleCharge(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the amount of LP Tokens that the Particle has generated representing\n /// the Kinetics of the Particle\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Kinetics balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The amount of LP tokens that have been generated\n function currentParticleKinetics(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _currentParticleKinetics(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the total amount of ERC721 Tokens that the Particle holds\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param basketManagerId The ID of the BasketManager to check the token balance of\n /// @return The total amount of ERC721 tokens that are held within the Particle\n function currentParticleCovalentBonds(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId\n )\n external\n view\n virtual\n override\n basketEnabled(basketManagerId)\n returns (uint256)\n {\n return _currentParticleCovalentBonds(contractAddress, tokenId, basketManagerId);\n }\n\n\n /***********************************|\n | Energize Particles |\n |__________________________________*/\n\n /// @notice Fund Particle with Asset Token\n /// Must be called by the account providing the Asset\n /// Account must Approve THIS contract as Operator of Asset\n ///\n /// NOTE: DO NOT Energize an ERC20 Token, as anyone who holds any amount\n /// of the same ERC20 token could discharge or release the funds.\n /// All holders of the ERC20 token would essentially be owners of the Charged Particle.\n ///\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param walletManagerId The Asset-Pair to Energize the Token with\n /// @param assetToken The Address of the Asset Token being used\n /// @param assetAmount The Amount of Asset Token to Energize the Token with\n /// @return yieldTokensAmount The amount of Yield-bearing Tokens added to the escrow for the Token\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 yieldTokensAmount)\n {\n _validateDeposit(contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n\n // Transfer ERC20 Token from Caller to Contract (reverts on fail)\n uint256 feeAmount = _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n yieldTokensAmount = _depositIntoWalletManager(contractAddress, tokenId, walletManagerId, assetToken, assetAmount, feeAmount);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onEnergize(_msgSender(), referrer, contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n }\n\n\n /***********************************|\n | Discharge Particles |\n |__________________________________*/\n\n /// @notice Allows the owner or operator of the Token to collect or transfer the interest generated\n /// from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @return creatorAmount Amount of Asset Token discharged to the Creator\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateDischarge(contractAddress, tokenId);\n\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).discharge(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount);\n }\n }\n\n /// @notice Allows the owner or operator of the Token to collect or transfer a specific amount of the interest\n /// generated from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @param assetAmount The specific amount of Asset Token to Discharge from the Token\n /// @return creatorAmount Amount of Asset Token discharged to the Creator\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateDischarge(contractAddress, tokenId);\n\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).dischargeAmount(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n assetAmount,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount);\n }\n }\n\n /// @notice Allows the Creator of the Token to collect or transfer a their portion of the interest (if any)\n /// generated from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @param assetAmount The specific amount of Asset Token to Discharge from the Particle\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 receiverAmount)\n {\n address sender = _msgSender();\n address tokenCreator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId);\n require(sender == tokenCreator, \"CP:E-104\");\n\n receiverAmount = _chargedManagers.getWalletManager(walletManagerId).dischargeAmountForCreator(\n receiver,\n contractAddress,\n tokenId,\n sender,\n assetToken,\n assetAmount\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischargeForCreator(contractAddress, tokenId, walletManagerId, sender, assetToken, receiverAmount);\n }\n }\n\n\n /***********************************|\n | Release Particles |\n |__________________________________*/\n\n /// @notice Releases the Full amount of Asset + Interest held within the Particle by LP of the Assets\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Release\n /// @param tokenId The ID of the Token to Release\n /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token\n /// @param assetToken The Address of the Asset Token being released\n /// @return creatorAmount Amount of Asset Token released to the Creator\n /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount)\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateRelease(contractAddress, tokenId);\n\n // Release Particle to Receiver\n uint256 principalAmount;\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).release(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n }\n\n\n /// @notice Releases a partial amount of Asset + Interest held within the Particle by LP of the Assets\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Release\n /// @param tokenId The ID of the Token to Release\n /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token\n /// @param assetToken The Address of the Asset Token being released\n /// @param assetAmount The specific amount of Asset Token to Release from the Particle\n /// @return creatorAmount Amount of Asset Token released to the Creator\n /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount)\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateRelease(contractAddress, tokenId);\n\n // Release Particle to Receiver\n uint256 principalAmount;\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).releaseAmount(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n assetAmount,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n }\n\n\n /***********************************|\n | Covalent Bonding |\n |__________________________________*/\n\n /// @notice Deposit other NFT Assets into the Particle\n /// Must be called by the account providing the Asset\n /// Account must Approve THIS contract as Operator of Asset\n ///\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n basketEnabled(basketManagerId)\n nonReentrant\n returns (bool success)\n {\n _validateNftDeposit(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Transfer ERC721 Token from Caller to Contract (reverts on fail)\n _collectNftToken(_msgSender(), nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n success = _depositIntoBasketManager(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onCovalentBond(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n }\n\n /// @notice Release NFT Assets from the Particle\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Withdraw (ERC1155-specific)\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n basketEnabled(basketManagerId)\n nonReentrant\n returns (bool success)\n {\n _validateBreakBond(contractAddress, tokenId);\n\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked(\"generic\"))) {\n basketMgr.prepareTransferAmount(nftTokenAmount);\n }\n\n // Release Particle to Receiver\n success = basketMgr.removeFromBasket(\n receiver,\n contractAddress,\n tokenId,\n nftTokenAddress,\n nftTokenId\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onCovalentBreak(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"universe\"))) {\n _universe = IUniverse(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"state\"))) {\n _chargedState = IChargedState(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"managers\"))) {\n _chargedManagers = IChargedManagers(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"leptons\"))) {\n _lepton = controller;\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"forwarder\"))) {\n trustedForwarder = controller;\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n\n /***********************************|\n | Protocol Fees |\n |__________________________________*/\n\n /// @dev Setup the Base Deposit Fee for the Protocol\n function setDepositFee(uint256 fee) external onlyOwner {\n require(fee < PERCENTAGE_SCALE, \"CP:E-421\");\n depositFee = fee;\n emit DepositFeeSet(fee);\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n internal\n virtual\n {\n _chargedManagers.validateDeposit(_msgSender(), contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _validateNftDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n {\n _chargedManagers.validateNftDeposit(_msgSender(), contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function _validateDischarge(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateDischarge(_msgSender(), contractAddress, tokenId);\n }\n\n function _validateRelease(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateRelease(_msgSender(), contractAddress, tokenId);\n }\n\n function _validateBreakBond(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateBreakBond(_msgSender(), contractAddress, tokenId);\n }\n\n /// @dev Deposit Asset Tokens into an NFT via the Wallet Manager\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n /// @param feeAmount The Amount of Protocol Fees charged\n function _depositIntoWalletManager(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 feeAmount\n )\n internal\n virtual\n returns (uint256)\n {\n // Get Wallet-Manager for LP\n IWalletManager lpWalletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n address wallet = lpWalletMgr.getWalletAddressById(contractAddress, tokenId, creator, annuityPct);\n IERC20Upgradeable(assetToken).transfer(wallet, assetAmount);\n\n emit ProtocolFeesCollected(assetToken, assetAmount, feeAmount);\n\n return lpWalletMgr.energize(contractAddress, tokenId, assetToken, assetAmount);\n }\n\n /// @dev Deposit NFT Tokens into the Basket Manager\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @param basketManagerId The Wallet Manager of the Assets to Deposit\n /// @param nftTokenAddress The Address of the Asset Token to Deposit\n /// @param nftTokenId The specific amount of Asset Token to Deposit\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _depositIntoBasketManager(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n returns (bool)\n {\n // Deposit NFT Token directly into Smart Wallet (reverts on fail) and Update BasketManager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId);\n\n if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked(\"generic\"))) {\n basketMgr.prepareTransferAmount(nftTokenAmount);\n }\n\n if (_isERC1155(nftTokenAddress)) {\n if (nftTokenAmount == 0) { nftTokenAmount = 1; }\n IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(address(this), wallet, nftTokenId, nftTokenAmount, \"\");\n } else {\n IERC721Upgradeable(nftTokenAddress).transferFrom(address(this), wallet, nftTokenId);\n }\n return basketMgr.addToBasket(contractAddress, tokenId, nftTokenAddress, nftTokenId);\n }\n\n /**\n * @dev Calculates the amount of Fees to be paid for a specific deposit amount\n * Fees are calculated in Interest-Token as they are the type collected for Fees\n * @param assetAmount The Amount of Assets to calculate Fees on\n * @return protocolFee The amount of fees reserved for the protocol\n */\n function _getFeesForDeposit(\n uint256 assetAmount\n )\n internal\n view\n returns (uint256 protocolFee)\n {\n if (depositFee > 0) {\n protocolFee = assetAmount.mul(depositFee).div(PERCENTAGE_SCALE);\n }\n }\n\n /// @dev Collects the Required ERC20 Token(s) from the users wallet\n /// Be sure to Approve this Contract to transfer your Token(s)\n /// @param from The owner address to collect the tokens from\n /// @param tokenAddress The addres of the token to transfer\n /// @param tokenAmount The amount of tokens to collect\n function _collectAssetToken(address from, address tokenAddress, uint256 tokenAmount) internal virtual returns (uint256 protocolFee) {\n protocolFee = _getFeesForDeposit(tokenAmount);\n IERC20Upgradeable(tokenAddress).safeTransferFrom(from, address(this), tokenAmount.add(protocolFee));\n }\n\n /// @dev Collects the Required ERC721 Token(s) from the users wallet\n /// Be sure to Approve this Contract to transfer your Token(s)\n /// @param from The owner address to collect the tokens from\n /// @param nftTokenAddress The address of the NFT token to transfer\n /// @param nftTokenId The ID of the NFT token to transfer\n /// @param nftTokenAmount The amount of Tokens to Transfer (ERC1155-specific)\n function _collectNftToken(address from, address nftTokenAddress, uint256 nftTokenId, uint256 nftTokenAmount) internal virtual {\n if (_isERC1155(nftTokenAddress)) {\n IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId, nftTokenAmount, \"\");\n } else {\n IERC721Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId);\n }\n }\n\n /// @dev Checks if an NFT token contract supports the ERC1155 standard interface\n function _isERC1155(address nftTokenAddress) internal view virtual returns (bool) {\n bytes4 _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n return IERC165Upgradeable(nftTokenAddress).supportsInterface(_INTERFACE_ID_ERC1155);\n }\n\n /// @dev See {ChargedParticles-baseParticleMass}.\n function _baseParticleMass(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n return _chargedManagers.getWalletManager(walletManagerId).getPrincipal(contractAddress, tokenId, assetToken);\n }\n\n /// @dev See {ChargedParticles-currentParticleCharge}.\n function _currentParticleCharge(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n (, uint256 ownerInterest) = _chargedManagers.getWalletManager(walletManagerId).getInterest(contractAddress, tokenId, assetToken);\n return ownerInterest;\n }\n\n /// @dev See {ChargedParticles-currentParticleKinetics}.\n function _currentParticleKinetics(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n return _chargedManagers.getWalletManager(walletManagerId).getRewards(contractAddress, tokenId, assetToken);\n }\n\n /// @dev See {ChargedParticles-currentParticleCovalentBonds}.\n function _currentParticleCovalentBonds(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId\n )\n internal\n view\n virtual\n returns (uint256)\n {\n return _chargedManagers.getBasketManager(basketManagerId).getTokenTotalCount(contractAddress, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier managerEnabled(string calldata walletManagerId) {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"CP:E-419\");\n _;\n }\n\n modifier basketEnabled(string calldata basketManagerId) {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"CP:E-419\");\n _;\n }\n}\n" + }, + "contracts/v1/ChargedSettings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/RelayRecipient.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\nimport \"./lib/TokenInfoProxy.sol\";\n\n/**\n * @notice Charged Particles Settings Contract\n */\ncontract ChargedSettings is\n IChargedSettings,\n Initializable,\n OwnableUpgradeable,\n RelayRecipient,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using Bitwise for uint32;\n\n uint256 constant internal MAX_ANNUITIES = 1e4; // 10000 (100%)\n\n // NftSettings - actionPerms\n uint32 constant internal PERM_CHARGE_NFT = 1; // NFT Contracts that can have assets Deposited into them (Charged)\n uint32 constant internal PERM_BASKET_NFT = 2; // NFT Contracts that can have other NFTs Deposited into them\n uint32 constant internal PERM_TIMELOCK_ANY_NFT = 4; // NFT Contracts that can timelock any NFT on behalf of users (primarily used for Front-run Protection)\n uint32 constant internal PERM_TIMELOCK_OWN_NFT = 8; // NFT Contracts that can timelock their own NFTs on behalf of their users\n uint32 constant internal PERM_RESTRICTED_ASSETS = 16; // NFT Contracts that have restricted deposits to specific assets\n\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // Current Settings for External NFT Token Contracts;\n // - Any user can add any ERC721 or ERC1155 token as a Charged Particle without Limits,\n // unless the Owner of the ERC721 or ERC1155 token contract registers the token\n // and sets the Custom Settings for their token(s)\n mapping (address => uint32) internal _nftActionPerms;\n\n mapping (address => string) internal _nftRequiredWalletManager;\n mapping (address => string) internal _nftRequiredBasketManager;\n\n // ERC20\n mapping (address => mapping(address => bool)) internal _nftAllowedAssetTokens;\n mapping (address => mapping (address => uint256)) internal _nftDepositMin;\n mapping (address => mapping (address => uint256)) internal _nftDepositMax;\n\n // ERC721 / ERC1155\n mapping (address => mapping (address => uint256)) internal _nftMaxNfts; // NFT Token Address => Max\n\n // Optional Configs for individual NFTs set by NFT Creator (by Token UUID)\n mapping (uint256 => uint256) internal _creatorAnnuityPercent;\n mapping (uint256 => address) internal _creatorAnnuityRedirect;\n\n mapping (address => uint256) internal _depositCap;\n uint256 internal _tempLockExpiryBlocks;\n\n // Blacklist for non-compliant tokens\n mapping (address => bool) internal _invalidAssets;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n /// @dev Gets the amount of creator annuities reserved for the creator for the specified NFT\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @return creator The address of the creator\n /// @return annuityPct The percentage amount of annuities reserved for the creator\n function getCreatorAnnuities(\n address contractAddress,\n uint256 tokenId\n )\n external\n override\n virtual\n returns (address creator, uint256 annuityPct)\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n creator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId);\n annuityPct = _creatorAnnuityPercent[tokenUuid];\n }\n\n function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId)\n external\n view\n override\n virtual\n returns (address)\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _creatorAnnuityRedirect[tokenUuid];\n }\n\n function getTempLockExpiryBlocks() external view override virtual returns (uint256) {\n return _tempLockExpiryBlocks;\n }\n\n function getTimelockApprovals(address operator)\n external\n view\n override\n virtual\n returns (bool timelockAny, bool timelockOwn)\n {\n timelockAny = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_ANY_NFT);\n timelockOwn = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_OWN_NFT);\n }\n\n function getAssetRequirements(address contractAddress, address assetToken)\n external\n view\n override\n virtual\n returns (\n string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n )\n {\n requiredWalletManager = _nftRequiredWalletManager[contractAddress];\n energizeEnabled = _nftActionPerms[contractAddress].hasBit(PERM_CHARGE_NFT);\n restrictedAssets = _nftActionPerms[contractAddress].hasBit(PERM_RESTRICTED_ASSETS);\n validAsset = _nftAllowedAssetTokens[contractAddress][assetToken];\n depositCap = _depositCap[assetToken];\n depositMin = _nftDepositMin[contractAddress][assetToken];\n depositMax = _nftDepositMax[contractAddress][assetToken];\n invalidAsset = _invalidAssets[assetToken];\n }\n\n function getNftAssetRequirements(address contractAddress, address nftTokenAddress)\n external\n view\n override\n virtual\n returns (string memory requiredBasketManager, bool basketEnabled, uint256 maxNfts)\n {\n requiredBasketManager = _nftRequiredBasketManager[contractAddress];\n basketEnabled = _nftActionPerms[contractAddress].hasBit(PERM_BASKET_NFT);\n maxNfts = _nftMaxNfts[contractAddress][nftTokenAddress];\n }\n\n\n /***********************************|\n | Only NFT Creator |\n |__________________________________*/\n\n /// @notice Sets the Custom Configuration for Creators of Proton-based NFTs\n /// @param contractAddress The Address to the Proton-based NFT to configure\n /// @param tokenId The token ID of the Proton-based NFT to configure\n /// @param creator The creator of the Proton-based NFT\n /// @param annuityPercent The percentage of interest-annuities to reserve for the creator\n function setCreatorAnnuities(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent\n )\n external\n virtual\n override\n {\n require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), \"CP:E-104\");\n _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent);\n }\n\n /// @notice Sets a Custom Receiver Address for the Creator Annuities\n /// @param contractAddress The Address to the Proton-based NFT to configure\n /// @param tokenId The token ID of the Proton-based NFT to configure\n /// @param receiver The receiver of the Creator interest-annuities\n function setCreatorAnnuitiesRedirect(\n address contractAddress,\n uint256 tokenId,\n address receiver\n )\n external\n virtual\n override\n {\n require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), \"CP:E-104\");\n _setCreatorAnnuitiesRedirect(contractAddress, tokenId, receiver);\n }\n\n\n /***********************************|\n | Register Contract Settings |\n |(For External Contract Integration)|\n |__________________________________*/\n\n /// @notice Sets a Required Wallet-Manager for External NFT Contracts (otherwise set to \"none\" to allow any Wallet-Manager)\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param walletManager If set, will only allow deposits from this specific Wallet-Manager\n function setRequiredWalletManager(\n address contractAddress,\n string calldata walletManager\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (keccak256(bytes(walletManager)) == keccak256(bytes(\"none\"))) {\n _nftRequiredWalletManager[contractAddress] = \"\";\n } else {\n _nftRequiredWalletManager[contractAddress] = walletManager;\n }\n\n emit RequiredWalletManagerSet(\n contractAddress,\n walletManager\n );\n }\n\n /// @notice Sets a Required Basket-Manager for External NFT Contracts (otherwise set to \"none\" to allow any Basket-Manager)\n /// @param contractAddress The Address to the External Contract to configure\n /// @param basketManager If set, will only allow deposits from this specific Basket-Manager\n function setRequiredBasketManager(\n address contractAddress,\n string calldata basketManager\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (keccak256(bytes(basketManager)) == keccak256(bytes(\"none\"))) {\n _nftRequiredBasketManager[contractAddress] = \"\";\n } else {\n _nftRequiredBasketManager[contractAddress] = basketManager;\n }\n\n emit RequiredBasketManagerSet(\n contractAddress,\n basketManager\n );\n }\n\n /// @notice Enables or Disables Asset-Token Restrictions for External NFT Contracts\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param restrictionsEnabled If set, will only allow deposits from Allowed Asset Tokens\n function setAssetTokenRestrictions(\n address contractAddress,\n bool restrictionsEnabled\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (restrictionsEnabled) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_RESTRICTED_ASSETS);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_RESTRICTED_ASSETS);\n }\n\n emit AssetTokenRestrictionsSet(\n contractAddress,\n restrictionsEnabled\n );\n }\n\n /// @notice Enables or Disables Allowed Asset Tokens for External NFT Contracts\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param assetToken The Address of the Asset Token to Allow or Disallow\n /// @param isAllowed True if the Asset Token is allowed\n function setAllowedAssetToken(\n address contractAddress,\n address assetToken,\n bool isAllowed\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftAllowedAssetTokens[contractAddress][assetToken] = isAllowed;\n\n emit AllowedAssetTokenSet(\n contractAddress,\n assetToken,\n isAllowed\n );\n }\n\n /// @notice Sets the Custom Configuration for External Contracts\n /// @param contractAddress The Address to the External Contract to configure\n /// @param assetToken The address of the Asset Token to set Limits for\n /// @param depositMin If set, will define the minimum amount of Asset tokens the NFT may hold, otherwise any amount\n /// @param depositMax If set, will define the maximum amount of Asset tokens the NFT may hold, otherwise any amount\n function setAssetTokenLimits(\n address contractAddress,\n address assetToken,\n uint256 depositMin,\n uint256 depositMax\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftDepositMin[contractAddress][assetToken] = depositMin;\n _nftDepositMax[contractAddress][assetToken] = depositMax;\n\n emit AssetTokenLimitsSet(\n contractAddress,\n assetToken,\n depositMin,\n depositMax\n );\n }\n\n /// @notice Sets the Max Number of NFTs that can be held by a Charged Particle NFT\n /// @param contractAddress The Address to the External Contract to configure\n /// @param nftTokenAddress The address of the NFT Token to set a Max for\n /// @param maxNfts The maximum numbers of NFTs that can be held by a given NFT (0 = unlimited)\n function setMaxNfts(\n address contractAddress,\n address nftTokenAddress,\n uint256 maxNfts\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftMaxNfts[contractAddress][nftTokenAddress] = maxNfts;\n\n emit MaxNftsSet(\n contractAddress,\n nftTokenAddress,\n maxNfts\n );\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n function setAssetInvalidity(address assetToken, bool invalidity) external virtual override onlyOwner {\n _invalidAssets[assetToken] = invalidity;\n emit AssetInvaliditySet(assetToken, invalidity);\n }\n\n function setDepositCap(address assetToken, uint256 cap) external virtual onlyOwner {\n _depositCap[assetToken] = cap;\n emit DepositCapSet(assetToken, cap);\n }\n\n function setTempLockExpiryBlocks(uint256 numBlocks) external virtual onlyOwner {\n _tempLockExpiryBlocks = numBlocks;\n emit TempLockExpirySet(numBlocks);\n }\n\n function enableNftContracts(address[] calldata contracts) external override virtual onlyOwner {\n uint count = contracts.length;\n for (uint i = 0; i < count; i++) {\n address tokenContract = contracts[i];\n _setPermsForCharge(tokenContract, true);\n _setPermsForBasket(tokenContract, true);\n _setPermsForTimelockSelf(tokenContract, true);\n }\n }\n\n function migrateToken(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent,\n address annuityReceiver\n )\n external\n onlyOwner\n {\n _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent);\n if (annuityReceiver != address(0)) {\n _setCreatorAnnuitiesRedirect(contractAddress, tokenId, annuityReceiver);\n }\n }\n\n /// @dev Update the list of NFT contracts that can be Charged\n function setPermsForCharge(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForCharge(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can hold other NFTs\n function setPermsForBasket(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForBasket(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection\n function setPermsForTimelockAny(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForTimelockAny(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock their own tokens\n function setPermsForTimelockSelf(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForTimelockSelf(contractAddress, state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Update the list of NFT contracts that can be Charged\n function _setPermsForCharge(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_CHARGE_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_CHARGE_NFT);\n }\n emit PermsSetForCharge(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can hold other NFTs\n function _setPermsForBasket(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_BASKET_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_BASKET_NFT);\n }\n emit PermsSetForBasket(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection\n function _setPermsForTimelockAny(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_ANY_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_ANY_NFT);\n }\n emit PermsSetForTimelockAny(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock their own tokens\n function _setPermsForTimelockSelf(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_OWN_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_OWN_NFT);\n }\n emit PermsSetForTimelockSelf(contractAddress, state);\n }\n\n /// @dev see setCreatorAnnuities()\n function _setCreatorAnnuities(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent\n )\n internal\n virtual\n {\n require(annuityPercent <= MAX_ANNUITIES, \"CP:E-421\");\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Update Configs for External Token Creator\n _creatorAnnuityPercent[tokenUuid] = annuityPercent;\n\n emit TokenCreatorConfigsSet(\n contractAddress,\n tokenId,\n creator,\n annuityPercent\n );\n }\n\n /// @dev see setCreatorAnnuitiesRedirect()\n function _setCreatorAnnuitiesRedirect(\n address contractAddress,\n uint256 tokenId,\n address receiver\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _creatorAnnuityRedirect[tokenUuid] = receiver;\n emit TokenCreatorAnnuitiesRedirected(contractAddress, tokenId, receiver);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyValidExternalContract(address contractAddress) {\n require(contractAddress.isContract(), \"CP:E-420\");\n _;\n }\n\n modifier onlyContractOwnerOrAdmin(address contractAddress, address sender) {\n require(sender == owner() || contractAddress.isContractOwner(sender), \"CP:E-103\");\n _;\n }\n}\n" + }, + "contracts/v1/ChargedState.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedState.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/RelayRecipient.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Settings Contract\n */\ncontract ChargedState is\n IChargedState,\n Initializable,\n OwnableUpgradeable,\n RelayRecipient,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using Bitwise for uint32;\n\n // NftState - actionPerms\n uint32 constant internal PERM_RESTRICT_ENERGIZE_FROM_ALL = 1; // NFTs that have Restrictions on Energize\n uint32 constant internal PERM_ALLOW_DISCHARGE_FROM_ALL = 2; // NFTs that allow Discharge by anyone\n uint32 constant internal PERM_ALLOW_RELEASE_FROM_ALL = 4; // NFTs that allow Release by anyone\n uint32 constant internal PERM_RESTRICT_BOND_FROM_ALL = 8; // NFTs that have Restrictions on Covalent Bonds\n uint32 constant internal PERM_ALLOW_BREAK_BOND_FROM_ALL = 16; // NFTs that allow Breaking Covalent Bonds by anyone\n\n IChargedSettings internal _chargedSettings;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // NftTimelocks\n /// @dev discharge unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftDischargeTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftDischargeTimelockLockedBy;\n\n /// @dev release unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftReleaseTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftReleaseTimelockLockedBy;\n\n /// @dev release unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftBreakBondTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftBreakBondTimelockLockedBy;\n\n // NftState\n /// @dev maps nft by tokenId to actionPermissions uint32 which is a composite of all possible NftState - actionPerms\n mapping (uint256 => uint32) internal _nftActionPerms;\n\n /// @dev maps nft by tokenId to its tempLockExpiry\n mapping (uint256 => uint256) internal _nftTempLockExpiry;\n\n /// @dev maps tokenId to user address to operator address for approving various actions\n mapping (uint256 => mapping(address => address)) internal _nftDischargeApproval;\n mapping (uint256 => mapping(address => address)) internal _nftReleaseApproval;\n mapping (uint256 => mapping(address => address)) internal _nftBreakBondApproval;\n mapping (uint256 => mapping(address => address)) internal _nftTimelockApproval;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftDischargeTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftDischargeTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftReleaseTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftReleaseTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftBreakBondTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftBreakBondTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n\n /// @notice Checks if an operator is allowed to Discharge a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForDischarge(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Release a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForRelease(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Break Covalent Bonds on a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForBreakBond(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Timelock a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForTimelock(contractAddress, tokenId, operator);\n }\n\n\n function isEnergizeRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n }\n\n\n function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_BOND_FROM_ALL);\n }\n\n\n function getDischargeState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n isApproved = _isApprovedForDischarge(contractAddress, tokenId, sender);\n timelock = _nftDischargeTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n function getReleaseState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_RELEASE_FROM_ALL);\n isApproved = _isApprovedForRelease(contractAddress, tokenId, sender);\n timelock = _nftReleaseTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n function getBreakBondState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n isApproved = _isApprovedForBreakBond(contractAddress, tokenId, sender);\n timelock = _nftBreakBondTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n\n /***********************************|\n | Only NFT Owner/Operator |\n |__________________________________*/\n\n /// @notice Sets an Operator as Approved to Discharge a specific Token\n /// This allows an operator to withdraw the interest-portion only\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setDischargeApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Release a specific Token\n /// This allows an operator to withdraw the principal + interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setReleaseApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token\n /// This allows an operator to withdraw Basket NFTs\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setBreakBondApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Timelock a specific Token\n /// This allows an operator to timelock the principal or interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setTimelockApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Discharge/Release/Timelock a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setApprovalForAll(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @dev Updates Restrictions on Energizing an NFT\n function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForRestrictCharge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowDischarge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowRelease(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Restrictions on Covalent Bonds on an NFT\n function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForRestrictBond(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone\n function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowBreakBond(contractAddress, tokenId, state);\n }\n\n /// @notice Sets a Timelock on the ability to Discharge the Interest of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setDischargeTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftDischargeTimelockLockedBy[tokenUuid] == sender) {\n delete _nftDischargeTimelockUnlockBlock[tokenUuid];\n delete _nftDischargeTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftDischargeTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftDischargeTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftDischargeTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenDischargeTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n /// @notice Sets a Timelock on the ability to Release the Assets of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setReleaseTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftReleaseTimelockLockedBy[tokenUuid] == sender) {\n delete _nftReleaseTimelockUnlockBlock[tokenUuid];\n delete _nftReleaseTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftReleaseTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftReleaseTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftReleaseTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenReleaseTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n /// @notice Sets a Timelock on the ability to Break the Covalent Bond of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setBreakBondTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftBreakBondTimelockLockedBy[tokenUuid] == sender) {\n delete _nftBreakBondTimelockUnlockBlock[tokenUuid];\n delete _nftBreakBondTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftBreakBondTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftBreakBondTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftBreakBondTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenBreakBondTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n\n /***********************************|\n | Only NFT Contract |\n |__________________________________*/\n\n /// @notice Sets a Temporary-Lock on the ability to Release/Discharge the Assets of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param isLocked The locked state; contracts are expected to disable this lock before expiry\n function setTemporaryLock(\n address contractAddress,\n uint256 tokenId,\n bool isLocked\n )\n external\n override\n virtual\n {\n require(msg.sender == contractAddress, \"CP:E-112\");\n\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n uint256 unlockBlock;\n if (isLocked && _nftTempLockExpiry[tokenUuid] == 0) {\n unlockBlock = block.number.add(_chargedSettings.getTempLockExpiryBlocks());\n _nftTempLockExpiry[tokenUuid] = unlockBlock;\n }\n if (!isLocked) {\n _nftTempLockExpiry[tokenUuid] = 0;\n }\n\n emit TokenTempLock(contractAddress, tokenId, unlockBlock);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n function migrateToken(\n address contractAddress,\n uint256 tokenId,\n uint256 releaseTimelockExpiry,\n address releaseTimelockLockedBy,\n uint256 tempLockExpiry\n )\n external\n onlyOwner\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (releaseTimelockExpiry > block.number && releaseTimelockLockedBy != address(0)) {\n _nftReleaseTimelockUnlockBlock[tokenUuid] = releaseTimelockExpiry;\n _nftReleaseTimelockLockedBy[tokenUuid] = releaseTimelockLockedBy;\n emit TokenReleaseTimelock(contractAddress, tokenId, releaseTimelockLockedBy, releaseTimelockExpiry);\n }\n\n if (tempLockExpiry > 0) {\n _nftTempLockExpiry[tokenUuid] = tempLockExpiry;\n emit TokenTempLock(contractAddress, tokenId, tempLockExpiry);\n }\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev See {ChargedParticles-isApprovedForDischarge}.\n function _isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftDischargeApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForRelease}.\n function _isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftReleaseApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForBreakBond}.\n function _isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftBreakBondApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForTimelock}.\n function _isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n (bool timelockAny, bool timelockOwn) = _chargedSettings.getTimelockApprovals(operator);\n if (timelockAny || (timelockOwn && contractAddress == operator)) { return true; }\n\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return tokenOwner == operator || _nftTimelockApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @notice Sets an Operator as Approved to Discharge a specific Token\n /// This allows an operator to withdraw the interest-portion only\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setDischargeApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftDischargeApproval[tokenUuid][tokenOwner] = operator;\n emit DischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Release a specific Token\n /// This allows an operator to withdraw the principal + interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setReleaseApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftReleaseApproval[tokenUuid][tokenOwner] = operator;\n emit ReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token\n /// This allows an operator to withdraw Basket NFTs\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setBreakBondApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftBreakBondApproval[tokenUuid][tokenOwner] = operator;\n emit BreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Timelock a specific Token\n /// This allows an operator to timelock the principal or interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setTimelockApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftTimelockApproval[tokenUuid][tokenOwner] = operator;\n emit TimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @dev Updates Restrictions on Energizing an NFT\n function _setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n }\n emit PermsSetForRestrictCharge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function _setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n }\n emit PermsSetForAllowDischarge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function _setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_RELEASE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_RELEASE_FROM_ALL);\n }\n emit PermsSetForAllowRelease(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Restrictions on Covalent Bonds on an NFT\n function _setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_BOND_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_BOND_FROM_ALL);\n }\n emit PermsSetForRestrictBond(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone\n function _setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n }\n emit PermsSetForAllowBreakBond(contractAddress, tokenId, state);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) {\n require(_tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender), \"CP:E-105\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/CommunityVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract CommunityVault is Ownable, BlackholePrevention {\n\n IERC20 private immutable _ionx;\n\n constructor (address ionx) public {\n _ionx = IERC20(ionx);\n }\n\n event SetAllowance(address indexed caller, address indexed spender, uint256 amount);\n\n function setAllowance(address spender, uint amount) public onlyOwner {\n _ionx.approve(spender, amount);\n\n emit SetAllowance(msg.sender, spender, amount);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens other than IONX, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n require(tokenAddress != address(_ionx), \"CommunityVault: cannot withdraw IONX\");\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n}" + }, + "contracts/v1/incentives/MerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_) public {\n token = token_;\n merkleRoot = merkleRoot_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), 'MerkleDistributor: Drop already claimed.');\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), 'MerkleDistributor: Invalid proof.');\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), 'MerkleDistributor: Transfer failed.');\n\n emit Claimed(index, account, amount);\n }\n}\n" + }, + "contracts/v1/incentives/MerkleDistributor2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor2 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"MerkleDistributor2: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"MerkleDistributor2: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor2: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"MerkleDistributor2: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"MerkleDistributor2: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"MerkleDistributor2: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/MerkleDistributor3.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor3 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"MerkleDistributor3: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"MerkleDistributor3: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor3: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"MerkleDistributor3: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"MerkleDistributor3: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"MerkleDistributor3: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/RewardProgram.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// RewardProgram.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/IRewardProgram.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/introspection/IERC165.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"../interfaces/IUniverseRP.sol\";\nimport \"../interfaces/IChargedManagers.sol\";\nimport \"../interfaces/IWalletManager.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IERC20Detailed.sol\";\n\ncontract RewardProgram is\n IRewardProgram,\n BlackholePrevention,\n IERC165,\n ReentrancyGuard,\n IERC721Receiver,\n IERC1155Receiver\n{\n using SafeMath for uint256;\n using TokenInfo for address;\n using SafeERC20 for IERC20;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n\n address private _owner;\n IUniverseRP private _universe;\n IChargedManagers private _chargedManagers;\n ProgramRewardData private _programData;\n mapping(uint256 => AssetStake) private _assetStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public {}\n\n function initialize(\n address stakingToken,\n address rewardToken,\n uint256 baseMultiplier,\n address chargedManagers,\n address universe,\n address owner\n ) external override {\n require(_owner == address(0x0), \"Already initialized\");\n _owner = owner;\n\n // Prepare Reward Program\n _programData.stakingToken = stakingToken;\n _programData.rewardToken = rewardToken;\n _programData.baseMultiplier = baseMultiplier; // Basis Points\n\n // Connect to Charged Particles\n _chargedManagers = IChargedManagers(chargedManagers);\n _universe = IUniverseRP(universe);\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getProgramData() external view override returns (ProgramRewardData memory) {\n return _programData;\n }\n\n function getAssetStake(uint256 parentNftUuid) external view override returns (AssetStake memory) {\n return _assetStake[parentNftUuid];\n }\n\n function getFundBalance() external view override returns (uint256) {\n return _getFundBalance();\n }\n\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) public view override returns (uint256) {\n return _calculateRewardsEarned(parentNftUuid, interestAmount);\n }\n\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n return _assetStake[parentNftUuid].claimableRewards;\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\n return \"\";\n }\n\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(IERC165)\n returns (bool)\n {\n // default interface support\n if (\n interfaceId == type(IERC721Receiver).interfaceId ||\n interfaceId == type(IERC1155Receiver).interfaceId ||\n interfaceId == type(IERC165).interfaceId\n ) {\n return true;\n }\n }\n\n function owner() public view returns (address) {\n return _owner;\n }\n\n\n /***********************************|\n | Only Universe |\n |__________________________________*/\n\n function registerAssetDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n uint256 principalAmount\n )\n external\n override\n onlyUniverse\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n if (assetStake.start == 0) {\n assetStake.start = block.number;\n assetStake.walletManagerId = walletManagerId;\n }\n emit AssetDeposit(contractAddress, tokenId, walletManagerId, principalAmount);\n }\n\n function registerAssetRelease(\n address contractAddress,\n uint256 tokenId,\n uint256 interestAmount\n )\n external\n override\n onlyUniverse\n nonReentrant\n returns (uint256 rewards)\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n if (assetStake.start > 0) {\n // Update Claimable Rewards\n uint256 newRewards = _calculateRewardsEarned(parentNftUuid, interestAmount);\n assetStake.claimableRewards = assetStake.claimableRewards.add(newRewards);\n\n // Reset Stake if Principal Balance falls to Zero\n IWalletManager walletMgr = _chargedManagers.getWalletManager(assetStake.walletManagerId);\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\n if (principal == 0) {\n assetStake.start = 0;\n }\n\n // Issue Rewards to NFT Owner\n rewards = _claimRewards(contractAddress, tokenId);\n\n emit AssetRelease(contractAddress, tokenId, interestAmount);\n }\n }\n\n\n /***********************************|\n | Reward Calculation |\n |__________________________________*/\n\n function _calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) internal view returns (uint256 totalReward) {\n uint256 baseReward = _calculateBaseReward(interestAmount);\n uint256 leptonMultipliedReward = _calculateMultipliedReward(parentNftUuid, baseReward);\n totalReward = _convertDecimals(leptonMultipliedReward);\n }\n\n function _calculateBaseReward(uint256 amount) internal view returns(uint256 baseReward) {\n baseReward = amount.mul(_programData.baseMultiplier).div(PERCENTAGE_SCALE);\n }\n\n function _calculateMultipliedReward(uint256 parentNftUuid, uint256 baseReward) internal view returns(uint256) {\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n if (assetStake.start == 0) { return baseReward; }\n\n IUniverseRP.NftStake memory nftStake = _universe.getNftStake(parentNftUuid);\n uint256 multiplierBP = nftStake.multiplier;\n\n uint256 assetDepositLength = block.number.sub(assetStake.start);\n uint256 nftDepositLength = 0;\n if (nftStake.releaseBlockNumber > 0) {\n nftDepositLength = nftStake.releaseBlockNumber.sub(nftStake.depositBlockNumber);\n } else {\n nftDepositLength = block.number.sub(nftStake.depositBlockNumber);\n }\n\n if (multiplierBP == 0 || nftDepositLength == 0 || assetDepositLength == 0) {\n return baseReward;\n }\n\n if (nftDepositLength > assetDepositLength) {\n nftDepositLength = assetDepositLength;\n }\n\n // Percentage of the total program that the Multiplier Nft was deposited for\n uint256 nftRewardRatioBP = nftDepositLength.mul(PERCENTAGE_SCALE).div(assetDepositLength);\n\n // Amount of reward that the Multiplier Nft is responsible for\n uint256 amountGeneratedDuringNftDeposit = baseReward.mul(nftRewardRatioBP).div(PERCENTAGE_SCALE);\n\n // Amount of Multiplied Reward from NFT\n uint256 multipliedReward = amountGeneratedDuringNftDeposit.mul(multiplierBP.mul(LEPTON_MULTIPLIER_SCALE)).div(PERCENTAGE_SCALE);\n\n // Amount of Base Reward without Multiplied NFT Rewards\n uint256 amountGeneratedWithoutNftDeposit = baseReward.sub(amountGeneratedDuringNftDeposit);\n\n // Amount of Base Rewards + Multiplied NFT Rewards\n return amountGeneratedWithoutNftDeposit.add(multipliedReward);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function fundProgram(uint256 amount) external onlyOwner {\n require(_programData.rewardToken != address(0), \"RP:E-405\");\n IERC20(_programData.rewardToken).safeTransferFrom(msg.sender, address(this), amount);\n emit RewardProgramFunded(amount);\n }\n\n function setStakingToken(address newStakingToken) external onlyOwner {\n _programData.stakingToken = newStakingToken;\n }\n\n function setRewardToken(address newRewardToken) external onlyOwner {\n _programData.rewardToken = newRewardToken;\n }\n\n function setBaseMultiplier(uint256 newMultiplier) external onlyOwner {\n _programData.baseMultiplier = newMultiplier; // Basis Points\n }\n\n function setChargedManagers(address manager) external onlyOwner {\n _chargedManagers = IChargedManagers(manager);\n }\n\n function setUniverse(address universe) external onlyOwner {\n _universe = IUniverseRP(universe);\n }\n\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external override onlyOwner {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n\n // Initiate Asset Stake\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\n if (principal > 0) {\n _assetStake[parentNftUuid] = AssetStake(block.number, 0, walletManagerId);\n emit AssetRegistered(contractAddress, tokenId, walletManagerId, principal);\n }\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _claimRewards(\n address contractAddress,\n uint256 tokenId\n )\n internal\n returns (uint256 totalReward)\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n // Rewards Receiver\n address receiver = IERC721(contractAddress).ownerOf(tokenId);\n\n // Ensure Reward Pool has Sufficient Balance\n totalReward = assetStake.claimableRewards;\n uint256 fundBalance = _getFundBalance();\n uint256 unavailReward = totalReward > fundBalance ? totalReward.sub(fundBalance) : 0;\n\n // Determine amount of Rewards to Transfer\n if (unavailReward > 0) {\n totalReward = totalReward.sub(unavailReward);\n emit RewardProgramOutOfFunds();\n }\n\n // Update Asset Stake\n assetStake.claimableRewards = unavailReward;\n\n if (totalReward > 0) {\n // Transfer Available Rewards to Receiver\n IERC20(_programData.rewardToken).safeTransfer(receiver, totalReward);\n }\n\n emit RewardsClaimed(contractAddress, tokenId, receiver, totalReward, unavailReward);\n }\n\n function _convertDecimals(uint256 reward) internal view returns (uint256) {\n uint8 stakingTokenDecimals = IERC20Detailed(_programData.stakingToken).decimals();\n return reward.mul(10**(18 - uint256(stakingTokenDecimals)));\n }\n\n function _getFundBalance() internal view returns (uint256) {\n return IERC20Detailed(_programData.rewardToken).balanceOf(address(this));\n }\n\n\n modifier onlyOwner() {\n require(_owner == msg.sender, \"Caller is not the owner\");\n _;\n }\n\n modifier onlyUniverse() {\n require(msg.sender == address(_universe), \"RP:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/RewardProgramFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// RewardProgramFactory.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport \"./RewardProgram.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract RewardProgramFactory is BlackholePrevention, Ownable {\n event RewardProgramCreated(address indexed rewardProgram);\n\n address public _template;\n\n constructor () public {\n _template = address(new RewardProgram());\n }\n\n // function _msgSender() internal view override returns (address payable) {\n // return msg.sender;\n // }\n\n function createRewardProgram(\n address stakingToken,\n address rewardToken,\n uint256 baseMultiplier,\n address chargedManagers,\n address universe\n )\n external\n onlyOwner\n returns (address)\n {\n address newRewardProgram = _createClone(_template);\n RewardProgram rewardProgram = RewardProgram(newRewardProgram);\n rewardProgram.initialize(stakingToken, rewardToken, baseMultiplier, chargedManagers, universe, _msgSender());\n emit RewardProgramCreated(newRewardProgram);\n return newRewardProgram;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n}\n" + }, + "contracts/v1/incentives/Staking.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/Staking2.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking2 is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/Staking3.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking3 is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/YieldFarm.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/incentives/YieldFarm2.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm2 is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/incentives/YieldFarm3.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm3 is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/interfaces/IAaveBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IAaveBridge.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n\ninterface IAaveBridge {\n function getReserveInterestToken(address assetToken) external view returns (address aTokenAddress);\n function isReserveActive(address assetToken) external view returns (bool);\n\n function getTotalBalance(address account, address assetToken) external view returns (uint256);\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(address receiver, address assetToken, uint256 assetAmount) external;\n}\n" + }, + "contracts/v1/interfaces/IBaseProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IBaseProton is IERC721 {\n event PausedStateSet(bool isPaused);\n event SalePriceSet(uint256 indexed tokenId, uint256 salePrice);\n event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct);\n event FeesWithdrawn(address indexed receiver, uint256 amount);\n event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties);\n event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view returns (address);\n function getSalePrice(uint256 tokenId) external view returns (uint256);\n function getLastSellPrice(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyalties(address account) external view returns (uint256);\n function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address);\n\n function buyProton(uint256 tokenId, uint256 gasLimit) external payable returns (bool);\n function claimCreatorRoyalties() external returns (uint256);\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n ) external returns (uint256 newTokenId);\n\n function createProtons(\n address creator,\n address receiver,\n string[] calldata tokenMetaUris\n ) external returns (bool);\n\n function createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n ) external returns (bool);\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice) external;\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external;\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external;\n}" + }, + "contracts/v1/interfaces/IBasketManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Particle Basket Manager interface\n * @dev The basket-manager for underlying assets attached to Charged Particles\n * @dev Manages the link between NFTs and their respective Smart-Baskets\n */\ninterface IBasketManager {\n\n event ControllerSet(address indexed controller);\n event ExecutorSet(address indexed executor);\n event PausedStateSet(bool isPaused);\n event NewSmartBasket(address indexed contractAddress, uint256 indexed tokenId, address indexed smartBasket);\n event BasketAdd(address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\n event BasketRemove(address indexed receiver, address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\n event BasketRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\n event RewardProgramSet(address indexed rewardProgram);\n\n function isPaused() external view returns (bool);\n\n function getTokenTotalCount(address contractAddress, uint256 tokenId) external view returns (uint256);\n function getTokenCountByType(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (uint256);\n\n function prepareTransferAmount(uint256 nftTokenAmount) external;\n function addToBasket(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function getBasketAddressById(address contractAddress, uint256 tokenId) external returns (address);\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/IChargedManagers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IWalletManager.sol\";\nimport \"./IBasketManager.sol\";\n\n/**\n * @notice Interface for Charged Wallet-Managers\n */\ninterface IChargedManagers {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function isContractOwner(address contractAddress, address account) external view returns (bool);\n\n // ERC20\n function isWalletManagerEnabled(string calldata walletManagerId) external view returns (bool);\n function getWalletManager(string calldata walletManagerId) external view returns (IWalletManager);\n\n // ERC721\n function isNftBasketEnabled(string calldata basketId) external view returns (bool);\n function getBasketManager(string calldata basketId) external view returns (IBasketManager);\n\n // Validation\n function validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external;\n function validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external;\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external;\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event WalletManagerRegistered(string indexed walletManagerId, address indexed walletManager);\n event BasketManagerRegistered(string indexed basketId, address indexed basketManager);\n}\n" + }, + "contracts/v1/interfaces/IChargedParticles.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Charged Particles\n */\ninterface IChargedParticles {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getStateAddress() external view returns (address stateAddress);\n function getSettingsAddress() external view returns (address settingsAddress);\n function getManagersAddress() external view returns (address managersAddress);\n\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\n\n /***********************************|\n | Particle Mechanics |\n |__________________________________*/\n\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n ) external returns (uint256 yieldTokensAmount);\n\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 receiverAmount);\n\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositFeeSet(uint256 depositFee);\n event ProtocolFeesCollected(address indexed assetToken, uint256 depositAmount, uint256 feesCollected);\n}\n" + }, + "contracts/v1/interfaces/IChargedSettings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IWalletManager.sol\";\nimport \"./IBasketManager.sol\";\n\n/**\n * @notice Interface for Charged Settings\n */\ninterface IChargedSettings {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n // function isContractOwner(address contractAddress, address account) external view returns (bool);\n function getCreatorAnnuities(address contractAddress, uint256 tokenId) external returns (address creator, uint256 annuityPct);\n function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId) external view returns (address);\n function getTempLockExpiryBlocks() external view returns (uint256);\n function getTimelockApprovals(address operator) external view returns (bool timelockAny, bool timelockOwn);\n function getAssetRequirements(\n address contractAddress,\n address assetToken\n ) external view returns (\n string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n );\n function getNftAssetRequirements(\n address contractAddress,\n address nftTokenAddress\n ) external view returns (\n string memory requiredBasketManager,\n bool basketEnabled,\n uint256 maxNfts\n );\n\n /***********************************|\n | Only NFT Creator |\n |__________________________________*/\n\n function setCreatorAnnuities(address contractAddress, uint256 tokenId, address creator, uint256 annuityPercent) external;\n function setCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId, address receiver) external;\n\n\n /***********************************|\n | Only NFT Contract Owner |\n |__________________________________*/\n\n function setRequiredWalletManager(address contractAddress, string calldata walletManager) external;\n function setRequiredBasketManager(address contractAddress, string calldata basketManager) external;\n function setAssetTokenRestrictions(address contractAddress, bool restrictionsEnabled) external;\n function setAllowedAssetToken(address contractAddress, address assetToken, bool isAllowed) external;\n function setAssetTokenLimits(address contractAddress, address assetToken, uint256 depositMin, uint256 depositMax) external;\n function setMaxNfts(address contractAddress, address nftTokenAddress, uint256 maxNfts) external;\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAssetInvalidity(address assetToken, bool invalidity) external;\n function enableNftContracts(address[] calldata contracts) external;\n function setPermsForCharge(address contractAddress, bool state) external;\n function setPermsForBasket(address contractAddress, bool state) external;\n function setPermsForTimelockAny(address contractAddress, bool state) external;\n function setPermsForTimelockSelf(address contractAddress, bool state) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositCapSet(address assetToken, uint256 depositCap);\n event TempLockExpirySet(uint256 expiryBlocks);\n\n event RequiredWalletManagerSet(address indexed contractAddress, string walletManager);\n event RequiredBasketManagerSet(address indexed contractAddress, string basketManager);\n event AssetTokenRestrictionsSet(address indexed contractAddress, bool restrictionsEnabled);\n event AllowedAssetTokenSet(address indexed contractAddress, address assetToken, bool isAllowed);\n event AssetTokenLimitsSet(address indexed contractAddress, address assetToken, uint256 assetDepositMin, uint256 assetDepositMax);\n event MaxNftsSet(address indexed contractAddress, address indexed nftTokenAddress, uint256 maxNfts);\n event AssetInvaliditySet(address indexed assetToken, bool invalidity);\n\n event TokenCreatorConfigsSet(address indexed contractAddress, uint256 indexed tokenId, address indexed creatorAddress, uint256 annuityPercent);\n event TokenCreatorAnnuitiesRedirected(address indexed contractAddress, uint256 indexed tokenId, address indexed redirectAddress);\n\n event PermsSetForCharge(address indexed contractAddress, bool state);\n event PermsSetForBasket(address indexed contractAddress, bool state);\n event PermsSetForTimelockAny(address indexed contractAddress, bool state);\n event PermsSetForTimelockSelf(address indexed contractAddress, bool state);\n}\n" + }, + "contracts/v1/interfaces/IChargedState.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IChargedSettings.sol\";\n\n/**\n * @notice Interface for Charged State\n */\ninterface IChargedState {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n\n function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n\n function isEnergizeRestricted(address contractAddress, uint256 tokenId) external view returns (bool);\n function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external view returns (bool);\n\n function getDischargeState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n function getReleaseState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n function getBreakBondState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n\n /***********************************|\n | Only NFT Owner/Operator |\n |__________________________________*/\n\n function setDischargeApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setReleaseApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setBreakBondApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setTimelockApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setApprovalForAll(address contractAddress, uint256 tokenId, address operator) external;\n\n function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) external;\n\n function setDischargeTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n function setReleaseTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n function setBreakBondTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n /***********************************|\n | Only NFT Contract |\n |__________________________________*/\n\n function setTemporaryLock(\n address contractAddress,\n uint256 tokenId,\n bool isLocked\n ) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n\n event DischargeApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event ReleaseApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event BreakBondApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event TimelockApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n\n event TokenDischargeTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenReleaseTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenBreakBondTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenTempLock(address indexed contractAddress, uint256 indexed tokenId, uint256 unlockBlock);\n\n event PermsSetForRestrictCharge(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowDischarge(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowRelease(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForRestrictBond(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowBreakBond(address indexed contractAddress, uint256 indexed tokenId, bool state);\n}\n" + }, + "contracts/v1/interfaces/IDai.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\ninterface IDai is IERC20Upgradeable {\n // --- Approve by signature ---\n function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external;\n function transferFrom(address src, address dst, uint wad) external override returns (bool);\n}" + }, + "contracts/v1/interfaces/IERC20Detailed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Detailed {\n function decimals() external view returns (uint8);\n function symbol() external view returns (string memory);\n function name() external view returns (string memory);\n\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(address sender, address recipient, uint256 amount) 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" + }, + "contracts/v1/interfaces/IERC721Chargeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IERC721Chargeable.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\n\ninterface IERC721Chargeable is IERC165Upgradeable {\n function owner() external view returns (address);\n function creatorOf(uint256 tokenId) external view returns (address);\n function balanceOf(address tokenOwner) external view returns (uint256 balance);\n function ownerOf(uint256 tokenId) external view returns (address tokenOwner);\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n function transferFrom(address from, address to, uint256 tokenId) external;\n function approve(address to, uint256 tokenId) external;\n function getApproved(uint256 tokenId) external view returns (address operator);\n function setApprovalForAll(address operator, bool _approved) external;\n function isApprovedForAll(address tokenOwner, address operator) external view returns (bool);\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "contracts/v1/interfaces/ILepton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ILepton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Lepton Interface\n * @dev ...\n */\ninterface ILepton {\n\n struct Classification {\n string tokenUri;\n uint256 price;\n uint128 _upperBounds;\n uint32 supply;\n uint32 multiplier;\n uint32 bonus;\n }\n\n function mintLepton() external payable returns (uint256 newTokenId);\n function batchMintLepton(uint256 count) external payable;\n function getNextType() external view returns (uint256);\n function getNextPrice() external view returns (uint256);\n function getMultiplier(uint256 tokenId) external view returns (uint256);\n function getBonus(uint256 tokenId) external view returns (uint256);\n\n\n event MaxMintPerTxSet(uint256 maxAmount);\n event LeptonTypeAdded(string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\n event LeptonTypeUpdated(uint256 leptonIndex, string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\n event LeptonMinted(address indexed receiver, uint256 indexed tokenId, uint256 price, uint32 multiplier);\n event LeptonBatchMinted(address indexed receiver, uint256 indexed tokenId, uint256 count, uint256 price, uint32 multiplier);\n event PausedStateSet(bool isPaused);\n}\n" + }, + "contracts/v1/interfaces/IMerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.6.0;\n\n// Allows anyone to claim a token if they exist in a merkle root.\ninterface IMerkleDistributor {\n // Returns the address of the token distributed by this contract.\n function token() external view returns (address);\n // Returns the merkle root of the merkle tree containing account balances available to claim.\n function merkleRoot() external view returns (bytes32);\n // Returns true if the index has been marked claimed.\n function isClaimed(uint256 index) external view returns (bool);\n // Claim the given amount of the token to the given address. Reverts if the inputs are invalid.\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external;\n\n // This event is triggered whenever a call to #claim succeeds.\n event Claimed(uint256 index, address account, uint256 amount);\n}" + }, + "contracts/v1/interfaces/IParticleSplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IParticleSplitter.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Particle Splitter\n */\ninterface IParticleSplitter {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function executeForWallet(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address externalAddress,\n bytes memory encodedParams\n ) external payable returns (bytes memory);\n\n function executeForBasket(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address externalAddress,\n bytes memory encodedParams\n ) external payable returns (bytes memory);\n\n function withdrawWalletRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n ) external returns (uint256 amountWithdrawn);\n\n function withdrawBasketRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n ) external returns (uint256 amountWithdrawn);\n\n function refreshWalletPrincipal(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external;\n\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event ChargedManagersSet(address indexed chargedManagers);\n event TokenInfoProxySet(address indexed tokenInfoProxy);\n\n event ExecuteForWallet(\n address indexed contractAddress,\n uint256 tokenId,\n string walletManagerId,\n address indexed externalAddress,\n bytes encodedParams,\n uint256 ethValue\n );\n event ExecuteForBasket(\n address indexed contractAddress,\n uint256 tokenId,\n string basketManagerId,\n address indexed externalAddress,\n bytes encodedParams,\n uint256 ethValue\n );\n event PrincipalRefreshed(\n address contractAddress,\n uint256 tokenId,\n string walletManagerId,\n address assetToken\n );\n event PermsSetForExternal(\n address indexed contractAddress,\n bool state\n );\n}\n" + }, + "contracts/v1/interfaces/IProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IProton is IERC721 {\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n event PausedStateSet(bool isPaused);\n event SalePriceSet(uint256 indexed tokenId, uint256 salePrice);\n event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct);\n event FeesWithdrawn(address indexed receiver, uint256 amount);\n event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties);\n event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view returns (address);\n function getSalePrice(uint256 tokenId) external view returns (uint256);\n function getLastSellPrice(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyalties(address account) external view returns (uint256);\n function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address);\n\n function buyProton(uint256 tokenId) external payable returns (bool);\n function claimCreatorRoyalties() external returns (uint256);\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n ) external returns (uint256 newTokenId);\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n ) external returns (uint256 newTokenId);\n\n function batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n ) external;\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice) external;\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external;\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external;\n}" + }, + "contracts/v1/interfaces/IProtonB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IProtonB is IERC721 {\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n ) external returns (uint256 newTokenId);\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n}" + }, + "contracts/v1/interfaces/IRewardNft.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IRewardNft.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Reward-NFT Interface\n * @dev ...\n */\ninterface IRewardNft {\n function getMultiplier(uint256 tokenId) external view returns (uint256);\n function getBonus(uint256 tokenId) external view returns (uint256);\n}\n" + }, + "contracts/v1/interfaces/IRewardProgram.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IRewardProgram.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\ninterface IRewardProgram {\n /* admin events */\n event RewardProgramFunded(uint256 amount);\n event RewardProgramOutOfFunds();\n\n /* user events */\n event RewardsClaimed(address indexed contractAddress, uint256 tokenId, address indexed receiver, uint256 rewarded, uint256 remaining);\n\n event AssetRegistered(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\n event AssetDeposit(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\n event AssetRelease(address indexed contractAddress, uint256 tokenId, uint256 interestAmount);\n\n /* data types */\n struct ProgramRewardData {\n address stakingToken;\n address rewardToken;\n uint256 baseMultiplier; // Basis Points\n }\n\n struct AssetStake {\n uint256 start;\n uint256 claimableRewards;\n string walletManagerId;\n }\n\n function initialize(address stakingToken, address rewardToken, uint256 baseMultiplier, address chargedManagers, address universe, address owner) external;\n\n /* user functions */\n function getProgramData() external view returns (ProgramRewardData memory programData);\n function getAssetStake(uint256 uuid) external view returns (AssetStake memory);\n function getFundBalance() external view returns (uint256);\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) external view returns (uint256);\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external;\n function registerAssetDeposit(address contractAddress, uint256 tokenId, string calldata walletManagerId, uint256 principalAmount) external;\n function registerAssetRelease(address contractAddress, uint256 tokenId, uint256 interestAmount) external returns (uint256 rewards);\n}" + }, + "contracts/v1/interfaces/ISmartBasket.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartBasket.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Basket\n * @dev Manages holding and transferring NFTs within an NFT (if any),\n */\ninterface ISmartBasket {\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function addToBasket(address contractAddress, uint256 tokenId) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId) external returns (bool);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartBasketB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartBasketB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Basket \"B\"\n * @dev Manages holding and transferring NFTs within an NFT (if any),\n */\ninterface ISmartBasketB {\n function getNestedNftCount() external view returns (uint256);\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool);\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Wallet\n * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any),\n */\ninterface ISmartWallet {\n function getAssetTokenCount() external view returns (uint256);\n function getAssetTokenByIndex(uint256 index) external view returns (address);\n\n function setNftCreator(address creator, uint256 annuityPct) external;\n\n function isReserveActive(address assetToken) external view returns (bool);\n function getReserveInterestToken(address assetToken) external view returns (address);\n\n function getPrincipal(address assetToken) external returns (uint256);\n function getInterest(address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getTotal(address assetToken) external returns (uint256);\n function getRewards(address assetToken) external returns (uint256);\n\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(address receiver, address creatorRedirect, address assetToken) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function withdrawAmount(address receiver, address creatorRedirect, address assetToken, uint256 assetAmount) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function withdrawAmountForCreator(address receiver, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address assetToken) external;\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Wallet\n * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any),\n */\ninterface ISmartWalletB {\n function getAssetTokenCount() external view returns (uint256);\n function getAssetTokenByIndex(uint256 index) external view returns (address);\n\n function isReserveActive(address assetToken) external view returns (bool);\n function getReserveInterestToken(address assetToken) external view returns (address);\n\n function getPrincipal(address assetToken) external returns (uint256);\n function getInterest(address assetToken, uint256 creatorPct) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getTotal(address assetToken) external returns (uint256);\n function getRewards(address assetToken) external returns (uint256);\n\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken\n ) external returns (\n uint256 creatorAmount,\n uint256 receiverAmount\n );\n function withdrawAmount(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n ) external returns (\n uint256 creatorAmount,\n uint256 receiverAmount\n );\n function withdrawAmountForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n ) external returns (\n uint256 receiverAmount\n );\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address assetToken) external;\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/IStaking.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\ninterface IStaking {\n function manualEpochInit(address[] memory tokens, uint128 epochId) external;\n function getCurrentEpoch() external view returns (uint128);\n function getEpochId(uint timestamp) external view returns (uint); // get epoch id\n function getEpochUserBalance(address user, address token, uint128 epoch) external view returns(uint);\n function getEpochPoolSize(address token, uint128 epoch) external view returns (uint);\n function epoch1Start() external view returns (uint);\n function epochDuration() external view returns (uint);\n}" + }, + "contracts/v1/interfaces/ITokenInfoProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfoProxy.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\n\ninterface ITokenInfoProxy {\n\n event ContractFunctionSignatureSet(address indexed contractAddress, string fnName, bytes4 fnSig);\n\n struct FnSignatures {\n bytes4 ownerOf;\n bytes4 creatorOf;\n }\n\n function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external;\n function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external;\n\n function getTokenUUID(address contractAddress, uint256 tokenId) external pure returns (uint256);\n function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external returns (bool);\n function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external returns (bool);\n function getTokenOwner(address contractAddress, uint256 tokenId) external returns (address);\n function getTokenCreator(address contractAddress, uint256 tokenId) external returns (address);\n}\n" + }, + "contracts/v1/interfaces/IUniverse.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IUniverse.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Universal Controller interface\n * @dev ...\n */\ninterface IUniverse {\n\n event ChargedParticlesSet(address indexed chargedParticles);\n event PhotonSet(address indexed photonToken, uint256 maxSupply);\n event ProtonTokenSet(address indexed protonToken);\n event LeptonTokenSet(address indexed leptonToken);\n event QuarkTokenSet(address indexed quarkToken);\n event BosonTokenSet(address indexed bosonToken);\n event EsaMultiplierSet(address indexed assetToken, uint256 multiplier);\n event ElectrostaticAttraction(address indexed account, address photonSource, uint256 energy, uint256 multiplier);\n event ElectrostaticDischarge(address indexed account, address photonSource, uint256 energy);\n\n function onEnergize(\n address sender,\n address referrer,\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 assetEnergy\n ) external;\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n ) external;\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address creator,\n address assetToken,\n uint256 receiverEnergy\n ) external;\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 principalEnergy,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n ) external;\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n ) external;\n}\n" + }, + "contracts/v1/interfaces/IUniverseRP.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IUniverseRP.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport \"./IUniverse.sol\";\n\n/**\n * @title Universal Controller interface for Rewards Program\n * @dev ...\n */\ninterface IUniverseRP is IUniverse {\n event RewardProgramSet(address indexed assetToken, address indexed rewardProgram);\n event RewardProgramRemoved(address indexed assetToken);\n event NftDeposit(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\n event NftRelease(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\n\n struct NftStake {\n uint256 multiplier; // in Basis Points\n uint256 depositBlockNumber;\n uint256 releaseBlockNumber;\n }\n\n function getRewardProgram(address asset) external view returns (address);\n function getNftStake(uint256 uuid) external view returns (NftStake memory);\n}\n" + }, + "contracts/v1/interfaces/IWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Particle Wallet Manager interface\n * @dev The wallet-manager for underlying assets attached to Charged Particles\n * @dev Manages the link between NFTs and their respective Smart-Wallets\n */\ninterface IWalletManager {\n\n event ControllerSet(address indexed controller);\n event ExecutorSet(address indexed executor);\n event PausedStateSet(bool isPaused);\n event NewSmartWallet(address indexed contractAddress, uint256 indexed tokenId, address indexed smartWallet, address creator, uint256 annuityPct);\n event WalletEnergized(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 assetAmount, uint256 yieldTokensAmount);\n event WalletDischarged(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 creatorAmount, uint256 receiverAmount);\n event WalletDischargedForCreator(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, address creator, uint256 receiverAmount);\n event WalletReleased(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address assetToken, uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n event WalletRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\n\n function isPaused() external view returns (bool);\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view returns (bool);\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view returns (address);\n\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\n function getInterest(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken) external returns (uint256);\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount) external returns (uint256 yieldTokensAmount);\n function discharge(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function dischargeAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function dischargeAmountForCreator(address receiver, address contractAddress, uint256 tokenId, address creator, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\n function release(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n function releaseAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken) external;\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct) external returns (address);\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\n}\n" + }, + "contracts/v1/leptons/store.sol": { + "content": "pragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../tokens/Ionx.sol\";\nimport \"../tokens/Lepton2.sol\";\n\ninterface ILepsonsStore {\n function load(uint256 amount) external payable;\n function setLepton(address _lepton) external;\n}\n\ncontract LeptonsStore is ILepsonsStore, IERC721Receiver, Ownable, BlackholePrevention {\n using SafeMath for uint256;\n\n event SoldLepton(address indexed buyer, uint256 amount, uint256 price);\n\n Lepton2 public lepton;\n Ionx public ionx;\n\n uint256 internal nextTokenId;\n uint256 public ionxPerLepton;\n\n constructor(address _lepton, address _ionx, uint256 _ionxPerLepton) public {\n lepton = Lepton2(_lepton);\n ionx = Ionx(_ionx);\n ionxPerLepton = _ionxPerLepton;\n }\n\n function buyWithIonx(\n uint256 leptonAmount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n uint256 ionxAmount = leptonAmount * ionxPerLepton;\n require(ionx.balanceOf(msg.sender) >= ionxAmount, \"Insufficient IONX balance\");\n\n ionx.permit(msg.sender, address(this), ionxAmount, deadline, v, r, s);\n ionx.transferFrom(msg.sender, address(this), ionxAmount);\n\n for (uint256 i = 0; i < leptonAmount; ++i) {\n uint256 tokenId = nextTokenId;\n nextTokenId = nextTokenId.add(1);\n\n lepton.safeTransferFrom(address(this), msg.sender, tokenId);\n }\n\n emit SoldLepton(msg.sender, leptonAmount, ionxAmount);\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function load(uint256 amount) external payable override onlyOwner {\n require(lepton.balanceOf(address(this)) == 0, \"store not empty\");\n nextTokenId = lepton.totalSupply().add(1);\n lepton.batchMintLepton{ value: msg.value }(amount);\n }\n\n function setLepton(address _lepton) external override onlyOwner {\n require(_lepton != address(0), \"Invalid address\");\n lepton = Lepton2(_lepton);\n }\n\n function setIonx(address _ionx) external onlyOwner {\n require(_ionx != address(0), \"Invalid address\");\n ionx = Ionx(_ionx);\n }\n\n function setIonxPerLepton(uint256 ionxAmount) external onlyOwner {\n ionxPerLepton = ionxAmount;\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n}" + }, + "contracts/v1/lib/BaseProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IBaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n/// @title Base Proton Contract for Charged Particles compatible ERC721 NFTs\n/// @dev MUST NOT be Upgradeable, as Upgradeable NFTs are incompatible with Charged Particles.\ncontract BaseProton is \n IBaseProton, \n ERC721, \n Ownable, \n RelayRecipient, \n ReentrancyGuard, \n BlackholePrevention \n{\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n event Received(address, uint);\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n /// @dev Sequential Token IDs storage\n Counters.Counter internal _tokenIds;\n\n /// @dev NFT Token Creator settings\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct;\n mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect;\n mapping (address => uint256) internal _tokenCreatorClaimableRoyalties;\n\n /// @dev NFT Token Sale settings\n mapping (uint256 => uint256) internal _tokenSalePrice;\n mapping (uint256 => uint256) internal _tokenLastSellPrice;\n\n /// @dev Whether of not the Contract is Paused\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n /// @dev Inherit from ERC721 standard\n constructor(string memory _name, string memory _symbol) public ERC721(_name, _symbol) {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n receive() external payable virtual {\n emit Received(msg.sender, msg.value);\n }\n\n /// Returns the Creator address of an NFT by Token ID\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The address of the Creator account\n function creatorOf(uint256 tokenId) external view virtual override returns (address) {\n return _tokenCreator[tokenId];\n }\n\n /// Returns the Sale Price of an NFT by Token ID\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The sale price of the NFT\n function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenSalePrice[tokenId];\n }\n\n /// Returns the Last Sale Price of an NFT by Token ID\n /// @notice This is used to determine any increase in sale price used in royalties calculations\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The last sale price of the NFT\n function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenLastSellPrice[tokenId];\n }\n\n /// Returns the Claimable Royalties for the NFT Creator\n /// @param account The address of the Creator account to lookup\n /// @return The amount of earned royalties for the creator account\n function getCreatorRoyalties(address account) external view virtual override returns (uint256) {\n return _tokenCreatorClaimableRoyalties[account];\n }\n\n /// Returns the Percentage of Royalties reserved for the NFT Creator\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The percentage of royalties reserved for the creator\n function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenCreatorRoyaltiesPct[tokenId];\n }\n\n /// Returns the Receiving address of the Creator Royalties (or Creator if not set)\n /// @dev Returns the creator address if a receiving address has not been configured\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The Receiving address of the Creator Royalties\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) {\n return _creatorRoyaltiesReceiver(tokenId);\n }\n\n /// Allows an NFT Creator to Claim any Royalties that have been earned from NFT sales\n /// @dev Must be called by the royalties receiver account (not neccessarily the creator)\n /// @return The amout of creator royalties claimed\n function claimCreatorRoyalties()\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256)\n {\n return _claimCreatorRoyalties(_msgSender());\n }\n\n\n /***********************************|\n | Create Single Protons |\n |__________________________________*/\n\n /// Creates a Basic NFT with no Royalties and no initial Sale Price\n /// @dev Royalties and Sale Price can be configured later\n /// @param creator The address of the NFT Creator (can be different from the caller)\n /// @param receiver The receiving address of the NFT (can be different from the caller)\n /// @param tokenMetaUri The unique metadata URI for the NFT\n /// @return newTokenId The newly minted NFT Token ID\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n\n /***********************************|\n | Create Multiple Protons |\n |__________________________________*/\n\n function createProtons(\n address creator,\n address receiver,\n string[] calldata tokenMetaUris\n )\n external\n virtual\n override\n whenNotPaused\n returns (bool)\n {\n _createProtons(\n creator,\n receiver,\n 0, // royaltiesPercent\n tokenMetaUris\n );\n return true;\n }\n\n function createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n external\n virtual\n override\n whenNotPaused\n returns (bool)\n {\n _createProtonsForSale(\n creator,\n receiver,\n royaltiesPercent,\n tokenMetaUris,\n salePrices\n );\n return true;\n }\n\n\n /***********************************|\n | Buy Protons |\n |__________________________________*/\n\n function buyProton(uint256 tokenId, uint256 gasLimit)\n external\n payable\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (bool)\n {\n _buyProton(tokenId, gasLimit);\n return true;\n }\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice)\n external\n virtual\n override\n whenNotPaused\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setSalePrice(tokenId, salePrice);\n }\n\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setRoyaltiesPct(tokenId, royaltiesPct);\n }\n\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n {\n _tokenCreatorRoyaltiesRedirect[tokenId] = receiver;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual {\n _tokenSalePrice[tokenId] = salePrice;\n emit SalePriceSet(tokenId, salePrice);\n }\n\n function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual {\n require(royaltiesPct <= PERCENTAGE_SCALE, \"PRT:E-421\");\n _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct;\n emit CreatorRoyaltiesSet(tokenId, royaltiesPct);\n }\n\n function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) {\n address receiver = _tokenCreatorRoyaltiesRedirect[tokenId];\n if (receiver == address(0x0)) {\n receiver = _tokenCreator[tokenId];\n }\n return receiver;\n }\n\n function _createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n _tokenIds.increment();\n\n newTokenId = _tokenIds.current();\n _safeMint(receiver, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUri);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n }\n\n function _createProtons(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris\n )\n internal\n virtual\n {\n uint256 count = tokenMetaUris.length;\n for (uint256 i; i < count; i++) {\n _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, 0);\n }\n }\n\n function _createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n internal\n virtual\n {\n require(tokenMetaUris.length == salePrices.length, \"PRT:E-202\");\n\n uint256 count = tokenMetaUris.length;\n for (uint256 i; i < count; i++) {\n _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, salePrices[i]);\n }\n }\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n contractAddress = address(this);\n tokenId = _tokenId;\n salePrice = _tokenSalePrice[_tokenId];\n require(salePrice > 0, \"PRT:E-416\");\n require(msg.value >= salePrice, \"PRT:E-414\");\n\n uint256 ownerAmount = salePrice;\n creatorAmount;\n oldOwner = ownerOf(_tokenId);\n newOwner = _msgSender();\n\n // Creator Royalties\n royaltiesReceiver = _creatorRoyaltiesReceiver(_tokenId);\n uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[_tokenId];\n uint256 lastSellPrice = _tokenLastSellPrice[_tokenId];\n if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) {\n creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE);\n ownerAmount = ownerAmount.sub(creatorAmount);\n }\n _tokenLastSellPrice[_tokenId] = salePrice;\n\n // Reserve Royalties for Creator\n if (creatorAmount > 0) {\n _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount);\n }\n\n // Transfer Token\n _transfer(oldOwner, newOwner, _tokenId);\n\n // Transfer Payment\n if (ownerAmount > 0) {\n payable(oldOwner).sendValue(ownerAmount, _gasLimit);\n }\n\n emit ProtonSold(_tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n\n _refundOverpayment(salePrice, _gasLimit);\n }\n\n /**\n * @dev Pays out the Creator Royalties of the calling account\n * @param receiver The receiver of the claimable royalties\n * @return The amount of Creator Royalties claimed\n */\n function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) {\n uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver];\n require(claimableAmount > 0, \"PRT:E-411\");\n\n delete _tokenCreatorClaimableRoyalties[receiver];\n payable(receiver).sendValue(claimableAmount, 0);\n\n emit RoyaltiesClaimed(receiver, claimableAmount);\n }\n\n /**\n * @dev Collects the Required Asset Token from the users wallet\n * @param from The owner address to collect the Assets from\n * @param assetAmount The Amount of Asset Tokens to Collect\n */\n function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual {\n uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from);\n require(assetAmount <= _userAssetBalance, \"PRT:E-411\");\n // Be sure to Approve this Contract to transfer your Asset Token\n require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), \"PRT:E-401\");\n }\n\n function _refundOverpayment(uint256 threshold, uint256 gasLimit) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage, gasLimit);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n _tokenSalePrice[tokenId] = 0;\n super._transfer(from, to, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"PRT:E-101\");\n _;\n }\n\n modifier onlyTokenOwnerOrApproved(uint256 tokenId) {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"PRT:E-105\");\n _;\n }\n\n modifier onlyTokenCreator(uint256 tokenId) {\n require(_tokenCreator[tokenId] == _msgSender(), \"PRT:E-104\");\n _;\n }\n}" + }, + "contracts/v1/lib/Bitwise.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Bitwise.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nlibrary Bitwise {\n function negate(uint32 a) internal pure returns (uint32) {\n return a ^ maxInt();\n }\n\n function shiftLeft(uint32 a, uint32 n) internal pure returns (uint32) {\n return a * uint32(2) ** n;\n }\n\n function shiftRight(uint32 a, uint32 n) internal pure returns (uint32) {\n return a / uint32(2) ** n;\n }\n\n function maxInt() internal pure returns (uint32) {\n return uint32(-1);\n }\n\n // Get bit value at position\n function hasBit(uint32 a, uint32 n) internal pure returns (bool) {\n return a & shiftLeft(0x01, n) != 0;\n }\n\n // Set bit value at position\n function setBit(uint32 a, uint32 n) internal pure returns (uint32) {\n return a | shiftLeft(0x01, n);\n }\n\n // Set the bit into state \"false\"\n function clearBit(uint32 a, uint32 n) internal pure returns (uint32) {\n uint32 mask = negate(shiftLeft(0x01, n));\n return a & mask;\n }\n}\n" + }, + "contracts/v1/lib/BlackholePrevention.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\n\n/**\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\n * the Owner/DAO to pull them out on behalf of a user\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\n */\ncontract BlackholePrevention {\n using Address for address payable;\n using SafeERC20 for IERC20;\n\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\n\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (address(this).balance >= amount) {\n receiver.sendValue(amount);\n emit WithdrawStuckEther(receiver, amount);\n }\n }\n\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\n IERC20(tokenAddress).safeTransfer(receiver, amount);\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\n }\n }\n\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\n }\n }\n\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \"\");\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\n }\n }\n}\n" + }, + "contracts/v1/lib/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/GSN/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableMap.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n /**\n * @dev Emitted when `tokenId` token is transfered from `from` to `to`.\n */\n event TransferBatch(address indexed from, address indexed to, uint256 startTokenId, uint256 count);\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721:E-403\");\n\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721:E-405\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"ERC721:E-405\");\n return _tokenURIs[tokenId];\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721:E-111\");\n\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \"ERC721:E-105\");\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view override returns (address) {\n require(_exists(tokenId), \"ERC721:E-405\");\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 require(operator != _msgSender(), \"ERC721:E-111\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721:E-402\");\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 returns (bool) {\n return _tokenOwners.contains(tokenId);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721:E-405\");\n address owner = ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721:E-402\");\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 _safeMintBatch(address to, uint256 startTokenId, uint256 count, bytes memory _data) internal virtual {\n _mintBatch(to, startTokenId, count);\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \"ERC721:E-402\");\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:E-403\");\n require(!_exists(tokenId), \"ERC721:E-407\");\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\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 _mintBatch(address to, uint256 startTokenId, uint256 count) internal virtual {\n require(to != address(0), \"ERC721:E-403\");\n require(!_exists(startTokenId), \"ERC721:E-407\");\n\n for (uint i = 0; i < count; i++) {\n uint256 tokenId = startTokenId.add(i);\n _holderTokens[to].add(tokenId);\n _tokenOwners.set(tokenId, to);\n }\n\n emit TransferBatch(address(0), to, startTokenId, count);\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(address from, address to, uint256 tokenId) internal virtual {\n require(ownerOf(tokenId) == from, \"ERC721:E-102\");\n require(to != address(0), \"ERC721:E-403\");\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721:E-405\");\n _tokenURIs[tokenId] = _tokenURI;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721:E-402\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\n }\n}\n" + }, + "contracts/v1/lib/ERC721Basic.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/GSN/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Basic is Context, ERC165, IERC721, IERC721Metadata {\n using SafeMath for uint256;\n using Address for address;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 internal constant _ERC721_RECEIVED = 0x150b7a02;\n\n // mapping from token ids to their owners\n mapping (uint256 => address) internal _tokenOwners;\n\n // mapping from owner to token balance\n mapping (address => uint256) internal _ownerBalance;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) internal _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) internal _operatorApprovals;\n\n // Token name\n string internal _name;\n\n // Token symbol\n string internal _symbol;\n\n // Token Count\n uint256 internal _tokenCount;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 internal constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 internal constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721:E-403\");\n return _ownerBalance[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners[tokenId];\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view 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 return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721:E-111\");\n\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \"ERC721:E-105\");\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view override returns (address) {\n require(_exists(tokenId), \"ERC721:E-405\");\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721:E-111\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721:E-402\");\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 returns (bool) {\n return _tokenOwners[tokenId] != address(0x0);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721:E-405\");\n address owner = ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\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(address to, bytes memory _data) internal virtual returns (uint256) {\n uint256 tokenId = _mint(to);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721:E-402\");\n return 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 _safeMintBatch(address to, uint256 count, bytes memory _data) internal virtual {\n uint256 startTokenId = _mintBatch(to, count);\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \"ERC721:E-402\");\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) internal virtual returns (uint256) {\n require(to != address(0), \"ERC721:E-403\");\n\n _tokenCount = _tokenCount.add(1);\n uint256 tokenId = _tokenCount;\n require(!_exists(tokenId), \"ERC721:E-407\");\n\n _tokenOwners[tokenId] = to;\n _ownerBalance[to] = _ownerBalance[to].add(1);\n\n emit Transfer(address(0), to, tokenId);\n return tokenId;\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 _mintBatch(address to, uint256 count) internal virtual returns (uint256) {\n require(to != address(0), \"ERC721:E-403\");\n\n uint256 startTokenId = _tokenCount.add(1);\n for (uint i = 1; i <= count; i++) {\n uint256 tokenId = _tokenCount.add(i);\n _tokenOwners[tokenId] = to;\n emit Transfer(address(0), to, tokenId);\n }\n\n _tokenCount = _tokenCount.add(count);\n _ownerBalance[to] = _ownerBalance[to].add(count);\n return startTokenId;\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(address from, address to, uint256 tokenId) internal virtual {\n require(ownerOf(tokenId) == from, \"ERC721:E-102\");\n require(to != address(0), \"ERC721:E-403\");\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _tokenOwners[tokenId] = to;\n _ownerBalance[from] = _ownerBalance[from].sub(1);\n _ownerBalance[to] = _ownerBalance[to].add(1);\n\n emit Transfer(from, to, tokenId);\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(address from, address to, uint256 tokenId, bytes memory _data)\n internal returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721:E-402\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) internal {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\n }\n}\n" + }, + "contracts/v1/lib/IERC5192.sol": { + "content": "// SPDX-License-Identifier: CC0-1.0\npragma solidity ^0.6.0;\n\ninterface IERC5192 {\n /// @notice Emitted when the locking status is changed to locked.\n /// @dev If a token is minted and the status is locked, this event should be emitted.\n /// @param tokenId The identifier for a token.\n event Locked(uint256 tokenId);\n\n /// @notice Emitted when the locking status is changed to unlocked.\n /// @dev If a token is minted and the status is unlocked, this event should be emitted.\n /// @param tokenId The identifier for a token.\n event Unlocked(uint256 tokenId);\n\n /// @notice Returns the locking status of an Soulbound Token\n /// @dev SBTs assigned to zero address are considered invalid, and queries\n /// about them do throw.\n /// @param tokenId The identifier for an SBT.\n function locked(uint256 tokenId) external view returns (bool);\n}\n" + }, + "contracts/v1/lib/NftTokenType.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// NftTokenType.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/introspection/IERC165.sol\";\n\nlibrary NftTokenType {\n bytes4 constant internal INTERFACE_SIGNATURE_ERC721 = 0x80ac58cd;\n bytes4 constant internal INTERFACE_SIGNATURE_ERC1155 = 0xd9b67a26;\n\n uint256 constant internal TYPE_MASK = uint256(uint128(~0)) << 128;\n uint256 constant internal TYPE_NFT_BIT = 1 << 255;\n\n function isERC721(address contractAddress) internal view returns (bool) {\n return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC721);\n }\n\n function isERC1155(address contractAddress) internal view returns (bool) {\n return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC1155);\n }\n\n function getTokenType(address contractAddress, uint256 tokenId) internal view returns (uint256) {\n IERC165 tokenInterface = IERC165(contractAddress);\n bool is1155 = tokenInterface.supportsInterface(INTERFACE_SIGNATURE_ERC1155);\n\n if (!is1155 || (tokenId & TYPE_NFT_BIT != TYPE_NFT_BIT)) { return 0; }\n\n return tokenId & TYPE_MASK;\n }\n}\n" + }, + "contracts/v1/lib/ReentrancyGuard.sol": { + "content": "pragma solidity 0.6.12;\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 () public {\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 _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\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 /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}" + }, + "contracts/v1/lib/RelayRecipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0;\n\nimport \"@opengsn/gsn/contracts/BaseRelayRecipient.sol\";\n\ncontract RelayRecipient is BaseRelayRecipient {\n function versionRecipient() external override view returns (string memory) {\n return \"1.0.0-beta.1/charged-particles.relay.recipient\";\n }\n}\n" + }, + "contracts/v1/lib/SmartWalletBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// SmartWalletBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../interfaces/ISmartWallet.sol\";\nimport \"./BlackholePrevention.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract SmartWalletBase is ISmartWallet, BlackholePrevention {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n address internal _walletManager;\n\n address internal nftCreator;\n uint256 internal nftCreatorAnnuityPct;\n uint256 internal nftCreatorAmountDischarged;\n\n EnumerableSet.AddressSet internal _assetTokens;\n\n // Asset Token => Principal Balance\n mapping (address => uint256) internal _assetPrincipalBalance;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initializeBase() public {\n require(_walletManager == address(0x0), \"SWB:E-002\");\n _walletManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getAssetTokenCount() external view virtual override returns (uint256) {\n return _assetTokens.length();\n }\n\n function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) {\n if (index >= _assetTokens.length()) {\n return address(0);\n }\n return _assetTokens.at(index);\n }\n\n function setNftCreator(address creator, uint256 annuityPct) external virtual override onlyWalletManager {\n nftCreator = creator;\n nftCreatorAnnuityPct = annuityPct;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyWalletManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n function refreshPrincipal(address assetToken)\n external\n virtual\n override\n onlyWalletManager\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getPrincipal(address assetToken) internal view virtual returns (uint256) {\n return _assetPrincipalBalance[assetToken];\n }\n\n function _trackAssetToken(address assetToken) internal virtual {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n }\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the wallet manager\n modifier onlyWalletManager() {\n require(_walletManager == msg.sender, \"SWB:E-109\");\n _;\n }\n}" + }, + "contracts/v1/lib/SmartWalletBaseB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// SmartWalletBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../interfaces/ISmartWalletB.sol\";\nimport \"./BlackholePrevention.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract SmartWalletBaseB is ISmartWalletB, BlackholePrevention {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n address internal _walletManager;\n\n EnumerableSet.AddressSet internal _assetTokens;\n\n // Asset Token => Principal Balance\n mapping (address => uint256) internal _assetPrincipalBalance;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initializeBase() public {\n require(_walletManager == address(0x0), \"SWB:E-002\");\n _walletManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getAssetTokenCount() external view virtual override returns (uint256) {\n return _assetTokens.length();\n }\n\n function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) {\n if (index >= _assetTokens.length()) {\n return address(0);\n }\n return _assetTokens.at(index);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyWalletManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getPrincipal(address assetToken) internal view virtual returns (uint256) {\n return _assetPrincipalBalance[assetToken];\n }\n\n function _trackAssetToken(address assetToken) internal virtual {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n }\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the wallet manager\n modifier onlyWalletManager() {\n require(_walletManager == msg.sender, \"SWB:E-109\");\n _;\n }\n}" + }, + "contracts/v1/lib/Soul.sol": { + "content": "// SPDX-License-Identifier: CC0-1.0\npragma solidity ^0.6.12;\n\nimport \"./IERC5192.sol\";\n\ncontract Soul is IERC5192 {\n \n mapping (uint256 => bool) public lockedTokens;\n\n function _lockToken(uint256 tokenId) internal {\n lockedTokens[tokenId] = true;\n emit Locked(tokenId);\n }\n\n function _unlockToken(uint256 tokenId) internal {\n lockedTokens[tokenId] = false;\n emit Unlocked(tokenId);\n }\n\n function locked(uint256 tokenId)\n external\n view\n override(IERC5192)\n returns (bool)\n {\n return lockedTokens[tokenId];\n }\n}\n" + }, + "contracts/v1/lib/TokenInfo.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfo.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"../interfaces/IERC721Chargeable.sol\";\n\nlibrary TokenInfo {\n function getTokenUUID(address contractAddress, uint256 tokenId) internal pure virtual returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n function getTokenOwner(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n return tokenInterface.ownerOf(tokenId);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n function getTokenCreator(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n return tokenInterface.creatorOf(tokenId);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Owner of an External NFT contract\n /// @param contractAddress The Address to the Contract of the NFT to check\n /// @param account The Address of the Account to check\n /// @return True if the account owns the contract\n function isContractOwner(address contractAddress, address account) internal view virtual returns (bool) {\n address contractOwner = IERC721Chargeable(contractAddress).owner();\n return contractOwner != address(0x0) && contractOwner == account;\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Creator of a Proton-based NFT\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the Proton-based NFT\n function isTokenCreator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenCreator = tokenInterface.creatorOf(tokenId);\n return (sender == tokenCreator);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the Proton-based NFT or the Contract itself\n function isTokenContractOrCreator(address contractAddress, uint256 tokenId, address creator, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenCreator = tokenInterface.creatorOf(tokenId);\n if (sender == contractAddress && creator == tokenCreator) { return true; }\n return (sender == tokenCreator);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Owner or Operator of an External NFT\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the Owner or Operator of the External NFT\n function isErc721OwnerOrOperator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenOwner = tokenInterface.ownerOf(tokenId);\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\n }\n\n /**\n * @dev Returns true if `account` is a contract.\n * @dev Taken from OpenZeppelin library\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\n // for accounts without code, i.e. `keccak256('')`\n bytes32 codehash;\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n // solhint-disable-next-line no-inline-assembly\n assembly { codehash := extcodehash(account) }\n return (codehash != accountHash && codehash != 0x0);\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 * @dev Taken from OpenZeppelin library\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, uint256 gasLimit) internal {\n require(address(this).balance >= amount, \"TokenInfo: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = (gasLimit > 0)\n ? recipient.call{ value: amount, gas: gasLimit }(\"\")\n : recipient.call{ value: amount }(\"\");\n require(success, \"TokenInfo: unable to send value, recipient may have reverted\");\n }\n}\n" + }, + "contracts/v1/lib/TokenInfoProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfoProxy.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../interfaces/ITokenInfoProxy.sol\";\nimport \"../interfaces/IERC721Chargeable.sol\";\n\n\ncontract TokenInfoProxy is ITokenInfoProxy, Ownable {\n using Address for address;\n\n mapping (address => FnSignatures) internal _remappedFnSigs;\n\n function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner {\n _remappedFnSigs[contractAddress].ownerOf = fnSig;\n emit ContractFunctionSignatureSet(contractAddress, \"ownerOf\", fnSig);\n }\n\n function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner {\n _remappedFnSigs[contractAddress].creatorOf = fnSig;\n emit ContractFunctionSignatureSet(contractAddress, \"creatorOf\", fnSig);\n }\n\n\n function getTokenUUID(address contractAddress, uint256 tokenId) external pure virtual override returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n function getTokenOwner(address contractAddress, uint256 tokenId) external virtual override returns (address) {\n return _getTokenOwner(contractAddress, tokenId);\n }\n\n function getTokenCreator(address contractAddress, uint256 tokenId) external virtual override returns (address) {\n return _getTokenCreator(contractAddress, tokenId);\n }\n\n function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenOwner = _getTokenOwner(contractAddress, tokenId);\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\n }\n\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the NFT or the Contract itself\n function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) {\n address tokenCreator = _getTokenCreator(contractAddress, tokenId);\n return (sender == tokenCreator || sender == contractAddress);\n }\n\n\n\n function _getTokenCreator(address contractAddress, uint256 tokenId) internal returns (address) {\n bytes4 fnSig = IERC721Chargeable.creatorOf.selector;\n if (_remappedFnSigs[contractAddress].creatorOf != bytes4(0)) {\n fnSig = _remappedFnSigs[contractAddress].creatorOf;\n }\n\n // solhint-disable-next-line\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n if (success) {\n return abi.decode(returnData, (address));\n } else {\n return address(0x0);\n }\n }\n\n function _getTokenOwner(address contractAddress, uint256 tokenId) internal returns (address) {\n bytes4 fnSig = IERC721Chargeable.ownerOf.selector;\n if (_remappedFnSigs[contractAddress].ownerOf != bytes4(0)) {\n fnSig = _remappedFnSigs[contractAddress].ownerOf;\n }\n\n // solhint-disable-next-line\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n if (success) {\n return abi.decode(returnData, (address));\n } else {\n return address(0x0);\n }\n }\n}\n" + }, + "contracts/v1/lib/WalletManagerBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// WalletManagerBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IWalletManager.sol\";\nimport \"../interfaces/ISmartWallet.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"./BlackholePrevention.sol\";\n\n\n/**\n * @notice Wallet-Manager Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract WalletManagerBase is Ownable, BlackholePrevention, IWalletManager {\n using TokenInfo for address;\n\n // The Controller Contract Address\n address internal _controller;\n\n // The Executor Contract Address\n address internal _executor;\n\n // Template Contract for creating Token Smart-Wallet Bridges\n address internal _walletTemplate;\n\n // TokenID => Token Smart-Wallet Address\n mapping (uint256 => address) internal _wallets;\n\n // State of Wallet Manager\n bool internal _paused;\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Wallet Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n /**\n * @dev Connects to the ExecForAccount Controller\n */\n function setExecutor(address executor) external onlyOwner {\n _executor = executor;\n emit ExecutorSet(executor);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartWallet(wallet).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartWallet(wallet).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartWallet(wallet).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Executor contract\n modifier onlyExecutor() {\n require(_executor == msg.sender, \"WMB:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Controller or Executor contract\n modifier onlyControllerOrExecutor() {\n require(_executor == msg.sender || _controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"WMB:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/ParticleSplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ParticleSplitter.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"./interfaces/IParticleSplitter.sol\";\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IWalletManager.sol\";\nimport \"./interfaces/IBasketManager.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Contract\n * @dev Upgradeable Contract\n */\ncontract ParticleSplitter is IParticleSplitter, Ownable, ReentrancyGuard, BlackholePrevention\n{\n IChargedManagers internal _chargedManagers;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n mapping (address => bool) internal _externalAddressesAllowed;\n\n\n /***********************************|\n | Execute for Account |\n |__________________________________*/\n\n /// @notice Executes an arbitrary command on an NFT Wallet\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Wallet Manager controlling the NFT Wallet to execute on\n /// @param externalAddress The Address of the External Contract to execute on\n /// @param encodedParams The encoded function call to execute\n function executeForWallet(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address externalAddress,\n bytes memory encodedParams\n )\n external\n payable\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (bytes memory)\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n require(_externalAddressesAllowed[externalAddress], \"PS:E-117\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Wallet Manager\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n // Get Address of Wallet to send any ETH into\n if (msg.value > 0) {\n address wallet = walletMgr.getWalletAddressById(contractAddress, tokenId, address(0), 0);\n payable(wallet).sendValue(msg.value);\n }\n\n emit ExecuteForWallet(contractAddress, tokenId, walletManagerId, externalAddress, encodedParams, msg.value);\n\n // Execute command for NFT Wallet\n return walletMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams);\n }\n\n /// @notice Executes an arbitrary command on an NFT Basket\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param basketManagerId The Basket Manager controlling the NFT Wallet to execute on\n /// @param externalAddress The Address of the External Contract to execute on\n /// @param encodedParams The encoded function call to execute\n function executeForBasket(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address externalAddress,\n bytes memory encodedParams\n )\n external\n payable\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (bytes memory)\n {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"PS:E-419\");\n require(_externalAddressesAllowed[externalAddress], \"PS:E-117\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Basket Manager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n\n // Get Address of Wallet to send any ETH into\n if (msg.value > 0) {\n address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId);\n payable(wallet).sendValue(msg.value);\n }\n\n emit ExecuteForBasket(contractAddress, tokenId, basketManagerId, externalAddress, encodedParams, msg.value);\n\n // Execute command for NFT Wallet\n return basketMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams);\n }\n\n function withdrawWalletRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (uint256 amountWithdrawn)\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Wallet Manager\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n // Withdraw Rewards for NFT Wallet\n return walletMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount);\n }\n\n function withdrawBasketRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (uint256 amountWithdrawn)\n {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"PS:E-419\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Basket Manager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n\n // Withdraw Rewards for NFT Basket\n return basketMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount);\n }\n\n function refreshWalletPrincipal(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n walletMgr.refreshPrincipal(contractAddress, tokenId, assetToken);\n\n emit PrincipalRefreshed(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedManagers Interface\n */\n function setChargedManagers(address chargedManagers) external virtual onlyOwner {\n _chargedManagers = IChargedManagers(chargedManagers);\n emit ChargedManagersSet(chargedManagers);\n }\n\n /**\n * @dev Setup the ChargedManagers Interface\n */\n function setTokenInfoProxy(address tokenInfoProxy) external virtual onlyOwner {\n _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy);\n emit TokenInfoProxySet(tokenInfoProxy);\n }\n\n /**\n * @dev Allows/Disallows execute from on specific contracts\n */\n function setExternalContracts(address[] calldata contracts, bool state) external onlyOwner {\n uint count = contracts.length;\n for (uint i; i < count; i++) {\n address externalContract = contracts[i];\n _externalAddressesAllowed[externalContract] = state;\n emit PermsSetForExternal(externalContract, state);\n }\n }\n\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyTokenOwner(address contractAddress, uint256 tokenId) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(msg.sender == tokenOwner, \"PS:E-102\");\n _;\n }\n}\n" + }, + "contracts/v1/test/Dai.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"../interfaces/IDai.sol\";\n\ncontract Dai is IDai {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (uint256 chainId_) public {\n string memory version = \"1\";\n\n _name = \"Dai Stablecoin\";\n _symbol = \"DAI\";\n _decimals = 18;\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(_name)),\n keccak256(bytes(version)),\n chainId_,\n address(this)\n )\n );\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view 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(msg.sender, 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(msg.sender, 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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(msg.sender, spender, _allowances[msg.sender][spender].add(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 _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20:E-403\");\n require(recipient != address(0), \"ERC20:E-403\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20:E-403\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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:E-403\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20:E-403\");\n require(spender != address(0), \"ERC20:E-403\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n\n mapping (address => uint) public nonces;\n\n // --- EIP712 niceties ---\n bytes32 public DOMAIN_SEPARATOR;\n // bytes32 public constant PERMIT_TYPEHASH = keccak256(\"Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)\");\n bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;\n\n // --- Approve by signature ---\n function permit(\n address holder, address spender, uint256 nonce, uint256 expiry,\n bool allowed, uint8 v, bytes32 r, bytes32 s) external override\n {\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n holder,\n spender,\n nonce,\n expiry,\n allowed\n )\n )\n )\n );\n\n require(holder != address(0), \"Dai/invalid-address-0\");\n require(holder == ecrecover(digest, v, r, s), \"Dai/invalid-permit\");\n require(expiry == 0 || now <= expiry, \"Dai/permit-expired\");\n require(nonce == nonces[holder]++, \"Dai/invalid-nonce\");\n uint wad = allowed ? uint(-1) : 0;\n _allowances[holder][spender] = wad;\n emit Approval(holder, spender, wad);\n }\n\n function mint(address to, uint256 amount) external {\n _mint(to, amount);\n }\n}" + }, + "contracts/v1/test/ERC20Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.7.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/**\n * @dev Extension of {ERC20} that adds a set of accounts with the {MinterRole},\n * which have permission to mint (create) new tokens as they see fit.\n *\n * At construction, the deployer of the contract is the only minter.\n */\ncontract ERC20Mintable is ERC20Upgradeable {\n\n constructor(string memory _name, string memory _symbol) public {\n __ERC20_init(_name, _symbol);\n }\n\n /**\n * @dev See {ERC20-_mint}.\n *\n * Requirements:\n *\n * - the caller must have the {MinterRole}.\n */\n function mint(address account, uint256 amount) public returns (bool) {\n _mint(account, amount);\n return true;\n }\n\n function burn(address account, uint256 amount) public returns (bool) {\n _burn(account, amount);\n return true;\n }\n}" + }, + "contracts/v1/test/ERC721Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.7.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\n\n/**\n * @dev Extension of {ERC721} for Minting/Burning\n */\ncontract ERC721Mintable is ERC721Upgradeable {\n\n constructor () public {\n __ERC721_init(\"ERC 721\", \"NFT\");\n }\n\n /**\n * @dev See {ERC721-_mint}.\n */\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n\n /**\n * @dev See {ERC721-_burn}.\n */\n function burn(uint256 tokenId) public {\n _burn(tokenId);\n }\n}\n" + }, + "contracts/v1/tokens/ExternalERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ExternalERC721.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\n\ncontract ExternalERC721 is ERC721 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n\n constructor() public ERC721(\"Charged Particles - ExternalERC721\", \"ExNFT\") {}\n\n function mintNft(address receiver, string memory tokenUri) external returns (uint256 newTokenId) {\n return _mintNft(receiver, tokenUri);\n }\n\n function _mintNft(address receiver, string memory tokenUri) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n\n _safeMint(receiver, newTokenId, \"\");\n\n _setTokenURI(newTokenId, tokenUri);\n }\n}\n" + }, + "contracts/v1/tokens/FungibleERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// FungibleERC1155.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract FungibleERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n\n constructor() public ERC1155(\"https://staging.app.charged.fi/erc1155/metadata.json\") {}\n\n function mintNft(address receiver, uint256 amount) external returns (uint256 newTokenId) {\n return _mintNft(receiver, amount);\n }\n\n function _mintNft(address receiver, uint256 amount) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n _mint(receiver, newTokenId, amount, \"\");\n }\n}\n" + }, + "contracts/v1/tokens/Ionx.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Ionx.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"erc20permit/contracts/ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\n\ncontract Ionx is ERC20Permit, Ownable, BlackholePrevention {\n using SafeMath for uint256;\n\n /// @notice An event thats emitted when the minter address is changed\n event MinterChanged(address minter, address newMinter);\n\n /// @notice Total number of tokens in circulation\n uint256 constant public INITIAL_SUPPLY = 1e8 ether;\n\n /// @notice Minimum time between mints\n uint32 public constant INFLATION_EPOCH = 1 days * 365;\n\n /// @notice Cap on the percentage of totalSupply that can be minted at each mint\n uint8 public constant INFLATION_CAP = 2;\n\n /// @notice Address which may mint new tokens\n address public minter;\n\n /// @notice The timestamp after which minting may occur\n uint256 public mintingAllowedAfter;\n\n\n constructor() public ERC20Permit(\"Charged Particles - IONX\", \"IONX\") {}\n\n\n /**\n * @notice Change the minter address\n * @param newMinter The address of the new minter\n */\n function setMinter(address newMinter) external onlyOwner {\n emit MinterChanged(minter, newMinter);\n minter = newMinter;\n }\n\n /**\n * @notice Mint new tokens\n * @param receiver The address of the destination account\n * @param amount The number of tokens to be minted\n */\n function mint(address receiver, uint256 amount) external onlyMinter {\n require(block.timestamp >= mintingAllowedAfter, \"Ionx:E-114\");\n require(receiver != address(0), \"Ionx:E-403\");\n\n uint256 amountToMint = amount;\n uint256 _totalSupply = totalSupply();\n\n // From Inflationary Supply\n if (_totalSupply >= INITIAL_SUPPLY) {\n mintingAllowedAfter = mintingAllowedAfter.add(INFLATION_EPOCH);\n amountToMint = _totalSupply.mul(INFLATION_CAP).div(100);\n }\n\n // From Initial Supply\n else {\n if (_totalSupply.add(amountToMint) > INITIAL_SUPPLY) {\n amountToMint = INITIAL_SUPPLY.sub(_totalSupply);\n }\n if (_totalSupply.add(amountToMint) == INITIAL_SUPPLY) {\n mintingAllowedAfter = block.timestamp.add(INFLATION_EPOCH);\n }\n }\n\n // transfer the amount to the recipient\n _mint(receiver, amountToMint);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n modifier onlyMinter() {\n require(msg.sender == minter, \"Ionx:E-113\");\n _;\n }\n}\n" + }, + "contracts/v1/tokens/Lepton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Lepton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/ILepton.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\n\ncontract Lepton is ILepton, ERC721, Ownable, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenIds;\n Classification[] internal _leptonTypes;\n mapping (uint256 => Classification) internal _leptonData;\n\n uint256 internal _typeIndex;\n uint256 internal _maxSupply;\n uint256 internal _maxMintPerTx;\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721(\"Charged Particles - Lepton\", \"LEPTON\") {\n _paused = true;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function mintLepton() external payable virtual override nonReentrant whenNotPaused returns (uint256 newTokenId) {\n newTokenId = _mintLepton(msg.sender);\n }\n\n function batchMintLepton(uint256 count) external payable virtual override nonReentrant whenNotPaused {\n _batchMintLepton(msg.sender, count);\n }\n\n function getNextType() external view virtual override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _typeIndex;\n }\n\n function getNextPrice() external view virtual override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _leptonTypes[_typeIndex].price;\n }\n\n function getMultiplier(uint256 tokenId) external view virtual override returns (uint256) {\n return _leptonData[tokenId].multiplier;\n }\n\n function getBonus(uint256 tokenId) external view virtual override returns (uint256) {\n return _leptonData[tokenId].bonus;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function addLeptonType(\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n virtual\n onlyOwner\n {\n _maxSupply = _maxSupply.add(uint256(supply));\n\n Classification memory lepton = Classification({\n tokenUri: tokenUri,\n price: price,\n supply: supply,\n multiplier: multiplier,\n bonus: bonus,\n _upperBounds: uint128(_maxSupply)\n });\n _leptonTypes.push(lepton);\n\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function updateLeptonType(\n uint256 leptonIndex,\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n virtual\n onlyOwner\n {\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\n _leptonTypes[leptonIndex].price = price;\n _leptonTypes[leptonIndex].supply = supply;\n _leptonTypes[leptonIndex].multiplier = multiplier;\n _leptonTypes[leptonIndex].bonus = bonus;\n\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function setMaxMintPerTx(uint256 maxAmount) external virtual onlyOwner {\n _maxMintPerTx = maxAmount;\n emit MaxMintPerTxSet(maxAmount);\n }\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _mintLepton(address receiver) internal virtual returns (uint256 newTokenId) {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n require(msg.value >= lepton.price, \"LPT:E-414\");\n\n _tokenIds.increment();\n newTokenId = _tokenIds.current();\n\n _leptonData[newTokenId] = lepton;\n _safeMint(receiver, newTokenId, \"\");\n _setTokenURI(newTokenId, lepton.tokenUri);\n\n // Distribute Next Type\n if (newTokenId == lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n emit LeptonMinted(receiver, newTokenId, lepton.price, lepton.multiplier);\n\n _refundOverpayment(lepton.price);\n }\n\n\n function _batchMintLepton(address receiver, uint256 count) internal virtual {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \"LPT:E-429\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n\n uint256 startTokenId = _tokenIds.current();\n uint256 endTokenId = startTokenId.add(count);\n if (endTokenId > lepton._upperBounds) {\n count = count.sub(endTokenId.sub(lepton._upperBounds));\n }\n\n uint256 salePrice = lepton.price.mul(count);\n require(msg.value >= salePrice, \"LPT:E-414\");\n\n _safeMintBatch(receiver, startTokenId.add(1), count, \"\");\n\n for (uint i = 0; i < count; i++) {\n _tokenIds.increment();\n startTokenId = _tokenIds.current();\n\n _leptonData[startTokenId] = lepton;\n _setTokenURI(startTokenId, lepton.tokenUri);\n }\n\n // Distribute Next Type\n if (startTokenId >= lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n emit LeptonBatchMinted(receiver, startTokenId, count, lepton.price, lepton.multiplier);\n\n _refundOverpayment(salePrice);\n }\n\n function _refundOverpayment(uint256 threshold) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"LPT:E-101\");\n _;\n }\n}" + }, + "contracts/v1/tokens/Lepton2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Lepton2.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"../lib/ERC721Basic.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\n\nimport \"../interfaces/ILepton.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Lepton2 is ILepton, ERC721Basic, Ownable, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n\n Classification[] internal _leptonTypes;\n\n uint256 internal _typeIndex;\n uint256 internal _maxSupply;\n uint256 internal _maxMintPerTx;\n uint256 internal _migratedCount;\n\n bool internal _paused;\n bool internal _migrationComplete;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721Basic(\"Charged Particles - Lepton2\", \"LEPTON2\") {\n _paused = true;\n _migrationComplete = false;\n _migratedCount = 0;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function mintLepton() external payable override nonReentrant whenNotPaused returns (uint256 newTokenId) {\n newTokenId = _mintLepton(msg.sender);\n }\n\n function batchMintLepton(uint256 count) external payable override nonReentrant whenNotPaused {\n _batchMintLepton(msg.sender, count);\n }\n\n function totalSupply() public view returns (uint256) {\n return _tokenCount;\n }\n\n function maxSupply() external view returns (uint256) {\n return _maxSupply;\n }\n\n function getNextType() external view override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _typeIndex;\n }\n\n function getNextPrice() external view override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _leptonTypes[_typeIndex].price;\n }\n\n function getMultiplier(uint256 tokenId) external view override returns (uint256) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).multiplier;\n }\n\n function getBonus(uint256 tokenId) external view override returns (uint256) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).bonus;\n }\n\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).tokenUri;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function addLeptonType(\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n onlyOwner\n {\n _maxSupply = _maxSupply.add(uint256(supply));\n\n Classification memory lepton = Classification({\n tokenUri: tokenUri,\n price: price,\n supply: supply,\n multiplier: multiplier,\n bonus: bonus,\n _upperBounds: uint128(_maxSupply)\n });\n _leptonTypes.push(lepton);\n\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function updateLeptonType(\n uint256 leptonIndex,\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n onlyOwner\n {\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\n _leptonTypes[leptonIndex].price = price;\n _leptonTypes[leptonIndex].supply = supply;\n _leptonTypes[leptonIndex].multiplier = multiplier;\n _leptonTypes[leptonIndex].bonus = bonus;\n\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function setMaxMintPerTx(uint256 maxAmount) external onlyOwner {\n _maxMintPerTx = maxAmount;\n emit MaxMintPerTxSet(maxAmount);\n }\n\n function setPausedState(bool state) external onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function migrateAccounts(address oldLeptonContract, uint256 count) external onlyOwner whenNotMigrated {\n uint256 oldSupply = IERC721Enumerable(oldLeptonContract).totalSupply();\n require(oldSupply == 0 || oldSupply > _migratedCount, \"LPT:E-004\");\n\n if (oldSupply > 0) {\n uint256 endTokenId = _migratedCount.add(count);\n if (endTokenId > oldSupply) {\n count = count.sub(endTokenId.sub(oldSupply));\n }\n\n for (uint256 i = 1; i <= count; i++) {\n uint256 tokenId = _migratedCount.add(i);\n address tokenOwner = IERC721(oldLeptonContract).ownerOf(tokenId);\n _mint(tokenOwner);\n }\n _migratedCount = _migratedCount.add(count);\n }\n\n if (oldSupply == _migratedCount) {\n _finalizeMigration();\n }\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getLepton(uint256 tokenId) internal view returns (Classification memory) {\n uint256 types = _leptonTypes.length;\n for (uint256 i = 0; i < types; i++) {\n Classification memory lepton = _leptonTypes[i];\n if (tokenId <= lepton._upperBounds) {\n return lepton;\n }\n }\n }\n\n function _mintLepton(address receiver) internal returns (uint256 newTokenId) {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n require(msg.value >= lepton.price, \"LPT:E-414\");\n\n newTokenId = _safeMint(receiver, \"\");\n\n // Determine Next Type\n if (newTokenId == lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n _refundOverpayment(lepton.price);\n }\n\n function _batchMintLepton(address receiver, uint256 count) internal {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \"LPT:E-429\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n\n uint256 endTokenId = _tokenCount.add(count);\n if (endTokenId > lepton._upperBounds) {\n count = count.sub(endTokenId.sub(lepton._upperBounds));\n }\n\n uint256 salePrice = lepton.price.mul(count);\n require(msg.value >= salePrice, \"LPT:E-414\");\n\n _safeMintBatch(receiver, count, \"\");\n\n // Determine Next Type\n if (endTokenId >= lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n _refundOverpayment(salePrice);\n }\n\n function _refundOverpayment(uint256 threshold) internal {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n function _finalizeMigration() internal {\n // Determine Next Type\n _typeIndex = 0;\n for (uint256 i = 0; i < _leptonTypes.length; i++) {\n Classification memory lepton = _leptonTypes[i];\n if (_migratedCount >= lepton._upperBounds) {\n _typeIndex = i + 1;\n }\n }\n _migrationComplete = true;\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotMigrated() {\n require(!_migrationComplete, \"LPT:E-004\");\n _;\n }\n\n modifier whenNotPaused() {\n require(!_paused, \"LPT:E-101\");\n _;\n }\n}" + }, + "contracts/v1/tokens/NonFungibleERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// NonFungibleERC1155.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract NonFungibleERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => address) internal _tokenOwner;\n\n constructor() public ERC1155(\"https://staging.app.charged.fi/erc1155/metadata.json\") {}\n\n function creatorOf(uint256 tokenId) external view returns (address) {\n return _tokenCreator[tokenId];\n }\n\n function ownerOf(uint256 tokenId) external view returns (address) {\n return _tokenOwner[tokenId];\n }\n\n function mintNft(address receiver) external returns (uint256 newTokenId) {\n return _mintNft(msg.sender, receiver);\n }\n\n function _mintNft(address creator, address receiver) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n\n _mint(receiver, newTokenId, 1, \"\");\n _tokenCreator[newTokenId] = creator;\n _tokenOwner[newTokenId] = receiver;\n }\n}\n" + }, + "contracts/v1/tokens/Proton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IProton.sol\";\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ncontract Proton is IProton, ERC721, Ownable, RelayRecipient, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n using Counters for Counters.Counter;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n uint256 constant internal MAX_ROYALTIES = 8e3; // 8000 (80%)\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n Counters.Counter internal _tokenIds;\n\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct;\n mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect;\n mapping (address => uint256) internal _tokenCreatorClaimableRoyalties;\n\n mapping (uint256 => uint256) internal _tokenSalePrice;\n mapping (uint256 => uint256) internal _tokenLastSellPrice;\n\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721(\"Charged Particles - Proton\", \"PROTON\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view virtual override returns (address) {\n return _tokenCreator[tokenId];\n }\n\n function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenSalePrice[tokenId];\n }\n\n function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenLastSellPrice[tokenId];\n }\n\n function getCreatorRoyalties(address account) external view virtual override returns (uint256) {\n return _tokenCreatorClaimableRoyalties[account];\n }\n\n function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenCreatorRoyaltiesPct[tokenId];\n }\n\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) {\n return _creatorRoyaltiesReceiver(tokenId);\n }\n\n function claimCreatorRoyalties()\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256)\n {\n return _claimCreatorRoyalties(_msgSender());\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // annuityPercent,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n royaltiesPercent,\n salePrice\n );\n }\n\n function batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n external\n virtual\n override\n whenNotPaused\n {\n _batchProtonsForSale(\n creator,\n annuityPercent,\n royaltiesPercent,\n tokenMetaUris,\n salePrices\n );\n }\n\n function buyProton(uint256 tokenId)\n external\n payable\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (bool)\n {\n return _buyProton(tokenId);\n }\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice)\n external\n virtual\n override\n whenNotPaused\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setSalePrice(tokenId, salePrice);\n }\n\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setRoyaltiesPct(tokenId, royaltiesPct);\n }\n\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n {\n _tokenCreatorRoyaltiesRedirect[tokenId] = receiver;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual {\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n\n _tokenSalePrice[tokenId] = salePrice;\n emit SalePriceSet(tokenId, salePrice);\n }\n\n function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual {\n require(royaltiesPct <= MAX_ROYALTIES, \"PRT:E-421\");\n _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct;\n emit CreatorRoyaltiesSet(tokenId, royaltiesPct);\n }\n\n function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) {\n address receiver = _tokenCreatorRoyaltiesRedirect[tokenId];\n if (receiver == address(0x0)) {\n receiver = _tokenCreator[tokenId];\n }\n return receiver;\n }\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, annuityPercent, 0, 0);\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n _tokenIds.increment();\n\n newTokenId = _tokenIds.current();\n _safeMint(receiver, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUri);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function _batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n internal\n virtual\n {\n require(tokenMetaUris.length == salePrices.length, \"PRT:E-202\");\n address self = address(this);\n\n uint256 count = tokenMetaUris.length;\n for (uint256 i = 0; i < count; i++) {\n _tokenIds.increment();\n uint256 newTokenId = _tokenIds.current();\n\n _safeMint(creator, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUris[i]);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n uint256 salePrice = salePrices[i];\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n self,\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n function _buyProton(uint256 tokenId)\n internal\n virtual\n returns (bool)\n {\n uint256 salePrice = _tokenSalePrice[tokenId];\n require(salePrice > 0, \"PRT:E-416\");\n require(msg.value >= salePrice, \"PRT:E-414\");\n\n uint256 ownerAmount = salePrice;\n uint256 creatorAmount;\n address oldOwner = ownerOf(tokenId);\n address newOwner = _msgSender();\n\n // Creator Royalties\n address royaltiesReceiver = _creatorRoyaltiesReceiver(tokenId);\n uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[tokenId];\n uint256 lastSellPrice = _tokenLastSellPrice[tokenId];\n if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) {\n creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE);\n ownerAmount = ownerAmount.sub(creatorAmount);\n }\n _tokenLastSellPrice[tokenId] = salePrice;\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(address(this), tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n\n // Reserve Royalties for Creator\n if (creatorAmount > 0) {\n _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount);\n }\n\n // Transfer Token\n _transfer(oldOwner, newOwner, tokenId);\n\n // Transfer Payment\n payable(oldOwner).sendValue(ownerAmount);\n\n emit ProtonSold(tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n\n _refundOverpayment(salePrice);\n return true;\n }\n\n /**\n * @dev Pays out the Creator Royalties of the calling account\n * @param receiver The receiver of the claimable royalties\n * @return The amount of Creator Royalties claimed\n */\n function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) {\n uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver];\n require(claimableAmount > 0, \"PRT:E-411\");\n\n delete _tokenCreatorClaimableRoyalties[receiver];\n payable(receiver).sendValue(claimableAmount);\n\n emit RoyaltiesClaimed(receiver, claimableAmount);\n }\n\n /**\n * @dev Collects the Required Asset Token from the users wallet\n * @param from The owner address to collect the Assets from\n * @param assetAmount The Amount of Asset Tokens to Collect\n */\n function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual {\n uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from);\n require(assetAmount <= _userAssetBalance, \"PRT:E-411\");\n // Be sure to Approve this Contract to transfer your Asset Token\n require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), \"PRT:E-401\");\n }\n\n function _refundOverpayment(uint256 threshold) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n _tokenSalePrice[tokenId] = 0;\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n super._transfer(from, to, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"PRT:E-101\");\n _;\n }\n\n modifier onlyTokenOwnerOrApproved(uint256 tokenId) {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"PRT:E-105\");\n _;\n }\n\n modifier onlyTokenCreator(uint256 tokenId) {\n require(_tokenCreator[tokenId] == _msgSender(), \"PRT:E-104\");\n _;\n }\n}" + }, + "contracts/v1/tokens/ProtonB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\nimport \"../interfaces/IProtonB.sol\";\n\nimport \"../lib/BaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ncontract ProtonB is BaseProton, IProtonB {\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public BaseProton(\"Charged Particles - ProtonB\", \"PROTON.B\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n external\n virtual\n override\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n royaltiesPercent,\n salePrice\n );\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n /// @dev for backwards compatibility with v1\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0);\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n\n /***********************************|\n | Function Overrides |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override {\n super._setSalePrice(tokenId, salePrice);\n\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n }\n\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n override\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n }\n\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n // Unlock NFT\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n\n super._transfer(from, to, tokenId);\n }\n}" + }, + "contracts/v1/tokens/ProtonC.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\nimport \"../lib/Soul.sol\";\n\n\ncontract ProtonC is BaseProton, Soul {\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public BaseProton(\"Charged Particles - ProtonC\", \"PROTON.C\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createBondedToken(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent\n )\n external\n virtual\n payable\n returns (uint256 newTokenId)\n {\n uint256 tokenId = createProtonForSale(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n royaltiesPercent,\n 0\n );\n lockToken(tokenId);\n\n return tokenId;\n }\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n public \n virtual\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n royaltiesPercent,\n salePrice\n );\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n nonReentrant\n whenNotPaused\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n /// @dev for backwards compatibility with v1\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n whenNotPaused\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function burn(uint256 tokenId) public {\n requireTokenOwner(tokenId); \n _burn(tokenId);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n function requireTokenOwner(uint256 tokenId) public view {\n require(ownerOf(tokenId) == msg.sender, \"Only token owner\");\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0);\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n function _burn(uint256 tokenId) internal {\n _unlockToken(tokenId);\n _transfer(ownerOf(tokenId), address(0x000000000000000000000000000000000000dEaD), tokenId);\n }\n\n /***********************************|\n | Soul bounded |\n |__________________________________*/\n\n function lockToken(uint256 tokenId) public {\n requireTokenOwner(tokenId);\n _lockToken(tokenId);\n }\n\n /***********************************|\n | Function Overrides |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override {\n super._setSalePrice(tokenId, salePrice);\n\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n }\n\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n override\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n require(lockedTokens[tokenId] == false, \"BondedToken: Token is locked\");\n\n // Unlock NFT\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n\n super._transfer(from, to, tokenId);\n }\n}" + }, + "contracts/v1/Universe.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\n\nimport \"./interfaces/IUniverse.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n\n/**\n * @notice Charged Particles Universe Contract\n * @dev Upgradeable Contract\n */\ncontract Universe is IUniverse, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n // The ChargedParticles Contract Address\n address public chargedParticles;\n address public proton;\n address public lepton;\n address public quark;\n address public boson;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // Positive Charge\n uint256 internal photonMaxSupply;\n uint256 internal totalPhotonDischarged;\n\n // Source of Positive Charge\n IERC20Upgradeable public photonSource;\n\n // Asset Token => Electrostatic Attraction Multiplier\n mapping (address => uint256) internal esaMultiplier;\n\n // Account => Electrostatic Attraction Levels\n mapping (address => uint256) internal esaLevel;\n\n // Energizing Account => Referral Source\n mapping (address => address) internal referralSource;\n\n // NFT Token UUID => Bonded Lepton Mass\n mapping (uint256 => uint256) internal bondedLeptonMass;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getStaticCharge(address /* account */) external pure virtual returns (uint256 positiveEnergy) {\n return 0;\n }\n\n function conductElectrostaticDischarge(address /* account */, uint256 /* amount */) external pure virtual returns (uint256 positiveEnergy) {\n return 0;\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n onlyProton\n {\n // no-op\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(controller)\n {\n chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setPhoton(\n address token,\n uint256 maxSupply\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n photonSource = IERC20Upgradeable(token);\n photonMaxSupply = maxSupply;\n emit PhotonSet(token, maxSupply);\n }\n\n function setProtonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n proton = token;\n emit ProtonTokenSet(token);\n }\n\n function setLeptonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n lepton = token;\n emit LeptonTokenSet(token);\n }\n\n function setQuarkToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n quark = token;\n emit QuarkTokenSet(token);\n }\n\n function setBosonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n boson = token;\n emit BosonTokenSet(token);\n }\n\n function setEsaMultiplier(\n address assetToken,\n uint256 multiplier\n )\n external\n virtual\n onlyOwner\n {\n esaMultiplier[assetToken] = multiplier;\n emit EsaMultiplierSet(assetToken, multiplier);\n }\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _electrostaticAttraction(uint256 tokenUuid, address receiver, address assetToken, uint256 baseAmount) internal virtual {\n }\n\n function _conductElectrostaticDischarge(address /* account */, uint256 /* energy */) internal virtual pure returns (uint256) {\n return 0;\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Proton NFT contract\n modifier onlyProton() {\n require(proton == msg.sender, \"UNI:E-110\");\n _;\n }\n}\n" + }, + "contracts/v1/UniverseRP.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"./interfaces/IUniverseRP.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./interfaces/IRewardNft.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\nimport \"./interfaces/IRewardProgram.sol\";\n\n/**\n * @notice Charged Particles Universe Contract with Rewards Program\n * @dev Upgradeable Contract\n */\ncontract UniverseRP is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // The ChargedParticles Contract Address\n address public _chargedParticles;\n\n // The Lepton NFT Contract Address\n address public _multiplierNft;\n\n // Asset Token => Reward Program\n mapping (address => address) internal _assetRewardPrograms;\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\n\n // Token UUID => NFT Staking Data\n mapping (uint256 => NftStake) private _nftStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n function getRewardProgram(address asset) external view override returns (address) {\n return _getRewardProgram(asset);\n }\n\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\n return _nftStake[uuid];\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetDeposit(\n contractAddress,\n tokenId,\n walletManagerId,\n assetAmount\n );\n }\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\n }\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n // \"receiverEnergy\" includes the \"principalAmount\"\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n onlyOwner\n onlyValidContractAddress(controller)\n {\n _chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setMultiplierNft(address nftTokenAddress)\n external\n onlyOwner\n onlyValidContractAddress(nftTokenAddress)\n {\n _multiplierNft = nftTokenAddress;\n }\n\n function setRewardProgram(\n address rewardProgam,\n address assetToken\n )\n external\n onlyOwner\n onlyValidContractAddress(rewardProgam)\n {\n require(assetToken != address(0x0), \"UNI:E-403\");\n _assetRewardPrograms[assetToken] = rewardProgam;\n emit RewardProgramSet(assetToken, rewardProgam);\n }\n\n function removeRewardProgram(address assetToken) external onlyOwner {\n delete _assetRewardPrograms[assetToken];\n emit RewardProgramRemoved(assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getRewardProgram(address assetToken) internal view returns (address) {\n return _assetRewardPrograms[assetToken];\n }\n\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != depositNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n uint256 multiplier = _getNftMultiplier(depositNftAddress, depositNftTokenId);\n\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\n // Add to Multipliers Set\n _multiplierNftsSet[parentNftUuid].add(multiplier);\n\n // Update NFT Stake\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\n } else {\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\n }\n }\n\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\n }\n\n function _registerNftRelease(\n address contractAddress,\n uint256 tokenId,\n address releaseNftAddress,\n uint256 releaseNftTokenId,\n uint256 /* nftTokenAmount */\n )\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != releaseNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n NftStake storage nftStake = _nftStake[parentNftUuid];\n\n // Remove from Multipliers Set\n uint256 multiplier = _getNftMultiplier(releaseNftAddress, releaseNftTokenId);\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\n\n // Determine New Multiplier or Mark as Released\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\n } else {\n nftStake.releaseBlockNumber = block.number;\n }\n\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\n }\n\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\n uint256 multiplier = 0;\n uint256 loss = 50;\n uint256 i = 0;\n\n for (; i < len; i++) {\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\n }\n if (len > 1) {\n multiplier = multiplier.sub(loss.mul(len));\n }\n return multiplier;\n }\n\n function _getNftMultiplier(address contractAddress, uint256 tokenId) internal returns (uint256) {\n bytes4 fnSig = IRewardNft.getMultiplier.selector;\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n\n if (success) {\n return abi.decode(returnData, (uint256));\n } else {\n return 0;\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(_chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/UniveserRPPolygon.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"./interfaces/IUniverseRP.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./interfaces/IRewardNft.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\nimport \"./interfaces/IRewardProgram.sol\";\n\n/**\n * @notice Charged Particles Universe Contract with Rewards Program\n * @dev Upgradeable Contract\n */\ncontract UniverseRPPolygon is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // The ChargedParticles Contract Address\n address public _chargedParticles;\n\n // The Lepton NFT Contract Address\n address public _multiplierNft;\n\n // Asset Token => Reward Program\n mapping (address => address) internal _assetRewardPrograms;\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\n\n // Token UUID => NFT Staking Data\n mapping (uint256 => NftStake) private _nftStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n function getRewardProgram(address asset) external view override returns (address) {\n return _getRewardProgram(asset);\n }\n\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\n return _nftStake[uuid];\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetDeposit(\n contractAddress,\n tokenId,\n walletManagerId,\n assetAmount\n );\n }\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\n }\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n // \"receiverEnergy\" includes the \"principalAmount\"\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n onlyOwner\n onlyValidContractAddress(controller)\n {\n _chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setMultiplierNft(address nftTokenAddress)\n external\n onlyOwner\n onlyValidContractAddress(nftTokenAddress)\n {\n _multiplierNft = nftTokenAddress;\n }\n\n function setRewardProgram(\n address rewardProgam,\n address assetToken\n )\n external\n onlyOwner\n onlyValidContractAddress(rewardProgam)\n {\n require(assetToken != address(0x0), \"UNI:E-403\");\n _assetRewardPrograms[assetToken] = rewardProgam;\n emit RewardProgramSet(assetToken, rewardProgam);\n }\n\n function removeRewardProgram(address assetToken) external onlyOwner {\n delete _assetRewardPrograms[assetToken];\n emit RewardProgramRemoved(assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getRewardProgram(address assetToken) internal view returns (address) {\n return _assetRewardPrograms[assetToken];\n }\n\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != depositNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n uint256 multiplier = _getNftMultiplier(depositNftTokenId);\n\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\n // Add to Multipliers Set\n _multiplierNftsSet[parentNftUuid].add(multiplier);\n\n // Update NFT Stake\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\n } else {\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\n }\n }\n\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\n }\n\n function _registerNftRelease(\n address contractAddress,\n uint256 tokenId,\n address releaseNftAddress,\n uint256 releaseNftTokenId,\n uint256 /* nftTokenAmount */\n )\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != releaseNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n NftStake storage nftStake = _nftStake[parentNftUuid];\n\n // Remove from Multipliers Set\n uint256 multiplier = _getNftMultiplier(releaseNftTokenId);\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\n\n // Determine New Multiplier or Mark as Released\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\n } else {\n nftStake.releaseBlockNumber = block.number;\n }\n\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\n }\n\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\n uint256 multiplier = 0;\n uint256 loss = 50;\n uint256 i = 0;\n\n for (; i < len; i++) {\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\n }\n if (len > 1) {\n multiplier = multiplier.sub(loss.mul(len));\n }\n return multiplier;\n }\n\n function _getNftMultiplier(uint256 tokenId) internal pure returns (uint256) {\n if (tokenId >= 1 && tokenId <= 721) {\n return 110;\n } else if (tokenId > 721 && tokenId <= 1122) {\n return 130;\n } else if (tokenId > 1122 && tokenId <= 1423) {\n return 150;\n } else if (tokenId > 1423 && tokenId <= 1624) {\n return 180;\n } else if (tokenId > 1624 && tokenId <= 1712) {\n return 230;\n } else if (tokenId > 1712 && tokenId <= 1733) {\n return 510;\n } else {\n return 1;\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(_chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/vesting/VestingClaim7.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract VestingClaim7 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"VestingClaim7: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"VestingClaim7: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"VestingClaim7: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"VestingClaim7: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"VestingClaim7: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"VestingClaim7: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveSmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\nimport \"../../interfaces/IAaveBridge.sol\";\nimport \"../../lib/SmartWalletBase.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet for Aave Assets\n * @dev Non-upgradeable Contract\n */\ncontract AaveSmartWallet is SmartWalletBase {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 constant internal RAY = 1e27;\n\n IAaveBridge internal _bridge;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(\n address aaveBridge\n )\n public\n {\n SmartWalletBase.initializeBase();\n _bridge = IAaveBridge(aaveBridge);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _bridge.isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address) {\n return _bridge.getReserveInterestToken(assetToken);\n }\n\n function getPrincipal(address assetToken) external override returns (uint256) {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address assetToken) external override returns (uint256 creatorInterest, uint256 ownerInterest) {\n return _getInterest(assetToken);\n }\n\n function getTotal(address assetToken) external override returns (uint256) {\n return _getTotal(assetToken);\n }\n\n function getRewards(address rewardToken) external override returns (uint256) {\n return IERC20(rewardToken).balanceOf(address(this));\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _deposit(assetToken, assetAmount, referralCode);\n }\n\n\n function withdraw(\n address receiver,\n address creatorRedirect,\n address assetToken\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (, uint256 ownerInterest) = _getInterest(assetToken);\n return _withdraw(receiver, creatorRedirect, assetToken, walletPrincipal.add(ownerInterest));\n }\n\n function withdrawAmount(\n address receiver,\n address creatorRedirect,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return _withdraw(receiver, creatorRedirect, assetToken, assetAmount);\n }\n\n function withdrawAmountForCreator(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return _withdrawForCreator(receiver, assetToken, assetAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _withdrawRewards(receiver, rewardsToken, rewardsAmount);\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n internal\n returns (uint256)\n {\n _trackAssetToken(assetToken);\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n\n // Deposit Assets into Aave (reverts on fail)\n _sendToken(address(_bridge), assetToken, assetAmount);\n uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function _withdraw(\n address receiver,\n address creatorRedirect,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken);\n\n // Withdraw from Interest only\n if (assetAmount < ownerInterest) {\n if (creatorInterest > 0) {\n uint256 ratio = assetAmount.mul(RAY).div(ownerInterest);\n creatorAmount = creatorInterest.add(nftCreatorAmountDischarged).mul(ratio).div(RAY);\n\n if (creatorAmount <= nftCreatorAmountDischarged) {\n nftCreatorAmountDischarged = nftCreatorAmountDischarged.sub(creatorAmount);\n creatorAmount = 0;\n }\n\n else {\n creatorAmount = creatorAmount.sub(nftCreatorAmountDischarged);\n nftCreatorAmountDischarged = 0;\n }\n }\n receiverAmount = assetAmount;\n }\n\n // Withdraw from Interest + Principal\n else {\n uint256 fromPrincipal = assetAmount.sub(ownerInterest);\n if (fromPrincipal > walletPrincipal) {\n fromPrincipal = walletPrincipal.sub(ownerInterest);\n }\n\n creatorAmount = creatorInterest;\n receiverAmount = ownerInterest.add(fromPrincipal);\n nftCreatorAmountDischarged = 0;\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal);\n }\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount));\n\n // Withdraw Assets for Creator\n if (creatorAmount > 0) {\n address receivesForCreator = (creatorRedirect != address(0x0)) ? creatorRedirect : nftCreator;\n _bridge.withdraw(receivesForCreator, assetToken, creatorAmount);\n }\n\n // Withdraw Assets for Receiver\n _bridge.withdraw(receiver, assetToken, receiverAmount);\n }\n\n function _withdrawForCreator(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 receiverAmount)\n {\n (uint256 creatorInterest,) = _getInterest(assetToken);\n if (creatorInterest == 0) { return 0; }\n if (assetAmount > creatorInterest) {\n assetAmount = creatorInterest;\n }\n\n nftCreatorAmountDischarged = nftCreatorAmountDischarged.add(assetAmount);\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, assetAmount);\n\n // Withdraw Assets for Receiver on behalf of Creator\n _bridge.withdraw(receiver, assetToken, assetAmount);\n }\n\n function _withdrawRewards(\n address receiver,\n address rewardsTokenAddress,\n uint256 rewardsAmount\n )\n internal\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"ASW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function _getTotal(address assetToken) internal view returns (uint256) {\n return _bridge.getTotalBalance(address(this), assetToken);\n }\n\n function _getInterest(address assetToken) internal view returns (uint256 creatorInterest, uint256 ownerInterest) {\n uint256 total = _getTotal(assetToken);\n uint256 principal = _getPrincipal(assetToken);\n uint256 interest = total.sub(principal);\n\n // Creator Royalties\n if (nftCreatorAnnuityPct > 0) {\n\n // Interest too small to calculate percentage;\n if (interest <= PERCENTAGE_SCALE) {\n // creatorInterest = interest.div(2); // split evenly?\n creatorInterest = 0; // All to owner\n }\n\n // Calculate percentage for Creator\n else {\n creatorInterest = interest\n .add(nftCreatorAmountDischarged)\n .mul(nftCreatorAnnuityPct)\n .div(PERCENTAGE_SCALE)\n .sub(nftCreatorAmountDischarged);\n }\n }\n\n // Owner Portion\n ownerInterest = interest.sub(creatorInterest);\n }\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveSmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\nimport \"../../interfaces/IAaveBridge.sol\";\nimport \"../../lib/SmartWalletBaseB.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet for Aave Assets\n * @dev Non-upgradeable Contract\n */\ncontract AaveSmartWalletB is SmartWalletBaseB {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 constant internal RAY = 1e27;\n\n IAaveBridge internal _bridge;\n\n uint256 internal _nftCreatorAmountDischarged;\n\n mapping (address => address) internal _assetATokens;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(\n address aaveBridge\n )\n public\n {\n SmartWalletBaseB.initializeBase();\n _bridge = IAaveBridge(aaveBridge);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _bridge.isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address) {\n return _bridge.getReserveInterestToken(assetToken);\n }\n\n function getPrincipal(address assetToken) external override returns (uint256) {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address assetToken, uint256 creatorPct) external override returns (uint256 creatorInterest, uint256 ownerInterest) {\n return _getInterest(assetToken, creatorPct);\n }\n\n function getTotal(address assetToken) external override returns (uint256) {\n return _getTotal(assetToken);\n }\n\n function getRewards(address rewardToken) external override returns (uint256) {\n return IERC20(rewardToken).balanceOf(address(this));\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _deposit(assetToken, assetAmount, referralCode);\n }\n\n\n function withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (, uint256 ownerInterest) = _getInterest(assetToken, creatorPct);\n return _withdraw(receiver, creator, creatorPct, assetToken, walletPrincipal.add(ownerInterest));\n }\n\n function withdrawAmount(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return _withdraw(receiver, creator, creatorPct, assetToken, assetAmount);\n }\n\n function withdrawAmountForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return _withdrawForCreator(receiver, creatorPct, assetToken, assetAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _withdrawRewards(receiver, rewardsToken, rewardsAmount);\n }\n\n function refreshPrincipal(address assetToken) external virtual override onlyWalletManager {\n uint256 aTokenBalance = IERC20(_assetATokens[assetToken]).balanceOf(address(this));\n if (_assetPrincipalBalance[assetToken] > aTokenBalance) {\n _assetPrincipalBalance[assetToken] = aTokenBalance;\n }\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n internal\n returns (uint256)\n {\n _trackAssetToken(assetToken);\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n\n // Deposit Assets into Aave (reverts on fail)\n _sendToken(address(_bridge), assetToken, assetAmount);\n uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function _withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken, creatorPct);\n\n // Withdraw from Interest only\n if (assetAmount < ownerInterest) {\n if (creatorInterest > 0) {\n uint256 ratio = assetAmount.mul(RAY).div(ownerInterest);\n creatorAmount = creatorInterest.add(_nftCreatorAmountDischarged).mul(ratio).div(RAY);\n\n if (creatorAmount <= _nftCreatorAmountDischarged) {\n _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.sub(creatorAmount);\n creatorAmount = 0;\n }\n else {\n creatorAmount = creatorAmount.sub(_nftCreatorAmountDischarged);\n _nftCreatorAmountDischarged = 0;\n }\n }\n receiverAmount = assetAmount;\n }\n\n // Withdraw from Interest + Principal\n else {\n uint256 fromPrincipal = assetAmount.sub(ownerInterest);\n if (fromPrincipal > walletPrincipal) {\n fromPrincipal = walletPrincipal.sub(ownerInterest);\n }\n\n creatorAmount = creatorInterest;\n receiverAmount = ownerInterest.add(fromPrincipal);\n _nftCreatorAmountDischarged = 0;\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal);\n }\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount));\n\n // Withdraw Assets for Creator\n if (creatorAmount > 0) {\n if (creator != address(0)) {\n _bridge.withdraw(creator, assetToken, creatorAmount);\n } else {\n receiverAmount = receiverAmount.add(creatorAmount);\n creatorAmount = 0;\n }\n }\n\n // Withdraw Assets for Receiver\n _bridge.withdraw(receiver, assetToken, receiverAmount);\n }\n\n function _withdrawForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 receiverAmount)\n {\n (uint256 creatorInterest,) = _getInterest(assetToken, creatorPct);\n if (creatorInterest == 0) { return 0; }\n if (assetAmount > creatorInterest) {\n assetAmount = creatorInterest;\n }\n\n _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.add(assetAmount);\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, assetAmount);\n\n // Withdraw Assets for Receiver on behalf of Creator\n _bridge.withdraw(receiver, assetToken, assetAmount);\n }\n\n function _withdrawRewards(\n address receiver,\n address rewardsTokenAddress,\n uint256 rewardsAmount\n )\n internal\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"ASW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function _getTotal(address assetToken) internal view returns (uint256) {\n return _bridge.getTotalBalance(address(this), assetToken);\n }\n\n function _getInterest(address assetToken, uint256 creatorPct) internal view returns (uint256 creatorInterest, uint256 ownerInterest) {\n uint256 total = _getTotal(assetToken);\n uint256 principal = _getPrincipal(assetToken);\n uint256 interest = total.sub(principal);\n\n // Creator Royalties\n if (creatorPct > 0) {\n\n // Interest too small to calculate percentage;\n if (interest <= PERCENTAGE_SCALE) {\n // creatorInterest = interest.div(2); // split evenly?\n creatorInterest = 0; // All to owner\n }\n\n // Calculate percentage for Creator\n else {\n creatorInterest = interest\n .add(_nftCreatorAmountDischarged)\n .mul(creatorPct)\n .div(PERCENTAGE_SCALE)\n .sub(_nftCreatorAmountDischarged);\n }\n }\n\n // Owner Portion\n ownerInterest = interest.sub(creatorInterest);\n }\n\n function _trackAssetToken(address assetToken) internal override {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _assetATokens[assetToken] = aTokenAddress;\n }\n }\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../lib/WalletManagerBase.sol\";\n\nimport \"./AaveSmartWallet.sol\";\n\n/**\n * @notice Wallet Manager for Aave\n * @dev Non-upgradeable Contract\n */\ncontract AaveWalletManager is WalletManagerBase {\n using SafeMath for uint256;\n\n event AaveBridgeSet(address indexed aaveBridge);\n event ValidRewardsTokenSet(address indexed rewardsToken, bool state);\n\n address internal _aaveBridge;\n uint256 internal _referralCode;\n\n mapping (address => bool) public rewardsTokenWhitelist;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new AaveSmartWallet());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return AaveSmartWallet(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return AaveSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return AaveSmartWallet(_wallets[uuid]).getInterest(assetToken);\n }\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getTotal(assetToken);\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getRewards(_rewardToken);\n }\n\n\n /***********************************|\n | Only Controller |\n |__________________________________*/\n\n function energize(\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = AaveSmartWallet(wallet).deposit(assetToken, assetAmount, _referralCode);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(ownerInterest > 0, \"AWM:E-412\");\n\n // Discharge the full amount of interest\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, ownerInterest);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(assetAmount > 0 && ownerInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmountForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address creator,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (uint256 creatorInterest,) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(assetAmount > 0 && creatorInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n receiverAmount = AaveSmartWallet(wallet).withdrawAmountForCreator(receiver, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount);\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = AaveSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0;\n\n // Release from interest first + principal if needed\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n require(rewardsTokenWhitelist[rewardsToken], \"AWM:E-423\");\n\n // Withdraw Rewards to Receiver\n amount = AaveSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 tokenId,\n address externalAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return AaveSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n // no-op\n }\n\n function getWalletAddressById(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPct\n )\n external\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n\n if (creator != address(0x0)) {\n AaveSmartWallet(wallet).setNftCreator(creator, annuityPct);\n }\n\n emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAaveBridge(address aaveBridge) external onlyOwner {\n require(aaveBridge != address(0x0), \"AWM:E-403\");\n _aaveBridge = aaveBridge;\n emit AaveBridgeSet(aaveBridge);\n }\n\n // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool\n function setReferralCode(uint256 referralCode) external onlyOwner {\n _referralCode = referralCode;\n }\n\n function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner {\n rewardsTokenWhitelist[rewardsToken] = state;\n emit ValidRewardsTokenSet(rewardsToken, state);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n AaveSmartWallet(newWallet).initialize(_aaveBridge);\n return newWallet;\n }\n}" + }, + "contracts/v1/yield/aave/AaveWalletManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../lib/WalletManagerBase.sol\";\nimport \"../../interfaces/IChargedSettings.sol\";\nimport \"./AaveSmartWalletB.sol\";\n\n/**\n * @notice Wallet Manager for Aave\n * @dev Non-upgradeable Contract\n */\ncontract AaveWalletManagerB is WalletManagerBase {\n using SafeMath for uint256;\n\n event AaveBridgeSet(address indexed aaveBridge);\n event ChargedSettingsSet(address indexed settings);\n event ValidRewardsTokenSet(address indexed rewardsToken, bool state);\n\n IChargedSettings internal _chargedSettings;\n\n address internal _aaveBridge;\n uint256 internal _referralCode;\n\n mapping (address => bool) public _rewardsTokenWhitelist;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new AaveSmartWalletB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return AaveSmartWalletB(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return AaveSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n return AaveSmartWalletB(_wallets[uuid]).getInterest(assetToken, annuityPct);\n }\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getTotal(assetToken);\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getRewards(_rewardToken);\n }\n\n\n /***********************************|\n | Only Controller |\n |__________________________________*/\n\n function energize(\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = AaveSmartWalletB(wallet).deposit(assetToken, assetAmount, _referralCode);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(ownerInterest > 0, \"AWM:E-412\");\n\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Discharge the full amount of interest\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, ownerInterest);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(assetAmount > 0 && ownerInterest >= assetAmount, \"AWM:E-412\");\n\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Discharge a portion of the interest\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmountForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address creator,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (uint256 creatorInterest,) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(assetAmount > 0 && creatorInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n receiverAmount = AaveSmartWalletB(wallet).withdrawAmountForCreator(receiver, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount);\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Release Principal + Interest\n principalAmount = AaveSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdraw(receiver, creator, annuityPct, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0;\n\n // Release from interest first + principal if needed\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n require(_rewardsTokenWhitelist[rewardsToken], \"AWM:E-423\");\n\n // Withdraw Rewards to Receiver\n amount = AaveSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 tokenId,\n address externalAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return AaveSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n AaveSmartWalletB(wallet).refreshPrincipal(assetToken);\n }\n\n function getWalletAddressById(\n address contractAddress,\n uint256 tokenId,\n address /* creator */,\n uint256 /* annuityPct */\n )\n external\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAaveBridge(address aaveBridge) external onlyOwner {\n require(aaveBridge != address(0x0), \"AWM:E-403\");\n _aaveBridge = aaveBridge;\n emit AaveBridgeSet(aaveBridge);\n }\n\n function setChargedSettings(address settings) external onlyOwner {\n require(settings != address(0x0), \"AWM:E-403\");\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool\n function setReferralCode(uint256 referralCode) external onlyOwner {\n _referralCode = referralCode;\n }\n\n function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner {\n _rewardsTokenWhitelist[rewardsToken] = state;\n emit ValidRewardsTokenSet(rewardsToken, state);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n AaveSmartWalletB(newWallet).initialize(_aaveBridge);\n return newWallet;\n }\n}" + }, + "contracts/v1/yield/aave/v2/AaveBridgeV2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveBridgeV2.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/SafeCast.sol\";\n\nimport \"./IATokenV2.sol\";\nimport \"./ILendingPoolV2.sol\";\nimport \"./ILendingPoolAddressesProviderV2.sol\";\n\nimport \"../../../interfaces/IAaveBridge.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\n\ncontract AaveBridgeV2 is Ownable, IAaveBridge, BlackholePrevention {\n using SafeMath for uint256;\n using SafeCast for uint256;\n using SafeERC20 for IERC20;\n using ReserveLogic for ReserveLogic.ReserveData;\n\n ILendingPoolAddressesProviderV2 public provider;\n ILendingPoolV2 public lendingPool;\n\n constructor (address lendingPoolProvider) public {\n provider = ILendingPoolAddressesProviderV2(lendingPoolProvider);\n lendingPool = ILendingPoolV2(provider.getLendingPool());\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address aTokenAddress) {\n return _getReserveInterestToken(assetToken);\n }\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _isReserveActive(assetToken);\n }\n\n function getTotalBalance(address account, address assetToken) external view override returns (uint256) {\n address aTokenAddress = _getReserveInterestToken(assetToken);\n if (aTokenAddress == address(0x0)) { return 0; }\n return IATokenV2(aTokenAddress).balanceOf(account);\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n returns (uint256)\n {\n address self = address(this);\n address aTokenAddress = _getReserveInterestToken(assetToken);\n require(_isReserveActive(assetToken), \"ABV2:E-424\");\n\n IERC20 token = IERC20(assetToken);\n IATokenV2 aToken = IATokenV2(aTokenAddress);\n\n if (token.allowance(address(this), address(lendingPool)) < assetAmount) {\n token.approve(address(lendingPool), uint256(-1));\n }\n\n // Deposit Assets into Aave\n uint256 preBalance = aToken.balanceOf(self);\n lendingPool.deposit(assetToken, assetAmount, self, referralCode.toUint16());\n uint256 postBalance = aToken.balanceOf(self);\n uint256 aTokensAmount = postBalance.sub(preBalance);\n\n // Transfer back the Interest Tokens\n _sendToken(msg.sender, aTokenAddress, aTokensAmount);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function withdraw(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n {\n address self = address(this);\n require(_isReserveActive(assetToken), \"ABV2:E-424\");\n\n // Redeem aTokens for Asset Tokens\n lendingPool.withdraw(assetToken, assetAmount, self);\n\n // Transfer back the Asset Tokens\n _sendToken(receiver, assetToken, assetAmount);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n\n function _getReserveInterestToken(address assetToken) internal view returns (address aTokenAddress) {\n ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken);\n return config.aTokenAddress;\n }\n\n function _isReserveActive(address assetToken) internal view returns (bool) {\n ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken);\n uint256 isActiveFlag = 2 ** 56; // bit 56: reserve is active\n return (config.configuration.data & isActiveFlag) == isActiveFlag;\n }\n}\n" + }, + "contracts/v1/yield/aave/v2/IATokenV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\n\ninterface IATokenV2 {\n function balanceOf(address account) external view returns (uint256);\n}\n" + }, + "contracts/v1/yield/aave/v2/ILendingPoolAddressesProviderV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\n\ninterface ILendingPoolAddressesProviderV2 {\n function getLendingPool() external view returns (address);\n}" + }, + "contracts/v1/yield/aave/v2/ILendingPoolV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport \"./ILendingPoolAddressesProviderV2.sol\";\n\nlibrary ReserveConfiguration {\n struct Map {\n uint256 data;\n }\n}\n\nlibrary ReserveLogic {\n struct ReserveData {\n ReserveConfiguration.Map configuration;\n uint128 liquidityIndex;\n uint128 variableBorrowIndex;\n uint128 currentLiquidityRate;\n uint128 currentVariableBorrowRate;\n uint128 currentStableBorrowRate;\n uint40 lastUpdateTimestamp;\n address aTokenAddress;\n address stableDebtTokenAddress;\n address variableDebtTokenAddress;\n address interestRateStrategyAddress;\n uint8 id;\n }\n}\n\ninterface ILendingPoolV2 {\n function deposit(address reserve, uint256 amount, address onBehalfOf, uint16 referralCode) external;\n function withdraw(address reserve, uint256 amount, address to) external;\n function getReserveData(address asset) external view returns (ReserveLogic.ReserveData memory);\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericSmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"../../../lib/SmartWalletBase.sol\";\n\n\n/**\n * @notice Generic ERC20-Token Smart-Wallet Bridge\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartWallet is SmartWalletBase {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize()\n public\n {\n SmartWalletBase.initializeBase();\n }\n\n function isReserveActive(address assetToken)\n external\n override\n view\n returns (bool)\n {\n return _getPrincipal(assetToken) == 0;\n }\n\n function getReserveInterestToken(address assetToken)\n external\n override\n view\n returns (address)\n {\n return assetToken;\n }\n\n function getPrincipal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address /* assetToken */)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n return (0, 0);\n }\n\n function getTotal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getRewards(address assetToken)\n external\n override\n returns (uint256)\n {\n return IERC20(assetToken).balanceOf(address(this));\n }\n\n function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n // Track Principal\n _trackAssetToken(assetToken);\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n }\n\n function withdraw(address receiver, address /* creatorRedirect */, address assetToken)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmount(address receiver, address /* creatorRedirect */, address assetToken, uint256 assetAmount)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n if (receiverAmount >= assetAmount) {\n receiverAmount = assetAmount;\n }\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmountForCreator(\n address /* receiver */,\n address /* assetToken */,\n uint256 /* assetID */\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericSmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWalletB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"../../../lib/SmartWalletBaseB.sol\";\n\n\n/**\n * @notice Generic ERC20-Token Smart-Wallet Bridge\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartWalletB is SmartWalletBaseB {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize()\n public\n {\n SmartWalletBaseB.initializeBase();\n }\n\n function isReserveActive(address assetToken)\n external\n override\n view\n returns (bool)\n {\n return _getPrincipal(assetToken) == 0;\n }\n\n function getReserveInterestToken(address assetToken)\n external\n override\n view\n returns (address)\n {\n return assetToken;\n }\n\n function getPrincipal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address /* assetToken */, uint256 /* creatorPct */)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n return (0, 0);\n }\n\n function getTotal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getRewards(address assetToken)\n external\n override\n returns (uint256)\n {\n return IERC20(assetToken).balanceOf(address(this));\n }\n\n function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n // Track Principal\n _trackAssetToken(assetToken);\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n }\n\n function withdraw(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmount(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken, uint256 assetAmount)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n if (receiverAmount >= assetAmount) {\n receiverAmount = assetAmount;\n }\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmountForCreator(\n address /* receiver */,\n uint256 /* creatorPct */,\n address /* assetToken */,\n uint256 /* assetID */\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function refreshPrincipal(address assetToken) external virtual override onlyWalletManager {\n _assetPrincipalBalance[assetToken] = IERC20(assetToken).balanceOf(address(this));\n }\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../../lib/WalletManagerBase.sol\";\nimport \"./GenericSmartWallet.sol\";\n\n/**\n * @notice Generic ERC20 Wallet Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericWalletManager is WalletManagerBase {\n using SafeMath for uint256;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new GenericSmartWallet());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return GenericSmartWallet(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return GenericSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getTotal(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return GenericSmartWallet(_wallets[uuid]).getInterest(assetToken);\n }\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getRewards(rewardToken);\n }\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount)\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = GenericSmartWallet(wallet).deposit(assetToken, assetAmount, 0);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmountForCreator(\n address /* receiver */,\n address /* contractAddress */,\n uint256 /* tokenId */,\n address /* creator */,\n address /* assetToken */,\n uint256 /* assetAmount */\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release from interest first + principal if needed\n principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n external\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return GenericSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n // no-op\n }\n\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct)\n external\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n\n if (creator != address(0x0)) {\n GenericSmartWallet(wallet).setNftCreator(creator, annuityPct);\n }\n\n emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n GenericSmartWallet(newWallet).initialize();\n return newWallet;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericWalletManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericWalletManagerB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../../lib/WalletManagerBase.sol\";\nimport \"./GenericSmartWalletB.sol\";\n\n/**\n * @notice Generic ERC20 Wallet Manager B\n * @dev Non-upgradeable Contract\n */\ncontract GenericWalletManagerB is WalletManagerBase {\n using SafeMath for uint256;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new GenericSmartWalletB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return GenericSmartWalletB(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return GenericSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getTotal(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return GenericSmartWalletB(_wallets[uuid]).getInterest(assetToken, 0);\n }\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getRewards(rewardToken);\n }\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount)\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = GenericSmartWalletB(wallet).deposit(assetToken, assetAmount, 0);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmountForCreator(\n address /* receiver */,\n address /* contractAddress */,\n uint256 /* tokenId */,\n address /* creator */,\n address /* assetToken */,\n uint256 /* assetAmount */\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdraw(receiver, creatorRedirect, 0, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release from interest first + principal if needed\n principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdrawAmount(receiver, creatorRedirect, 0, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyControllerOrExecutor\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n external\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return GenericSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n GenericSmartWalletB(wallet).refreshPrincipal(assetToken);\n }\n\n function getWalletAddressById(address contractAddress, uint256 tokenId, address /* creator */, uint256 /* annuityPct */)\n external\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n GenericSmartWalletB(newWallet).initialize();\n return newWallet;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericBasketManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"../../../interfaces/IBasketManager.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"./GenericSmartBasket.sol\";\n\n/**\n * @notice Generic ERC721 Basket Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericBasketManager is Ownable, BlackholePrevention, IBasketManager {\n using Counters for Counters.Counter;\n using TokenInfo for address;\n\n // The Controller Contract Address\n address internal _controller;\n\n // Template Contract for creating Token Smart-Baskets\n address internal _basketTemplate;\n\n // TokenID => Token Smart-Basket Address\n mapping (uint256 => address) internal _baskets;\n\n mapping (uint256 => Counters.Counter) internal _totalTokens;\n\n // State of Basket Manager\n bool internal _paused;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _basketTemplate = address(new GenericSmartBasket());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n function getTokenTotalCount(\n address contractAddress,\n uint256 tokenId\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n return _totalTokens[uuid].current();\n }\n\n function getTokenCountByType(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n external\n override\n returns (uint256)\n {\n address basket = getBasketAddressById(contractAddress, tokenId);\n return GenericSmartBasket(basket).getTokenCountByType(basketTokenAddress, basketTokenId);\n }\n\n function prepareTransferAmount(uint256 /* nftTokenAmount */) external override onlyController {\n // no-op\n }\n\n function addToBasket(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n whenNotPaused\n returns (bool added)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n added = GenericSmartBasket(basket).addToBasket(basketTokenAddress, basketTokenId);\n\n // Log Event\n if (added) {\n _totalTokens[uuid].increment();\n emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, 1);\n }\n }\n\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n returns (bool removed)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n removed = GenericSmartBasket(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId);\n\n // Log Event\n if (removed) {\n _totalTokens[uuid].decrement();\n emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, 1);\n }\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyController\n returns (uint256 amount)\n {\n // no-op\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n public\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n return GenericSmartBasket(basket).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function getBasketAddressById(address contractAddress, uint256 tokenId)\n public\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n // Create Smart-Basket if none exists\n if (basket == address(0x0)) {\n basket = _createBasket();\n _baskets[uuid] = basket;\n\n emit NewSmartBasket(contractAddress, tokenId, basket);\n }\n\n return basket;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Basket Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartBasket(basket).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n function _createBasket()\n internal\n returns (address)\n {\n address newBasket = _createClone(_basketTemplate);\n GenericSmartBasket(newBasket).initialize();\n return newBasket;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"GBM:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"GBM:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericBasketManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport \"../../../interfaces/IBasketManager.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../interfaces/ITokenInfoProxy.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"../../../lib/NftTokenType.sol\";\nimport \"./GenericSmartBasketB.sol\";\n\n/**\n * @notice Generic ERC721 Basket Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericBasketManagerB is Ownable, BlackholePrevention, IBasketManager {\n using Counters for Counters.Counter;\n using TokenInfo for address;\n using NftTokenType for address;\n\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // The Controller Contract Address\n address internal _controller;\n\n // The Executor Contract Address\n address internal _executor;\n\n // Template Contract for creating Token Smart-Baskets\n address internal _basketTemplate;\n\n // TokenID => Token Smart-Basket Address\n mapping (uint256 => address) internal _baskets;\n\n // Prepared Amount\n uint256 internal _preparedAmount;\n\n // State of Basket Manager\n bool internal _paused;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _basketTemplate = address(new GenericSmartBasketB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n function getTokenTotalCount(\n address contractAddress,\n uint256 tokenId\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n if (basket == address(0)) { return 0; }\n return GenericSmartBasketB(basket).getNestedNftCount();\n }\n\n function getTokenCountByType(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n if (basket == address(0)) { return 0; }\n return GenericSmartBasketB(basket).getTokenCountByType(basketTokenAddress, basketTokenId);\n }\n\n function prepareTransferAmount(uint256 nftTokenAmount) external override onlyController {\n _preparedAmount = nftTokenAmount;\n }\n\n function addToBasket(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n whenNotPaused\n returns (bool added)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n uint256 nftTokenAmount = 1;\n if (_preparedAmount > 0) {\n nftTokenAmount = _preparedAmount;\n _preparedAmount = 0;\n }\n\n added = GenericSmartBasketB(basket).addToBasket(basketTokenAddress, basketTokenId, nftTokenAmount);\n if (added) {\n emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount);\n }\n }\n\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n returns (bool removed)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n uint256 nftTokenAmount = 1;\n if (_preparedAmount > 0) {\n nftTokenAmount = _preparedAmount;\n _preparedAmount = 0;\n }\n\n removed = GenericSmartBasketB(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId, nftTokenAmount);\n if (removed) {\n emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount);\n }\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyControllerOrExecutor\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartBasketB(basket).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit BasketRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n public\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n return GenericSmartBasketB(basket).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function getBasketAddressById(address contractAddress, uint256 tokenId)\n public\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n // Create Smart-Basket if none exists\n if (basket == address(0x0)) {\n basket = _createBasket();\n _baskets[uuid] = basket;\n\n emit NewSmartBasket(contractAddress, tokenId, basket);\n }\n\n return basket;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Basket Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n /**\n * @dev Connects to the ExecForAccount Controller\n */\n function setExecutor(address executor) external onlyOwner {\n _executor = executor;\n emit ExecutorSet(executor);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setTokenInfoProxy(address tokenInfoProxy) external onlyOwner {\n _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartBasket(basket).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createBasket()\n internal\n returns (address)\n {\n address newBasket = _createClone(_basketTemplate);\n GenericSmartBasketB(newBasket).initialize(_tokenInfoProxy);\n return newBasket;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"GBM:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Controller or Executor contract\n modifier onlyControllerOrExecutor() {\n require(_executor == msg.sender || _controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"GBM:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericSmartBasket.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/NftTokenType.sol\";\n\n\n/**\n * @notice Generic ERC721-Token Smart-Basket\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartBasket is ISmartBasket, BlackholePrevention, IERC721Receiver {\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableSet for EnumerableSet.AddressSet;\n using NftTokenType for address;\n\n address internal _basketManager;\n\n // NFT contract address => Token Ids in Basket\n mapping (address => mapping(uint256 => EnumerableSet.UintSet)) internal _nftContractTokens;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public {\n require(_basketManager == address(0x0), \"GSB:E-002\");\n _basketManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n return _nftContractTokens[contractAddress][nftType].length();\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver(0).onERC721Received.selector;\n }\n\n function addToBasket(address contractAddress, uint256 tokenId)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n require(!_nftContractTokens[contractAddress][nftType].contains(tokenId), \"GSB:E-425\");\n\n bool added = _nftContractTokens[contractAddress][nftType].add(tokenId);\n if (added) {\n // NFT should have been Transferred into here via Charged-Particles\n added = (IERC721(contractAddress).ownerOf(tokenId) == address(this));\n }\n return added;\n }\n\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n require(_nftContractTokens[contractAddress][nftType].contains(tokenId), \"GSB:E-426\");\n\n bool removed = _nftContractTokens[contractAddress][nftType].remove(tokenId);\n if (removed) {\n IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId);\n }\n return removed;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyBasketManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the basket manager\n modifier onlyBasketManager() {\n require(_basketManager == msg.sender, \"GSB:E-109\");\n _;\n }\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericSmartBasketB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155Receiver.sol\";\nimport \"../../../interfaces/ISmartBasketB.sol\";\nimport \"../../../interfaces/ITokenInfoProxy.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"../../../lib/NftTokenType.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\n\n/**\n * @notice Generic ERC721-Token Smart-Basket\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartBasketB is ISmartBasketB, BlackholePrevention, IERC721Receiver, ERC1155Receiver {\n using TokenInfo for address;\n using NftTokenType for address;\n\n address internal _basketManager;\n\n // NFT TokenUUID => ERC1155 Balance\n mapping (uint256 => uint256) internal _nftContractTokenBalance;\n uint256 internal _nestedNftCount;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(ITokenInfoProxy /* tokenInfoProxy */) public {\n require(_basketManager == address(0x0), \"GSB:E-002\");\n _basketManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getNestedNftCount() external view override returns (uint256) {\n return _nestedNftCount;\n }\n\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n return _nftContractTokenBalance[contractAddress.getTokenUUID(tokenId)];\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver(0).onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\n return IERC1155Receiver(0).onERC1155Received.selector;\n }\n\n // Unimplemented\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\n return \"\"; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector;\n }\n\n function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n _nftContractTokenBalance[uuid] += nftTokenAmount;\n _nestedNftCount += nftTokenAmount;\n return true;\n }\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n uint256 nftTokenAmount\n )\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n _nftContractTokenBalance[uuid] -= nftTokenAmount;\n _nestedNftCount -= nftTokenAmount;\n\n if (contractAddress.isERC1155()) {\n IERC1155(contractAddress).safeTransferFrom(address(this), receiver, tokenId, nftTokenAmount, \"\");\n } else {\n IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId);\n }\n return true;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyBasketManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSB:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyBasketManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the basket manager\n modifier onlyBasketManager() {\n require(_basketManager == msg.sender, \"GSB:E-109\");\n _;\n }\n}\n" + }, + "erc20permit/contracts/ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"./IERC2612.sol\";\n\n/**\n * @author Georgios Konstantopoulos\n * @dev Extension of {ERC20} that allows token holders to use their tokens\n * without sending any transactions by setting {IERC20-allowance} with a\n * signature using the {permit} method, and then spend them via\n * {IERC20-transferFrom}.\n *\n * The {permit} signature mechanism conforms to the {IERC2612} interface.\n */\nabstract contract ERC20Permit is ERC20, IERC2612 {\n mapping (address => uint256) public override nonces;\n\n bytes32 public immutable PERMIT_TYPEHASH = keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public immutable DOMAIN_SEPARATOR;\n\n constructor(string memory name_, string memory symbol_) internal ERC20(name_, symbol_) {\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name_)),\n keccak256(bytes(\"1\")),\n chainId,\n address(this)\n )\n );\n }\n\n /**\n * @dev See {IERC2612-permit}.\n *\n * In cases where the free option is not a concern, deadline can simply be\n * set to uint(-1), so it should be seen as an optional parameter\n */\n function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {\n require(deadline >= block.timestamp, \"ERC20Permit: expired deadline\");\n\n bytes32 hashStruct = keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n amount,\n nonces[owner]++,\n deadline\n )\n );\n\n bytes32 hash = keccak256(\n abi.encodePacked(\n '\\x19\\x01',\n DOMAIN_SEPARATOR,\n hashStruct\n )\n );\n\n address signer = ecrecover(hash, v, r, s);\n require(\n signer != address(0) && signer == owner,\n \"ERC20Permit: invalid signature\"\n );\n\n _approve(owner, spender, amount);\n }\n}\n" + }, + "erc20permit/contracts/IERC2612.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC2612 standard as defined in the EIP.\n *\n * Adds the {permit} method, which can be used to change one's\n * {IERC20-allowance} without having to send a transaction, by signing a\n * message. This allows users to spend tokens without having to hold Ether.\n *\n * See https://eips.ethereum.org/EIPS/eip-2612.\n */\ninterface IERC2612 {\n /**\n * @dev Sets `amount` 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 * - `owner` cannot be the zero address.\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(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n /**\n * @dev Returns the current ERC2612 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" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "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/deployments/polygon/solcInputs/d89205a24fa74c6b69fc21ff47ad23be.json b/deployments/polygon/solcInputs/d89205a24fa74c6b69fc21ff47ad23be.json new file mode 100644 index 0000000..0a60ca0 --- /dev/null +++ b/deployments/polygon/solcInputs/d89205a24fa74c6b69fc21ff47ad23be.json @@ -0,0 +1,458 @@ +{ + "language": "Solidity", + "sources": { + "@opengsn/gsn/contracts/BaseRelayRecipient.sol": { + "content": "// SPDX-License-Identifier:MIT\n// solhint-disable no-inline-assembly\npragma solidity ^0.6.2;\n\nimport \"./interfaces/IRelayRecipient.sol\";\n\n/**\n * A base contract to be inherited by any contract that want to receive relayed transactions\n * A subclass must use \"_msgSender()\" instead of \"msg.sender\"\n */\nabstract contract BaseRelayRecipient is IRelayRecipient {\n\n /*\n * Forwarder singleton we accept calls from\n */\n address public trustedForwarder;\n\n function isTrustedForwarder(address forwarder) public override view returns(bool) {\n return forwarder == trustedForwarder;\n }\n\n /**\n * return the sender of this call.\n * if the call came through our trusted forwarder, return the original sender.\n * otherwise, return `msg.sender`.\n * should be used in the contract anywhere instead of msg.sender\n */\n function _msgSender() internal override virtual view returns (address payable ret) {\n if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // so we trust that the last bytes of msg.data are the verified sender address.\n // extract sender address from the end of msg.data\n assembly {\n ret := shr(96,calldataload(sub(calldatasize(),20)))\n }\n } else {\n return msg.sender;\n }\n }\n\n /**\n * return the msg.data of this call.\n * if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes\n * of the msg.data - so this method will strip those 20 bytes off.\n * otherwise, return `msg.data`\n * should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly\n * signing or hashing the\n */\n function _msgData() internal override virtual view returns (bytes memory ret) {\n if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) {\n // At this point we know that the sender is a trusted forwarder,\n // we copy the msg.data , except the last 20 bytes (and update the total length)\n assembly {\n let ptr := mload(0x40)\n // copy only size-20 bytes\n let size := sub(calldatasize(),20)\n // structure RLP data as \n mstore(ptr, 0x20)\n mstore(add(ptr,32), size)\n calldatacopy(add(ptr,64), 0, size)\n return(ptr, add(size,64))\n }\n } else {\n return msg.data;\n }\n }\n}\n" + }, + "@opengsn/gsn/contracts/interfaces/IRelayRecipient.sol": { + "content": "// SPDX-License-Identifier:MIT\npragma solidity ^0.6.2;\n\n/**\n * a contract must implement this interface in order to support relayed transaction.\n * It is better to inherit the BaseRelayRecipient as its implementation.\n */\nabstract contract IRelayRecipient {\n\n /**\n * return if the forwarder is trusted to forward relayed transactions to us.\n * the forwarder is required to verify the sender's signature, and verify\n * the call is not a replay.\n */\n function isTrustedForwarder(address forwarder) public virtual view returns(bool);\n\n /**\n * return the sender of this call.\n * if the call came through our trusted forwarder, then the real sender is appended as the last 20 bytes\n * of the msg.data.\n * otherwise, return `msg.sender`\n * should be used in the contract anywhere instead of msg.sender\n */\n function _msgSender() internal virtual view returns (address payable);\n\n /**\n * return the msg.data of this call.\n * if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes\n * of the msg.data - so this method will strip those 20 bytes off.\n * otherwise, return `msg.data`\n * should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly\n * signing or hashing the\n */\n function _msgData() internal virtual view returns (bytes memory);\n\n function versionRecipient() external virtual view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\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 initializer {\n __Context_init_unchained();\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal initializer {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), 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 emit OwnershipTransferred(_owner, address(0));\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../proxy/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n function __ERC165_init() internal initializer {\n __ERC165_init_unchained();\n }\n\n function __ERC165_init_unchained() internal initializer {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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/math/SafeMathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMathUpgradeable {\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 uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\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 if (b > a) return (false, 0);\n return (true, a - b);\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 // 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 * @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 if (b == 0) return (false, 0);\n return (true, a / b);\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 if (b == 0) return (false, 0);\n return (true, a % b);\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 uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n return c;\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 require(b <= a, \"SafeMath: subtraction overflow\");\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 if (a == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n return c;\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. 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(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: division by zero\");\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 require(b > 0, \"SafeMath: modulo by zero\");\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n return a - b;\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 * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a / b;\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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// solhint-disable-next-line compiler-version\npragma solidity >=0.4.24 <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 {UpgradeableProxy-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 */\nabstract contract Initializable {\n\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 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 /// @dev Returns true if and only if the function is running in the constructor\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155ReceiverUpgradeable is IERC165Upgradeable {\n\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 )\n external\n 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 )\n external\n returns(bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable {\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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC20Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../proxy/Initializable.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 guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable {\n using SafeMathUpgradeable for uint256;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal initializer {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer {\n _name = name_;\n _symbol = symbol_;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal virtual {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n uint256[44] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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(address sender, address recipient, uint256 amount) 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/ERC20/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.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 SafeERC20Upgradeable {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n\n function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) 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(IERC20Upgradeable token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\n require((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(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\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(IERC20Upgradeable 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) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"./IERC721Upgradeable.sol\";\nimport \"./IERC721MetadataUpgradeable.sol\";\nimport \"./IERC721EnumerableUpgradeable.sol\";\nimport \"./IERC721ReceiverUpgradeable.sol\";\nimport \"../../introspection/ERC165Upgradeable.sol\";\nimport \"../../math/SafeMathUpgradeable.sol\";\nimport \"../../utils/AddressUpgradeable.sol\";\nimport \"../../utils/EnumerableSetUpgradeable.sol\";\nimport \"../../utils/EnumerableMapUpgradeable.sol\";\nimport \"../../utils/StringsUpgradeable.sol\";\nimport \"../../proxy/Initializable.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable, IERC721EnumerableUpgradeable {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.UintSet;\n using EnumerableMapUpgradeable for EnumerableMapUpgradeable.UintToAddressMap;\n using StringsUpgradeable for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSetUpgradeable.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMapUpgradeable.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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 initializer {\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 initializer {\n _name = name_;\n _symbol = symbol_;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\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 _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\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 _tokenURI = _tokenURIs[tokenId];\n string memory base = baseURI();\n\n // If there is no base URI, return the token URI.\n if (bytes(base).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(base, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(base, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view virtual returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view virtual override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\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(_msgSender() == owner || ERC721Upgradeable.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 require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) 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(address from, address to, uint256 tokenId, bytes memory _data) 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 _tokenOwners.contains(tokenId);\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 || ERC721Upgradeable.isApprovedForAll(owner, spender));\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n d*\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\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 _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(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); // internal owner\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(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(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721Upgradeable.ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\"); // internal owner\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721ReceiverUpgradeable(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721Upgradeable.ownerOf(tokenId), to, tokenId); // internal owner\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(address from, address to, uint256 tokenId) internal virtual { }\n uint256[41] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721EnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 /**\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/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 /**\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\npragma solidity >=0.6.0 <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(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\nimport \"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <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 // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) 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 // solhint-disable-next-line avoid-low-level-calls\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(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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 // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/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 GSN 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 initializer {\n __Context_init_unchained();\n }\n\n function __Context_init_unchained() internal initializer {\n }\n function _msgSender() internal view virtual returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/EnumerableMapUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMapUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n */\n function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {\n uint256 keyIndex = map._indexes[key];\n if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)\n return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, \"EnumerableMap: nonexistent key\"); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {_tryGet}.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint160(uint256(value))));\n }\n\n /**\n * @dev Tries to returns the value associated with `key`. O(1).\n * Does not revert if `key` is not in the map.\n *\n * _Available since v3.4._\n */\n function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));\n return (success, address(uint160(uint256(value))));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key)))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryGet}.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <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 EnumerableSetUpgradeable {\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\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\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] = toDeleteIndex + 1; // All indexes are 1-based\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 require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\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 // 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 // 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" + }, + "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\nimport \"../proxy/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 initializer {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal initializer {\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 make 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/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n /**\n * @dev Converts a `uint256` to its ASCII `string` 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 uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = bytes1(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../GSN/Context.sol\";\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 */\ncontract 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 () internal {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), msgSender);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view 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 emit OwnershipTransferred(_owner, address(0));\n _owner = 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 emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n" + }, + "@openzeppelin/contracts/cryptography/MerkleProof.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev These functions deal with verification of Merkle trees (hash trees),\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(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {\n bytes32 computedHash = leaf;\n\n for (uint256 i = 0; i < proof.length; i++) {\n bytes32 proofElement = proof[i];\n\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\n // Check if the computed hash (root) is equal to the provided root\n return computedHash == root;\n }\n}\n" + }, + "@openzeppelin/contracts/GSN/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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 GSN 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 payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\ncontract ERC165 is IERC165 {\n /*\n * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n */\n bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n constructor () internal {\n // Derived contracts need only register support for their own interfaces,\n // we register support for ERC165 itself here\n _registerInterface(_INTERFACE_ID_ERC165);\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n *\n * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) public view override returns (bool) {\n return _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n" + }, + "@openzeppelin/contracts/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\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 uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\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 sub(a, b, \"SafeMath: subtraction overflow\");\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 * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\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 // 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) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts 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(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts 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 mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/ERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155MetadataURI.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"../../GSN/Context.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\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 SafeMath for uint256;\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 * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e\n * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a\n * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6\n *\n * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^\n * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26\n */\n bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n\n /*\n * bytes4(keccak256('uri(uint256)')) == 0x0e89341c\n */\n bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;\n\n /**\n * @dev See {_setURI}.\n */\n constructor (string memory uri) public {\n _setURI(uri);\n\n // register the supported interfaces to conform to ERC1155 via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155);\n\n // register the supported interfaces to conform to ERC1155MetadataURI via ERC165\n _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);\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) external view 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 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(\n address[] memory accounts,\n uint256[] memory ids\n )\n public\n view\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 require(accounts[i] != address(0), \"ERC1155: batch balance query for the zero address\");\n batchBalances[i] = _balances[ids[i]][accounts[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 require(_msgSender() != operator, \"ERC1155: setting approval status for self\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC1155-isApprovedForAll}.\n */\n function isApprovedForAll(address account, address operator) public view 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 )\n public\n virtual\n override\n {\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: caller is not owner nor approved\"\n );\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][from] = _balances[id][from].sub(amount, \"ERC1155: insufficient balance for transfer\");\n _balances[id][to] = _balances[id][to].add(amount);\n\n emit TransferSingle(operator, from, to, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, 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 )\n public\n virtual\n override\n {\n require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n require(to != address(0), \"ERC1155: transfer to the zero address\");\n require(\n from == _msgSender() || isApprovedForAll(from, _msgSender()),\n \"ERC1155: transfer caller is not owner nor approved\"\n );\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 _balances[id][from] = _balances[id][from].sub(\n amount,\n \"ERC1155: insufficient balance for transfer\"\n );\n _balances[id][to] = _balances[id][to].add(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 `account`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `account` 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(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {\n require(account != address(0), \"ERC1155: mint to the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);\n\n _balances[id][account] = _balances[id][account].add(amount);\n emit TransferSingle(operator, address(0), account, id, amount);\n\n _doSafeTransferAcceptanceCheck(operator, address(0), account, 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(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) 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 (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);\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 `account`\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens of token type `id`.\n */\n function _burn(address account, uint256 id, uint256 amount) internal virtual {\n require(account != address(0), \"ERC1155: burn from the zero address\");\n\n address operator = _msgSender();\n\n _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), \"\");\n\n _balances[id][account] = _balances[id][account].sub(\n amount,\n \"ERC1155: burn amount exceeds balance\"\n );\n\n emit TransferSingle(operator, account, 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(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {\n require(account != 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, account, address(0), ids, amounts, \"\");\n\n for (uint i = 0; i < ids.length; i++) {\n _balances[ids[i]][account] = _balances[ids[i]][account].sub(\n amounts[i],\n \"ERC1155: burn amount exceeds balance\"\n );\n }\n\n emit TransferBatch(operator, account, address(0), ids, amounts);\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 )\n internal virtual\n { }\n\n function _doSafeTransferAcceptanceCheck(\n address operator,\n address from,\n address to,\n uint256 id,\n uint256 amount,\n bytes memory data\n )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).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 )\n private\n {\n if (to.isContract()) {\n try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {\n if (response != IERC1155Receiver(to).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/token/ERC1155/ERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC1155Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n constructor() public {\n _registerInterface(\n ERC1155Receiver(0).onERC1155Received.selector ^\n ERC1155Receiver(0).onERC1155BatchReceived.selector\n );\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\nimport \"../../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(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);\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) external view 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(address from, address to, uint256 id, uint256 amount, bytes calldata data) 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(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../introspection/IERC165.sol\";\n\n/**\n * _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n\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 )\n external\n 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 )\n external\n returns(bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.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 guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 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 {\n using SafeMath for uint256;\n using Address for address;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name, string memory symbol) public {\n _name = name;\n _symbol = symbol;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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].add(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 _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) 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 _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` 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 = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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 _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) 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 Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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(address sender, address recipient, uint256 amount) 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/token/ERC20/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.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 SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) 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(IERC20 token, address spender, uint256 value) 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 // solhint-disable-next-line max-line-length\n require((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(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\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) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC721.sol\";\nimport \"./IERC721Metadata.sol\";\nimport \"./IERC721Enumerable.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"../../introspection/ERC165.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/EnumerableSet.sol\";\nimport \"../../utils/EnumerableMap.sol\";\nimport \"../../utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping (uint256 => string) private _tokenURIs;\n\n // Base URI\n string private _baseURI;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721: balance query for the zero address\");\n\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721: owner query for nonexistent token\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n\n string memory _tokenURI = _tokenURIs[tokenId];\n\n // If there is no base URI, return the token URI.\n if (bytes(_baseURI).length == 0) {\n return _tokenURI;\n }\n // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).\n if (bytes(_tokenURI).length > 0) {\n return string(abi.encodePacked(_baseURI, _tokenURI));\n }\n // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.\n return string(abi.encodePacked(_baseURI, tokenId.toString()));\n }\n\n /**\n * @dev Returns the base URI set via {_setBaseURI}. This will be\n * automatically added as a prefix in {tokenURI} to each token's URI, or\n * to the token ID if no specific URI is set for that token ID.\n */\n function baseURI() public view returns (string memory) {\n return _baseURI;\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(_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 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 require(operator != _msgSender(), \"ERC721: approve to caller\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) 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(address from, address to, uint256 tokenId, bytes memory _data) 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 returns (bool) {\n return _tokenOwners.contains(tokenId);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n address owner = 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 d*\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\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 _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(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 = ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n // Clear metadata (if any)\n if (bytes(_tokenURIs[tokenId]).length != 0) {\n delete _tokenURIs[tokenId];\n }\n\n _holderTokens[owner].remove(tokenId);\n\n _tokenOwners.remove(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(address from, address to, uint256 tokenId) internal virtual {\n require(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 _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n _tokenURIs[tokenId] = _tokenURI;\n }\n\n /**\n * @dev Internal function to set the base URI for all token IDs. It is\n * automatically added as a prefix to the value returned in {tokenURI},\n * or to the token ID if {tokenURI} is empty.\n */\n function _setBaseURI(string memory baseURI_) internal virtual {\n _baseURI = baseURI_;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721: transfer to non ERC721Receiver implementer\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\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(address from, address to, uint256 tokenId) internal virtual { }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\n\nimport \"../../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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId) 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(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 /**\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/token/ERC721/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 /**\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/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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(address operator, address from, uint256 tokenId, bytes calldata data)\n external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.2;\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 in 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 // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\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 // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\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(address target, bytes memory data, string memory errorMessage) 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(address target, bytes memory data, uint256 value) 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(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n return _functionCallWithValue(target, data, value, errorMessage);\n }\n\n function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\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 // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"../math/SafeMath.sol\";\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented or decremented by one. 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 * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}\n * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never\n * directly accessed.\n */\nlibrary Counters {\n using SafeMath for uint256;\n\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 // The {SafeMath} overflow check can be skipped here, see the comment at the top\n counter._value += 1;\n }\n\n function decrement(Counter storage counter) internal {\n counter._value = counter._value.sub(1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableMap.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n * // Declare a set state variable\n * EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are\n * supported.\n */\nlibrary EnumerableMap {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Map type with\n // bytes32 keys and values.\n // The Map implementation uses private functions, and user-facing\n // implementations (such as Uint256ToAddressMap) are just wrappers around\n // the underlying Map.\n // This means that we can only create new EnumerableMaps for types that fit\n // in bytes32.\n\n struct MapEntry {\n bytes32 _key;\n bytes32 _value;\n }\n\n struct Map {\n // Storage of map keys and values\n MapEntry[] _entries;\n\n // Position of the entry defined by a key in the `entries` array, plus 1\n // because index 0 means a key is not in the map.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex == 0) { // Equivalent to !contains(map, key)\n map._entries.push(MapEntry({ _key: key, _value: value }));\n // The entry is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n map._indexes[key] = map._entries.length;\n return true;\n } else {\n map._entries[keyIndex - 1]._value = value;\n return false;\n }\n }\n\n /**\n * @dev Removes a key-value pair from a map. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function _remove(Map storage map, bytes32 key) private returns (bool) {\n // We read and store the key's index to prevent multiple reads from the same storage slot\n uint256 keyIndex = map._indexes[key];\n\n if (keyIndex != 0) { // Equivalent to contains(map, key)\n // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one\n // in the array, and then remove the last entry (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = keyIndex - 1;\n uint256 lastIndex = map._entries.length - 1;\n\n // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n MapEntry storage lastEntry = map._entries[lastIndex];\n\n // Move the last entry to the index where the entry to delete is\n map._entries[toDeleteIndex] = lastEntry;\n // Update the index for the moved entry\n map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved entry was stored\n map._entries.pop();\n\n // Delete the index for the deleted slot\n delete map._indexes[key];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function _contains(Map storage map, bytes32 key) private view returns (bool) {\n return map._indexes[key] != 0;\n }\n\n /**\n * @dev Returns the number of key-value pairs in the map. O(1).\n */\n function _length(Map storage map) private view returns (uint256) {\n return map._entries.length;\n }\n\n /**\n * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n *\n * Note that there are no guarantees on the ordering of entries inside the\n * array, and it may change when more entries are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {\n require(map._entries.length > index, \"EnumerableMap: index out of bounds\");\n\n MapEntry storage entry = map._entries[index];\n return (entry._key, entry._value);\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function _get(Map storage map, bytes32 key) private view returns (bytes32) {\n return _get(map, key, \"EnumerableMap: nonexistent key\");\n }\n\n /**\n * @dev Same as {_get}, with a custom error message when `key` is not in the map.\n */\n function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {\n uint256 keyIndex = map._indexes[key];\n require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)\n return map._entries[keyIndex - 1]._value; // All indexes are 1-based\n }\n\n // UintToAddressMap\n\n struct UintToAddressMap {\n Map _inner;\n }\n\n /**\n * @dev Adds a key-value pair to a map, or updates the value for an existing\n * key. O(1).\n *\n * Returns true if the key was added to the map, that is if it was not\n * already present.\n */\n function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n return _set(map._inner, bytes32(key), bytes32(uint256(value)));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the key was removed from the map, that is if it was present.\n */\n function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n return _remove(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns true if the key is in the map. O(1).\n */\n function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n return _contains(map._inner, bytes32(key));\n }\n\n /**\n * @dev Returns the number of elements in the map. O(1).\n */\n function length(UintToAddressMap storage map) internal view returns (uint256) {\n return _length(map._inner);\n }\n\n /**\n * @dev Returns the element stored at position `index` in the set. O(1).\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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n (bytes32 key, bytes32 value) = _at(map._inner, index);\n return (uint256(key), address(uint256(value)));\n }\n\n /**\n * @dev Returns the value associated with `key`. O(1).\n *\n * Requirements:\n *\n * - `key` must be in the map.\n */\n function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n return address(uint256(_get(map._inner, bytes32(key))));\n }\n\n /**\n * @dev Same as {get}, with a custom error message when `key` is not in the map.\n */\n function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {\n return address(uint256(_get(map._inner, bytes32(key), errorMessage)));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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.0.0, only sets of type `address` (`AddressSet`) and `uint256`\n * (`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\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) { // 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 // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\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] = toDeleteIndex + 1; // All indexes are 1-based\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 require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\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(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(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(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(uint256(_at(set._inner, index)));\n }\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" + }, + "@openzeppelin/contracts/utils/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.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 */\ncontract 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 () internal {\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 make 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/utils/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value < 2**128, \"SafeCast: value doesn\\'t fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value < 2**64, \"SafeCast: value doesn\\'t fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value < 2**32, \"SafeCast: value doesn\\'t fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value < 2**16, \"SafeCast: value doesn\\'t fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value < 2**8, \"SafeCast: value doesn\\'t fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= -2**127 && value < 2**127, \"SafeCast: value doesn\\'t fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= -2**63 && value < 2**63, \"SafeCast: value doesn\\'t fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= -2**31 && value < 2**31, \"SafeCast: value doesn\\'t fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= -2**15 && value < 2**15, \"SafeCast: value doesn\\'t fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits.\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= -2**7 && value < 2**7, \"SafeCast: value doesn\\'t fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n require(value < 2**255, \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n /**\n * @dev Converts a `uint256` to its ASCII `string` 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 uint256 index = digits - 1;\n temp = value;\n while (temp != 0) {\n buffer[index--] = byte(uint8(48 + temp % 10));\n temp /= 10;\n }\n return string(buffer);\n }\n}\n" + }, + "contracts/v1/ChargedManagers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Wallet-Managers Contract\n */\ncontract ChargedManagers is\n IChargedManagers,\n Initializable,\n OwnableUpgradeable,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n\n IChargedSettings internal _chargedSettings;\n IChargedState internal _chargedState;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // Wallet/Basket Managers (by Unique Manager ID)\n mapping (string => IWalletManager) internal _ftWalletManager;\n mapping (string => IBasketManager) internal _nftBasketManager;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n /// @notice Checks if an Account is the Owner of an NFT Contract\n /// When Custom Contracts are registered, only the \"owner\" or operator of the Contract\n /// is allowed to register them and define custom rules for how their tokens are \"Charged\".\n /// Otherwise, any token can be \"Charged\" according to the default rules of Charged Particles.\n /// @param contractAddress The Address to the External NFT Contract to check\n /// @param account The Account to check if it is the Owner of the specified Contract\n /// @return True if the account is the Owner of the _contract\n function isContractOwner(address contractAddress, address account) external view override virtual returns (bool) {\n return contractAddress.isContractOwner(account);\n }\n\n function isWalletManagerEnabled(string calldata walletManagerId) external virtual override view returns (bool) {\n return _isWalletManagerEnabled(walletManagerId);\n }\n\n function getWalletManager(string calldata walletManagerId) external virtual override view returns (IWalletManager) {\n return _ftWalletManager[walletManagerId];\n }\n\n function isNftBasketEnabled(string calldata basketId) external virtual override view returns (bool) {\n return _isNftBasketEnabled(basketId);\n }\n\n function getBasketManager(string calldata basketId) external virtual override view returns (IBasketManager) {\n return _nftBasketManager[basketId];\n }\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param sender The sender address to validate against\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external virtual override {\n _validateDeposit(sender, contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param sender The sender address to validate against\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external virtual override {\n _validateNftDeposit(sender, contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateDischarge(sender, contractAddress, tokenId);\n }\n\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateRelease(sender, contractAddress, tokenId);\n }\n\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external virtual override {\n _validateBreakBond(sender, contractAddress, tokenId);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"state\"))) {\n _chargedState = IChargedState(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n /// @dev Register Contracts as wallet managers with a unique liquidity provider ID\n function registerWalletManager(string calldata walletManagerId, address walletManager) external virtual onlyOwner {\n // Validate wallet manager\n IWalletManager newWalletMgr = IWalletManager(walletManager);\n require(newWalletMgr.isPaused() != true, \"CP:E-418\");\n\n // Register LP ID\n _ftWalletManager[walletManagerId] = newWalletMgr;\n emit WalletManagerRegistered(walletManagerId, walletManager);\n }\n\n /// @dev Register Contracts as basket managers with a unique basket ID\n function registerBasketManager(string calldata basketId, address basketManager) external virtual onlyOwner {\n // Validate basket manager\n IBasketManager newBasketMgr = IBasketManager(basketManager);\n require(newBasketMgr.isPaused() != true, \"CP:E-418\");\n\n // Register Basket ID\n _nftBasketManager[basketId] = newBasketMgr;\n emit BasketManagerRegistered(basketId, basketManager);\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev See {ChargedParticles-isWalletManagerEnabled}.\n function _isWalletManagerEnabled(string calldata walletManagerId) internal view virtual returns (bool) {\n return (address(_ftWalletManager[walletManagerId]) != address(0x0) && !_ftWalletManager[walletManagerId].isPaused());\n }\n\n /// @dev See {ChargedParticles-isNftBasketEnabled}.\n function _isNftBasketEnabled(string calldata basketId) internal view virtual returns (bool) {\n return (address(_nftBasketManager[basketId]) != address(0x0) && !_nftBasketManager[basketId].isPaused());\n }\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n internal\n virtual\n {\n if (_chargedState.isEnergizeRestricted(contractAddress, tokenId)) {\n bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender);\n require(isNFTOwnerOrOperator, \"CP:E-105\");\n }\n\n ( string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n ) = _chargedSettings.getAssetRequirements(contractAddress, assetToken);\n\n require(energizeEnabled, \"CP:E-417\");\n\n require(!invalidAsset, \"CP:E-424\");\n\n // Valid Wallet Manager?\n if (bytes(requiredWalletManager).length > 0) {\n require(keccak256(abi.encodePacked(requiredWalletManager)) == keccak256(abi.encodePacked(walletManagerId)), \"CP:E-419\");\n }\n\n // Valid Asset?\n if (restrictedAssets) {\n require(validAsset, \"CP:E-424\");\n }\n\n _validateDepositAmount(\n contractAddress,\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n depositCap,\n depositMin,\n depositMax\n );\n }\n\n /// @dev Validates a Deposit-Amount according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDepositAmount(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax\n )\n internal\n virtual\n {\n uint256 existingBalance = _ftWalletManager[walletManagerId].getPrincipal(contractAddress, tokenId, assetToken);\n uint256 newBalance = assetAmount.add(existingBalance);\n\n // Validate Deposit Cap\n if (depositCap > 0) {\n require(newBalance <= depositCap, \"CP:E-408\");\n }\n\n // Valid Amount for Deposit?\n if (depositMin > 0) {\n require(newBalance >= depositMin, \"CP:E-410\");\n }\n if (depositMax > 0) {\n require(newBalance <= depositMax, \"CP:E-410\");\n }\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n {\n // Prevent Ouroboros NFTs\n require(contractAddress.getTokenUUID(tokenId) != nftTokenAddress.getTokenUUID(nftTokenId), \"CP:E-433\");\n\n if (_chargedState.isCovalentBondRestricted(contractAddress, tokenId)) {\n bool isNFTOwnerOrOperator = _tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender);\n require(isNFTOwnerOrOperator, \"CP:E-105\");\n }\n\n ( string memory requiredBasketManager,\n bool basketEnabled,\n uint256 maxNfts\n ) = _chargedSettings.getNftAssetRequirements(contractAddress, nftTokenAddress);\n\n require(basketEnabled, \"CP:E-417\");\n\n // Valid Basket Manager?\n if (bytes(requiredBasketManager).length > 0) {\n require(keccak256(abi.encodePacked(requiredBasketManager)) == keccak256(abi.encodePacked(basketManagerId)), \"CP:E-419\");\n }\n\n if (maxNfts > 0) {\n uint256 tokenCount = _nftBasketManager[basketManagerId].getTokenTotalCount(contractAddress, tokenId);\n require(maxNfts >= (tokenCount + nftTokenAmount), \"CP:E-427\");\n }\n }\n\n function _validateDischarge(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getDischargeState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateRelease(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getReleaseState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateBreakBond(address sender, address contractAddress, uint256 tokenId) internal virtual {\n ( bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n ) = _chargedState.getBreakBondState(contractAddress, tokenId, sender);\n _validateState(allowFromAll, isApproved, timelock, tempLockExpiry);\n }\n\n function _validateState(\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n internal\n view\n virtual\n {\n if (!allowFromAll) {\n require(isApproved, \"CP:E-105\");\n }\n if (timelock > 0) {\n require(block.number >= timelock, \"CP:E-302\");\n }\n if (tempLockExpiry > 0) {\n require(block.number >= tempLockExpiry, \"CP:E-303\");\n }\n }\n}\n" + }, + "contracts/v1/ChargedParticles.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\n\nimport \"./interfaces/IUniverse.sol\";\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/IWalletManager.sol\";\nimport \"./interfaces/IBasketManager.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/RelayRecipient.sol\";\n\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles V2 Contract\n * @dev Upgradeable Contract\n */\ncontract ChargedParticles is\n IChargedParticles,\n Initializable,\n OwnableUpgradeable,\n ReentrancyGuardUpgradeable,\n RelayRecipient,\n IERC721ReceiverUpgradeable,\n BlackholePrevention,\n IERC1155ReceiverUpgradeable\n{\n using SafeMathUpgradeable for uint256;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using Bitwise for uint32;\n using AddressUpgradeable for address;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n //\n // Particle Terminology\n //\n // Particle - Non-fungible Token (NFT)\n // Mass - Underlying Asset of a Token (ex; DAI)\n // Charge - Accrued Interest on the Underlying Asset of a Token\n // Charged Particle - Any NFT that has a Mass and a Positive Charge\n // Neutral Particle - Any NFT that has a Mass and No Charge\n // Energize / Recharge - Deposit of an Underlying Asset into an NFT\n // Discharge - Withdraw the Accrued Interest of an NFT leaving the Particle with its initial Mass\n // Release - Withdraw the Underlying Asset & Accrued Interest of an NFT leaving the Particle with No Mass or Charge\n //\n // Proton - NFTs minted from the Charged Particle Accelerator\n // - A proton is a subatomic particle, symbol p or p⁺, with a positive electric charge of +1e elementary\n // charge and a mass slightly less than that of a neutron.\n // Ion - Platform Governance Token\n // - A charged subatomic particle. An atom or group of atoms that carries a positive or negative electric charge\n // as a result of having lost or gained one or more electrons.\n //\n\n // Linked Contracts\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n address internal _lepton;\n uint256 internal depositFee;\n ITokenInfoProxy internal _tokenInfoProxy;\n IChargedManagers internal _chargedManagers;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n __ReentrancyGuard_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getStateAddress() external view virtual override returns (address stateAddress) {\n return address(_chargedState);\n }\n\n function getSettingsAddress() external view virtual override returns (address settingsAddress) {\n return address(_chargedSettings);\n }\n\n function getManagersAddress() external view virtual override returns (address managersAddress) {\n return address(_chargedManagers);\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external virtual override returns (bytes4) {\n return IERC721ReceiverUpgradeable(0).onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external virtual override returns (bytes4) {\n return IERC1155ReceiverUpgradeable(0).onERC1155Received.selector;\n }\n\n // Unimplemented\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external virtual override returns (bytes4) {\n return \"\"; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector;\n }\n\n function supportsInterface(bytes4 /* interfaceId */) external view virtual override returns (bool) {\n return false;\n }\n\n /// @notice Calculates the amount of Fees to be paid for a specific deposit amount\n /// @param assetAmount The Amount of Assets to calculate Fees on\n /// @return protocolFee The amount of deposit fees for the protocol\n function getFeesForDeposit(\n uint256 assetAmount\n )\n external\n override\n view\n returns (uint256 protocolFee)\n {\n protocolFee = _getFeesForDeposit(assetAmount);\n }\n\n /// @notice Gets the Amount of Asset Tokens that have been Deposited into the Particle\n /// representing the Mass of the Particle.\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Asset balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The Amount of underlying Assets held within the Token\n function baseParticleMass(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _baseParticleMass(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the amount of Interest that the Particle has generated representing\n /// the Charge of the Particle\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Interest balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The amount of interest the Token has generated (in Asset Token)\n function currentParticleCharge(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _currentParticleCharge(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the amount of LP Tokens that the Particle has generated representing\n /// the Kinetics of the Particle\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Liquidity-Provider ID to check the Kinetics balance of\n /// @param assetToken The Address of the Asset Token to check\n /// @return The amount of LP tokens that have been generated\n function currentParticleKinetics(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n returns (uint256)\n {\n return _currentParticleKinetics(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n /// @notice Gets the total amount of ERC721 Tokens that the Particle holds\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param basketManagerId The ID of the BasketManager to check the token balance of\n /// @return The total amount of ERC721 tokens that are held within the Particle\n function currentParticleCovalentBonds(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId\n )\n external\n view\n virtual\n override\n basketEnabled(basketManagerId)\n returns (uint256)\n {\n return _currentParticleCovalentBonds(contractAddress, tokenId, basketManagerId);\n }\n\n\n /***********************************|\n | Energize Particles |\n |__________________________________*/\n\n /// @notice Fund Particle with Asset Token\n /// Must be called by the account providing the Asset\n /// Account must Approve THIS contract as Operator of Asset\n ///\n /// NOTE: DO NOT Energize an ERC20 Token, as anyone who holds any amount\n /// of the same ERC20 token could discharge or release the funds.\n /// All holders of the ERC20 token would essentially be owners of the Charged Particle.\n ///\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param walletManagerId The Asset-Pair to Energize the Token with\n /// @param assetToken The Address of the Asset Token being used\n /// @param assetAmount The Amount of Asset Token to Energize the Token with\n /// @return yieldTokensAmount The amount of Yield-bearing Tokens added to the escrow for the Token\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 yieldTokensAmount)\n {\n _validateDeposit(contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n\n // Transfer ERC20 Token from Caller to Contract (reverts on fail)\n uint256 feeAmount = _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n yieldTokensAmount = _depositIntoWalletManager(contractAddress, tokenId, walletManagerId, assetToken, assetAmount, feeAmount);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onEnergize(_msgSender(), referrer, contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n }\n\n\n /***********************************|\n | Discharge Particles |\n |__________________________________*/\n\n /// @notice Allows the owner or operator of the Token to collect or transfer the interest generated\n /// from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @return creatorAmount Amount of Asset Token discharged to the Creator\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateDischarge(contractAddress, tokenId);\n\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).discharge(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount);\n }\n }\n\n /// @notice Allows the owner or operator of the Token to collect or transfer a specific amount of the interest\n /// generated from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @param assetAmount The specific amount of Asset Token to Discharge from the Token\n /// @return creatorAmount Amount of Asset Token discharged to the Creator\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateDischarge(contractAddress, tokenId);\n\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).dischargeAmount(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n assetAmount,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischarge(contractAddress, tokenId, walletManagerId, assetToken, creatorAmount, receiverAmount);\n }\n }\n\n /// @notice Allows the Creator of the Token to collect or transfer a their portion of the interest (if any)\n /// generated from the token without removing the underlying Asset that is held within the token.\n /// @param receiver The Address to Receive the Discharged Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Discharge\n /// @param tokenId The ID of the Token to Discharge\n /// @param walletManagerId The Wallet Manager of the Assets to Discharge from the Token\n /// @param assetToken The Address of the Asset Token being discharged\n /// @param assetAmount The specific amount of Asset Token to Discharge from the Particle\n /// @return receiverAmount Amount of Asset Token discharged to the Receiver\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 receiverAmount)\n {\n address sender = _msgSender();\n address tokenCreator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId);\n require(sender == tokenCreator, \"CP:E-104\");\n\n receiverAmount = _chargedManagers.getWalletManager(walletManagerId).dischargeAmountForCreator(\n receiver,\n contractAddress,\n tokenId,\n sender,\n assetToken,\n assetAmount\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onDischargeForCreator(contractAddress, tokenId, walletManagerId, sender, assetToken, receiverAmount);\n }\n }\n\n\n /***********************************|\n | Release Particles |\n |__________________________________*/\n\n /// @notice Releases the Full amount of Asset + Interest held within the Particle by LP of the Assets\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Release\n /// @param tokenId The ID of the Token to Release\n /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token\n /// @param assetToken The Address of the Asset Token being released\n /// @return creatorAmount Amount of Asset Token released to the Creator\n /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount)\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateRelease(contractAddress, tokenId);\n\n // Release Particle to Receiver\n uint256 principalAmount;\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).release(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n }\n\n\n /// @notice Releases a partial amount of Asset + Interest held within the Particle by LP of the Assets\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Release\n /// @param tokenId The ID of the Token to Release\n /// @param walletManagerId The Wallet Manager of the Assets to Release from the Token\n /// @param assetToken The Address of the Asset Token being released\n /// @param assetAmount The specific amount of Asset Token to Release from the Particle\n /// @return creatorAmount Amount of Asset Token released to the Creator\n /// @return receiverAmount Amount of Asset Token released to the Receiver (includes principalAmount)\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n managerEnabled(walletManagerId)\n nonReentrant\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n _validateRelease(contractAddress, tokenId);\n\n // Release Particle to Receiver\n uint256 principalAmount;\n address creatorRedirect = _chargedSettings.getCreatorAnnuitiesRedirect(contractAddress, tokenId);\n (principalAmount, creatorAmount, receiverAmount) = _chargedManagers.getWalletManager(walletManagerId).releaseAmount(\n receiver,\n contractAddress,\n tokenId,\n assetToken,\n assetAmount,\n creatorRedirect\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onRelease(contractAddress, tokenId, walletManagerId, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n }\n\n\n /***********************************|\n | Covalent Bonding |\n |__________________________________*/\n\n /// @notice Deposit other NFT Assets into the Particle\n /// Must be called by the account providing the Asset\n /// Account must Approve THIS contract as Operator of Asset\n ///\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n basketEnabled(basketManagerId)\n nonReentrant\n returns (bool success)\n {\n _validateNftDeposit(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Transfer ERC721 Token from Caller to Contract (reverts on fail)\n _collectNftToken(_msgSender(), nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n success = _depositIntoBasketManager(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onCovalentBond(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n }\n\n /// @notice Release NFT Assets from the Particle\n /// @param receiver The Address to Receive the Released Asset Tokens\n /// @param contractAddress The Address to the Contract of the Token to Energize\n /// @param tokenId The ID of the Token to Energize\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Withdraw (ERC1155-specific)\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n basketEnabled(basketManagerId)\n nonReentrant\n returns (bool success)\n {\n _validateBreakBond(contractAddress, tokenId);\n\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked(\"generic\"))) {\n basketMgr.prepareTransferAmount(nftTokenAmount);\n }\n\n // Release Particle to Receiver\n success = basketMgr.removeFromBasket(\n receiver,\n contractAddress,\n tokenId,\n nftTokenAddress,\n nftTokenId\n );\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onCovalentBreak(contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"universe\"))) {\n _universe = IUniverse(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"state\"))) {\n _chargedState = IChargedState(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"managers\"))) {\n _chargedManagers = IChargedManagers(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"leptons\"))) {\n _lepton = controller;\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"forwarder\"))) {\n trustedForwarder = controller;\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n\n /***********************************|\n | Protocol Fees |\n |__________________________________*/\n\n /// @dev Setup the Base Deposit Fee for the Protocol\n function setDepositFee(uint256 fee) external onlyOwner {\n require(fee < PERCENTAGE_SCALE, \"CP:E-421\");\n depositFee = fee;\n emit DepositFeeSet(fee);\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Validates a Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n function _validateDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n internal\n virtual\n {\n _chargedManagers.validateDeposit(_msgSender(), contractAddress, tokenId, walletManagerId, assetToken, assetAmount);\n }\n\n /// @dev Validates an NFT Deposit according to the rules set by the Token Contract\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param basketManagerId The Basket to Deposit the NFT into\n /// @param nftTokenAddress The Address of the NFT Token being deposited\n /// @param nftTokenId The ID of the NFT Token being deposited\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _validateNftDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n {\n _chargedManagers.validateNftDeposit(_msgSender(), contractAddress, tokenId, basketManagerId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function _validateDischarge(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateDischarge(_msgSender(), contractAddress, tokenId);\n }\n\n function _validateRelease(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateRelease(_msgSender(), contractAddress, tokenId);\n }\n\n function _validateBreakBond(address contractAddress, uint256 tokenId) internal virtual {\n _chargedManagers.validateBreakBond(_msgSender(), contractAddress, tokenId);\n }\n\n /// @dev Deposit Asset Tokens into an NFT via the Wallet Manager\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @param walletManagerId The Wallet Manager of the Assets to Deposit\n /// @param assetToken The Address of the Asset Token to Deposit\n /// @param assetAmount The specific amount of Asset Token to Deposit\n /// @param feeAmount The Amount of Protocol Fees charged\n function _depositIntoWalletManager(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 feeAmount\n )\n internal\n virtual\n returns (uint256)\n {\n // Get Wallet-Manager for LP\n IWalletManager lpWalletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n\n // Deposit Asset Token directly into Smart Wallet (reverts on fail) and Update WalletManager\n address wallet = lpWalletMgr.getWalletAddressById(contractAddress, tokenId, creator, annuityPct);\n IERC20Upgradeable(assetToken).transfer(wallet, assetAmount);\n\n emit ProtocolFeesCollected(assetToken, assetAmount, feeAmount);\n\n return lpWalletMgr.energize(contractAddress, tokenId, assetToken, assetAmount);\n }\n\n /// @dev Deposit NFT Tokens into the Basket Manager\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @param basketManagerId The Wallet Manager of the Assets to Deposit\n /// @param nftTokenAddress The Address of the Asset Token to Deposit\n /// @param nftTokenId The specific amount of Asset Token to Deposit\n /// @param nftTokenAmount The amount of Tokens to Deposit (ERC1155-specific)\n function _depositIntoBasketManager(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n internal\n virtual\n returns (bool)\n {\n // Deposit NFT Token directly into Smart Wallet (reverts on fail) and Update BasketManager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId);\n\n if (keccak256(abi.encodePacked(basketManagerId)) != keccak256(abi.encodePacked(\"generic\"))) {\n basketMgr.prepareTransferAmount(nftTokenAmount);\n }\n\n if (_isERC1155(nftTokenAddress)) {\n if (nftTokenAmount == 0) { nftTokenAmount = 1; }\n IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(address(this), wallet, nftTokenId, nftTokenAmount, \"\");\n } else {\n IERC721Upgradeable(nftTokenAddress).transferFrom(address(this), wallet, nftTokenId);\n }\n return basketMgr.addToBasket(contractAddress, tokenId, nftTokenAddress, nftTokenId);\n }\n\n /**\n * @dev Calculates the amount of Fees to be paid for a specific deposit amount\n * Fees are calculated in Interest-Token as they are the type collected for Fees\n * @param assetAmount The Amount of Assets to calculate Fees on\n * @return protocolFee The amount of fees reserved for the protocol\n */\n function _getFeesForDeposit(\n uint256 assetAmount\n )\n internal\n view\n returns (uint256 protocolFee)\n {\n if (depositFee > 0) {\n protocolFee = assetAmount.mul(depositFee).div(PERCENTAGE_SCALE);\n }\n }\n\n /// @dev Collects the Required ERC20 Token(s) from the users wallet\n /// Be sure to Approve this Contract to transfer your Token(s)\n /// @param from The owner address to collect the tokens from\n /// @param tokenAddress The addres of the token to transfer\n /// @param tokenAmount The amount of tokens to collect\n function _collectAssetToken(address from, address tokenAddress, uint256 tokenAmount) internal virtual returns (uint256 protocolFee) {\n protocolFee = _getFeesForDeposit(tokenAmount);\n IERC20Upgradeable(tokenAddress).safeTransferFrom(from, address(this), tokenAmount.add(protocolFee));\n }\n\n /// @dev Collects the Required ERC721 Token(s) from the users wallet\n /// Be sure to Approve this Contract to transfer your Token(s)\n /// @param from The owner address to collect the tokens from\n /// @param nftTokenAddress The address of the NFT token to transfer\n /// @param nftTokenId The ID of the NFT token to transfer\n /// @param nftTokenAmount The amount of Tokens to Transfer (ERC1155-specific)\n function _collectNftToken(address from, address nftTokenAddress, uint256 nftTokenId, uint256 nftTokenAmount) internal virtual {\n if (_isERC1155(nftTokenAddress)) {\n IERC1155Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId, nftTokenAmount, \"\");\n } else {\n IERC721Upgradeable(nftTokenAddress).safeTransferFrom(from, address(this), nftTokenId);\n }\n }\n\n /// @dev Checks if an NFT token contract supports the ERC1155 standard interface\n function _isERC1155(address nftTokenAddress) internal view virtual returns (bool) {\n bytes4 _INTERFACE_ID_ERC1155 = 0xd9b67a26;\n return IERC165Upgradeable(nftTokenAddress).supportsInterface(_INTERFACE_ID_ERC1155);\n }\n\n /// @dev See {ChargedParticles-baseParticleMass}.\n function _baseParticleMass(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n return _chargedManagers.getWalletManager(walletManagerId).getPrincipal(contractAddress, tokenId, assetToken);\n }\n\n /// @dev See {ChargedParticles-currentParticleCharge}.\n function _currentParticleCharge(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n (, uint256 ownerInterest) = _chargedManagers.getWalletManager(walletManagerId).getInterest(contractAddress, tokenId, assetToken);\n return ownerInterest;\n }\n\n /// @dev See {ChargedParticles-currentParticleKinetics}.\n function _currentParticleKinetics(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n internal\n virtual\n returns (uint256)\n {\n return _chargedManagers.getWalletManager(walletManagerId).getRewards(contractAddress, tokenId, assetToken);\n }\n\n /// @dev See {ChargedParticles-currentParticleCovalentBonds}.\n function _currentParticleCovalentBonds(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId\n )\n internal\n view\n virtual\n returns (uint256)\n {\n return _chargedManagers.getBasketManager(basketManagerId).getTokenTotalCount(contractAddress, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier managerEnabled(string calldata walletManagerId) {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"CP:E-419\");\n _;\n }\n\n modifier basketEnabled(string calldata basketManagerId) {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"CP:E-419\");\n _;\n }\n}\n" + }, + "contracts/v1/ChargedSettings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedSettings.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/RelayRecipient.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\nimport \"./lib/TokenInfoProxy.sol\";\n\n/**\n * @notice Charged Particles Settings Contract\n */\ncontract ChargedSettings is\n IChargedSettings,\n Initializable,\n OwnableUpgradeable,\n RelayRecipient,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using Bitwise for uint32;\n\n uint256 constant internal MAX_ANNUITIES = 1e4; // 10000 (100%)\n\n // NftSettings - actionPerms\n uint32 constant internal PERM_CHARGE_NFT = 1; // NFT Contracts that can have assets Deposited into them (Charged)\n uint32 constant internal PERM_BASKET_NFT = 2; // NFT Contracts that can have other NFTs Deposited into them\n uint32 constant internal PERM_TIMELOCK_ANY_NFT = 4; // NFT Contracts that can timelock any NFT on behalf of users (primarily used for Front-run Protection)\n uint32 constant internal PERM_TIMELOCK_OWN_NFT = 8; // NFT Contracts that can timelock their own NFTs on behalf of their users\n uint32 constant internal PERM_RESTRICTED_ASSETS = 16; // NFT Contracts that have restricted deposits to specific assets\n\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // Current Settings for External NFT Token Contracts;\n // - Any user can add any ERC721 or ERC1155 token as a Charged Particle without Limits,\n // unless the Owner of the ERC721 or ERC1155 token contract registers the token\n // and sets the Custom Settings for their token(s)\n mapping (address => uint32) internal _nftActionPerms;\n\n mapping (address => string) internal _nftRequiredWalletManager;\n mapping (address => string) internal _nftRequiredBasketManager;\n\n // ERC20\n mapping (address => mapping(address => bool)) internal _nftAllowedAssetTokens;\n mapping (address => mapping (address => uint256)) internal _nftDepositMin;\n mapping (address => mapping (address => uint256)) internal _nftDepositMax;\n\n // ERC721 / ERC1155\n mapping (address => mapping (address => uint256)) internal _nftMaxNfts; // NFT Token Address => Max\n\n // Optional Configs for individual NFTs set by NFT Creator (by Token UUID)\n mapping (uint256 => uint256) internal _creatorAnnuityPercent;\n mapping (uint256 => address) internal _creatorAnnuityRedirect;\n\n mapping (address => uint256) internal _depositCap;\n uint256 internal _tempLockExpiryBlocks;\n\n // Blacklist for non-compliant tokens\n mapping (address => bool) internal _invalidAssets;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n /// @dev Gets the amount of creator annuities reserved for the creator for the specified NFT\n /// @param contractAddress The Address to the Contract of the NFT\n /// @param tokenId The Token ID of the NFT\n /// @return creator The address of the creator\n /// @return annuityPct The percentage amount of annuities reserved for the creator\n function getCreatorAnnuities(\n address contractAddress,\n uint256 tokenId\n )\n external\n override\n virtual\n returns (address creator, uint256 annuityPct)\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n creator = _tokenInfoProxy.getTokenCreator(contractAddress, tokenId);\n annuityPct = _creatorAnnuityPercent[tokenUuid];\n }\n\n function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId)\n external\n view\n override\n virtual\n returns (address)\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _creatorAnnuityRedirect[tokenUuid];\n }\n\n function getTempLockExpiryBlocks() external view override virtual returns (uint256) {\n return _tempLockExpiryBlocks;\n }\n\n function getTimelockApprovals(address operator)\n external\n view\n override\n virtual\n returns (bool timelockAny, bool timelockOwn)\n {\n timelockAny = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_ANY_NFT);\n timelockOwn = _nftActionPerms[operator].hasBit(PERM_TIMELOCK_OWN_NFT);\n }\n\n function getAssetRequirements(address contractAddress, address assetToken)\n external\n view\n override\n virtual\n returns (\n string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n )\n {\n requiredWalletManager = _nftRequiredWalletManager[contractAddress];\n energizeEnabled = _nftActionPerms[contractAddress].hasBit(PERM_CHARGE_NFT);\n restrictedAssets = _nftActionPerms[contractAddress].hasBit(PERM_RESTRICTED_ASSETS);\n validAsset = _nftAllowedAssetTokens[contractAddress][assetToken];\n depositCap = _depositCap[assetToken];\n depositMin = _nftDepositMin[contractAddress][assetToken];\n depositMax = _nftDepositMax[contractAddress][assetToken];\n invalidAsset = _invalidAssets[assetToken];\n }\n\n function getNftAssetRequirements(address contractAddress, address nftTokenAddress)\n external\n view\n override\n virtual\n returns (string memory requiredBasketManager, bool basketEnabled, uint256 maxNfts)\n {\n requiredBasketManager = _nftRequiredBasketManager[contractAddress];\n basketEnabled = _nftActionPerms[contractAddress].hasBit(PERM_BASKET_NFT);\n maxNfts = _nftMaxNfts[contractAddress][nftTokenAddress];\n }\n\n\n /***********************************|\n | Only NFT Creator |\n |__________________________________*/\n\n /// @notice Sets the Custom Configuration for Creators of Proton-based NFTs\n /// @param contractAddress The Address to the Proton-based NFT to configure\n /// @param tokenId The token ID of the Proton-based NFT to configure\n /// @param creator The creator of the Proton-based NFT\n /// @param annuityPercent The percentage of interest-annuities to reserve for the creator\n function setCreatorAnnuities(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent\n )\n external\n virtual\n override\n {\n require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), \"CP:E-104\");\n _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent);\n }\n\n /// @notice Sets a Custom Receiver Address for the Creator Annuities\n /// @param contractAddress The Address to the Proton-based NFT to configure\n /// @param tokenId The token ID of the Proton-based NFT to configure\n /// @param receiver The receiver of the Creator interest-annuities\n function setCreatorAnnuitiesRedirect(\n address contractAddress,\n uint256 tokenId,\n address receiver\n )\n external\n virtual\n override\n {\n require(_tokenInfoProxy.isNFTContractOrCreator(contractAddress, tokenId, _msgSender()), \"CP:E-104\");\n _setCreatorAnnuitiesRedirect(contractAddress, tokenId, receiver);\n }\n\n\n /***********************************|\n | Register Contract Settings |\n |(For External Contract Integration)|\n |__________________________________*/\n\n /// @notice Sets a Required Wallet-Manager for External NFT Contracts (otherwise set to \"none\" to allow any Wallet-Manager)\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param walletManager If set, will only allow deposits from this specific Wallet-Manager\n function setRequiredWalletManager(\n address contractAddress,\n string calldata walletManager\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (keccak256(bytes(walletManager)) == keccak256(bytes(\"none\"))) {\n _nftRequiredWalletManager[contractAddress] = \"\";\n } else {\n _nftRequiredWalletManager[contractAddress] = walletManager;\n }\n\n emit RequiredWalletManagerSet(\n contractAddress,\n walletManager\n );\n }\n\n /// @notice Sets a Required Basket-Manager for External NFT Contracts (otherwise set to \"none\" to allow any Basket-Manager)\n /// @param contractAddress The Address to the External Contract to configure\n /// @param basketManager If set, will only allow deposits from this specific Basket-Manager\n function setRequiredBasketManager(\n address contractAddress,\n string calldata basketManager\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (keccak256(bytes(basketManager)) == keccak256(bytes(\"none\"))) {\n _nftRequiredBasketManager[contractAddress] = \"\";\n } else {\n _nftRequiredBasketManager[contractAddress] = basketManager;\n }\n\n emit RequiredBasketManagerSet(\n contractAddress,\n basketManager\n );\n }\n\n /// @notice Enables or Disables Asset-Token Restrictions for External NFT Contracts\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param restrictionsEnabled If set, will only allow deposits from Allowed Asset Tokens\n function setAssetTokenRestrictions(\n address contractAddress,\n bool restrictionsEnabled\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n if (restrictionsEnabled) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_RESTRICTED_ASSETS);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_RESTRICTED_ASSETS);\n }\n\n emit AssetTokenRestrictionsSet(\n contractAddress,\n restrictionsEnabled\n );\n }\n\n /// @notice Enables or Disables Allowed Asset Tokens for External NFT Contracts\n /// @param contractAddress The Address to the External NFT Contract to configure\n /// @param assetToken The Address of the Asset Token to Allow or Disallow\n /// @param isAllowed True if the Asset Token is allowed\n function setAllowedAssetToken(\n address contractAddress,\n address assetToken,\n bool isAllowed\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftAllowedAssetTokens[contractAddress][assetToken] = isAllowed;\n\n emit AllowedAssetTokenSet(\n contractAddress,\n assetToken,\n isAllowed\n );\n }\n\n /// @notice Sets the Custom Configuration for External Contracts\n /// @param contractAddress The Address to the External Contract to configure\n /// @param assetToken The address of the Asset Token to set Limits for\n /// @param depositMin If set, will define the minimum amount of Asset tokens the NFT may hold, otherwise any amount\n /// @param depositMax If set, will define the maximum amount of Asset tokens the NFT may hold, otherwise any amount\n function setAssetTokenLimits(\n address contractAddress,\n address assetToken,\n uint256 depositMin,\n uint256 depositMax\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftDepositMin[contractAddress][assetToken] = depositMin;\n _nftDepositMax[contractAddress][assetToken] = depositMax;\n\n emit AssetTokenLimitsSet(\n contractAddress,\n assetToken,\n depositMin,\n depositMax\n );\n }\n\n /// @notice Sets the Max Number of NFTs that can be held by a Charged Particle NFT\n /// @param contractAddress The Address to the External Contract to configure\n /// @param nftTokenAddress The address of the NFT Token to set a Max for\n /// @param maxNfts The maximum numbers of NFTs that can be held by a given NFT (0 = unlimited)\n function setMaxNfts(\n address contractAddress,\n address nftTokenAddress,\n uint256 maxNfts\n )\n external\n virtual\n override\n onlyValidExternalContract(contractAddress)\n onlyContractOwnerOrAdmin(contractAddress, msg.sender)\n {\n // Update Configs for External Token Contract\n _nftMaxNfts[contractAddress][nftTokenAddress] = maxNfts;\n\n emit MaxNftsSet(\n contractAddress,\n nftTokenAddress,\n maxNfts\n );\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n function setAssetInvalidity(address assetToken, bool invalidity) external virtual override onlyOwner {\n _invalidAssets[assetToken] = invalidity;\n emit AssetInvaliditySet(assetToken, invalidity);\n }\n\n function setDepositCap(address assetToken, uint256 cap) external virtual onlyOwner {\n _depositCap[assetToken] = cap;\n emit DepositCapSet(assetToken, cap);\n }\n\n function setTempLockExpiryBlocks(uint256 numBlocks) external virtual onlyOwner {\n _tempLockExpiryBlocks = numBlocks;\n emit TempLockExpirySet(numBlocks);\n }\n\n function enableNftContracts(address[] calldata contracts) external override virtual onlyOwner {\n uint count = contracts.length;\n for (uint i = 0; i < count; i++) {\n address tokenContract = contracts[i];\n _setPermsForCharge(tokenContract, true);\n _setPermsForBasket(tokenContract, true);\n _setPermsForTimelockSelf(tokenContract, true);\n }\n }\n\n function migrateToken(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent,\n address annuityReceiver\n )\n external\n onlyOwner\n {\n _setCreatorAnnuities(contractAddress, tokenId, creator, annuityPercent);\n if (annuityReceiver != address(0)) {\n _setCreatorAnnuitiesRedirect(contractAddress, tokenId, annuityReceiver);\n }\n }\n\n /// @dev Update the list of NFT contracts that can be Charged\n function setPermsForCharge(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForCharge(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can hold other NFTs\n function setPermsForBasket(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForBasket(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection\n function setPermsForTimelockAny(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForTimelockAny(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock their own tokens\n function setPermsForTimelockSelf(address contractAddress, bool state)\n external\n override\n virtual\n onlyOwner\n {\n _setPermsForTimelockSelf(contractAddress, state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Update the list of NFT contracts that can be Charged\n function _setPermsForCharge(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_CHARGE_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_CHARGE_NFT);\n }\n emit PermsSetForCharge(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can hold other NFTs\n function _setPermsForBasket(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_BASKET_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_BASKET_NFT);\n }\n emit PermsSetForBasket(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock any NFT for Front-run Protection\n function _setPermsForTimelockAny(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_ANY_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_ANY_NFT);\n }\n emit PermsSetForTimelockAny(contractAddress, state);\n }\n\n /// @dev Update the list of NFT contracts that can Timelock their own tokens\n function _setPermsForTimelockSelf(address contractAddress, bool state) internal virtual {\n if (state) {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].setBit(PERM_TIMELOCK_OWN_NFT);\n } else {\n _nftActionPerms[contractAddress] = _nftActionPerms[contractAddress].clearBit(PERM_TIMELOCK_OWN_NFT);\n }\n emit PermsSetForTimelockSelf(contractAddress, state);\n }\n\n /// @dev see setCreatorAnnuities()\n function _setCreatorAnnuities(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPercent\n )\n internal\n virtual\n {\n require(annuityPercent <= MAX_ANNUITIES, \"CP:E-421\");\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Update Configs for External Token Creator\n _creatorAnnuityPercent[tokenUuid] = annuityPercent;\n\n emit TokenCreatorConfigsSet(\n contractAddress,\n tokenId,\n creator,\n annuityPercent\n );\n }\n\n /// @dev see setCreatorAnnuitiesRedirect()\n function _setCreatorAnnuitiesRedirect(\n address contractAddress,\n uint256 tokenId,\n address receiver\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _creatorAnnuityRedirect[tokenUuid] = receiver;\n emit TokenCreatorAnnuitiesRedirected(contractAddress, tokenId, receiver);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyValidExternalContract(address contractAddress) {\n require(contractAddress.isContract(), \"CP:E-420\");\n _;\n }\n\n modifier onlyContractOwnerOrAdmin(address contractAddress, address sender) {\n require(sender == owner() || contractAddress.isContractOwner(sender), \"CP:E-103\");\n _;\n }\n}\n" + }, + "contracts/v1/ChargedState.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ChargedState.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\n\nimport \"./interfaces/IChargedState.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\n\nimport \"./lib/Bitwise.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/RelayRecipient.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Settings Contract\n */\ncontract ChargedState is\n IChargedState,\n Initializable,\n OwnableUpgradeable,\n RelayRecipient,\n BlackholePrevention\n{\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using Bitwise for uint32;\n\n // NftState - actionPerms\n uint32 constant internal PERM_RESTRICT_ENERGIZE_FROM_ALL = 1; // NFTs that have Restrictions on Energize\n uint32 constant internal PERM_ALLOW_DISCHARGE_FROM_ALL = 2; // NFTs that allow Discharge by anyone\n uint32 constant internal PERM_ALLOW_RELEASE_FROM_ALL = 4; // NFTs that allow Release by anyone\n uint32 constant internal PERM_RESTRICT_BOND_FROM_ALL = 8; // NFTs that have Restrictions on Covalent Bonds\n uint32 constant internal PERM_ALLOW_BREAK_BOND_FROM_ALL = 16; // NFTs that allow Breaking Covalent Bonds by anyone\n\n IChargedSettings internal _chargedSettings;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // NftTimelocks\n /// @dev discharge unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftDischargeTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftDischargeTimelockLockedBy;\n\n /// @dev release unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftReleaseTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftReleaseTimelockLockedBy;\n\n /// @dev release unlockBlock and lockedBy\n mapping (uint256 => uint256) internal _nftBreakBondTimelockUnlockBlock;\n mapping (uint256 => address) internal _nftBreakBondTimelockLockedBy;\n\n // NftState\n /// @dev maps nft by tokenId to actionPermissions uint32 which is a composite of all possible NftState - actionPerms\n mapping (uint256 => uint32) internal _nftActionPerms;\n\n /// @dev maps nft by tokenId to its tempLockExpiry\n mapping (uint256 => uint256) internal _nftTempLockExpiry;\n\n /// @dev maps tokenId to user address to operator address for approving various actions\n mapping (uint256 => mapping(address => address)) internal _nftDischargeApproval;\n mapping (uint256 => mapping(address => address)) internal _nftReleaseApproval;\n mapping (uint256 => mapping(address => address)) internal _nftBreakBondApproval;\n mapping (uint256 => mapping(address => address)) internal _nftTimelockApproval;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(address initiator) public initializer {\n __Ownable_init();\n emit Initialized(initiator);\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftDischargeTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftDischargeTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftReleaseTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftReleaseTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view virtual override returns (uint256 lockExpiry) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (_nftBreakBondTimelockUnlockBlock[tokenUuid] > block.number) {\n lockExpiry = _nftBreakBondTimelockUnlockBlock[tokenUuid];\n }\n if (_nftTempLockExpiry[tokenUuid] > block.number && _nftTempLockExpiry[tokenUuid] > lockExpiry) {\n lockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n }\n\n\n /// @notice Checks if an operator is allowed to Discharge a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForDischarge(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Release a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForRelease(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Break Covalent Bonds on a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForBreakBond(contractAddress, tokenId, operator);\n }\n\n /// @notice Checks if an operator is allowed to Timelock a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the operator to check\n /// @return True if the operator is Approved\n function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external virtual override returns (bool) {\n return _isApprovedForTimelock(contractAddress, tokenId, operator);\n }\n\n\n function isEnergizeRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n }\n\n\n function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external virtual override view returns (bool) {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return _nftActionPerms[tokenUuid].hasBit(PERM_RESTRICT_BOND_FROM_ALL);\n }\n\n\n function getDischargeState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n isApproved = _isApprovedForDischarge(contractAddress, tokenId, sender);\n timelock = _nftDischargeTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n function getReleaseState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_RELEASE_FROM_ALL);\n isApproved = _isApprovedForRelease(contractAddress, tokenId, sender);\n timelock = _nftReleaseTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n function getBreakBondState(address contractAddress, uint256 tokenId, address sender)\n external\n virtual\n override\n returns (\n bool allowFromAll,\n bool isApproved,\n uint256 timelock,\n uint256 tempLockExpiry\n )\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n allowFromAll = _nftActionPerms[tokenUuid].hasBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n isApproved = _isApprovedForBreakBond(contractAddress, tokenId, sender);\n timelock = _nftBreakBondTimelockUnlockBlock[tokenUuid];\n tempLockExpiry = _nftTempLockExpiry[tokenUuid];\n }\n\n\n\n\n /***********************************|\n | Only NFT Owner/Operator |\n |__________________________________*/\n\n /// @notice Sets an Operator as Approved to Discharge a specific Token\n /// This allows an operator to withdraw the interest-portion only\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setDischargeApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Release a specific Token\n /// This allows an operator to withdraw the principal + interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setReleaseApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token\n /// This allows an operator to withdraw Basket NFTs\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setBreakBondApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Timelock a specific Token\n /// This allows an operator to timelock the principal or interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setTimelockApproval(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Discharge/Release/Timelock a specific Token\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param operator The Address of the Operator to Approve\n function setApprovalForAll(\n address contractAddress,\n uint256 tokenId,\n address operator\n )\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(operator != tokenOwner, \"CP:E-106\");\n _setDischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n _setReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n _setBreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n _setTimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @dev Updates Restrictions on Energizing an NFT\n function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForRestrictCharge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowDischarge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowRelease(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Restrictions on Covalent Bonds on an NFT\n function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForRestrictBond(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone\n function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state)\n external\n virtual\n override\n onlyNFTOwnerOrOperator(contractAddress, tokenId, _msgSender())\n {\n _setPermsForAllowBreakBond(contractAddress, tokenId, state);\n }\n\n /// @notice Sets a Timelock on the ability to Discharge the Interest of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setDischargeTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftDischargeTimelockLockedBy[tokenUuid] == sender) {\n delete _nftDischargeTimelockUnlockBlock[tokenUuid];\n delete _nftDischargeTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftDischargeTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftDischargeTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftDischargeTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenDischargeTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n /// @notice Sets a Timelock on the ability to Release the Assets of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setReleaseTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftReleaseTimelockLockedBy[tokenUuid] == sender) {\n delete _nftReleaseTimelockUnlockBlock[tokenUuid];\n delete _nftReleaseTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftReleaseTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftReleaseTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftReleaseTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenReleaseTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n /// @notice Sets a Timelock on the ability to Break the Covalent Bond of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param unlockBlock The Ethereum Block-number to Timelock until (~15 seconds per block)\n function setBreakBondTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n )\n external\n override\n virtual\n {\n address sender = _msgSender();\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n // Clear Timelock\n if (unlockBlock == 0 && _nftBreakBondTimelockLockedBy[tokenUuid] == sender) {\n delete _nftBreakBondTimelockUnlockBlock[tokenUuid];\n delete _nftBreakBondTimelockLockedBy[tokenUuid];\n }\n\n // Set Timelock\n else {\n require(_isApprovedForTimelock(contractAddress, tokenId, sender), \"CP:E-105\");\n require(block.number >= _nftBreakBondTimelockUnlockBlock[tokenUuid], \"CP:E-302\");\n\n _nftBreakBondTimelockUnlockBlock[tokenUuid] = unlockBlock;\n _nftBreakBondTimelockLockedBy[tokenUuid] = sender;\n }\n\n emit TokenBreakBondTimelock(contractAddress, tokenId, sender, unlockBlock);\n }\n\n\n /***********************************|\n | Only NFT Contract |\n |__________________________________*/\n\n /// @notice Sets a Temporary-Lock on the ability to Release/Discharge the Assets of a Particle\n /// @param contractAddress The Address to the NFT to Timelock\n /// @param tokenId The token ID of the NFT to Timelock\n /// @param isLocked The locked state; contracts are expected to disable this lock before expiry\n function setTemporaryLock(\n address contractAddress,\n uint256 tokenId,\n bool isLocked\n )\n external\n override\n virtual\n {\n require(msg.sender == contractAddress, \"CP:E-112\");\n\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n uint256 unlockBlock;\n if (isLocked && _nftTempLockExpiry[tokenUuid] == 0) {\n unlockBlock = block.number.add(_chargedSettings.getTempLockExpiryBlocks());\n _nftTempLockExpiry[tokenUuid] = unlockBlock;\n }\n if (!isLocked) {\n _nftTempLockExpiry[tokenUuid] = 0;\n }\n\n emit TokenTempLock(contractAddress, tokenId, unlockBlock);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /// @dev Setup the various Charged-Controllers\n function setController(address controller, string calldata controllerId) external virtual onlyOwner {\n bytes32 controllerIdStr = keccak256(abi.encodePacked(controllerId));\n\n if (controllerIdStr == keccak256(abi.encodePacked(\"settings\"))) {\n _chargedSettings = IChargedSettings(controller);\n }\n else if (controllerIdStr == keccak256(abi.encodePacked(\"tokeninfo\"))) {\n _tokenInfoProxy = ITokenInfoProxy(controller);\n }\n\n emit ControllerSet(controller, controllerId);\n }\n\n function migrateToken(\n address contractAddress,\n uint256 tokenId,\n uint256 releaseTimelockExpiry,\n address releaseTimelockLockedBy,\n uint256 tempLockExpiry\n )\n external\n onlyOwner\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n\n if (releaseTimelockExpiry > block.number && releaseTimelockLockedBy != address(0)) {\n _nftReleaseTimelockUnlockBlock[tokenUuid] = releaseTimelockExpiry;\n _nftReleaseTimelockLockedBy[tokenUuid] = releaseTimelockLockedBy;\n emit TokenReleaseTimelock(contractAddress, tokenId, releaseTimelockLockedBy, releaseTimelockExpiry);\n }\n\n if (tempLockExpiry > 0) {\n _nftTempLockExpiry[tokenUuid] = tempLockExpiry;\n emit TokenTempLock(contractAddress, tokenId, tempLockExpiry);\n }\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev See {ChargedParticles-isApprovedForDischarge}.\n function _isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftDischargeApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForRelease}.\n function _isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftReleaseApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForBreakBond}.\n function _isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return contractAddress == operator || tokenOwner == operator || _nftBreakBondApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @dev See {ChargedParticles-isApprovedForTimelock}.\n function _isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) internal virtual returns (bool) {\n (bool timelockAny, bool timelockOwn) = _chargedSettings.getTimelockApprovals(operator);\n if (timelockAny || (timelockOwn && contractAddress == operator)) { return true; }\n\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n return tokenOwner == operator || _nftTimelockApproval[tokenUuid][tokenOwner] == operator;\n }\n\n /// @notice Sets an Operator as Approved to Discharge a specific Token\n /// This allows an operator to withdraw the interest-portion only\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setDischargeApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftDischargeApproval[tokenUuid][tokenOwner] = operator;\n emit DischargeApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Release a specific Token\n /// This allows an operator to withdraw the principal + interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setReleaseApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftReleaseApproval[tokenUuid][tokenOwner] = operator;\n emit ReleaseApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Break Covalent Bonds on a specific Token\n /// This allows an operator to withdraw Basket NFTs\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setBreakBondApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftBreakBondApproval[tokenUuid][tokenOwner] = operator;\n emit BreakBondApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @notice Sets an Operator as Approved to Timelock a specific Token\n /// This allows an operator to timelock the principal or interest\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param tokenOwner The Owner Address of the Token\n /// @param operator The Address of the Operator to Approve\n function _setTimelockApproval(\n address contractAddress,\n uint256 tokenId,\n address tokenOwner,\n address operator\n )\n internal\n virtual\n {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n _nftTimelockApproval[tokenUuid][tokenOwner] = operator;\n emit TimelockApproval(contractAddress, tokenId, tokenOwner, operator);\n }\n\n /// @dev Updates Restrictions on Energizing an NFT\n function _setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_ENERGIZE_FROM_ALL);\n }\n emit PermsSetForRestrictCharge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function _setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_DISCHARGE_FROM_ALL);\n }\n emit PermsSetForAllowDischarge(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Discharging an NFT by Anyone\n function _setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_RELEASE_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_RELEASE_FROM_ALL);\n }\n emit PermsSetForAllowRelease(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Restrictions on Covalent Bonds on an NFT\n function _setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_RESTRICT_BOND_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_RESTRICT_BOND_FROM_ALL);\n }\n emit PermsSetForRestrictBond(contractAddress, tokenId, state);\n }\n\n /// @dev Updates Allowance on Breaking Covalent Bonds on an NFT by Anyone\n function _setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) internal virtual {\n uint256 tokenUuid = contractAddress.getTokenUUID(tokenId);\n if (state) {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].setBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n } else {\n _nftActionPerms[tokenUuid] = _nftActionPerms[tokenUuid].clearBit(PERM_ALLOW_BREAK_BOND_FROM_ALL);\n }\n emit PermsSetForAllowBreakBond(contractAddress, tokenId, state);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, ContextUpgradeable)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) {\n require(_tokenInfoProxy.isNFTOwnerOrOperator(contractAddress, tokenId, sender), \"CP:E-105\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/CommunityVault.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract CommunityVault is Ownable, BlackholePrevention {\n\n IERC20 private immutable _ionx;\n\n constructor (address ionx) public {\n _ionx = IERC20(ionx);\n }\n\n event SetAllowance(address indexed caller, address indexed spender, uint256 amount);\n\n function setAllowance(address spender, uint amount) public onlyOwner {\n _ionx.approve(spender, amount);\n\n emit SetAllowance(msg.sender, spender, amount);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens other than IONX, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n require(tokenAddress != address(_ionx), \"CommunityVault: cannot withdraw IONX\");\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n}" + }, + "contracts/v1/incentives/MerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_) public {\n token = token_;\n merkleRoot = merkleRoot_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), 'MerkleDistributor: Drop already claimed.');\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), 'MerkleDistributor: Invalid proof.');\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), 'MerkleDistributor: Transfer failed.');\n\n emit Claimed(index, account, amount);\n }\n}\n" + }, + "contracts/v1/incentives/MerkleDistributor2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor2 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"MerkleDistributor2: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"MerkleDistributor2: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor2: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"MerkleDistributor2: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"MerkleDistributor2: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"MerkleDistributor2: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/MerkleDistributor3.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract MerkleDistributor3 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"MerkleDistributor3: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"MerkleDistributor3: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"MerkleDistributor3: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"MerkleDistributor3: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"MerkleDistributor3: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"MerkleDistributor3: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/RewardProgram.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// RewardProgram.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../interfaces/IRewardProgram.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/introspection/IERC165.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"../interfaces/IUniverseRP.sol\";\nimport \"../interfaces/IChargedManagers.sol\";\nimport \"../interfaces/IWalletManager.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IERC20Detailed.sol\";\n\ncontract RewardProgram is\n IRewardProgram,\n BlackholePrevention,\n IERC165,\n ReentrancyGuard,\n IERC721Receiver,\n IERC1155Receiver\n{\n using SafeMath for uint256;\n using TokenInfo for address;\n using SafeERC20 for IERC20;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n\n address private _owner;\n IUniverseRP private _universe;\n IChargedManagers private _chargedManagers;\n ProgramRewardData private _programData;\n mapping(uint256 => AssetStake) private _assetStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public {}\n\n function initialize(\n address stakingToken,\n address rewardToken,\n uint256 baseMultiplier,\n address chargedManagers,\n address universe,\n address owner\n ) external override {\n require(_owner == address(0x0), \"Already initialized\");\n _owner = owner;\n\n // Prepare Reward Program\n _programData.stakingToken = stakingToken;\n _programData.rewardToken = rewardToken;\n _programData.baseMultiplier = baseMultiplier; // Basis Points\n\n // Connect to Charged Particles\n _chargedManagers = IChargedManagers(chargedManagers);\n _universe = IUniverseRP(universe);\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getProgramData() external view override returns (ProgramRewardData memory) {\n return _programData;\n }\n\n function getAssetStake(uint256 parentNftUuid) external view override returns (AssetStake memory) {\n return _assetStake[parentNftUuid];\n }\n\n function getFundBalance() external view override returns (uint256) {\n return _getFundBalance();\n }\n\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) public view override returns (uint256) {\n return _calculateRewardsEarned(parentNftUuid, interestAmount);\n }\n\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n return _assetStake[parentNftUuid].claimableRewards;\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\n return \"\";\n }\n\n function supportsInterface(bytes4 interfaceId)\n public\n view\n virtual\n override(IERC165)\n returns (bool)\n {\n // default interface support\n if (\n interfaceId == type(IERC721Receiver).interfaceId ||\n interfaceId == type(IERC1155Receiver).interfaceId ||\n interfaceId == type(IERC165).interfaceId\n ) {\n return true;\n }\n }\n\n function owner() public view returns (address) {\n return _owner;\n }\n\n\n /***********************************|\n | Only Universe |\n |__________________________________*/\n\n function registerAssetDeposit(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n uint256 principalAmount\n )\n external\n override\n onlyUniverse\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n if (assetStake.start == 0) {\n assetStake.start = block.number;\n assetStake.walletManagerId = walletManagerId;\n }\n emit AssetDeposit(contractAddress, tokenId, walletManagerId, principalAmount);\n }\n\n function registerAssetRelease(\n address contractAddress,\n uint256 tokenId,\n uint256 interestAmount\n )\n external\n override\n onlyUniverse\n nonReentrant\n returns (uint256 rewards)\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n if (assetStake.start > 0) {\n // Update Claimable Rewards\n uint256 newRewards = _calculateRewardsEarned(parentNftUuid, interestAmount);\n assetStake.claimableRewards = assetStake.claimableRewards.add(newRewards);\n\n // Reset Stake if Principal Balance falls to Zero\n IWalletManager walletMgr = _chargedManagers.getWalletManager(assetStake.walletManagerId);\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\n if (principal == 0) {\n assetStake.start = 0;\n }\n\n // Issue Rewards to NFT Owner\n rewards = _claimRewards(contractAddress, tokenId);\n\n emit AssetRelease(contractAddress, tokenId, interestAmount);\n }\n }\n\n\n /***********************************|\n | Reward Calculation |\n |__________________________________*/\n\n function _calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) internal view returns (uint256 totalReward) {\n uint256 baseReward = _calculateBaseReward(interestAmount);\n uint256 leptonMultipliedReward = _calculateMultipliedReward(parentNftUuid, baseReward);\n totalReward = _convertDecimals(leptonMultipliedReward);\n }\n\n function _calculateBaseReward(uint256 amount) internal view returns(uint256 baseReward) {\n baseReward = amount.mul(_programData.baseMultiplier).div(PERCENTAGE_SCALE);\n }\n\n function _calculateMultipliedReward(uint256 parentNftUuid, uint256 baseReward) internal view returns(uint256) {\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n if (assetStake.start == 0) { return baseReward; }\n\n IUniverseRP.NftStake memory nftStake = _universe.getNftStake(parentNftUuid);\n uint256 multiplierBP = nftStake.multiplier;\n\n uint256 assetDepositLength = block.number.sub(assetStake.start);\n uint256 nftDepositLength = 0;\n if (nftStake.releaseBlockNumber > 0) {\n nftDepositLength = nftStake.releaseBlockNumber.sub(nftStake.depositBlockNumber);\n } else {\n nftDepositLength = block.number.sub(nftStake.depositBlockNumber);\n }\n\n if (multiplierBP == 0 || nftDepositLength == 0 || assetDepositLength == 0) {\n return baseReward;\n }\n\n if (nftDepositLength > assetDepositLength) {\n nftDepositLength = assetDepositLength;\n }\n\n // Percentage of the total program that the Multiplier Nft was deposited for\n uint256 nftRewardRatioBP = nftDepositLength.mul(PERCENTAGE_SCALE).div(assetDepositLength);\n\n // Amount of reward that the Multiplier Nft is responsible for\n uint256 amountGeneratedDuringNftDeposit = baseReward.mul(nftRewardRatioBP).div(PERCENTAGE_SCALE);\n\n // Amount of Multiplied Reward from NFT\n uint256 multipliedReward = amountGeneratedDuringNftDeposit.mul(multiplierBP.mul(LEPTON_MULTIPLIER_SCALE)).div(PERCENTAGE_SCALE);\n\n // Amount of Base Reward without Multiplied NFT Rewards\n uint256 amountGeneratedWithoutNftDeposit = baseReward.sub(amountGeneratedDuringNftDeposit);\n\n // Amount of Base Rewards + Multiplied NFT Rewards\n return amountGeneratedWithoutNftDeposit.add(multipliedReward);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function fundProgram(uint256 amount) external onlyOwner {\n require(_programData.rewardToken != address(0), \"RP:E-405\");\n IERC20(_programData.rewardToken).safeTransferFrom(msg.sender, address(this), amount);\n emit RewardProgramFunded(amount);\n }\n\n function setStakingToken(address newStakingToken) external onlyOwner {\n _programData.stakingToken = newStakingToken;\n }\n\n function setRewardToken(address newRewardToken) external onlyOwner {\n _programData.rewardToken = newRewardToken;\n }\n\n function setBaseMultiplier(uint256 newMultiplier) external onlyOwner {\n _programData.baseMultiplier = newMultiplier; // Basis Points\n }\n\n function setChargedManagers(address manager) external onlyOwner {\n _chargedManagers = IChargedManagers(manager);\n }\n\n function setUniverse(address universe) external onlyOwner {\n _universe = IUniverseRP(universe);\n }\n\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external override onlyOwner {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n\n // Initiate Asset Stake\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n uint256 principal = walletMgr.getPrincipal(contractAddress, tokenId, _programData.stakingToken);\n if (principal > 0) {\n _assetStake[parentNftUuid] = AssetStake(block.number, 0, walletManagerId);\n emit AssetRegistered(contractAddress, tokenId, walletManagerId, principal);\n }\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _claimRewards(\n address contractAddress,\n uint256 tokenId\n )\n internal\n returns (uint256 totalReward)\n {\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n AssetStake storage assetStake = _assetStake[parentNftUuid];\n\n // Rewards Receiver\n address receiver = IERC721(contractAddress).ownerOf(tokenId);\n\n // Ensure Reward Pool has Sufficient Balance\n totalReward = assetStake.claimableRewards;\n uint256 fundBalance = _getFundBalance();\n uint256 unavailReward = totalReward > fundBalance ? totalReward.sub(fundBalance) : 0;\n\n // Determine amount of Rewards to Transfer\n if (unavailReward > 0) {\n totalReward = totalReward.sub(unavailReward);\n emit RewardProgramOutOfFunds();\n }\n\n // Update Asset Stake\n assetStake.claimableRewards = unavailReward;\n\n if (totalReward > 0) {\n // Transfer Available Rewards to Receiver\n IERC20(_programData.rewardToken).safeTransfer(receiver, totalReward);\n }\n\n emit RewardsClaimed(contractAddress, tokenId, receiver, totalReward, unavailReward);\n }\n\n function _convertDecimals(uint256 reward) internal view returns (uint256) {\n uint8 stakingTokenDecimals = IERC20Detailed(_programData.stakingToken).decimals();\n return reward.mul(10**(18 - uint256(stakingTokenDecimals)));\n }\n\n function _getFundBalance() internal view returns (uint256) {\n return IERC20Detailed(_programData.rewardToken).balanceOf(address(this));\n }\n\n\n modifier onlyOwner() {\n require(_owner == msg.sender, \"Caller is not the owner\");\n _;\n }\n\n modifier onlyUniverse() {\n require(msg.sender == address(_universe), \"RP:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/incentives/RewardProgramFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// RewardProgramFactory.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\nimport \"./RewardProgram.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract RewardProgramFactory is BlackholePrevention, Ownable {\n event RewardProgramCreated(address indexed rewardProgram);\n\n address public _template;\n\n constructor () public {\n _template = address(new RewardProgram());\n }\n\n // function _msgSender() internal view override returns (address payable) {\n // return msg.sender;\n // }\n\n function createRewardProgram(\n address stakingToken,\n address rewardToken,\n uint256 baseMultiplier,\n address chargedManagers,\n address universe\n )\n external\n onlyOwner\n returns (address)\n {\n address newRewardProgram = _createClone(_template);\n RewardProgram rewardProgram = RewardProgram(newRewardProgram);\n rewardProgram.initialize(stakingToken, rewardToken, baseMultiplier, chargedManagers, universe, _msgSender());\n emit RewardProgramCreated(newRewardProgram);\n return newRewardProgram;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n}\n" + }, + "contracts/v1/incentives/Staking.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/Staking2.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking2 is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/Staking3.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Staking3 is\n Ownable,\n ReentrancyGuard,\n BlackholePrevention\n{\n using SafeMath for uint256;\n\n uint128 constant private BASE_MULTIPLIER = uint128(1 * 10 ** 18);\n\n bool internal _paused;\n\n // timestamp for the epoch 1\n // everything before that is considered epoch 0 which won't have a reward but allows for the initial stake\n uint256 public immutable epoch1Start;\n\n // duration of each epoch\n uint256 public immutable epochDuration;\n\n // holds the current balance of the user for each token\n mapping(address => mapping(address => uint256)) private balances;\n\n struct Pool {\n uint256 size;\n bool set;\n }\n\n // for each token, we store the total pool size\n mapping(address => mapping(uint256 => Pool)) private poolSize;\n\n // a checkpoint of the valid balance of a user for an epoch\n struct Checkpoint {\n uint128 epochId;\n uint128 multiplier;\n uint256 startBalance;\n uint256 newDeposits;\n }\n\n // balanceCheckpoints[user][token][]\n mapping(address => mapping(address => Checkpoint[])) private balanceCheckpoints;\n\n mapping(address => uint128) private lastWithdrawEpochId;\n\n event PausedStateSet(bool isPaused);\n event Deposit(address indexed user, address indexed tokenAddress, uint256 amount);\n event Withdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n event ManualEpochInit(address indexed caller, uint128 indexed epochId, address[] tokens);\n event EmergencyWithdraw(address indexed user, address indexed tokenAddress, uint256 amount);\n\n constructor (uint256 _epoch1Start, uint256 _epochDuration) public {\n _paused = false;\n epoch1Start = _epoch1Start;\n epochDuration = _epochDuration;\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n /*\n * Stores `amount` of `tokenAddress` tokens for the `user` into the vault\n */\n function deposit(address tokenAddress, uint256 amount) public nonReentrant whenNotPaused {\n require(amount > 0, \"STK:E-205\");\n\n IERC20 token = IERC20(tokenAddress);\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].add(amount);\n\n token.transferFrom(msg.sender, address(this), amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n uint128 currentMultiplier = currentEpochMultiplier();\n uint256 balance = balances[msg.sender][tokenAddress];\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the next epoch pool size\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n\n uint256 balanceBefore = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n // if there's no checkpoint yet, it means the user didn't have any activity\n // we want to store checkpoints both for the current epoch and next epoch because\n // if a user does a withdraw, the current epoch can also be modified and\n // we don't want to insert another checkpoint in the middle of the array as that could be expensive\n if (checkpoints.length == 0) {\n checkpoints.push(Checkpoint(currentEpoch, currentMultiplier, 0, amount));\n\n // next epoch => multiplier is 1, epoch deposits is 0\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, amount, 0));\n } else {\n uint256 last = checkpoints.length - 1;\n\n // the last action happened in an older epoch (e.g. a deposit in epoch 3, current epoch is >=5)\n if (checkpoints[last].epochId < currentEpoch) {\n uint128 multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n BASE_MULTIPLIER,\n amount,\n currentMultiplier\n );\n checkpoints.push(Checkpoint(currentEpoch, multiplier, getCheckpointBalance(checkpoints[last]), amount));\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the previous epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last]),\n checkpoints[last].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last].newDeposits = checkpoints[last].newDeposits.add(amount);\n\n checkpoints.push(Checkpoint(currentEpoch + 1, BASE_MULTIPLIER, balance, 0));\n }\n // the last action happened in the current epoch\n else {\n if (last >= 1 && checkpoints[last - 1].epochId == currentEpoch) {\n checkpoints[last - 1].multiplier = computeNewMultiplier(\n getCheckpointBalance(checkpoints[last - 1]),\n checkpoints[last - 1].multiplier,\n amount,\n currentMultiplier\n );\n checkpoints[last - 1].newDeposits = checkpoints[last - 1].newDeposits.add(amount);\n }\n\n checkpoints[last].startBalance = balance;\n }\n }\n\n uint256 balanceAfter = getEpochUserBalance(msg.sender, tokenAddress, currentEpoch);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.add(balanceAfter.sub(balanceBefore));\n\n emit Deposit(msg.sender, tokenAddress, amount);\n }\n\n /*\n * Removes the deposit of the user and sends the amount of `tokenAddress` back to the `user`\n */\n function withdraw(address tokenAddress, uint256 amount) public nonReentrant {\n require(balances[msg.sender][tokenAddress] >= amount, \"STK:E-432\");\n\n balances[msg.sender][tokenAddress] = balances[msg.sender][tokenAddress].sub(amount);\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, amount);\n\n // epoch logic\n uint128 currentEpoch = getCurrentEpoch();\n\n lastWithdrawEpochId[tokenAddress] = currentEpoch;\n\n if (!epochIsInitialized(tokenAddress, currentEpoch)) {\n address[] memory tokens = new address[](1);\n tokens[0] = tokenAddress;\n manualEpochInit(tokens, currentEpoch);\n }\n\n // update the pool size of the next epoch to its current balance\n Pool storage pNextEpoch = poolSize[tokenAddress][currentEpoch + 1];\n pNextEpoch.size = token.balanceOf(address(this));\n pNextEpoch.set = true;\n\n Checkpoint[] storage checkpoints = balanceCheckpoints[msg.sender][tokenAddress];\n uint256 last = checkpoints.length - 1;\n\n // note: it's impossible to have a withdraw and no checkpoints because the checkpoints[last] will be out of bound and revert\n\n // there was a deposit in an older epoch (more than 1 behind [eg: previous 0, now 5]) but no other action since then\n if (checkpoints[last].epochId < currentEpoch) {\n checkpoints.push(Checkpoint(currentEpoch, BASE_MULTIPLIER, balances[msg.sender][tokenAddress], 0));\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the `epochId - 1` epoch => we have a checkpoint for the current epoch\n else if (checkpoints[last].epochId == currentEpoch) {\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n checkpoints[last].newDeposits = 0;\n checkpoints[last].multiplier = BASE_MULTIPLIER;\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(amount);\n }\n // there was a deposit in the current epoch\n else {\n Checkpoint storage currentEpochCheckpoint = checkpoints[last - 1];\n\n uint256 balanceBefore = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n // in case of withdraw, we have 2 branches:\n // 1. the user withdraws less than he added in the current epoch\n // 2. the user withdraws more than he added in the current epoch (including 0)\n if (amount < currentEpochCheckpoint.newDeposits) {\n uint128 avgDepositMultiplier = uint128(\n balanceBefore.sub(currentEpochCheckpoint.startBalance).mul(BASE_MULTIPLIER).div(currentEpochCheckpoint.newDeposits)\n );\n\n currentEpochCheckpoint.newDeposits = currentEpochCheckpoint.newDeposits.sub(amount);\n\n currentEpochCheckpoint.multiplier = computeNewMultiplier(\n currentEpochCheckpoint.startBalance,\n BASE_MULTIPLIER,\n currentEpochCheckpoint.newDeposits,\n avgDepositMultiplier\n );\n } else {\n currentEpochCheckpoint.startBalance = currentEpochCheckpoint.startBalance.sub(\n amount.sub(currentEpochCheckpoint.newDeposits)\n );\n currentEpochCheckpoint.newDeposits = 0;\n currentEpochCheckpoint.multiplier = BASE_MULTIPLIER;\n }\n\n uint256 balanceAfter = getCheckpointEffectiveBalance(currentEpochCheckpoint);\n\n poolSize[tokenAddress][currentEpoch].size = poolSize[tokenAddress][currentEpoch].size.sub(balanceBefore.sub(balanceAfter));\n\n checkpoints[last].startBalance = balances[msg.sender][tokenAddress];\n }\n\n emit Withdraw(msg.sender, tokenAddress, amount);\n }\n\n /*\n * manualEpochInit can be used by anyone to initialize an epoch based on the previous one\n * This is only applicable if there was no action (deposit/withdraw) in the current epoch.\n * Any deposit and withdraw will automatically initialize the current and next epoch.\n */\n function manualEpochInit(address[] memory tokens, uint128 epochId) public whenNotPaused {\n require(epochId <= getCurrentEpoch(), \"STK:E-306\");\n\n\n for (uint i = 0; i < tokens.length; i++) {\n Pool storage p = poolSize[tokens[i]][epochId];\n if (epochId == 0) {\n p.size = uint256(0);\n p.set = true;\n } else {\n require(!epochIsInitialized(tokens[i], epochId), \"STK:E-002\");\n require(epochIsInitialized(tokens[i], epochId - 1), \"STK:E-305\");\n p.size = poolSize[tokens[i]][epochId - 1].size;\n p.set = true;\n }\n }\n\n emit ManualEpochInit(msg.sender, epochId, tokens);\n }\n\n function emergencyWithdraw(address tokenAddress) public {\n require((getCurrentEpoch() - lastWithdrawEpochId[tokenAddress]) >= 10, \"STK:E-304\");\n\n uint256 totalUserBalance = balances[msg.sender][tokenAddress];\n require(totalUserBalance > 0, \"STK:E-205\");\n\n balances[msg.sender][tokenAddress] = 0;\n\n IERC20 token = IERC20(tokenAddress);\n token.transfer(msg.sender, totalUserBalance);\n\n emit EmergencyWithdraw(msg.sender, tokenAddress, totalUserBalance);\n }\n\n /*\n * Returns the valid balance of a user that was taken into consideration in the total pool size for the epoch\n * A deposit will only change the next epoch balance.\n * A withdraw will decrease the current epoch (and subsequent) balance.\n */\n function getEpochUserBalance(address user, address token, uint128 epochId) public view returns (uint256) {\n Checkpoint[] storage checkpoints = balanceCheckpoints[user][token];\n\n // if there are no checkpoints, it means the user never deposited any tokens, so the balance is 0\n if (checkpoints.length == 0 || epochId < checkpoints[0].epochId) {\n return 0;\n }\n\n uint min = 0;\n uint max = checkpoints.length - 1;\n\n // shortcut for blocks newer than the latest checkpoint == current balance\n if (epochId >= checkpoints[max].epochId) {\n return getCheckpointEffectiveBalance(checkpoints[max]);\n }\n\n // binary search of the value in the array\n while (max > min) {\n uint mid = (max + min + 1) / 2;\n if (checkpoints[mid].epochId <= epochId) {\n min = mid;\n } else {\n max = mid - 1;\n }\n }\n\n return getCheckpointEffectiveBalance(checkpoints[min]);\n }\n\n /*\n * Returns the amount of `token` that the `user` has currently staked\n */\n function balanceOf(address user, address token) public view returns (uint256) {\n return balances[user][token];\n }\n\n /*\n * Returns the id of the current epoch derived from block.timestamp\n */\n function getCurrentEpoch() public view returns (uint128) {\n if (block.timestamp < epoch1Start) {\n return 0;\n }\n\n return uint128((block.timestamp - epoch1Start) / epochDuration + 1);\n }\n\n /*\n * Returns the total amount of `tokenAddress` that was locked from beginning to end of epoch identified by `epochId`\n */\n function getEpochPoolSize(address tokenAddress, uint128 epochId) public view returns (uint256) {\n // Premises:\n // 1. it's impossible to have gaps of uninitialized epochs\n // - any deposit or withdraw initialize the current epoch which requires the previous one to be initialized\n if (epochIsInitialized(tokenAddress, epochId)) {\n return poolSize[tokenAddress][epochId].size;\n }\n\n // epochId not initialized and epoch 0 not initialized => there was never any action on this pool\n if (!epochIsInitialized(tokenAddress, 0)) {\n return 0;\n }\n\n // epoch 0 is initialized => there was an action at some point but none that initialized the epochId\n // which means the current pool size is equal to the current balance of token held by the staking contract\n IERC20 token = IERC20(tokenAddress);\n return token.balanceOf(address(this));\n }\n\n /*\n * Returns the percentage of time left in the current epoch\n */\n function currentEpochMultiplier() public view returns (uint128) {\n uint128 currentEpoch = getCurrentEpoch();\n uint256 currentEpochEnd = epoch1Start + currentEpoch * epochDuration;\n uint256 timeLeft = currentEpochEnd - block.timestamp;\n uint128 multiplier = uint128(timeLeft * BASE_MULTIPLIER / epochDuration);\n\n return multiplier;\n }\n\n function computeNewMultiplier(uint256 prevBalance, uint128 prevMultiplier, uint256 amount, uint128 currentMultiplier) public pure returns (uint128) {\n uint256 prevAmount = prevBalance.mul(prevMultiplier).div(BASE_MULTIPLIER);\n uint256 addAmount = amount.mul(currentMultiplier).div(BASE_MULTIPLIER);\n uint128 newMultiplier = uint128(prevAmount.add(addAmount).mul(BASE_MULTIPLIER).div(prevBalance.add(amount)));\n\n return newMultiplier;\n }\n\n /*\n * Checks if an epoch is initialized, meaning we have a pool size set for it\n */\n function epochIsInitialized(address token, uint128 epochId) public view returns (bool) {\n return poolSize[token][epochId].set;\n }\n\n function getCheckpointBalance(Checkpoint memory c) internal pure returns (uint256) {\n return c.startBalance.add(c.newDeposits);\n }\n\n function getCheckpointEffectiveBalance(Checkpoint memory c) internal pure returns (uint256) {\n return getCheckpointBalance(c).mul(c.multiplier).div(BASE_MULTIPLIER);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"STK:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/incentives/YieldFarm.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/incentives/YieldFarm2.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm2 is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/incentives/YieldFarm3.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.11;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../interfaces/IStaking.sol\";\n\ncontract YieldFarm3 is Ownable, BlackholePrevention {\n\n // lib\n using SafeMath for uint;\n using SafeMath for uint128;\n\n // constants\n uint public immutable TOTAL_DISTRIBUTED_AMOUNT;\n uint public immutable NR_OF_EPOCHS;\n\n // state variables\n\n // addreses\n address private immutable _token;\n address private immutable _communityVault;\n // contracts\n IERC20 private immutable _ionx;\n IStaking private _staking;\n\n\n uint[] private epochs;\n uint private immutable _genesisEpochAmount;\n uint private _deprecationPerEpoch;\n uint128 public lastInitializedEpoch;\n bool internal _paused;\n mapping(address => uint128) public lastEpochIdHarvested;\n uint public epochDuration; // init from staking contract\n uint public immutable epochStart; // init from staking contract\n\n // events\n event PausedStateSet(bool isPaused);\n event MassHarvest(address indexed user, uint256 epochsHarvested, uint256 totalValue);\n event Harvest(address indexed user, uint128 indexed epochId, uint256 amount);\n\n // constructor\n constructor(address ionxTokenAddress, address token, address stakeContract, address communityVault, uint genesisEpochAmount, uint deprecationPerEpoch, uint nrOfEpochs) public {\n _paused = false;\n _ionx = IERC20(ionxTokenAddress);\n _token = token;\n _staking = IStaking(stakeContract);\n _communityVault = communityVault;\n epochDuration = _staking.epochDuration();\n epochStart = _staking.epoch1Start() + epochDuration;\n _deprecationPerEpoch = deprecationPerEpoch;\n uint n = nrOfEpochs;\n uint amountEpochN = genesisEpochAmount.sub(n.sub(1).mul(_deprecationPerEpoch));\n TOTAL_DISTRIBUTED_AMOUNT = n.mul((genesisEpochAmount.add(amountEpochN)).div(2));\n NR_OF_EPOCHS = nrOfEpochs;\n epochs = new uint[](nrOfEpochs + 1);\n _genesisEpochAmount = genesisEpochAmount;\n\n }\n\n function isPaused() external view returns (bool) {\n return _paused;\n }\n\n function getAmountClaimable() external view returns (uint) {\n uint totalClaimable;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n totalClaimable += _getAmountClaimableAtEpoch(msg.sender, i);\n }\n\n return totalClaimable;\n }\n\n // public method to harvest all the unharvested epochs until current epoch - 1\n function massHarvest() external whenNotPaused returns (uint){\n uint totalDistributedValue;\n uint epochId = _getEpochId().sub(1); // fails in epoch 0\n uint lastEpochIdHarvestedUser = lastEpochIdHarvested[msg.sender];\n\n // force max number of epochs\n if (epochId > NR_OF_EPOCHS) {\n epochId = NR_OF_EPOCHS;\n }\n\n for (uint128 i = lastEpochIdHarvested[msg.sender] + 1; i <= epochId; i++) {\n // i = epochId\n // compute distributed Value and do one single transfer at the end\n totalDistributedValue += _harvest(i);\n }\n\n emit MassHarvest(msg.sender, epochId - lastEpochIdHarvestedUser, totalDistributedValue);\n\n if (totalDistributedValue > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, totalDistributedValue);\n }\n\n return totalDistributedValue;\n }\n function harvest (uint128 epochId) external whenNotPaused returns (uint){\n // checks for requested epoch\n require (_getEpochId() > epochId, \"YLD:E-306\");\n require(epochId <= NR_OF_EPOCHS, \"YLD:E-408\");\n require (lastEpochIdHarvested[msg.sender].add(1) == epochId, \"YLD:E-204\");\n uint userReward = _harvest(epochId);\n if (userReward > 0) {\n _ionx.transferFrom(_communityVault, msg.sender, userReward);\n }\n emit Harvest(msg.sender, epochId, userReward);\n return userReward;\n }\n\n // views\n // calls to the staking smart contract to retrieve the epoch total pool size\n function getPoolSize(uint128 epochId) external view returns (uint) {\n return _getPoolSize(epochId);\n }\n\n function getCurrentEpoch() external view returns (uint) {\n return _getEpochId();\n }\n\n // calls to the staking smart contract to retrieve user balance for an epoch\n function getEpochStake(address userAddress, uint128 epochId) external view returns (uint) {\n return _getUserBalancePerEpoch(userAddress, epochId);\n }\n\n function getGenesisEpochAmount() external view returns (uint){\n return _genesisEpochAmount;\n }\n\n function getDeprecationPerEpoch() external view returns (uint){\n return _deprecationPerEpoch;\n }\n\n function userLastEpochIdHarvested() external view returns (uint){\n return lastEpochIdHarvested[msg.sender];\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n // internal methods\n\n function _initEpoch(uint128 epochId) internal {\n require(lastInitializedEpoch.add(1) == epochId, \"YLD:E-204\");\n lastInitializedEpoch = epochId;\n // call the staking smart contract to init the epoch\n epochs[epochId] = _getPoolSize(epochId);\n }\n\n function _getAmountClaimableAtEpoch(address account, uint128 epochId) internal view returns (uint) {\n if (epochs[epochId] == 0) { return 0; }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(account, epochId))\n .div(epochs[epochId]);\n }\n\n function _harvest (uint128 epochId) internal returns (uint) {\n // try to initialize an epoch. if it can't it fails\n // if it fails either user either a BarnBridge account will init not init epochs\n if (lastInitializedEpoch < epochId) {\n _initEpoch(epochId);\n }\n // Set user state for last harvested\n lastEpochIdHarvested[msg.sender] = epochId;\n // compute and return user total reward. For optimization reasons the transfer have been moved to an upper layer (i.e. massHarvest needs to do a single transfer)\n\n // exit if there is no stake on the epoch\n if (epochs[epochId] == 0) {\n return 0;\n }\n return _calcTotalAmountPerEpoch(epochId)\n .mul(_getUserBalancePerEpoch(msg.sender, epochId))\n .div(epochs[epochId]);\n }\n\n function _calcTotalAmountPerEpoch(uint256 epochId) internal view returns (uint) {\n return _genesisEpochAmount.sub(epochId.mul(_deprecationPerEpoch)); // .sub(1) ?\n }\n\n function _getPoolSize(uint128 epochId) internal view returns (uint) {\n // retrieve token token balance\n return _staking.getEpochPoolSize(_token, _stakingEpochId(epochId));\n }\n\n function _getUserBalancePerEpoch(address userAddress, uint128 epochId) internal view returns (uint){\n // retrieve token token balance per user per epoch\n return _staking.getEpochUserBalance(userAddress, _token, _stakingEpochId(epochId));\n }\n\n // compute epoch id from blocktimestamp and epochstart date\n function _getEpochId() internal view returns (uint128 epochId) {\n if (block.timestamp < epochStart) {\n return 0;\n }\n epochId = uint128(block.timestamp.sub(epochStart).div(epochDuration).add(1));\n }\n\n // get the staking epoch which is 1 epoch more\n function _stakingEpochId(uint128 epochId) pure internal returns (uint128) {\n return epochId + 1;\n }\n\n modifier whenNotPaused() {\n require(_paused != true, \"YLD:E-101\");\n _;\n }\n}" + }, + "contracts/v1/interfaces/IAaveBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IAaveBridge.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n\ninterface IAaveBridge {\n function getReserveInterestToken(address assetToken) external view returns (address aTokenAddress);\n function isReserveActive(address assetToken) external view returns (bool);\n\n function getTotalBalance(address account, address assetToken) external view returns (uint256);\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(address receiver, address assetToken, uint256 assetAmount) external;\n}\n" + }, + "contracts/v1/interfaces/IBaseProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IBaseProton is IERC721 {\n event PausedStateSet(bool isPaused);\n event SalePriceSet(uint256 indexed tokenId, uint256 salePrice);\n event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct);\n event FeesWithdrawn(address indexed receiver, uint256 amount);\n event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties);\n event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view returns (address);\n function getSalePrice(uint256 tokenId) external view returns (uint256);\n function getLastSellPrice(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyalties(address account) external view returns (uint256);\n function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address);\n\n function buyProton(uint256 tokenId, uint256 gasLimit) external payable returns (bool);\n function claimCreatorRoyalties() external returns (uint256);\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n ) external returns (uint256 newTokenId);\n\n function createProtons(\n address creator,\n address receiver,\n string[] calldata tokenMetaUris\n ) external returns (bool);\n\n function createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n ) external returns (bool);\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice) external;\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external;\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external;\n}" + }, + "contracts/v1/interfaces/IBasketManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Particle Basket Manager interface\n * @dev The basket-manager for underlying assets attached to Charged Particles\n * @dev Manages the link between NFTs and their respective Smart-Baskets\n */\ninterface IBasketManager {\n\n event ControllerSet(address indexed controller);\n event ExecutorSet(address indexed executor);\n event PausedStateSet(bool isPaused);\n event NewSmartBasket(address indexed contractAddress, uint256 indexed tokenId, address indexed smartBasket);\n event BasketAdd(address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\n event BasketRemove(address indexed receiver, address indexed contractAddress, uint256 indexed tokenId, address basketTokenAddress, uint256 basketTokenId, uint256 basketTokenAmount);\n event BasketRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\n event RewardProgramSet(address indexed rewardProgram);\n\n function isPaused() external view returns (bool);\n\n function getTokenTotalCount(address contractAddress, uint256 tokenId) external view returns (uint256);\n function getTokenCountByType(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (uint256);\n\n function prepareTransferAmount(uint256 nftTokenAmount) external;\n function addToBasket(address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, address basketTokenAddress, uint256 basketTokenId) external returns (bool);\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function getBasketAddressById(address contractAddress, uint256 tokenId) external returns (address);\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/IChargedManagers.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IWalletManager.sol\";\nimport \"./IBasketManager.sol\";\n\n/**\n * @notice Interface for Charged Wallet-Managers\n */\ninterface IChargedManagers {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function isContractOwner(address contractAddress, address account) external view returns (bool);\n\n // ERC20\n function isWalletManagerEnabled(string calldata walletManagerId) external view returns (bool);\n function getWalletManager(string calldata walletManagerId) external view returns (IWalletManager);\n\n // ERC721\n function isNftBasketEnabled(string calldata basketId) external view returns (bool);\n function getBasketManager(string calldata basketId) external view returns (IBasketManager);\n\n // Validation\n function validateDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external;\n function validateNftDeposit(\n address sender,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n function validateDischarge(address sender, address contractAddress, uint256 tokenId) external;\n function validateRelease(address sender, address contractAddress, uint256 tokenId) external;\n function validateBreakBond(address sender, address contractAddress, uint256 tokenId) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event WalletManagerRegistered(string indexed walletManagerId, address indexed walletManager);\n event BasketManagerRegistered(string indexed basketId, address indexed basketManager);\n}\n" + }, + "contracts/v1/interfaces/IChargedParticles.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedParticles.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Charged Particles\n */\ninterface IChargedParticles {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getStateAddress() external view returns (address stateAddress);\n function getSettingsAddress() external view returns (address settingsAddress);\n function getManagersAddress() external view returns (address managersAddress);\n\n function getFeesForDeposit(uint256 assetAmount) external view returns (uint256 protocolFee);\n function baseParticleMass(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCharge(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleKinetics(address contractAddress, uint256 tokenId, string calldata walletManagerId, address assetToken) external returns (uint256);\n function currentParticleCovalentBonds(address contractAddress, uint256 tokenId, string calldata basketManagerId) external view returns (uint256);\n\n /***********************************|\n | Particle Mechanics |\n |__________________________________*/\n\n function energizeParticle(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n ) external returns (uint256 yieldTokensAmount);\n\n function dischargeParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function dischargeParticleForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 receiverAmount);\n\n function releaseParticle(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function releaseParticleAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n ) external returns (uint256 creatorAmount, uint256 receiverAmount);\n\n function covalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n function breakCovalentBond(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external returns (bool success);\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositFeeSet(uint256 depositFee);\n event ProtocolFeesCollected(address indexed assetToken, uint256 depositAmount, uint256 feesCollected);\n}\n" + }, + "contracts/v1/interfaces/IChargedSettings.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IWalletManager.sol\";\nimport \"./IBasketManager.sol\";\n\n/**\n * @notice Interface for Charged Settings\n */\ninterface IChargedSettings {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n // function isContractOwner(address contractAddress, address account) external view returns (bool);\n function getCreatorAnnuities(address contractAddress, uint256 tokenId) external returns (address creator, uint256 annuityPct);\n function getCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId) external view returns (address);\n function getTempLockExpiryBlocks() external view returns (uint256);\n function getTimelockApprovals(address operator) external view returns (bool timelockAny, bool timelockOwn);\n function getAssetRequirements(\n address contractAddress,\n address assetToken\n ) external view returns (\n string memory requiredWalletManager,\n bool energizeEnabled,\n bool restrictedAssets,\n bool validAsset,\n uint256 depositCap,\n uint256 depositMin,\n uint256 depositMax,\n bool invalidAsset\n );\n function getNftAssetRequirements(\n address contractAddress,\n address nftTokenAddress\n ) external view returns (\n string memory requiredBasketManager,\n bool basketEnabled,\n uint256 maxNfts\n );\n\n /***********************************|\n | Only NFT Creator |\n |__________________________________*/\n\n function setCreatorAnnuities(address contractAddress, uint256 tokenId, address creator, uint256 annuityPercent) external;\n function setCreatorAnnuitiesRedirect(address contractAddress, uint256 tokenId, address receiver) external;\n\n\n /***********************************|\n | Only NFT Contract Owner |\n |__________________________________*/\n\n function setRequiredWalletManager(address contractAddress, string calldata walletManager) external;\n function setRequiredBasketManager(address contractAddress, string calldata basketManager) external;\n function setAssetTokenRestrictions(address contractAddress, bool restrictionsEnabled) external;\n function setAllowedAssetToken(address contractAddress, address assetToken, bool isAllowed) external;\n function setAssetTokenLimits(address contractAddress, address assetToken, uint256 depositMin, uint256 depositMax) external;\n function setMaxNfts(address contractAddress, address nftTokenAddress, uint256 maxNfts) external;\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAssetInvalidity(address assetToken, bool invalidity) external;\n function enableNftContracts(address[] calldata contracts) external;\n function setPermsForCharge(address contractAddress, bool state) external;\n function setPermsForBasket(address contractAddress, bool state) external;\n function setPermsForTimelockAny(address contractAddress, bool state) external;\n function setPermsForTimelockSelf(address contractAddress, bool state) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n event DepositCapSet(address assetToken, uint256 depositCap);\n event TempLockExpirySet(uint256 expiryBlocks);\n\n event RequiredWalletManagerSet(address indexed contractAddress, string walletManager);\n event RequiredBasketManagerSet(address indexed contractAddress, string basketManager);\n event AssetTokenRestrictionsSet(address indexed contractAddress, bool restrictionsEnabled);\n event AllowedAssetTokenSet(address indexed contractAddress, address assetToken, bool isAllowed);\n event AssetTokenLimitsSet(address indexed contractAddress, address assetToken, uint256 assetDepositMin, uint256 assetDepositMax);\n event MaxNftsSet(address indexed contractAddress, address indexed nftTokenAddress, uint256 maxNfts);\n event AssetInvaliditySet(address indexed assetToken, bool invalidity);\n\n event TokenCreatorConfigsSet(address indexed contractAddress, uint256 indexed tokenId, address indexed creatorAddress, uint256 annuityPercent);\n event TokenCreatorAnnuitiesRedirected(address indexed contractAddress, uint256 indexed tokenId, address indexed redirectAddress);\n\n event PermsSetForCharge(address indexed contractAddress, bool state);\n event PermsSetForBasket(address indexed contractAddress, bool state);\n event PermsSetForTimelockAny(address indexed contractAddress, bool state);\n event PermsSetForTimelockSelf(address indexed contractAddress, bool state);\n}\n" + }, + "contracts/v1/interfaces/IChargedState.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IChargedSettings.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"./IChargedSettings.sol\";\n\n/**\n * @notice Interface for Charged State\n */\ninterface IChargedState {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function getDischargeTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n function getReleaseTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n function getBreakBondTimelockExpiry(address contractAddress, uint256 tokenId) external view returns (uint256 lockExpiry);\n\n function isApprovedForDischarge(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForRelease(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForBreakBond(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n function isApprovedForTimelock(address contractAddress, uint256 tokenId, address operator) external returns (bool);\n\n function isEnergizeRestricted(address contractAddress, uint256 tokenId) external view returns (bool);\n function isCovalentBondRestricted(address contractAddress, uint256 tokenId) external view returns (bool);\n\n function getDischargeState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n function getReleaseState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n function getBreakBondState(address contractAddress, uint256 tokenId, address sender) external\n returns (bool allowFromAll, bool isApproved, uint256 timelock, uint256 tempLockExpiry);\n\n /***********************************|\n | Only NFT Owner/Operator |\n |__________________________________*/\n\n function setDischargeApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setReleaseApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setBreakBondApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setTimelockApproval(address contractAddress, uint256 tokenId, address operator) external;\n function setApprovalForAll(address contractAddress, uint256 tokenId, address operator) external;\n\n function setPermsForRestrictCharge(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowDischarge(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowRelease(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForRestrictBond(address contractAddress, uint256 tokenId, bool state) external;\n function setPermsForAllowBreakBond(address contractAddress, uint256 tokenId, bool state) external;\n\n function setDischargeTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n function setReleaseTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n function setBreakBondTimelock(\n address contractAddress,\n uint256 tokenId,\n uint256 unlockBlock\n ) external;\n\n /***********************************|\n | Only NFT Contract |\n |__________________________________*/\n\n function setTemporaryLock(\n address contractAddress,\n uint256 tokenId,\n bool isLocked\n ) external;\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event Initialized(address indexed initiator);\n event ControllerSet(address indexed controllerAddress, string controllerId);\n\n event DischargeApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event ReleaseApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event BreakBondApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n event TimelockApproval(address indexed contractAddress, uint256 indexed tokenId, address indexed owner, address operator);\n\n event TokenDischargeTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenReleaseTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenBreakBondTimelock(address indexed contractAddress, uint256 indexed tokenId, address indexed operator, uint256 unlockBlock);\n event TokenTempLock(address indexed contractAddress, uint256 indexed tokenId, uint256 unlockBlock);\n\n event PermsSetForRestrictCharge(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowDischarge(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowRelease(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForRestrictBond(address indexed contractAddress, uint256 indexed tokenId, bool state);\n event PermsSetForAllowBreakBond(address indexed contractAddress, uint256 indexed tokenId, bool state);\n}\n" + }, + "contracts/v1/interfaces/IDai.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\ninterface IDai is IERC20Upgradeable {\n // --- Approve by signature ---\n function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external;\n function transferFrom(address src, address dst, uint wad) external override returns (bool);\n}" + }, + "contracts/v1/interfaces/IERC20Detailed.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Detailed {\n function decimals() external view returns (uint8);\n function symbol() external view returns (string memory);\n function name() external view returns (string memory);\n\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(address sender, address recipient, uint256 amount) 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" + }, + "contracts/v1/interfaces/IERC721Chargeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IERC721Chargeable.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts-upgradeable/introspection/IERC165Upgradeable.sol\";\n\ninterface IERC721Chargeable is IERC165Upgradeable {\n function owner() external view returns (address);\n function creatorOf(uint256 tokenId) external view returns (address);\n function balanceOf(address tokenOwner) external view returns (uint256 balance);\n function ownerOf(uint256 tokenId) external view returns (address tokenOwner);\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n function transferFrom(address from, address to, uint256 tokenId) external;\n function approve(address to, uint256 tokenId) external;\n function getApproved(uint256 tokenId) external view returns (address operator);\n function setApprovalForAll(address operator, bool _approved) external;\n function isApprovedForAll(address tokenOwner, address operator) external view returns (bool);\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n}\n" + }, + "contracts/v1/interfaces/ILepton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ILepton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Lepton Interface\n * @dev ...\n */\ninterface ILepton {\n\n struct Classification {\n string tokenUri;\n uint256 price;\n uint128 _upperBounds;\n uint32 supply;\n uint32 multiplier;\n uint32 bonus;\n }\n\n function mintLepton() external payable returns (uint256 newTokenId);\n function batchMintLepton(uint256 count) external payable;\n function getNextType() external view returns (uint256);\n function getNextPrice() external view returns (uint256);\n function getMultiplier(uint256 tokenId) external view returns (uint256);\n function getBonus(uint256 tokenId) external view returns (uint256);\n\n\n event MaxMintPerTxSet(uint256 maxAmount);\n event LeptonTypeAdded(string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\n event LeptonTypeUpdated(uint256 leptonIndex, string tokenUri, uint256 price, uint32 supply, uint32 multiplier, uint32 bonus, uint256 upperBounds);\n event LeptonMinted(address indexed receiver, uint256 indexed tokenId, uint256 price, uint32 multiplier);\n event LeptonBatchMinted(address indexed receiver, uint256 indexed tokenId, uint256 count, uint256 price, uint32 multiplier);\n event PausedStateSet(bool isPaused);\n}\n" + }, + "contracts/v1/interfaces/IMerkleDistributor.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.6.0;\n\n// Allows anyone to claim a token if they exist in a merkle root.\ninterface IMerkleDistributor {\n // Returns the address of the token distributed by this contract.\n function token() external view returns (address);\n // Returns the merkle root of the merkle tree containing account balances available to claim.\n function merkleRoot() external view returns (bytes32);\n // Returns true if the index has been marked claimed.\n function isClaimed(uint256 index) external view returns (bool);\n // Claim the given amount of the token to the given address. Reverts if the inputs are invalid.\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external;\n\n // This event is triggered whenever a call to #claim succeeds.\n event Claimed(uint256 index, address account, uint256 amount);\n}" + }, + "contracts/v1/interfaces/IParticleSplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IParticleSplitter.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @notice Interface for Particle Splitter\n */\ninterface IParticleSplitter {\n\n /***********************************|\n | Public API |\n |__________________________________*/\n\n function executeForWallet(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address externalAddress,\n bytes memory encodedParams\n ) external payable returns (bytes memory);\n\n function executeForBasket(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address externalAddress,\n bytes memory encodedParams\n ) external payable returns (bytes memory);\n\n function withdrawWalletRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n ) external returns (uint256 amountWithdrawn);\n\n function withdrawBasketRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n ) external returns (uint256 amountWithdrawn);\n\n function refreshWalletPrincipal(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n ) external;\n\n\n /***********************************|\n | Particle Events |\n |__________________________________*/\n\n event ChargedManagersSet(address indexed chargedManagers);\n event TokenInfoProxySet(address indexed tokenInfoProxy);\n\n event ExecuteForWallet(\n address indexed contractAddress,\n uint256 tokenId,\n string walletManagerId,\n address indexed externalAddress,\n bytes encodedParams,\n uint256 ethValue\n );\n event ExecuteForBasket(\n address indexed contractAddress,\n uint256 tokenId,\n string basketManagerId,\n address indexed externalAddress,\n bytes encodedParams,\n uint256 ethValue\n );\n event PrincipalRefreshed(\n address contractAddress,\n uint256 tokenId,\n string walletManagerId,\n address assetToken\n );\n event PermsSetForExternal(\n address indexed contractAddress,\n bool state\n );\n}\n" + }, + "contracts/v1/interfaces/IProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IProton is IERC721 {\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n event PausedStateSet(bool isPaused);\n event SalePriceSet(uint256 indexed tokenId, uint256 salePrice);\n event CreatorRoyaltiesSet(uint256 indexed tokenId, uint256 royaltiesPct);\n event FeesWithdrawn(address indexed receiver, uint256 amount);\n event ProtonSold(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner, uint256 salePrice, address creator, uint256 creatorRoyalties);\n event RoyaltiesClaimed(address indexed receiver, uint256 amountClaimed);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view returns (address);\n function getSalePrice(uint256 tokenId) external view returns (uint256);\n function getLastSellPrice(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyalties(address account) external view returns (uint256);\n function getCreatorRoyaltiesPct(uint256 tokenId) external view returns (uint256);\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view returns (address);\n\n function buyProton(uint256 tokenId) external payable returns (bool);\n function claimCreatorRoyalties() external returns (uint256);\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n ) external returns (uint256 newTokenId);\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n ) external returns (uint256 newTokenId);\n\n function batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n ) external;\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice) external;\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) external;\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver) external;\n}" + }, + "contracts/v1/interfaces/IProtonB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ninterface IProtonB is IERC721 {\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n ) external returns (uint256 newTokenId);\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n ) external returns (uint256 newTokenId);\n}" + }, + "contracts/v1/interfaces/IRewardNft.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IRewardNft.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Reward-NFT Interface\n * @dev ...\n */\ninterface IRewardNft {\n function getMultiplier(uint256 tokenId) external view returns (uint256);\n function getBonus(uint256 tokenId) external view returns (uint256);\n}\n" + }, + "contracts/v1/interfaces/IRewardProgram.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IRewardProgram.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2023 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\ninterface IRewardProgram {\n /* admin events */\n event RewardProgramFunded(uint256 amount);\n event RewardProgramOutOfFunds();\n\n /* user events */\n event RewardsClaimed(address indexed contractAddress, uint256 tokenId, address indexed receiver, uint256 rewarded, uint256 remaining);\n\n event AssetRegistered(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\n event AssetDeposit(address indexed contractAddress, uint256 tokenId, string walletManagerId, uint256 principalAmount);\n event AssetRelease(address indexed contractAddress, uint256 tokenId, uint256 interestAmount);\n\n /* data types */\n struct ProgramRewardData {\n address stakingToken;\n address rewardToken;\n uint256 baseMultiplier; // Basis Points\n }\n\n struct AssetStake {\n uint256 start;\n uint256 claimableRewards;\n string walletManagerId;\n }\n\n function initialize(address stakingToken, address rewardToken, uint256 baseMultiplier, address chargedManagers, address universe, address owner) external;\n\n /* user functions */\n function getProgramData() external view returns (ProgramRewardData memory programData);\n function getAssetStake(uint256 uuid) external view returns (AssetStake memory);\n function getFundBalance() external view returns (uint256);\n function calculateRewardsEarned(uint256 parentNftUuid, uint256 interestAmount) external view returns (uint256);\n function getClaimableRewards(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function registerExistingDeposits(address contractAddress, uint256 tokenId, string calldata walletManagerId) external;\n function registerAssetDeposit(address contractAddress, uint256 tokenId, string calldata walletManagerId, uint256 principalAmount) external;\n function registerAssetRelease(address contractAddress, uint256 tokenId, uint256 interestAmount) external returns (uint256 rewards);\n}" + }, + "contracts/v1/interfaces/ISmartBasket.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartBasket.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Basket\n * @dev Manages holding and transferring NFTs within an NFT (if any),\n */\ninterface ISmartBasket {\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function addToBasket(address contractAddress, uint256 tokenId) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId) external returns (bool);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartBasketB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartBasketB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Basket \"B\"\n * @dev Manages holding and transferring NFTs within an NFT (if any),\n */\ninterface ISmartBasketB {\n function getNestedNftCount() external view returns (uint256);\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view returns (uint256);\n\n function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool);\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId, uint256 nftTokenAmount) external returns (bool);\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Wallet\n * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any),\n */\ninterface ISmartWallet {\n function getAssetTokenCount() external view returns (uint256);\n function getAssetTokenByIndex(uint256 index) external view returns (address);\n\n function setNftCreator(address creator, uint256 annuityPct) external;\n\n function isReserveActive(address assetToken) external view returns (bool);\n function getReserveInterestToken(address assetToken) external view returns (address);\n\n function getPrincipal(address assetToken) external returns (uint256);\n function getInterest(address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getTotal(address assetToken) external returns (uint256);\n function getRewards(address assetToken) external returns (uint256);\n\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(address receiver, address creatorRedirect, address assetToken) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function withdrawAmount(address receiver, address creatorRedirect, address assetToken, uint256 assetAmount) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function withdrawAmountForCreator(address receiver, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address assetToken) external;\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n}\n" + }, + "contracts/v1/interfaces/ISmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ISmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Charged Particles Smart Wallet\n * @dev Manages holding and transferring assets of an NFT to a specific LP for Yield (if any),\n */\ninterface ISmartWalletB {\n function getAssetTokenCount() external view returns (uint256);\n function getAssetTokenByIndex(uint256 index) external view returns (address);\n\n function isReserveActive(address assetToken) external view returns (bool);\n function getReserveInterestToken(address assetToken) external view returns (address);\n\n function getPrincipal(address assetToken) external returns (uint256);\n function getInterest(address assetToken, uint256 creatorPct) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getTotal(address assetToken) external returns (uint256);\n function getRewards(address assetToken) external returns (uint256);\n\n function deposit(address assetToken, uint256 assetAmount, uint256 referralCode) external returns (uint256);\n function withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken\n ) external returns (\n uint256 creatorAmount,\n uint256 receiverAmount\n );\n function withdrawAmount(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n ) external returns (\n uint256 creatorAmount,\n uint256 receiverAmount\n );\n function withdrawAmountForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n ) external returns (\n uint256 receiverAmount\n );\n function withdrawRewards(address receiver, address rewardsToken, uint256 rewardsAmount) external returns (uint256);\n function executeForAccount(address contractAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address assetToken) external;\n\n function withdrawEther(address payable receiver, uint256 amount) external;\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external;\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external;\n}\n" + }, + "contracts/v1/interfaces/IStaking.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\ninterface IStaking {\n function manualEpochInit(address[] memory tokens, uint128 epochId) external;\n function getCurrentEpoch() external view returns (uint128);\n function getEpochId(uint timestamp) external view returns (uint); // get epoch id\n function getEpochUserBalance(address user, address token, uint128 epoch) external view returns(uint);\n function getEpochPoolSize(address token, uint128 epoch) external view returns (uint);\n function epoch1Start() external view returns (uint);\n function epochDuration() external view returns (uint);\n}" + }, + "contracts/v1/interfaces/ITokenInfoProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfoProxy.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\n\ninterface ITokenInfoProxy {\n\n event ContractFunctionSignatureSet(address indexed contractAddress, string fnName, bytes4 fnSig);\n\n struct FnSignatures {\n bytes4 ownerOf;\n bytes4 creatorOf;\n }\n\n function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external;\n function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external;\n\n function getTokenUUID(address contractAddress, uint256 tokenId) external pure returns (uint256);\n function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external returns (bool);\n function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external returns (bool);\n function getTokenOwner(address contractAddress, uint256 tokenId) external returns (address);\n function getTokenCreator(address contractAddress, uint256 tokenId) external returns (address);\n}\n" + }, + "contracts/v1/interfaces/IUniverse.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IUniverse.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Universal Controller interface\n * @dev ...\n */\ninterface IUniverse {\n\n event ChargedParticlesSet(address indexed chargedParticles);\n event PhotonSet(address indexed photonToken, uint256 maxSupply);\n event ProtonTokenSet(address indexed protonToken);\n event LeptonTokenSet(address indexed leptonToken);\n event QuarkTokenSet(address indexed quarkToken);\n event BosonTokenSet(address indexed bosonToken);\n event EsaMultiplierSet(address indexed assetToken, uint256 multiplier);\n event ElectrostaticAttraction(address indexed account, address photonSource, uint256 energy, uint256 multiplier);\n event ElectrostaticDischarge(address indexed account, address photonSource, uint256 energy);\n\n function onEnergize(\n address sender,\n address referrer,\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 assetEnergy\n ) external;\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n ) external;\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address creator,\n address assetToken,\n uint256 receiverEnergy\n ) external;\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address assetToken,\n uint256 principalEnergy,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n ) external;\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata managerId,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n ) external;\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n ) external;\n}\n" + }, + "contracts/v1/interfaces/IUniverseRP.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IUniverseRP.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport \"./IUniverse.sol\";\n\n/**\n * @title Universal Controller interface for Rewards Program\n * @dev ...\n */\ninterface IUniverseRP is IUniverse {\n event RewardProgramSet(address indexed assetToken, address indexed rewardProgram);\n event RewardProgramRemoved(address indexed assetToken);\n event NftDeposit(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\n event NftRelease(address indexed contractAddress, uint256 tokenId, address indexed nftTokenAddress, uint256 nftTokenId);\n\n struct NftStake {\n uint256 multiplier; // in Basis Points\n uint256 depositBlockNumber;\n uint256 releaseBlockNumber;\n }\n\n function getRewardProgram(address asset) external view returns (address);\n function getNftStake(uint256 uuid) external view returns (NftStake memory);\n}\n" + }, + "contracts/v1/interfaces/IWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// IWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\n/**\n * @title Particle Wallet Manager interface\n * @dev The wallet-manager for underlying assets attached to Charged Particles\n * @dev Manages the link between NFTs and their respective Smart-Wallets\n */\ninterface IWalletManager {\n\n event ControllerSet(address indexed controller);\n event ExecutorSet(address indexed executor);\n event PausedStateSet(bool isPaused);\n event NewSmartWallet(address indexed contractAddress, uint256 indexed tokenId, address indexed smartWallet, address creator, uint256 annuityPct);\n event WalletEnergized(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 assetAmount, uint256 yieldTokensAmount);\n event WalletDischarged(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, uint256 creatorAmount, uint256 receiverAmount);\n event WalletDischargedForCreator(address indexed contractAddress, uint256 indexed tokenId, address indexed assetToken, address creator, uint256 receiverAmount);\n event WalletReleased(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address assetToken, uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n event WalletRewarded(address indexed contractAddress, uint256 indexed tokenId, address indexed receiver, address rewardsToken, uint256 rewardsAmount);\n\n function isPaused() external view returns (bool);\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view returns (bool);\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view returns (address);\n\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256);\n function getInterest(address contractAddress, uint256 tokenId, address assetToken) external returns (uint256 creatorInterest, uint256 ownerInterest);\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken) external returns (uint256);\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount) external returns (uint256 yieldTokensAmount);\n function discharge(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function dischargeAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 creatorAmount, uint256 receiverAmount);\n function dischargeAmountForCreator(address receiver, address contractAddress, uint256 tokenId, address creator, address assetToken, uint256 assetAmount) external returns (uint256 receiverAmount);\n function release(address receiver, address contractAddress, uint256 tokenId, address assetToken, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n function releaseAmount(address receiver, address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount, address creatorRedirect) external returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount);\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount) external returns (uint256 amount);\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams) external returns (bytes memory);\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken) external;\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct) external returns (address);\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount) external;\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount) external;\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId) external;\n}\n" + }, + "contracts/v1/leptons/store.sol": { + "content": "pragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../tokens/Ionx.sol\";\nimport \"../tokens/Lepton2.sol\";\n\ninterface ILepsonsStore {\n function load(uint256 amount) external payable;\n function setLepton(address _lepton) external;\n}\n\ncontract LeptonsStore is ILepsonsStore, IERC721Receiver, Ownable, BlackholePrevention {\n using SafeMath for uint256;\n\n event SoldLepton(address indexed buyer, uint256 amount, uint256 price);\n\n Lepton2 public lepton;\n Ionx public ionx;\n\n uint256 internal ionxPerLepton;\n uint256 internal nextTokenId;\n\n constructor(address _lepton, address _ionx, uint256 _ionxPerLepton) public {\n lepton = Lepton2(_lepton);\n ionx = Ionx(_ionx);\n ionxPerLepton = _ionxPerLepton;\n }\n\n function buyWithIonx(\n uint256 leptonAmount,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n uint256 ionxAmount = leptonAmount * ionxPerLepton;\n require(ionx.balanceOf(msg.sender) >= ionxAmount, \"Insufficient IONX balance\");\n\n ionx.permit(msg.sender, address(this), ionxAmount, deadline, v, r, s);\n ionx.transferFrom(msg.sender, address(this), ionxAmount);\n\n for (uint256 i = 0; i < leptonAmount; ++i) {\n uint256 tokenId = nextTokenId;\n nextTokenId = nextTokenId.add(1);\n\n lepton.safeTransferFrom(address(this), msg.sender, tokenId);\n }\n\n emit SoldLepton(msg.sender, leptonAmount, ionxAmount);\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function load(uint256 amount) external payable override onlyOwner {\n require(lepton.balanceOf(address(this)) == 0, \"store not empty\");\n nextTokenId = lepton.totalSupply().add(1);\n lepton.batchMintLepton{ value: msg.value }(amount);\n }\n\n function setLepton(address _lepton) external override onlyOwner {\n require(_lepton != address(0), \"Invalid address\");\n lepton = Lepton2(_lepton);\n }\n\n function setIonx(address _ionx) external onlyOwner {\n require(_ionx != address(0), \"Invalid address\");\n ionx = Ionx(_ionx);\n }\n\n function setIonxPerLepton(uint256 ionxAmount) external onlyOwner {\n ionxPerLepton = ionxAmount;\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n}" + }, + "contracts/v1/lib/BaseProton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IBaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n/// @title Base Proton Contract for Charged Particles compatible ERC721 NFTs\n/// @dev MUST NOT be Upgradeable, as Upgradeable NFTs are incompatible with Charged Particles.\ncontract BaseProton is \n IBaseProton, \n ERC721, \n Ownable, \n RelayRecipient, \n ReentrancyGuard, \n BlackholePrevention \n{\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n event Received(address, uint);\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n /// @dev Sequential Token IDs storage\n Counters.Counter internal _tokenIds;\n\n /// @dev NFT Token Creator settings\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct;\n mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect;\n mapping (address => uint256) internal _tokenCreatorClaimableRoyalties;\n\n /// @dev NFT Token Sale settings\n mapping (uint256 => uint256) internal _tokenSalePrice;\n mapping (uint256 => uint256) internal _tokenLastSellPrice;\n\n /// @dev Whether of not the Contract is Paused\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n /// @dev Inherit from ERC721 standard\n constructor(string memory _name, string memory _symbol) public ERC721(_name, _symbol) {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n receive() external payable virtual {\n emit Received(msg.sender, msg.value);\n }\n\n /// Returns the Creator address of an NFT by Token ID\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The address of the Creator account\n function creatorOf(uint256 tokenId) external view virtual override returns (address) {\n return _tokenCreator[tokenId];\n }\n\n /// Returns the Sale Price of an NFT by Token ID\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The sale price of the NFT\n function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenSalePrice[tokenId];\n }\n\n /// Returns the Last Sale Price of an NFT by Token ID\n /// @notice This is used to determine any increase in sale price used in royalties calculations\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The last sale price of the NFT\n function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenLastSellPrice[tokenId];\n }\n\n /// Returns the Claimable Royalties for the NFT Creator\n /// @param account The address of the Creator account to lookup\n /// @return The amount of earned royalties for the creator account\n function getCreatorRoyalties(address account) external view virtual override returns (uint256) {\n return _tokenCreatorClaimableRoyalties[account];\n }\n\n /// Returns the Percentage of Royalties reserved for the NFT Creator\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The percentage of royalties reserved for the creator\n function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenCreatorRoyaltiesPct[tokenId];\n }\n\n /// Returns the Receiving address of the Creator Royalties (or Creator if not set)\n /// @dev Returns the creator address if a receiving address has not been configured\n /// @param tokenId The ID of the NFT Token to lookup\n /// @return The Receiving address of the Creator Royalties\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) {\n return _creatorRoyaltiesReceiver(tokenId);\n }\n\n /// Allows an NFT Creator to Claim any Royalties that have been earned from NFT sales\n /// @dev Must be called by the royalties receiver account (not neccessarily the creator)\n /// @return The amout of creator royalties claimed\n function claimCreatorRoyalties()\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256)\n {\n return _claimCreatorRoyalties(_msgSender());\n }\n\n\n /***********************************|\n | Create Single Protons |\n |__________________________________*/\n\n /// Creates a Basic NFT with no Royalties and no initial Sale Price\n /// @dev Royalties and Sale Price can be configured later\n /// @param creator The address of the NFT Creator (can be different from the caller)\n /// @param receiver The receiving address of the NFT (can be different from the caller)\n /// @param tokenMetaUri The unique metadata URI for the NFT\n /// @return newTokenId The newly minted NFT Token ID\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n\n /***********************************|\n | Create Multiple Protons |\n |__________________________________*/\n\n function createProtons(\n address creator,\n address receiver,\n string[] calldata tokenMetaUris\n )\n external\n virtual\n override\n whenNotPaused\n returns (bool)\n {\n _createProtons(\n creator,\n receiver,\n 0, // royaltiesPercent\n tokenMetaUris\n );\n return true;\n }\n\n function createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n external\n virtual\n override\n whenNotPaused\n returns (bool)\n {\n _createProtonsForSale(\n creator,\n receiver,\n royaltiesPercent,\n tokenMetaUris,\n salePrices\n );\n return true;\n }\n\n\n /***********************************|\n | Buy Protons |\n |__________________________________*/\n\n function buyProton(uint256 tokenId, uint256 gasLimit)\n external\n payable\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (bool)\n {\n _buyProton(tokenId, gasLimit);\n return true;\n }\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice)\n external\n virtual\n override\n whenNotPaused\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setSalePrice(tokenId, salePrice);\n }\n\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setRoyaltiesPct(tokenId, royaltiesPct);\n }\n\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n {\n _tokenCreatorRoyaltiesRedirect[tokenId] = receiver;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual {\n _tokenSalePrice[tokenId] = salePrice;\n emit SalePriceSet(tokenId, salePrice);\n }\n\n function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual {\n require(royaltiesPct <= PERCENTAGE_SCALE, \"PRT:E-421\");\n _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct;\n emit CreatorRoyaltiesSet(tokenId, royaltiesPct);\n }\n\n function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) {\n address receiver = _tokenCreatorRoyaltiesRedirect[tokenId];\n if (receiver == address(0x0)) {\n receiver = _tokenCreator[tokenId];\n }\n return receiver;\n }\n\n function _createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n _tokenIds.increment();\n\n newTokenId = _tokenIds.current();\n _safeMint(receiver, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUri);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n }\n\n function _createProtons(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris\n )\n internal\n virtual\n {\n uint256 count = tokenMetaUris.length;\n for (uint256 i; i < count; i++) {\n _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, 0);\n }\n }\n\n function _createProtonsForSale(\n address creator,\n address receiver,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n internal\n virtual\n {\n require(tokenMetaUris.length == salePrices.length, \"PRT:E-202\");\n\n uint256 count = tokenMetaUris.length;\n for (uint256 i; i < count; i++) {\n _createProton(creator, receiver, tokenMetaUris[i], royaltiesPercent, salePrices[i]);\n }\n }\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n contractAddress = address(this);\n tokenId = _tokenId;\n salePrice = _tokenSalePrice[_tokenId];\n require(salePrice > 0, \"PRT:E-416\");\n require(msg.value >= salePrice, \"PRT:E-414\");\n\n uint256 ownerAmount = salePrice;\n creatorAmount;\n oldOwner = ownerOf(_tokenId);\n newOwner = _msgSender();\n\n // Creator Royalties\n royaltiesReceiver = _creatorRoyaltiesReceiver(_tokenId);\n uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[_tokenId];\n uint256 lastSellPrice = _tokenLastSellPrice[_tokenId];\n if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) {\n creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE);\n ownerAmount = ownerAmount.sub(creatorAmount);\n }\n _tokenLastSellPrice[_tokenId] = salePrice;\n\n // Reserve Royalties for Creator\n if (creatorAmount > 0) {\n _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount);\n }\n\n // Transfer Token\n _transfer(oldOwner, newOwner, _tokenId);\n\n // Transfer Payment\n if (ownerAmount > 0) {\n payable(oldOwner).sendValue(ownerAmount, _gasLimit);\n }\n\n emit ProtonSold(_tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n\n _refundOverpayment(salePrice, _gasLimit);\n }\n\n /**\n * @dev Pays out the Creator Royalties of the calling account\n * @param receiver The receiver of the claimable royalties\n * @return The amount of Creator Royalties claimed\n */\n function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) {\n uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver];\n require(claimableAmount > 0, \"PRT:E-411\");\n\n delete _tokenCreatorClaimableRoyalties[receiver];\n payable(receiver).sendValue(claimableAmount, 0);\n\n emit RoyaltiesClaimed(receiver, claimableAmount);\n }\n\n /**\n * @dev Collects the Required Asset Token from the users wallet\n * @param from The owner address to collect the Assets from\n * @param assetAmount The Amount of Asset Tokens to Collect\n */\n function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual {\n uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from);\n require(assetAmount <= _userAssetBalance, \"PRT:E-411\");\n // Be sure to Approve this Contract to transfer your Asset Token\n require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), \"PRT:E-401\");\n }\n\n function _refundOverpayment(uint256 threshold, uint256 gasLimit) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage, gasLimit);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n _tokenSalePrice[tokenId] = 0;\n super._transfer(from, to, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"PRT:E-101\");\n _;\n }\n\n modifier onlyTokenOwnerOrApproved(uint256 tokenId) {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"PRT:E-105\");\n _;\n }\n\n modifier onlyTokenCreator(uint256 tokenId) {\n require(_tokenCreator[tokenId] == _msgSender(), \"PRT:E-104\");\n _;\n }\n}" + }, + "contracts/v1/lib/Bitwise.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Bitwise.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nlibrary Bitwise {\n function negate(uint32 a) internal pure returns (uint32) {\n return a ^ maxInt();\n }\n\n function shiftLeft(uint32 a, uint32 n) internal pure returns (uint32) {\n return a * uint32(2) ** n;\n }\n\n function shiftRight(uint32 a, uint32 n) internal pure returns (uint32) {\n return a / uint32(2) ** n;\n }\n\n function maxInt() internal pure returns (uint32) {\n return uint32(-1);\n }\n\n // Get bit value at position\n function hasBit(uint32 a, uint32 n) internal pure returns (bool) {\n return a & shiftLeft(0x01, n) != 0;\n }\n\n // Set bit value at position\n function setBit(uint32 a, uint32 n) internal pure returns (uint32) {\n return a | shiftLeft(0x01, n);\n }\n\n // Set the bit into state \"false\"\n function clearBit(uint32 a, uint32 n) internal pure returns (uint32) {\n uint32 mask = negate(shiftLeft(0x01, n));\n return a & mask;\n }\n}\n" + }, + "contracts/v1/lib/BlackholePrevention.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// BlackholePrevention.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\n\n/**\n * @notice Prevents ETH or Tokens from getting stuck in a contract by allowing\n * the Owner/DAO to pull them out on behalf of a user\n * This is only meant to contracts that are not expected to hold tokens, but do handle transferring them.\n */\ncontract BlackholePrevention {\n using Address for address payable;\n using SafeERC20 for IERC20;\n\n event WithdrawStuckEther(address indexed receiver, uint256 amount);\n event WithdrawStuckERC20(address indexed receiver, address indexed tokenAddress, uint256 amount);\n event WithdrawStuckERC721(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId);\n event WithdrawStuckERC1155(address indexed receiver, address indexed tokenAddress, uint256 indexed tokenId, uint256 amount);\n\n function _withdrawEther(address payable receiver, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (address(this).balance >= amount) {\n receiver.sendValue(amount);\n emit WithdrawStuckEther(receiver, amount);\n }\n }\n\n function _withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC20(tokenAddress).balanceOf(address(this)) >= amount) {\n IERC20(tokenAddress).safeTransfer(receiver, amount);\n emit WithdrawStuckERC20(receiver, tokenAddress, amount);\n }\n }\n\n function _withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC721(tokenAddress).ownerOf(tokenId) == address(this)) {\n IERC721(tokenAddress).transferFrom(address(this), receiver, tokenId);\n emit WithdrawStuckERC721(receiver, tokenAddress, tokenId);\n }\n }\n\n function _withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) internal virtual {\n require(receiver != address(0x0), \"BHP:E-403\");\n if (IERC1155(tokenAddress).balanceOf(address(this), tokenId) >= amount) {\n IERC1155(tokenAddress).safeTransferFrom(address(this), receiver, tokenId, amount, \"\");\n emit WithdrawStuckERC1155(receiver, tokenAddress, tokenId, amount);\n }\n }\n}\n" + }, + "contracts/v1/lib/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/GSN/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableMap.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {\n using SafeMath for uint256;\n using Address for address;\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableMap for EnumerableMap.UintToAddressMap;\n using Strings for uint256;\n\n /**\n * @dev Emitted when `tokenId` token is transfered from `from` to `to`.\n */\n event TransferBatch(address indexed from, address indexed to, uint256 startTokenId, uint256 count);\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n // Mapping from holder address to their (enumerable) set of owned tokens\n mapping (address => EnumerableSet.UintSet) private _holderTokens;\n\n // Enumerable mapping from token ids to their owners\n EnumerableMap.UintToAddressMap private _tokenOwners;\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 // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Optional mapping for token URIs\n mapping(uint256 => string) private _tokenURIs;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n /*\n * bytes4(keccak256('totalSupply()')) == 0x18160ddd\n * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n *\n * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n */\n bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721:E-403\");\n\n return _holderTokens[owner].length();\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners.get(tokenId, \"ERC721:E-405\");\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"ERC721:E-405\");\n return _tokenURIs[tokenId];\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\n */\n function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {\n return _holderTokens[owner].at(index);\n }\n\n /**\n * @dev See {IERC721Enumerable-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds\n return _tokenOwners.length();\n }\n\n /**\n * @dev See {IERC721Enumerable-tokenByIndex}.\n */\n function tokenByIndex(uint256 index) public view override returns (uint256) {\n (uint256 tokenId, ) = _tokenOwners.at(index);\n return tokenId;\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721:E-111\");\n\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \"ERC721:E-105\");\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view override returns (address) {\n require(_exists(tokenId), \"ERC721:E-405\");\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 require(operator != _msgSender(), \"ERC721:E-111\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721:E-402\");\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 returns (bool) {\n return _tokenOwners.contains(tokenId);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721:E-405\");\n address owner = ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\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(address to, uint256 tokenId, bytes memory _data) internal virtual {\n _mint(to, tokenId);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721:E-402\");\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 _safeMintBatch(address to, uint256 startTokenId, uint256 count, bytes memory _data) internal virtual {\n _mintBatch(to, startTokenId, count);\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \"ERC721:E-402\");\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:E-403\");\n require(!_exists(tokenId), \"ERC721:E-407\");\n\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(address(0), to, tokenId);\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 _mintBatch(address to, uint256 startTokenId, uint256 count) internal virtual {\n require(to != address(0), \"ERC721:E-403\");\n require(!_exists(startTokenId), \"ERC721:E-407\");\n\n for (uint i = 0; i < count; i++) {\n uint256 tokenId = startTokenId.add(i);\n _holderTokens[to].add(tokenId);\n _tokenOwners.set(tokenId, to);\n }\n\n emit TransferBatch(address(0), to, startTokenId, count);\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(address from, address to, uint256 tokenId) internal virtual {\n require(ownerOf(tokenId) == from, \"ERC721:E-102\");\n require(to != address(0), \"ERC721:E-403\");\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _holderTokens[from].remove(tokenId);\n _holderTokens[to].add(tokenId);\n\n _tokenOwners.set(tokenId, to);\n\n emit Transfer(from, to, tokenId);\n }\n\n /**\n * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {\n require(_exists(tokenId), \"ERC721:E-405\");\n _tokenURIs[tokenId] = _tokenURI;\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(address from, address to, uint256 tokenId, bytes memory _data)\n private returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721:E-402\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) private {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\n }\n}\n" + }, + "contracts/v1/lib/ERC721Basic.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/GSN/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/introspection/ERC165.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\n\n/**\n * @title ERC721 Non-Fungible Token Standard basic implementation\n * @dev see https://eips.ethereum.org/EIPS/eip-721\n */\ncontract ERC721Basic is Context, ERC165, IERC721, IERC721Metadata {\n using SafeMath for uint256;\n using Address for address;\n\n // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n bytes4 internal constant _ERC721_RECEIVED = 0x150b7a02;\n\n // mapping from token ids to their owners\n mapping (uint256 => address) internal _tokenOwners;\n\n // mapping from owner to token balance\n mapping (address => uint256) internal _ownerBalance;\n\n // Mapping from token ID to approved address\n mapping (uint256 => address) internal _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping (address => mapping (address => bool)) internal _operatorApprovals;\n\n // Token name\n string internal _name;\n\n // Token symbol\n string internal _symbol;\n\n // Token Count\n uint256 internal _tokenCount;\n\n /*\n * bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n *\n * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n * 0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n */\n bytes4 internal constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n /*\n * bytes4(keccak256('name()')) == 0x06fdde03\n * bytes4(keccak256('symbol()')) == 0x95d89b41\n * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n *\n * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n */\n bytes4 internal constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\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) public {\n _name = name;\n _symbol = symbol;\n\n // register the supported interfaces to conform to ERC721 via ERC165\n _registerInterface(_INTERFACE_ID_ERC721);\n _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view override returns (uint256) {\n require(owner != address(0), \"ERC721:E-403\");\n return _ownerBalance[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view override returns (address) {\n return _tokenOwners[tokenId];\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view 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 return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ownerOf(tokenId);\n require(to != owner, \"ERC721:E-111\");\n\n require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), \"ERC721:E-105\");\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view override returns (address) {\n require(_exists(tokenId), \"ERC721:E-405\");\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n require(operator != _msgSender(), \"ERC721:E-111\");\n\n _operatorApprovals[_msgSender()][operator] = approved;\n emit ApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721:E-105\");\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 mecanisms 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(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721:E-402\");\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 returns (bool) {\n return _tokenOwners[tokenId] != address(0x0);\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 returns (bool) {\n require(_exists(tokenId), \"ERC721:E-405\");\n address owner = ownerOf(tokenId);\n return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\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(address to, bytes memory _data) internal virtual returns (uint256) {\n uint256 tokenId = _mint(to);\n require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721:E-402\");\n return 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 _safeMintBatch(address to, uint256 count, bytes memory _data) internal virtual {\n uint256 startTokenId = _mintBatch(to, count);\n require(_checkOnERC721Received(address(0), to, startTokenId, _data), \"ERC721:E-402\");\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) internal virtual returns (uint256) {\n require(to != address(0), \"ERC721:E-403\");\n\n _tokenCount = _tokenCount.add(1);\n uint256 tokenId = _tokenCount;\n require(!_exists(tokenId), \"ERC721:E-407\");\n\n _tokenOwners[tokenId] = to;\n _ownerBalance[to] = _ownerBalance[to].add(1);\n\n emit Transfer(address(0), to, tokenId);\n return tokenId;\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 _mintBatch(address to, uint256 count) internal virtual returns (uint256) {\n require(to != address(0), \"ERC721:E-403\");\n\n uint256 startTokenId = _tokenCount.add(1);\n for (uint i = 1; i <= count; i++) {\n uint256 tokenId = _tokenCount.add(i);\n _tokenOwners[tokenId] = to;\n emit Transfer(address(0), to, tokenId);\n }\n\n _tokenCount = _tokenCount.add(count);\n _ownerBalance[to] = _ownerBalance[to].add(count);\n return startTokenId;\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(address from, address to, uint256 tokenId) internal virtual {\n require(ownerOf(tokenId) == from, \"ERC721:E-102\");\n require(to != address(0), \"ERC721:E-403\");\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _tokenOwners[tokenId] = to;\n _ownerBalance[from] = _ownerBalance[from].sub(1);\n _ownerBalance[to] = _ownerBalance[to].add(1);\n\n emit Transfer(from, to, tokenId);\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(address from, address to, uint256 tokenId, bytes memory _data)\n internal returns (bool)\n {\n if (!to.isContract()) {\n return true;\n }\n bytes memory returndata = to.functionCall(abi.encodeWithSelector(\n IERC721Receiver(to).onERC721Received.selector,\n _msgSender(),\n from,\n tokenId,\n _data\n ), \"ERC721:E-402\");\n bytes4 retval = abi.decode(returndata, (bytes4));\n return (retval == _ERC721_RECEIVED);\n }\n\n function _approve(address to, uint256 tokenId) internal {\n _tokenApprovals[tokenId] = to;\n emit Approval(ownerOf(tokenId), to, tokenId);\n }\n}\n" + }, + "contracts/v1/lib/IERC5192.sol": { + "content": "// SPDX-License-Identifier: CC0-1.0\npragma solidity ^0.6.0;\n\ninterface IERC5192 {\n /// @notice Emitted when the locking status is changed to locked.\n /// @dev If a token is minted and the status is locked, this event should be emitted.\n /// @param tokenId The identifier for a token.\n event Locked(uint256 tokenId);\n\n /// @notice Emitted when the locking status is changed to unlocked.\n /// @dev If a token is minted and the status is unlocked, this event should be emitted.\n /// @param tokenId The identifier for a token.\n event Unlocked(uint256 tokenId);\n\n /// @notice Returns the locking status of an Soulbound Token\n /// @dev SBTs assigned to zero address are considered invalid, and queries\n /// about them do throw.\n /// @param tokenId The identifier for an SBT.\n function locked(uint256 tokenId) external view returns (bool);\n}\n" + }, + "contracts/v1/lib/NftTokenType.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// NftTokenType.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/introspection/IERC165.sol\";\n\nlibrary NftTokenType {\n bytes4 constant internal INTERFACE_SIGNATURE_ERC721 = 0x80ac58cd;\n bytes4 constant internal INTERFACE_SIGNATURE_ERC1155 = 0xd9b67a26;\n\n uint256 constant internal TYPE_MASK = uint256(uint128(~0)) << 128;\n uint256 constant internal TYPE_NFT_BIT = 1 << 255;\n\n function isERC721(address contractAddress) internal view returns (bool) {\n return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC721);\n }\n\n function isERC1155(address contractAddress) internal view returns (bool) {\n return IERC165(contractAddress).supportsInterface(INTERFACE_SIGNATURE_ERC1155);\n }\n\n function getTokenType(address contractAddress, uint256 tokenId) internal view returns (uint256) {\n IERC165 tokenInterface = IERC165(contractAddress);\n bool is1155 = tokenInterface.supportsInterface(INTERFACE_SIGNATURE_ERC1155);\n\n if (!is1155 || (tokenId & TYPE_NFT_BIT != TYPE_NFT_BIT)) { return 0; }\n\n return tokenId & TYPE_MASK;\n }\n}\n" + }, + "contracts/v1/lib/ReentrancyGuard.sol": { + "content": "pragma solidity 0.6.12;\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 () public {\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 _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\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 /**\n * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n * `nonReentrant` function in the call stack.\n */\n function _reentrancyGuardEntered() internal view returns (bool) {\n return _status == _ENTERED;\n }\n}" + }, + "contracts/v1/lib/RelayRecipient.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0;\n\nimport \"@opengsn/gsn/contracts/BaseRelayRecipient.sol\";\n\ncontract RelayRecipient is BaseRelayRecipient {\n function versionRecipient() external override view returns (string memory) {\n return \"1.0.0-beta.1/charged-particles.relay.recipient\";\n }\n}\n" + }, + "contracts/v1/lib/SmartWalletBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// SmartWalletBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../interfaces/ISmartWallet.sol\";\nimport \"./BlackholePrevention.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract SmartWalletBase is ISmartWallet, BlackholePrevention {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n address internal _walletManager;\n\n address internal nftCreator;\n uint256 internal nftCreatorAnnuityPct;\n uint256 internal nftCreatorAmountDischarged;\n\n EnumerableSet.AddressSet internal _assetTokens;\n\n // Asset Token => Principal Balance\n mapping (address => uint256) internal _assetPrincipalBalance;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initializeBase() public {\n require(_walletManager == address(0x0), \"SWB:E-002\");\n _walletManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getAssetTokenCount() external view virtual override returns (uint256) {\n return _assetTokens.length();\n }\n\n function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) {\n if (index >= _assetTokens.length()) {\n return address(0);\n }\n return _assetTokens.at(index);\n }\n\n function setNftCreator(address creator, uint256 annuityPct) external virtual override onlyWalletManager {\n nftCreator = creator;\n nftCreatorAnnuityPct = annuityPct;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyWalletManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n function refreshPrincipal(address assetToken)\n external\n virtual\n override\n onlyWalletManager\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getPrincipal(address assetToken) internal view virtual returns (uint256) {\n return _assetPrincipalBalance[assetToken];\n }\n\n function _trackAssetToken(address assetToken) internal virtual {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n }\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the wallet manager\n modifier onlyWalletManager() {\n require(_walletManager == msg.sender, \"SWB:E-109\");\n _;\n }\n}" + }, + "contracts/v1/lib/SmartWalletBaseB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// SmartWalletBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../interfaces/ISmartWalletB.sol\";\nimport \"./BlackholePrevention.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract SmartWalletBaseB is ISmartWalletB, BlackholePrevention {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n address internal _walletManager;\n\n EnumerableSet.AddressSet internal _assetTokens;\n\n // Asset Token => Principal Balance\n mapping (address => uint256) internal _assetPrincipalBalance;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initializeBase() public {\n require(_walletManager == address(0x0), \"SWB:E-002\");\n _walletManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getAssetTokenCount() external view virtual override returns (uint256) {\n return _assetTokens.length();\n }\n\n function getAssetTokenByIndex(uint256 index) external view virtual override returns (address) {\n if (index >= _assetTokens.length()) {\n return address(0);\n }\n return _assetTokens.at(index);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyWalletManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyWalletManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyWalletManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyWalletManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getPrincipal(address assetToken) internal view virtual returns (uint256) {\n return _assetPrincipalBalance[assetToken];\n }\n\n function _trackAssetToken(address assetToken) internal virtual {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n }\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the wallet manager\n modifier onlyWalletManager() {\n require(_walletManager == msg.sender, \"SWB:E-109\");\n _;\n }\n}" + }, + "contracts/v1/lib/Soul.sol": { + "content": "// SPDX-License-Identifier: CC0-1.0\npragma solidity ^0.6.12;\n\nimport \"./IERC5192.sol\";\n\ncontract Soul is IERC5192 {\n \n mapping (uint256 => bool) public lockedTokens;\n\n function _lockToken(uint256 tokenId) internal {\n lockedTokens[tokenId] = true;\n emit Locked(tokenId);\n }\n\n function _unlockToken(uint256 tokenId) internal {\n lockedTokens[tokenId] = false;\n emit Unlocked(tokenId);\n }\n\n function locked(uint256 tokenId)\n external\n view\n override(IERC5192)\n returns (bool)\n {\n return lockedTokens[tokenId];\n }\n}\n" + }, + "contracts/v1/lib/TokenInfo.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfo.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"../interfaces/IERC721Chargeable.sol\";\n\nlibrary TokenInfo {\n function getTokenUUID(address contractAddress, uint256 tokenId) internal pure virtual returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n function getTokenOwner(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n return tokenInterface.ownerOf(tokenId);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n function getTokenCreator(address contractAddress, uint256 tokenId) internal view virtual returns (address) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n return tokenInterface.creatorOf(tokenId);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Owner of an External NFT contract\n /// @param contractAddress The Address to the Contract of the NFT to check\n /// @param account The Address of the Account to check\n /// @return True if the account owns the contract\n function isContractOwner(address contractAddress, address account) internal view virtual returns (bool) {\n address contractOwner = IERC721Chargeable(contractAddress).owner();\n return contractOwner != address(0x0) && contractOwner == account;\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Creator of a Proton-based NFT\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the Proton-based NFT\n function isTokenCreator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenCreator = tokenInterface.creatorOf(tokenId);\n return (sender == tokenCreator);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the Proton-based NFT or the Contract itself\n function isTokenContractOrCreator(address contractAddress, uint256 tokenId, address creator, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenCreator = tokenInterface.creatorOf(tokenId);\n if (sender == contractAddress && creator == tokenCreator) { return true; }\n return (sender == tokenCreator);\n }\n\n /// @dev DEPRECATED; Prefer TokenInfoProxy\n /// @dev Checks if an account is the Owner or Operator of an External NFT\n /// @param contractAddress The Address to the Contract of the External NFT to check\n /// @param tokenId The Token ID of the External NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the Owner or Operator of the External NFT\n function isErc721OwnerOrOperator(address contractAddress, uint256 tokenId, address sender) internal view virtual returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenOwner = tokenInterface.ownerOf(tokenId);\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\n }\n\n /**\n * @dev Returns true if `account` is a contract.\n * @dev Taken from OpenZeppelin library\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 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\n // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\n // for accounts without code, i.e. `keccak256('')`\n bytes32 codehash;\n bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n // solhint-disable-next-line no-inline-assembly\n assembly { codehash := extcodehash(account) }\n return (codehash != accountHash && codehash != 0x0);\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 * @dev Taken from OpenZeppelin library\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, uint256 gasLimit) internal {\n require(address(this).balance >= amount, \"TokenInfo: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = (gasLimit > 0)\n ? recipient.call{ value: amount, gas: gasLimit }(\"\")\n : recipient.call{ value: amount }(\"\");\n require(success, \"TokenInfo: unable to send value, recipient may have reverted\");\n }\n}\n" + }, + "contracts/v1/lib/TokenInfoProxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// TokenInfoProxy.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../interfaces/ITokenInfoProxy.sol\";\nimport \"../interfaces/IERC721Chargeable.sol\";\n\n\ncontract TokenInfoProxy is ITokenInfoProxy, Ownable {\n using Address for address;\n\n mapping (address => FnSignatures) internal _remappedFnSigs;\n\n function setContractFnOwnerOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner {\n _remappedFnSigs[contractAddress].ownerOf = fnSig;\n emit ContractFunctionSignatureSet(contractAddress, \"ownerOf\", fnSig);\n }\n\n function setContractFnCreatorOf(address contractAddress, bytes4 fnSig) external virtual override onlyOwner {\n _remappedFnSigs[contractAddress].creatorOf = fnSig;\n emit ContractFunctionSignatureSet(contractAddress, \"creatorOf\", fnSig);\n }\n\n\n function getTokenUUID(address contractAddress, uint256 tokenId) external pure virtual override returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n function getTokenOwner(address contractAddress, uint256 tokenId) external virtual override returns (address) {\n return _getTokenOwner(contractAddress, tokenId);\n }\n\n function getTokenCreator(address contractAddress, uint256 tokenId) external virtual override returns (address) {\n return _getTokenCreator(contractAddress, tokenId);\n }\n\n function isNFTOwnerOrOperator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) {\n IERC721Chargeable tokenInterface = IERC721Chargeable(contractAddress);\n address tokenOwner = _getTokenOwner(contractAddress, tokenId);\n return (sender == tokenOwner || tokenInterface.isApprovedForAll(tokenOwner, sender));\n }\n\n /// @dev Checks if an account is the Creator of a Proton-based NFT or the Contract itself\n /// @param contractAddress The Address to the Contract of the Proton-based NFT to check\n /// @param tokenId The Token ID of the Proton-based NFT to check\n /// @param sender The Address of the Account to check\n /// @return True if the account is the creator of the NFT or the Contract itself\n function isNFTContractOrCreator(address contractAddress, uint256 tokenId, address sender) external virtual override returns (bool) {\n address tokenCreator = _getTokenCreator(contractAddress, tokenId);\n return (sender == tokenCreator || sender == contractAddress);\n }\n\n\n\n function _getTokenCreator(address contractAddress, uint256 tokenId) internal returns (address) {\n bytes4 fnSig = IERC721Chargeable.creatorOf.selector;\n if (_remappedFnSigs[contractAddress].creatorOf != bytes4(0)) {\n fnSig = _remappedFnSigs[contractAddress].creatorOf;\n }\n\n // solhint-disable-next-line\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n if (success) {\n return abi.decode(returnData, (address));\n } else {\n return address(0x0);\n }\n }\n\n function _getTokenOwner(address contractAddress, uint256 tokenId) internal returns (address) {\n bytes4 fnSig = IERC721Chargeable.ownerOf.selector;\n if (_remappedFnSigs[contractAddress].ownerOf != bytes4(0)) {\n fnSig = _remappedFnSigs[contractAddress].ownerOf;\n }\n\n // solhint-disable-next-line\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n if (success) {\n return abi.decode(returnData, (address));\n } else {\n return address(0x0);\n }\n }\n}\n" + }, + "contracts/v1/lib/WalletManagerBase.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// WalletManagerBase.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity >=0.6.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IWalletManager.sol\";\nimport \"../interfaces/ISmartWallet.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"./BlackholePrevention.sol\";\n\n\n/**\n * @notice Wallet-Manager Base Contract\n * @dev Non-upgradeable Contract\n */\nabstract contract WalletManagerBase is Ownable, BlackholePrevention, IWalletManager {\n using TokenInfo for address;\n\n // The Controller Contract Address\n address internal _controller;\n\n // The Executor Contract Address\n address internal _executor;\n\n // Template Contract for creating Token Smart-Wallet Bridges\n address internal _walletTemplate;\n\n // TokenID => Token Smart-Wallet Address\n mapping (uint256 => address) internal _wallets;\n\n // State of Wallet Manager\n bool internal _paused;\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Wallet Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n /**\n * @dev Connects to the ExecForAccount Controller\n */\n function setExecutor(address executor) external onlyOwner {\n _executor = executor;\n emit ExecutorSet(executor);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartWallet(wallet).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartWallet(wallet).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartWallet(wallet).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Executor contract\n modifier onlyExecutor() {\n require(_executor == msg.sender, \"WMB:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Controller or Executor contract\n modifier onlyControllerOrExecutor() {\n require(_executor == msg.sender || _controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"WMB:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/ParticleSplitter.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ParticleSplitter.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"./interfaces/IParticleSplitter.sol\";\nimport \"./interfaces/IChargedManagers.sol\";\nimport \"./interfaces/IWalletManager.sol\";\nimport \"./interfaces/IBasketManager.sol\";\nimport \"./interfaces/ITokenInfoProxy.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n/**\n * @notice Charged Particles Contract\n * @dev Upgradeable Contract\n */\ncontract ParticleSplitter is IParticleSplitter, Ownable, ReentrancyGuard, BlackholePrevention\n{\n IChargedManagers internal _chargedManagers;\n ITokenInfoProxy internal _tokenInfoProxy;\n\n mapping (address => bool) internal _externalAddressesAllowed;\n\n\n /***********************************|\n | Execute for Account |\n |__________________________________*/\n\n /// @notice Executes an arbitrary command on an NFT Wallet\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param walletManagerId The Wallet Manager controlling the NFT Wallet to execute on\n /// @param externalAddress The Address of the External Contract to execute on\n /// @param encodedParams The encoded function call to execute\n function executeForWallet(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address externalAddress,\n bytes memory encodedParams\n )\n external\n payable\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (bytes memory)\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n require(_externalAddressesAllowed[externalAddress], \"PS:E-117\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Wallet Manager\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n // Get Address of Wallet to send any ETH into\n if (msg.value > 0) {\n address wallet = walletMgr.getWalletAddressById(contractAddress, tokenId, address(0), 0);\n payable(wallet).sendValue(msg.value);\n }\n\n emit ExecuteForWallet(contractAddress, tokenId, walletManagerId, externalAddress, encodedParams, msg.value);\n\n // Execute command for NFT Wallet\n return walletMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams);\n }\n\n /// @notice Executes an arbitrary command on an NFT Basket\n /// @param contractAddress The Address to the Contract of the Token\n /// @param tokenId The ID of the Token\n /// @param basketManagerId The Basket Manager controlling the NFT Wallet to execute on\n /// @param externalAddress The Address of the External Contract to execute on\n /// @param encodedParams The encoded function call to execute\n function executeForBasket(\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address externalAddress,\n bytes memory encodedParams\n )\n external\n payable\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (bytes memory)\n {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"PS:E-419\");\n require(_externalAddressesAllowed[externalAddress], \"PS:E-117\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Basket Manager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n\n // Get Address of Wallet to send any ETH into\n if (msg.value > 0) {\n address wallet = basketMgr.getBasketAddressById(contractAddress, tokenId);\n payable(wallet).sendValue(msg.value);\n }\n\n emit ExecuteForBasket(contractAddress, tokenId, basketManagerId, externalAddress, encodedParams, msg.value);\n\n // Execute command for NFT Wallet\n return basketMgr.executeForAccount(contractAddress, tokenId, externalAddress, msg.value, encodedParams);\n }\n\n function withdrawWalletRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (uint256 amountWithdrawn)\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Wallet Manager\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n\n // Withdraw Rewards for NFT Wallet\n return walletMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount);\n }\n\n function withdrawBasketRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n string calldata basketManagerId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n virtual\n override\n onlyTokenOwner(contractAddress, tokenId)\n nonReentrant\n returns (uint256 amountWithdrawn)\n {\n require(_chargedManagers.isNftBasketEnabled(basketManagerId), \"PS:E-419\");\n\n // Validate Owner/Operator & Timelocks\n _chargedManagers.validateRelease(msg.sender, contractAddress, tokenId);\n\n // Get appropriate Basket Manager\n IBasketManager basketMgr = _chargedManagers.getBasketManager(basketManagerId);\n\n // Withdraw Rewards for NFT Basket\n return basketMgr.withdrawRewards(receiver, contractAddress, tokenId, rewardsToken, rewardsAmount);\n }\n\n function refreshWalletPrincipal(\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken\n )\n external\n virtual\n override\n {\n require(_chargedManagers.isWalletManagerEnabled(walletManagerId), \"PS:E-419\");\n\n IWalletManager walletMgr = _chargedManagers.getWalletManager(walletManagerId);\n walletMgr.refreshPrincipal(contractAddress, tokenId, assetToken);\n\n emit PrincipalRefreshed(contractAddress, tokenId, walletManagerId, assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedManagers Interface\n */\n function setChargedManagers(address chargedManagers) external virtual onlyOwner {\n _chargedManagers = IChargedManagers(chargedManagers);\n emit ChargedManagersSet(chargedManagers);\n }\n\n /**\n * @dev Setup the ChargedManagers Interface\n */\n function setTokenInfoProxy(address tokenInfoProxy) external virtual onlyOwner {\n _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy);\n emit TokenInfoProxySet(tokenInfoProxy);\n }\n\n /**\n * @dev Allows/Disallows execute from on specific contracts\n */\n function setExternalContracts(address[] calldata contracts, bool state) external onlyOwner {\n uint count = contracts.length;\n for (uint i; i < count; i++) {\n address externalContract = contracts[i];\n _externalAddressesAllowed[externalContract] = state;\n emit PermsSetForExternal(externalContract, state);\n }\n }\n\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier onlyTokenOwner(address contractAddress, uint256 tokenId) {\n address tokenOwner = _tokenInfoProxy.getTokenOwner(contractAddress, tokenId);\n require(msg.sender == tokenOwner, \"PS:E-102\");\n _;\n }\n}\n" + }, + "contracts/v1/test/Dai.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\n\nimport \"../interfaces/IDai.sol\";\n\ncontract Dai is IDai {\n using SafeMathUpgradeable for uint256;\n using AddressUpgradeable for address;\n\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 uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (uint256 chainId_) public {\n string memory version = \"1\";\n\n _name = \"Dai Stablecoin\";\n _symbol = \"DAI\";\n _decimals = 18;\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(_name)),\n keccak256(bytes(version)),\n chainId_,\n address(this)\n )\n );\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view 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 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 {_setupDecimals} is\n * called.\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 returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view 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(msg.sender, 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(msg.sender, 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 * - `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(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\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(msg.sender, spender, _allowances[msg.sender][spender].add(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 _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is 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(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20:E-403\");\n require(recipient != address(0), \"ERC20:E-403\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(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 * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20:E-403\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(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:E-403\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(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(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20:E-403\");\n require(spender != address(0), \"ERC20:E-403\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\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 to 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(address from, address to, uint256 amount) internal virtual { }\n\n mapping (address => uint) public nonces;\n\n // --- EIP712 niceties ---\n bytes32 public DOMAIN_SEPARATOR;\n // bytes32 public constant PERMIT_TYPEHASH = keccak256(\"Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)\");\n bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;\n\n // --- Approve by signature ---\n function permit(\n address holder, address spender, uint256 nonce, uint256 expiry,\n bool allowed, uint8 v, bytes32 r, bytes32 s) external override\n {\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR,\n keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n holder,\n spender,\n nonce,\n expiry,\n allowed\n )\n )\n )\n );\n\n require(holder != address(0), \"Dai/invalid-address-0\");\n require(holder == ecrecover(digest, v, r, s), \"Dai/invalid-permit\");\n require(expiry == 0 || now <= expiry, \"Dai/permit-expired\");\n require(nonce == nonces[holder]++, \"Dai/invalid-nonce\");\n uint wad = allowed ? uint(-1) : 0;\n _allowances[holder][spender] = wad;\n emit Approval(holder, spender, wad);\n }\n\n function mint(address to, uint256 amount) external {\n _mint(to, amount);\n }\n}" + }, + "contracts/v1/test/ERC20Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.7.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/**\n * @dev Extension of {ERC20} that adds a set of accounts with the {MinterRole},\n * which have permission to mint (create) new tokens as they see fit.\n *\n * At construction, the deployer of the contract is the only minter.\n */\ncontract ERC20Mintable is ERC20Upgradeable {\n\n constructor(string memory _name, string memory _symbol) public {\n __ERC20_init(_name, _symbol);\n }\n\n /**\n * @dev See {ERC20-_mint}.\n *\n * Requirements:\n *\n * - the caller must have the {MinterRole}.\n */\n function mint(address account, uint256 amount) public returns (bool) {\n _mint(account, amount);\n return true;\n }\n\n function burn(address account, uint256 amount) public returns (bool) {\n _burn(account, amount);\n return true;\n }\n}" + }, + "contracts/v1/test/ERC721Mintable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.7.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\";\n\n/**\n * @dev Extension of {ERC721} for Minting/Burning\n */\ncontract ERC721Mintable is ERC721Upgradeable {\n\n constructor () public {\n __ERC721_init(\"ERC 721\", \"NFT\");\n }\n\n /**\n * @dev See {ERC721-_mint}.\n */\n function mint(address to, uint256 tokenId) public {\n _mint(to, tokenId);\n }\n\n /**\n * @dev See {ERC721-_burn}.\n */\n function burn(uint256 tokenId) public {\n _burn(tokenId);\n }\n}\n" + }, + "contracts/v1/tokens/ExternalERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ExternalERC721.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\n\ncontract ExternalERC721 is ERC721 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n\n constructor() public ERC721(\"Charged Particles - ExternalERC721\", \"ExNFT\") {}\n\n function mintNft(address receiver, string memory tokenUri) external returns (uint256 newTokenId) {\n return _mintNft(receiver, tokenUri);\n }\n\n function _mintNft(address receiver, string memory tokenUri) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n\n _safeMint(receiver, newTokenId, \"\");\n\n _setTokenURI(newTokenId, tokenUri);\n }\n}\n" + }, + "contracts/v1/tokens/FungibleERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// FungibleERC1155.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract FungibleERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n\n constructor() public ERC1155(\"https://staging.app.charged.fi/erc1155/metadata.json\") {}\n\n function mintNft(address receiver, uint256 amount) external returns (uint256 newTokenId) {\n return _mintNft(receiver, amount);\n }\n\n function _mintNft(address receiver, uint256 amount) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n _mint(receiver, newTokenId, amount, \"\");\n }\n}\n" + }, + "contracts/v1/tokens/Ionx.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Ionx.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"erc20permit/contracts/ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\n\ncontract Ionx is ERC20Permit, Ownable, BlackholePrevention {\n using SafeMath for uint256;\n\n /// @notice An event thats emitted when the minter address is changed\n event MinterChanged(address minter, address newMinter);\n\n /// @notice Total number of tokens in circulation\n uint256 constant public INITIAL_SUPPLY = 1e8 ether;\n\n /// @notice Minimum time between mints\n uint32 public constant INFLATION_EPOCH = 1 days * 365;\n\n /// @notice Cap on the percentage of totalSupply that can be minted at each mint\n uint8 public constant INFLATION_CAP = 2;\n\n /// @notice Address which may mint new tokens\n address public minter;\n\n /// @notice The timestamp after which minting may occur\n uint256 public mintingAllowedAfter;\n\n\n constructor() public ERC20Permit(\"Charged Particles - IONX\", \"IONX\") {}\n\n\n /**\n * @notice Change the minter address\n * @param newMinter The address of the new minter\n */\n function setMinter(address newMinter) external onlyOwner {\n emit MinterChanged(minter, newMinter);\n minter = newMinter;\n }\n\n /**\n * @notice Mint new tokens\n * @param receiver The address of the destination account\n * @param amount The number of tokens to be minted\n */\n function mint(address receiver, uint256 amount) external onlyMinter {\n require(block.timestamp >= mintingAllowedAfter, \"Ionx:E-114\");\n require(receiver != address(0), \"Ionx:E-403\");\n\n uint256 amountToMint = amount;\n uint256 _totalSupply = totalSupply();\n\n // From Inflationary Supply\n if (_totalSupply >= INITIAL_SUPPLY) {\n mintingAllowedAfter = mintingAllowedAfter.add(INFLATION_EPOCH);\n amountToMint = _totalSupply.mul(INFLATION_CAP).div(100);\n }\n\n // From Initial Supply\n else {\n if (_totalSupply.add(amountToMint) > INITIAL_SUPPLY) {\n amountToMint = INITIAL_SUPPLY.sub(_totalSupply);\n }\n if (_totalSupply.add(amountToMint) == INITIAL_SUPPLY) {\n mintingAllowedAfter = block.timestamp.add(INFLATION_EPOCH);\n }\n }\n\n // transfer the amount to the recipient\n _mint(receiver, amountToMint);\n }\n\n // Note: This contract should never hold ETH, if any is accidentally sent in then the DAO can return it\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n // Note: This contract should never hold any tokens, if any are accidentally sent in then the DAO can return them\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n modifier onlyMinter() {\n require(msg.sender == minter, \"Ionx:E-113\");\n _;\n }\n}\n" + }, + "contracts/v1/tokens/Lepton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Lepton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/ILepton.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\n\ncontract Lepton is ILepton, ERC721, Ownable, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenIds;\n Classification[] internal _leptonTypes;\n mapping (uint256 => Classification) internal _leptonData;\n\n uint256 internal _typeIndex;\n uint256 internal _maxSupply;\n uint256 internal _maxMintPerTx;\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721(\"Charged Particles - Lepton\", \"LEPTON\") {\n _paused = true;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function mintLepton() external payable virtual override nonReentrant whenNotPaused returns (uint256 newTokenId) {\n newTokenId = _mintLepton(msg.sender);\n }\n\n function batchMintLepton(uint256 count) external payable virtual override nonReentrant whenNotPaused {\n _batchMintLepton(msg.sender, count);\n }\n\n function getNextType() external view virtual override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _typeIndex;\n }\n\n function getNextPrice() external view virtual override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _leptonTypes[_typeIndex].price;\n }\n\n function getMultiplier(uint256 tokenId) external view virtual override returns (uint256) {\n return _leptonData[tokenId].multiplier;\n }\n\n function getBonus(uint256 tokenId) external view virtual override returns (uint256) {\n return _leptonData[tokenId].bonus;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function addLeptonType(\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n virtual\n onlyOwner\n {\n _maxSupply = _maxSupply.add(uint256(supply));\n\n Classification memory lepton = Classification({\n tokenUri: tokenUri,\n price: price,\n supply: supply,\n multiplier: multiplier,\n bonus: bonus,\n _upperBounds: uint128(_maxSupply)\n });\n _leptonTypes.push(lepton);\n\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function updateLeptonType(\n uint256 leptonIndex,\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n virtual\n onlyOwner\n {\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\n _leptonTypes[leptonIndex].price = price;\n _leptonTypes[leptonIndex].supply = supply;\n _leptonTypes[leptonIndex].multiplier = multiplier;\n _leptonTypes[leptonIndex].bonus = bonus;\n\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function setMaxMintPerTx(uint256 maxAmount) external virtual onlyOwner {\n _maxMintPerTx = maxAmount;\n emit MaxMintPerTxSet(maxAmount);\n }\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _mintLepton(address receiver) internal virtual returns (uint256 newTokenId) {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n require(msg.value >= lepton.price, \"LPT:E-414\");\n\n _tokenIds.increment();\n newTokenId = _tokenIds.current();\n\n _leptonData[newTokenId] = lepton;\n _safeMint(receiver, newTokenId, \"\");\n _setTokenURI(newTokenId, lepton.tokenUri);\n\n // Distribute Next Type\n if (newTokenId == lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n emit LeptonMinted(receiver, newTokenId, lepton.price, lepton.multiplier);\n\n _refundOverpayment(lepton.price);\n }\n\n\n function _batchMintLepton(address receiver, uint256 count) internal virtual {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \"LPT:E-429\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n\n uint256 startTokenId = _tokenIds.current();\n uint256 endTokenId = startTokenId.add(count);\n if (endTokenId > lepton._upperBounds) {\n count = count.sub(endTokenId.sub(lepton._upperBounds));\n }\n\n uint256 salePrice = lepton.price.mul(count);\n require(msg.value >= salePrice, \"LPT:E-414\");\n\n _safeMintBatch(receiver, startTokenId.add(1), count, \"\");\n\n for (uint i = 0; i < count; i++) {\n _tokenIds.increment();\n startTokenId = _tokenIds.current();\n\n _leptonData[startTokenId] = lepton;\n _setTokenURI(startTokenId, lepton.tokenUri);\n }\n\n // Distribute Next Type\n if (startTokenId >= lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n emit LeptonBatchMinted(receiver, startTokenId, count, lepton.price, lepton.multiplier);\n\n _refundOverpayment(salePrice);\n }\n\n function _refundOverpayment(uint256 threshold) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"LPT:E-101\");\n _;\n }\n}" + }, + "contracts/v1/tokens/Lepton2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Lepton2.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"../lib/ERC721Basic.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol\";\n\nimport \"../interfaces/ILepton.sol\";\nimport \"../lib/BlackholePrevention.sol\";\n\ncontract Lepton2 is ILepton, ERC721Basic, Ownable, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n\n Classification[] internal _leptonTypes;\n\n uint256 internal _typeIndex;\n uint256 internal _maxSupply;\n uint256 internal _maxMintPerTx;\n uint256 internal _migratedCount;\n\n bool internal _paused;\n bool internal _migrationComplete;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721Basic(\"Charged Particles - Lepton2\", \"LEPTON2\") {\n _paused = true;\n _migrationComplete = false;\n _migratedCount = 0;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function mintLepton() external payable override nonReentrant whenNotPaused returns (uint256 newTokenId) {\n newTokenId = _mintLepton(msg.sender);\n }\n\n function batchMintLepton(uint256 count) external payable override nonReentrant whenNotPaused {\n _batchMintLepton(msg.sender, count);\n }\n\n function totalSupply() public view returns (uint256) {\n return _tokenCount;\n }\n\n function maxSupply() external view returns (uint256) {\n return _maxSupply;\n }\n\n function getNextType() external view override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _typeIndex;\n }\n\n function getNextPrice() external view override returns (uint256) {\n if (_typeIndex >= _leptonTypes.length) { return 0; }\n return _leptonTypes[_typeIndex].price;\n }\n\n function getMultiplier(uint256 tokenId) external view override returns (uint256) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).multiplier;\n }\n\n function getBonus(uint256 tokenId) external view override returns (uint256) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).bonus;\n }\n\n function tokenURI(uint256 tokenId) public view override returns (string memory) {\n require(_exists(tokenId), \"LPT:E-405\");\n return _getLepton(tokenId).tokenUri;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function addLeptonType(\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n onlyOwner\n {\n _maxSupply = _maxSupply.add(uint256(supply));\n\n Classification memory lepton = Classification({\n tokenUri: tokenUri,\n price: price,\n supply: supply,\n multiplier: multiplier,\n bonus: bonus,\n _upperBounds: uint128(_maxSupply)\n });\n _leptonTypes.push(lepton);\n\n emit LeptonTypeAdded(tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function updateLeptonType(\n uint256 leptonIndex,\n string calldata tokenUri,\n uint256 price,\n uint32 supply,\n uint32 multiplier,\n uint32 bonus\n )\n external\n onlyOwner\n {\n _leptonTypes[leptonIndex].tokenUri = tokenUri;\n _leptonTypes[leptonIndex].price = price;\n _leptonTypes[leptonIndex].supply = supply;\n _leptonTypes[leptonIndex].multiplier = multiplier;\n _leptonTypes[leptonIndex].bonus = bonus;\n\n emit LeptonTypeUpdated(leptonIndex, tokenUri, price, supply, multiplier, bonus, _maxSupply);\n }\n\n function setMaxMintPerTx(uint256 maxAmount) external onlyOwner {\n _maxMintPerTx = maxAmount;\n emit MaxMintPerTxSet(maxAmount);\n }\n\n function setPausedState(bool state) external onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function migrateAccounts(address oldLeptonContract, uint256 count) external onlyOwner whenNotMigrated {\n uint256 oldSupply = IERC721Enumerable(oldLeptonContract).totalSupply();\n require(oldSupply == 0 || oldSupply > _migratedCount, \"LPT:E-004\");\n\n if (oldSupply > 0) {\n uint256 endTokenId = _migratedCount.add(count);\n if (endTokenId > oldSupply) {\n count = count.sub(endTokenId.sub(oldSupply));\n }\n\n for (uint256 i = 1; i <= count; i++) {\n uint256 tokenId = _migratedCount.add(i);\n address tokenOwner = IERC721(oldLeptonContract).ownerOf(tokenId);\n _mint(tokenOwner);\n }\n _migratedCount = _migratedCount.add(count);\n }\n\n if (oldSupply == _migratedCount) {\n _finalizeMigration();\n }\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getLepton(uint256 tokenId) internal view returns (Classification memory) {\n uint256 types = _leptonTypes.length;\n for (uint256 i = 0; i < types; i++) {\n Classification memory lepton = _leptonTypes[i];\n if (tokenId <= lepton._upperBounds) {\n return lepton;\n }\n }\n }\n\n function _mintLepton(address receiver) internal returns (uint256 newTokenId) {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n require(msg.value >= lepton.price, \"LPT:E-414\");\n\n newTokenId = _safeMint(receiver, \"\");\n\n // Determine Next Type\n if (newTokenId == lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n _refundOverpayment(lepton.price);\n }\n\n function _batchMintLepton(address receiver, uint256 count) internal {\n require(_typeIndex < _leptonTypes.length, \"LPT:E-408\");\n require(_maxMintPerTx == 0 || count <= _maxMintPerTx, \"LPT:E-429\");\n\n Classification memory lepton = _leptonTypes[_typeIndex];\n\n uint256 endTokenId = _tokenCount.add(count);\n if (endTokenId > lepton._upperBounds) {\n count = count.sub(endTokenId.sub(lepton._upperBounds));\n }\n\n uint256 salePrice = lepton.price.mul(count);\n require(msg.value >= salePrice, \"LPT:E-414\");\n\n _safeMintBatch(receiver, count, \"\");\n\n // Determine Next Type\n if (endTokenId >= lepton._upperBounds) {\n _typeIndex = _typeIndex.add(1);\n }\n\n _refundOverpayment(salePrice);\n }\n\n function _refundOverpayment(uint256 threshold) internal {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n function _finalizeMigration() internal {\n // Determine Next Type\n _typeIndex = 0;\n for (uint256 i = 0; i < _leptonTypes.length; i++) {\n Classification memory lepton = _leptonTypes[i];\n if (_migratedCount >= lepton._upperBounds) {\n _typeIndex = i + 1;\n }\n }\n _migrationComplete = true;\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotMigrated() {\n require(!_migrationComplete, \"LPT:E-004\");\n _;\n }\n\n modifier whenNotPaused() {\n require(!_paused, \"LPT:E-101\");\n _;\n }\n}" + }, + "contracts/v1/tokens/NonFungibleERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// NonFungibleERC1155.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155.sol\";\n\ncontract NonFungibleERC1155 is ERC1155 {\n using Counters for Counters.Counter;\n\n Counters.Counter internal _tokenCount;\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => address) internal _tokenOwner;\n\n constructor() public ERC1155(\"https://staging.app.charged.fi/erc1155/metadata.json\") {}\n\n function creatorOf(uint256 tokenId) external view returns (address) {\n return _tokenCreator[tokenId];\n }\n\n function ownerOf(uint256 tokenId) external view returns (address) {\n return _tokenOwner[tokenId];\n }\n\n function mintNft(address receiver) external returns (uint256 newTokenId) {\n return _mintNft(msg.sender, receiver);\n }\n\n function _mintNft(address creator, address receiver) internal returns (uint256 newTokenId) {\n _tokenCount.increment();\n newTokenId = _tokenCount.current();\n\n _mint(receiver, newTokenId, 1, \"\");\n _tokenCreator[newTokenId] = creator;\n _tokenOwner[newTokenId] = receiver;\n }\n}\n" + }, + "contracts/v1/tokens/Proton.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Proton.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"../lib/ERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IProton.sol\";\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ncontract Proton is IProton, ERC721, Ownable, RelayRecipient, ReentrancyGuard, BlackholePrevention {\n using SafeMath for uint256;\n using Address for address payable;\n using Counters for Counters.Counter;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n uint256 constant internal MAX_ROYALTIES = 8e3; // 8000 (80%)\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n Counters.Counter internal _tokenIds;\n\n mapping (uint256 => address) internal _tokenCreator;\n mapping (uint256 => uint256) internal _tokenCreatorRoyaltiesPct;\n mapping (uint256 => address) internal _tokenCreatorRoyaltiesRedirect;\n mapping (address => uint256) internal _tokenCreatorClaimableRoyalties;\n\n mapping (uint256 => uint256) internal _tokenSalePrice;\n mapping (uint256 => uint256) internal _tokenLastSellPrice;\n\n bool internal _paused;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public ERC721(\"Charged Particles - Proton\", \"PROTON\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function creatorOf(uint256 tokenId) external view virtual override returns (address) {\n return _tokenCreator[tokenId];\n }\n\n function getSalePrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenSalePrice[tokenId];\n }\n\n function getLastSellPrice(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenLastSellPrice[tokenId];\n }\n\n function getCreatorRoyalties(address account) external view virtual override returns (uint256) {\n return _tokenCreatorClaimableRoyalties[account];\n }\n\n function getCreatorRoyaltiesPct(uint256 tokenId) external view virtual override returns (uint256) {\n return _tokenCreatorRoyaltiesPct[tokenId];\n }\n\n function getCreatorRoyaltiesReceiver(uint256 tokenId) external view virtual override returns (address) {\n return _creatorRoyaltiesReceiver(tokenId);\n }\n\n function claimCreatorRoyalties()\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256)\n {\n return _claimCreatorRoyalties(_msgSender());\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // annuityPercent,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n external\n virtual\n override\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n royaltiesPercent,\n salePrice\n );\n }\n\n function batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n external\n virtual\n override\n whenNotPaused\n {\n _batchProtonsForSale(\n creator,\n annuityPercent,\n royaltiesPercent,\n tokenMetaUris,\n salePrices\n );\n }\n\n function buyProton(uint256 tokenId)\n external\n payable\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (bool)\n {\n return _buyProton(tokenId);\n }\n\n /***********************************|\n | Only Token Creator/Owner |\n |__________________________________*/\n\n function setSalePrice(uint256 tokenId, uint256 salePrice)\n external\n virtual\n override\n whenNotPaused\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setSalePrice(tokenId, salePrice);\n }\n\n function setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n onlyTokenOwnerOrApproved(tokenId)\n {\n _setRoyaltiesPct(tokenId, royaltiesPct);\n }\n\n function setCreatorRoyaltiesReceiver(uint256 tokenId, address receiver)\n external\n virtual\n override\n whenNotPaused\n onlyTokenCreator(tokenId)\n {\n _tokenCreatorRoyaltiesRedirect[tokenId] = receiver;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setPausedState(bool state) external virtual onlyOwner {\n _paused = state;\n emit PausedStateSet(state);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n function setTrustedForwarder(address _trustedForwarder) external virtual onlyOwner {\n trustedForwarder = _trustedForwarder;\n }\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual {\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n\n _tokenSalePrice[tokenId] = salePrice;\n emit SalePriceSet(tokenId, salePrice);\n }\n\n function _setRoyaltiesPct(uint256 tokenId, uint256 royaltiesPct) internal virtual {\n require(royaltiesPct <= MAX_ROYALTIES, \"PRT:E-421\");\n _tokenCreatorRoyaltiesPct[tokenId] = royaltiesPct;\n emit CreatorRoyaltiesSet(tokenId, royaltiesPct);\n }\n\n function _creatorRoyaltiesReceiver(uint256 tokenId) internal view virtual returns (address) {\n address receiver = _tokenCreatorRoyaltiesRedirect[tokenId];\n if (receiver == address(0x0)) {\n receiver = _tokenCreator[tokenId];\n }\n return receiver;\n }\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, annuityPercent, 0, 0);\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _createProton(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n _tokenIds.increment();\n\n newTokenId = _tokenIds.current();\n _safeMint(receiver, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUri);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function _batchProtonsForSale(\n address creator,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n string[] calldata tokenMetaUris,\n uint256[] calldata salePrices\n )\n internal\n virtual\n {\n require(tokenMetaUris.length == salePrices.length, \"PRT:E-202\");\n address self = address(this);\n\n uint256 count = tokenMetaUris.length;\n for (uint256 i = 0; i < count; i++) {\n _tokenIds.increment();\n uint256 newTokenId = _tokenIds.current();\n\n _safeMint(creator, newTokenId, \"\");\n _tokenCreator[newTokenId] = creator;\n\n _setTokenURI(newTokenId, tokenMetaUris[i]);\n\n if (royaltiesPercent > 0) {\n _setRoyaltiesPct(newTokenId, royaltiesPercent);\n }\n\n uint256 salePrice = salePrices[i];\n if (salePrice > 0) {\n _setSalePrice(newTokenId, salePrice);\n }\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n self,\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n function _buyProton(uint256 tokenId)\n internal\n virtual\n returns (bool)\n {\n uint256 salePrice = _tokenSalePrice[tokenId];\n require(salePrice > 0, \"PRT:E-416\");\n require(msg.value >= salePrice, \"PRT:E-414\");\n\n uint256 ownerAmount = salePrice;\n uint256 creatorAmount;\n address oldOwner = ownerOf(tokenId);\n address newOwner = _msgSender();\n\n // Creator Royalties\n address royaltiesReceiver = _creatorRoyaltiesReceiver(tokenId);\n uint256 royaltiesPct = _tokenCreatorRoyaltiesPct[tokenId];\n uint256 lastSellPrice = _tokenLastSellPrice[tokenId];\n if (royaltiesPct > 0 && lastSellPrice > 0 && salePrice > lastSellPrice) {\n creatorAmount = (salePrice - lastSellPrice).mul(royaltiesPct).div(PERCENTAGE_SCALE);\n ownerAmount = ownerAmount.sub(creatorAmount);\n }\n _tokenLastSellPrice[tokenId] = salePrice;\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(address(this), tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n\n // Reserve Royalties for Creator\n if (creatorAmount > 0) {\n _tokenCreatorClaimableRoyalties[royaltiesReceiver] = _tokenCreatorClaimableRoyalties[royaltiesReceiver].add(creatorAmount);\n }\n\n // Transfer Token\n _transfer(oldOwner, newOwner, tokenId);\n\n // Transfer Payment\n payable(oldOwner).sendValue(ownerAmount);\n\n emit ProtonSold(tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n\n _refundOverpayment(salePrice);\n return true;\n }\n\n /**\n * @dev Pays out the Creator Royalties of the calling account\n * @param receiver The receiver of the claimable royalties\n * @return The amount of Creator Royalties claimed\n */\n function _claimCreatorRoyalties(address receiver) internal virtual returns (uint256) {\n uint256 claimableAmount = _tokenCreatorClaimableRoyalties[receiver];\n require(claimableAmount > 0, \"PRT:E-411\");\n\n delete _tokenCreatorClaimableRoyalties[receiver];\n payable(receiver).sendValue(claimableAmount);\n\n emit RoyaltiesClaimed(receiver, claimableAmount);\n }\n\n /**\n * @dev Collects the Required Asset Token from the users wallet\n * @param from The owner address to collect the Assets from\n * @param assetAmount The Amount of Asset Tokens to Collect\n */\n function _collectAssetToken(address from, address assetToken, uint256 assetAmount) internal virtual {\n uint256 _userAssetBalance = IERC20(assetToken).balanceOf(from);\n require(assetAmount <= _userAssetBalance, \"PRT:E-411\");\n // Be sure to Approve this Contract to transfer your Asset Token\n require(IERC20(assetToken).transferFrom(from, address(this), assetAmount), \"PRT:E-401\");\n }\n\n function _refundOverpayment(uint256 threshold) internal virtual {\n uint256 overage = msg.value.sub(threshold);\n if (overage > 0) {\n payable(_msgSender()).sendValue(overage);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n _tokenSalePrice[tokenId] = 0;\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n super._transfer(from, to, tokenId);\n }\n\n\n /***********************************|\n | GSN/MetaTx Relay |\n |__________________________________*/\n\n /// @dev See {BaseRelayRecipient-_msgSender}.\n function _msgSender()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (address payable)\n {\n return BaseRelayRecipient._msgSender();\n }\n\n /// @dev See {BaseRelayRecipient-_msgData}.\n function _msgData()\n internal\n view\n virtual\n override(BaseRelayRecipient, Context)\n returns (bytes memory)\n {\n return BaseRelayRecipient._msgData();\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n modifier whenNotPaused() {\n require(!_paused, \"PRT:E-101\");\n _;\n }\n\n modifier onlyTokenOwnerOrApproved(uint256 tokenId) {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"PRT:E-105\");\n _;\n }\n\n modifier onlyTokenCreator(uint256 tokenId) {\n require(_tokenCreator[tokenId] == _msgSender(), \"PRT:E-104\");\n _;\n }\n}" + }, + "contracts/v1/tokens/ProtonB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\nimport \"../interfaces/IProtonB.sol\";\n\nimport \"../lib/BaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\n\n\ncontract ProtonB is BaseProton, IProtonB {\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public BaseProton(\"Charged Particles - ProtonB\", \"PROTON.B\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n external\n virtual\n override\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n royaltiesPercent,\n salePrice\n );\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n override\n nonReentrant\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n /// @dev for backwards compatibility with v1\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n whenNotPaused\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0);\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n\n /***********************************|\n | Function Overrides |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override {\n super._setSalePrice(tokenId, salePrice);\n\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n }\n\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n override\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n }\n\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n // Unlock NFT\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n\n super._transfer(from, to, tokenId);\n }\n}" + }, + "contracts/v1/tokens/ProtonC.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// ProtonB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nimport \"../interfaces/IUniverse.sol\";\nimport \"../interfaces/IChargedState.sol\";\nimport \"../interfaces/IChargedSettings.sol\";\nimport \"../interfaces/IChargedParticles.sol\";\n\nimport \"../lib/BaseProton.sol\";\nimport \"../lib/TokenInfo.sol\";\nimport \"../lib/BlackholePrevention.sol\";\nimport \"../lib/RelayRecipient.sol\";\nimport \"../lib/Soul.sol\";\n\n\ncontract ProtonC is BaseProton, Soul {\n using SafeMath for uint256;\n using TokenInfo for address payable;\n using Counters for Counters.Counter;\n\n IUniverse internal _universe;\n IChargedState internal _chargedState;\n IChargedSettings internal _chargedSettings;\n IChargedParticles internal _chargedParticles;\n\n event UniverseSet(address indexed universe);\n event ChargedStateSet(address indexed chargedState);\n event ChargedSettingsSet(address indexed chargedSettings);\n event ChargedParticlesSet(address indexed chargedParticles);\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor() public BaseProton(\"Charged Particles - ProtonC\", \"PROTON.C\") {}\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function createBondedToken(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent\n )\n external\n virtual\n payable\n returns (uint256 newTokenId)\n {\n uint256 tokenId = createProtonForSale(\n creator,\n receiver,\n tokenMetaUri,\n annuityPercent,\n royaltiesPercent,\n 0\n );\n lockToken(tokenId);\n\n return tokenId;\n }\n\n function createProtonForSale(\n address creator,\n address receiver,\n string memory tokenMetaUri,\n uint256 annuityPercent,\n uint256 royaltiesPercent,\n uint256 salePrice\n )\n public \n virtual\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n royaltiesPercent,\n salePrice\n );\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n }\n\n function createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n external\n virtual\n nonReentrant\n whenNotPaused\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createChargedParticle(\n creator,\n receiver,\n referrer,\n tokenMetaUri,\n walletManagerId,\n assetToken,\n assetAmount,\n annuityPercent\n );\n }\n\n /// @dev for backwards compatibility with v1\n function createBasicProton(\n address creator,\n address receiver,\n string memory tokenMetaUri\n )\n external\n virtual\n whenNotPaused\n payable\n returns (uint256 newTokenId)\n {\n newTokenId = _createProton(\n creator,\n receiver,\n tokenMetaUri,\n 0, // royaltiesPercent\n 0 // salePrice\n );\n }\n\n function burn(uint256 tokenId) public {\n requireTokenOwner(tokenId); \n _burn(tokenId);\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setUniverse(address universe) external virtual onlyOwner {\n _universe = IUniverse(universe);\n emit UniverseSet(universe);\n }\n\n /**\n * @dev Setup the ChargedParticles Interface\n */\n function setChargedParticles(address chargedParticles) external virtual onlyOwner {\n _chargedParticles = IChargedParticles(chargedParticles);\n emit ChargedParticlesSet(chargedParticles);\n }\n\n /// @dev Setup the Charged-State Controller\n function setChargedState(address stateController) external virtual onlyOwner {\n _chargedState = IChargedState(stateController);\n emit ChargedStateSet(stateController);\n }\n\n /// @dev Setup the Charged-Settings Controller\n function setChargedSettings(address settings) external virtual onlyOwner {\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n function requireTokenOwner(uint256 tokenId) public view {\n require(ownerOf(tokenId) == msg.sender, \"Only token owner\");\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createChargedParticle(\n address creator,\n address receiver,\n address referrer,\n string memory tokenMetaUri,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n uint256 annuityPercent\n )\n internal\n virtual\n returns (uint256 newTokenId)\n {\n require(address(_chargedParticles) != address(0x0), \"PRT:E-107\");\n\n newTokenId = _createProton(creator, receiver, tokenMetaUri, 0, 0);\n\n if (annuityPercent > 0) {\n _chargedSettings.setCreatorAnnuities(\n address(this),\n newTokenId,\n creator,\n annuityPercent\n );\n }\n\n _chargeParticle(newTokenId, walletManagerId, assetToken, assetAmount, referrer);\n }\n\n function _chargeParticle(\n uint256 tokenId,\n string memory walletManagerId,\n address assetToken,\n uint256 assetAmount,\n address referrer\n )\n internal\n virtual\n {\n _collectAssetToken(_msgSender(), assetToken, assetAmount);\n\n IERC20(assetToken).approve(address(_chargedParticles), assetAmount);\n\n _chargedParticles.energizeParticle(\n address(this),\n tokenId,\n walletManagerId,\n assetToken,\n assetAmount,\n referrer\n );\n }\n\n function _burn(uint256 tokenId) internal {\n _unlockToken(tokenId);\n _transfer(ownerOf(tokenId), address(0x000000000000000000000000000000000000dEaD), tokenId);\n }\n\n /***********************************|\n | Soul bounded |\n |__________________________________*/\n\n function lockToken(uint256 tokenId) public {\n requireTokenOwner(tokenId);\n _lockToken(tokenId);\n }\n\n /***********************************|\n | Function Overrides |\n |__________________________________*/\n\n function _setSalePrice(uint256 tokenId, uint256 salePrice) internal virtual override {\n super._setSalePrice(tokenId, salePrice);\n\n // Temp-Lock/Unlock NFT\n // prevents front-running the sale and draining the value of the NFT just before sale\n _chargedState.setTemporaryLock(address(this), tokenId, (salePrice > 0));\n }\n\n\n function _buyProton(uint256 _tokenId, uint256 _gasLimit)\n internal\n virtual\n override\n returns (\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address royaltiesReceiver,\n uint256 creatorAmount\n )\n {\n (contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount) = super._buyProton(_tokenId, _gasLimit);\n\n // Signal to Universe Controller\n if (address(_universe) != address(0)) {\n _universe.onProtonSale(contractAddress, tokenId, oldOwner, newOwner, salePrice, royaltiesReceiver, creatorAmount);\n }\n }\n\n function _transfer(address from, address to, uint256 tokenId) internal virtual override {\n require(lockedTokens[tokenId] == false, \"BondedToken: Token is locked\");\n\n // Unlock NFT\n _chargedState.setTemporaryLock(address(this), tokenId, false);\n\n super._transfer(from, to, tokenId);\n }\n}" + }, + "contracts/v1/Universe.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\n\nimport \"./interfaces/IUniverse.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\n\n\n/**\n * @notice Charged Particles Universe Contract\n * @dev Upgradeable Contract\n */\ncontract Universe is IUniverse, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n\n // The ChargedParticles Contract Address\n address public chargedParticles;\n address public proton;\n address public lepton;\n address public quark;\n address public boson;\n\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // Positive Charge\n uint256 internal photonMaxSupply;\n uint256 internal totalPhotonDischarged;\n\n // Source of Positive Charge\n IERC20Upgradeable public photonSource;\n\n // Asset Token => Electrostatic Attraction Multiplier\n mapping (address => uint256) internal esaMultiplier;\n\n // Account => Electrostatic Attraction Levels\n mapping (address => uint256) internal esaLevel;\n\n // Energizing Account => Referral Source\n mapping (address => address) internal referralSource;\n\n // NFT Token UUID => Bonded Lepton Mass\n mapping (uint256 => uint256) internal bondedLeptonMass;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n\n /***********************************|\n | Public Functions |\n |__________________________________*/\n\n function getStaticCharge(address /* account */) external pure virtual returns (uint256 positiveEnergy) {\n return 0;\n }\n\n function conductElectrostaticDischarge(address /* account */, uint256 /* amount */) external pure virtual returns (uint256 positiveEnergy) {\n return 0;\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n // no-op\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n onlyProton\n {\n // no-op\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(controller)\n {\n chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setPhoton(\n address token,\n uint256 maxSupply\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n photonSource = IERC20Upgradeable(token);\n photonMaxSupply = maxSupply;\n emit PhotonSet(token, maxSupply);\n }\n\n function setProtonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n proton = token;\n emit ProtonTokenSet(token);\n }\n\n function setLeptonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n lepton = token;\n emit LeptonTokenSet(token);\n }\n\n function setQuarkToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n quark = token;\n emit QuarkTokenSet(token);\n }\n\n function setBosonToken(\n address token\n )\n external\n virtual\n onlyOwner\n onlyValidContractAddress(token)\n {\n boson = token;\n emit BosonTokenSet(token);\n }\n\n function setEsaMultiplier(\n address assetToken,\n uint256 multiplier\n )\n external\n virtual\n onlyOwner\n {\n esaMultiplier[assetToken] = multiplier;\n emit EsaMultiplierSet(assetToken, multiplier);\n }\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _electrostaticAttraction(uint256 tokenUuid, address receiver, address assetToken, uint256 baseAmount) internal virtual {\n }\n\n function _conductElectrostaticDischarge(address /* account */, uint256 /* energy */) internal virtual pure returns (uint256) {\n return 0;\n }\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Proton NFT contract\n modifier onlyProton() {\n require(proton == msg.sender, \"UNI:E-110\");\n _;\n }\n}\n" + }, + "contracts/v1/UniverseRP.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"./interfaces/IUniverseRP.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./interfaces/IRewardNft.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\nimport \"./interfaces/IRewardProgram.sol\";\n\n/**\n * @notice Charged Particles Universe Contract with Rewards Program\n * @dev Upgradeable Contract\n */\ncontract UniverseRP is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // The ChargedParticles Contract Address\n address public _chargedParticles;\n\n // The Lepton NFT Contract Address\n address public _multiplierNft;\n\n // Asset Token => Reward Program\n mapping (address => address) internal _assetRewardPrograms;\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\n\n // Token UUID => NFT Staking Data\n mapping (uint256 => NftStake) private _nftStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n function getRewardProgram(address asset) external view override returns (address) {\n return _getRewardProgram(asset);\n }\n\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\n return _nftStake[uuid];\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetDeposit(\n contractAddress,\n tokenId,\n walletManagerId,\n assetAmount\n );\n }\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\n }\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n // \"receiverEnergy\" includes the \"principalAmount\"\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n onlyOwner\n onlyValidContractAddress(controller)\n {\n _chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setMultiplierNft(address nftTokenAddress)\n external\n onlyOwner\n onlyValidContractAddress(nftTokenAddress)\n {\n _multiplierNft = nftTokenAddress;\n }\n\n function setRewardProgram(\n address rewardProgam,\n address assetToken\n )\n external\n onlyOwner\n onlyValidContractAddress(rewardProgam)\n {\n require(assetToken != address(0x0), \"UNI:E-403\");\n _assetRewardPrograms[assetToken] = rewardProgam;\n emit RewardProgramSet(assetToken, rewardProgam);\n }\n\n function removeRewardProgram(address assetToken) external onlyOwner {\n delete _assetRewardPrograms[assetToken];\n emit RewardProgramRemoved(assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getRewardProgram(address assetToken) internal view returns (address) {\n return _assetRewardPrograms[assetToken];\n }\n\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != depositNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n uint256 multiplier = _getNftMultiplier(depositNftAddress, depositNftTokenId);\n\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\n // Add to Multipliers Set\n _multiplierNftsSet[parentNftUuid].add(multiplier);\n\n // Update NFT Stake\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\n } else {\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\n }\n }\n\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\n }\n\n function _registerNftRelease(\n address contractAddress,\n uint256 tokenId,\n address releaseNftAddress,\n uint256 releaseNftTokenId,\n uint256 /* nftTokenAmount */\n )\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != releaseNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n NftStake storage nftStake = _nftStake[parentNftUuid];\n\n // Remove from Multipliers Set\n uint256 multiplier = _getNftMultiplier(releaseNftAddress, releaseNftTokenId);\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\n\n // Determine New Multiplier or Mark as Released\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\n } else {\n nftStake.releaseBlockNumber = block.number;\n }\n\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\n }\n\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\n uint256 multiplier = 0;\n uint256 loss = 50;\n uint256 i = 0;\n\n for (; i < len; i++) {\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\n }\n if (len > 1) {\n multiplier = multiplier.sub(loss.mul(len));\n }\n return multiplier;\n }\n\n function _getNftMultiplier(address contractAddress, uint256 tokenId) internal returns (uint256) {\n bytes4 fnSig = IRewardNft.getMultiplier.selector;\n (bool success, bytes memory returnData) = contractAddress.call(abi.encodeWithSelector(fnSig, tokenId));\n\n if (success) {\n return abi.decode(returnData, (uint256));\n } else {\n return 0;\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(_chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/UniveserRPPolygon.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// Universe.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\n\nimport \"./interfaces/IUniverseRP.sol\";\nimport \"./interfaces/IChargedParticles.sol\";\nimport \"./interfaces/ILepton.sol\";\nimport \"./interfaces/IRewardNft.sol\";\nimport \"./lib/TokenInfo.sol\";\nimport \"./lib/BlackholePrevention.sol\";\nimport \"./interfaces/IRewardProgram.sol\";\n\n/**\n * @notice Charged Particles Universe Contract with Rewards Program\n * @dev Upgradeable Contract\n */\ncontract UniverseRPPolygon is IUniverseRP, Initializable, OwnableUpgradeable, BlackholePrevention {\n using SafeMathUpgradeable for uint256;\n using TokenInfo for address;\n using SafeERC20Upgradeable for IERC20Upgradeable;\n using EnumerableSet for EnumerableSet.UintSet;\n\n uint256 constant private LEPTON_MULTIPLIER_SCALE = 1e2;\n uint256 constant internal PERCENTAGE_SCALE = 1e4; // 10000 (100%)\n\n // The ChargedParticles Contract Address\n address public _chargedParticles;\n\n // The Lepton NFT Contract Address\n address public _multiplierNft;\n\n // Asset Token => Reward Program\n mapping (address => address) internal _assetRewardPrograms;\n mapping (uint256 => EnumerableSet.UintSet) internal _multiplierNftsSet;\n\n // Token UUID => NFT Staking Data\n mapping (uint256 => NftStake) private _nftStake;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public initializer {\n __Ownable_init();\n }\n\n function getRewardProgram(address asset) external view override returns (address) {\n return _getRewardProgram(asset);\n }\n\n function getNftStake(uint256 uuid) external view override returns (NftStake memory) {\n return _nftStake[uuid];\n }\n\n /***********************************|\n | Only Charged Particles |\n |__________________________________*/\n\n function onEnergize(\n address /* sender */,\n address /* referrer */,\n address contractAddress,\n uint256 tokenId,\n string calldata walletManagerId,\n address assetToken,\n uint256 assetAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetDeposit(\n contractAddress,\n tokenId,\n walletManagerId,\n assetAmount\n );\n }\n }\n\n function onDischarge(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n uint256 totalInterest = receiverEnergy.add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onDischargeForCreator(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address /* creator */,\n address assetToken,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, receiverEnergy);\n }\n }\n\n function onRelease(\n address contractAddress,\n uint256 tokenId,\n string calldata /* walletManagerId */,\n address assetToken,\n uint256 principalAmount,\n uint256 creatorEnergy,\n uint256 receiverEnergy\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n address rewardProgram = _getRewardProgram(assetToken);\n if (rewardProgram != address(0)) {\n // \"receiverEnergy\" includes the \"principalAmount\"\n uint256 totalInterest = receiverEnergy.sub(principalAmount).add(creatorEnergy);\n IRewardProgram(rewardProgram).registerAssetRelease(contractAddress, tokenId, totalInterest);\n }\n }\n\n function onCovalentBond(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftDeposit(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onCovalentBreak(\n address contractAddress,\n uint256 tokenId,\n string calldata /* managerId */,\n address nftTokenAddress,\n uint256 nftTokenId,\n uint256 nftTokenAmount\n )\n external\n virtual\n override\n onlyChargedParticles\n {\n _registerNftRelease(contractAddress, tokenId, nftTokenAddress, nftTokenId, nftTokenAmount);\n }\n\n function onProtonSale(\n address contractAddress,\n uint256 tokenId,\n address oldOwner,\n address newOwner,\n uint256 salePrice,\n address creator,\n uint256 creatorRoyalties\n )\n external\n virtual\n override\n {\n // no-op\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setChargedParticles(\n address controller\n )\n external\n onlyOwner\n onlyValidContractAddress(controller)\n {\n _chargedParticles = controller;\n emit ChargedParticlesSet(controller);\n }\n\n function setMultiplierNft(address nftTokenAddress)\n external\n onlyOwner\n onlyValidContractAddress(nftTokenAddress)\n {\n _multiplierNft = nftTokenAddress;\n }\n\n function setRewardProgram(\n address rewardProgam,\n address assetToken\n )\n external\n onlyOwner\n onlyValidContractAddress(rewardProgam)\n {\n require(assetToken != address(0x0), \"UNI:E-403\");\n _assetRewardPrograms[assetToken] = rewardProgam;\n emit RewardProgramSet(assetToken, rewardProgam);\n }\n\n function removeRewardProgram(address assetToken) external onlyOwner {\n delete _assetRewardPrograms[assetToken];\n emit RewardProgramRemoved(assetToken);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external virtual onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual onlyOwner {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getRewardProgram(address assetToken) internal view returns (address) {\n return _assetRewardPrograms[assetToken];\n }\n\n function _registerNftDeposit(address contractAddress, uint256 tokenId, address depositNftAddress, uint256 depositNftTokenId, uint256 /* nftTokenAmount */)\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != depositNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n uint256 multiplier = _getNftMultiplier(depositNftTokenId);\n\n if (multiplier > 0 && !_multiplierNftsSet[parentNftUuid].contains(multiplier)) {\n // Add to Multipliers Set\n _multiplierNftsSet[parentNftUuid].add(multiplier);\n\n // Update NFT Stake\n uint256 combinedMultiplier = _calculateTotalMultiplier(parentNftUuid);\n if (_nftStake[parentNftUuid].depositBlockNumber == 0) {\n _nftStake[parentNftUuid] = NftStake(combinedMultiplier, block.number, 0);\n } else {\n uint256 blockDiff = block.number - _nftStake[parentNftUuid].depositBlockNumber;\n _nftStake[parentNftUuid].multiplier = combinedMultiplier;\n _nftStake[parentNftUuid].depositBlockNumber = _nftStake[parentNftUuid].depositBlockNumber.add(blockDiff.div(2));\n }\n }\n\n emit NftDeposit(contractAddress, tokenId, depositNftAddress, depositNftTokenId);\n }\n\n function _registerNftRelease(\n address contractAddress,\n uint256 tokenId,\n address releaseNftAddress,\n uint256 releaseNftTokenId,\n uint256 /* nftTokenAmount */\n )\n internal\n {\n // We only care about the Multiplier NFT\n if (_multiplierNft != releaseNftAddress) { return; }\n\n uint256 parentNftUuid = contractAddress.getTokenUUID(tokenId);\n NftStake storage nftStake = _nftStake[parentNftUuid];\n\n // Remove from Multipliers Set\n uint256 multiplier = _getNftMultiplier(releaseNftTokenId);\n _multiplierNftsSet[parentNftUuid].remove(multiplier);\n\n // Determine New Multiplier or Mark as Released\n if (_multiplierNftsSet[parentNftUuid].length() > 0) {\n nftStake.multiplier = _calculateTotalMultiplier(parentNftUuid);\n } else {\n nftStake.releaseBlockNumber = block.number;\n }\n\n emit NftRelease(contractAddress, tokenId, releaseNftAddress, releaseNftTokenId);\n }\n\n function _calculateTotalMultiplier(uint256 parentNftUuid) internal view returns (uint256) {\n uint256 len = _multiplierNftsSet[parentNftUuid].length();\n uint256 multiplier = 0;\n uint256 loss = 50;\n uint256 i = 0;\n\n for (; i < len; i++) {\n multiplier = multiplier.add(_multiplierNftsSet[parentNftUuid].at(i));\n }\n if (len > 1) {\n multiplier = multiplier.sub(loss.mul(len));\n }\n return multiplier;\n }\n\n function _getNftMultiplier(uint256 tokenId) internal pure returns (uint256) {\n if (tokenId >= 1 && tokenId <= 721) {\n return 110;\n } else if (tokenId > 721 && tokenId <= 1122) {\n return 130;\n } else if (tokenId > 1122 && tokenId <= 1423) {\n return 150;\n } else if (tokenId > 1423 && tokenId <= 1624) {\n return 180;\n } else if (tokenId > 1624 && tokenId <= 1712) {\n return 230;\n } else if (tokenId > 1712 && tokenId <= 1733) {\n return 510;\n } else {\n return 1;\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any non-account\n modifier onlyValidContractAddress(address account) {\n require(account != address(0x0) && account.isContract(), \"UNI:E-417\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Charged Particles contract\n modifier onlyChargedParticles() {\n require(_chargedParticles == msg.sender, \"UNI:E-108\");\n _;\n }\n}\n" + }, + "contracts/v1/vesting/VestingClaim7.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/cryptography/MerkleProof.sol\";\nimport \"../interfaces/IMerkleDistributor.sol\";\n\ncontract VestingClaim7 is IMerkleDistributor {\n address public immutable override token;\n bytes32 public immutable override merkleRoot;\n\n address public owner;\n uint256 public immutable expiryDate;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // This is a packed array of booleans.\n mapping(uint256 => uint256) private claimedBitMap;\n\n constructor(address token_, bytes32 merkleRoot_, uint256 expiryDate_) public {\n owner = msg.sender;\n token = token_;\n merkleRoot = merkleRoot_;\n expiryDate = expiryDate_;\n }\n\n function isClaimed(uint256 index) public view override returns (bool) {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n uint256 claimedWord = claimedBitMap[claimedWordIndex];\n uint256 mask = (1 << claimedBitIndex);\n return claimedWord & mask == mask;\n }\n\n function _setClaimed(uint256 index) private {\n uint256 claimedWordIndex = index / 256;\n uint256 claimedBitIndex = index % 256;\n claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);\n }\n\n function claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) external override {\n require(!isClaimed(index), \"VestingClaim7: Drop already claimed.\");\n\n // Verify the merkle proof.\n bytes32 node = keccak256(abi.encodePacked(index, account, amount));\n require(MerkleProof.verify(merkleProof, merkleRoot, node), \"VestingClaim7: Invalid proof.\");\n\n // Mark it claimed and send the token.\n _setClaimed(index);\n require(IERC20(token).transfer(account, amount), \"VestingClaim7: Transfer failed.\");\n\n emit Claimed(index, account, amount);\n }\n\n function expire(address exitAddress) external onlyOwner {\n require(block.timestamp >= expiryDate, \"VestingClaim7: expiry date not reached\");\n uint256 remainingBalance = IERC20(token).balanceOf(address(this));\n IERC20(token).transfer(exitAddress, remainingBalance);\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n require(newOwner != address(0), \"VestingClaim7: new owner is the zero address\");\n emit OwnershipTransferred(owner, newOwner);\n owner = newOwner;\n }\n\n modifier onlyOwner() {\n require(msg.sender == owner, \"VestingClaim7: not owner\");\n _;\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveSmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\nimport \"../../interfaces/IAaveBridge.sol\";\nimport \"../../lib/SmartWalletBase.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet for Aave Assets\n * @dev Non-upgradeable Contract\n */\ncontract AaveSmartWallet is SmartWalletBase {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 constant internal RAY = 1e27;\n\n IAaveBridge internal _bridge;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(\n address aaveBridge\n )\n public\n {\n SmartWalletBase.initializeBase();\n _bridge = IAaveBridge(aaveBridge);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _bridge.isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address) {\n return _bridge.getReserveInterestToken(assetToken);\n }\n\n function getPrincipal(address assetToken) external override returns (uint256) {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address assetToken) external override returns (uint256 creatorInterest, uint256 ownerInterest) {\n return _getInterest(assetToken);\n }\n\n function getTotal(address assetToken) external override returns (uint256) {\n return _getTotal(assetToken);\n }\n\n function getRewards(address rewardToken) external override returns (uint256) {\n return IERC20(rewardToken).balanceOf(address(this));\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _deposit(assetToken, assetAmount, referralCode);\n }\n\n\n function withdraw(\n address receiver,\n address creatorRedirect,\n address assetToken\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (, uint256 ownerInterest) = _getInterest(assetToken);\n return _withdraw(receiver, creatorRedirect, assetToken, walletPrincipal.add(ownerInterest));\n }\n\n function withdrawAmount(\n address receiver,\n address creatorRedirect,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return _withdraw(receiver, creatorRedirect, assetToken, assetAmount);\n }\n\n function withdrawAmountForCreator(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return _withdrawForCreator(receiver, assetToken, assetAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _withdrawRewards(receiver, rewardsToken, rewardsAmount);\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n internal\n returns (uint256)\n {\n _trackAssetToken(assetToken);\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n\n // Deposit Assets into Aave (reverts on fail)\n _sendToken(address(_bridge), assetToken, assetAmount);\n uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function _withdraw(\n address receiver,\n address creatorRedirect,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken);\n\n // Withdraw from Interest only\n if (assetAmount < ownerInterest) {\n if (creatorInterest > 0) {\n uint256 ratio = assetAmount.mul(RAY).div(ownerInterest);\n creatorAmount = creatorInterest.add(nftCreatorAmountDischarged).mul(ratio).div(RAY);\n\n if (creatorAmount <= nftCreatorAmountDischarged) {\n nftCreatorAmountDischarged = nftCreatorAmountDischarged.sub(creatorAmount);\n creatorAmount = 0;\n }\n\n else {\n creatorAmount = creatorAmount.sub(nftCreatorAmountDischarged);\n nftCreatorAmountDischarged = 0;\n }\n }\n receiverAmount = assetAmount;\n }\n\n // Withdraw from Interest + Principal\n else {\n uint256 fromPrincipal = assetAmount.sub(ownerInterest);\n if (fromPrincipal > walletPrincipal) {\n fromPrincipal = walletPrincipal.sub(ownerInterest);\n }\n\n creatorAmount = creatorInterest;\n receiverAmount = ownerInterest.add(fromPrincipal);\n nftCreatorAmountDischarged = 0;\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal);\n }\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount));\n\n // Withdraw Assets for Creator\n if (creatorAmount > 0) {\n address receivesForCreator = (creatorRedirect != address(0x0)) ? creatorRedirect : nftCreator;\n _bridge.withdraw(receivesForCreator, assetToken, creatorAmount);\n }\n\n // Withdraw Assets for Receiver\n _bridge.withdraw(receiver, assetToken, receiverAmount);\n }\n\n function _withdrawForCreator(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 receiverAmount)\n {\n (uint256 creatorInterest,) = _getInterest(assetToken);\n if (creatorInterest == 0) { return 0; }\n if (assetAmount > creatorInterest) {\n assetAmount = creatorInterest;\n }\n\n nftCreatorAmountDischarged = nftCreatorAmountDischarged.add(assetAmount);\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, assetAmount);\n\n // Withdraw Assets for Receiver on behalf of Creator\n _bridge.withdraw(receiver, assetToken, assetAmount);\n }\n\n function _withdrawRewards(\n address receiver,\n address rewardsTokenAddress,\n uint256 rewardsAmount\n )\n internal\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"ASW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function _getTotal(address assetToken) internal view returns (uint256) {\n return _bridge.getTotalBalance(address(this), assetToken);\n }\n\n function _getInterest(address assetToken) internal view returns (uint256 creatorInterest, uint256 ownerInterest) {\n uint256 total = _getTotal(assetToken);\n uint256 principal = _getPrincipal(assetToken);\n uint256 interest = total.sub(principal);\n\n // Creator Royalties\n if (nftCreatorAnnuityPct > 0) {\n\n // Interest too small to calculate percentage;\n if (interest <= PERCENTAGE_SCALE) {\n // creatorInterest = interest.div(2); // split evenly?\n creatorInterest = 0; // All to owner\n }\n\n // Calculate percentage for Creator\n else {\n creatorInterest = interest\n .add(nftCreatorAmountDischarged)\n .mul(nftCreatorAnnuityPct)\n .div(PERCENTAGE_SCALE)\n .sub(nftCreatorAmountDischarged);\n }\n }\n\n // Owner Portion\n ownerInterest = interest.sub(creatorInterest);\n }\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveSmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\nimport \"../../interfaces/IAaveBridge.sol\";\nimport \"../../lib/SmartWalletBaseB.sol\";\n\n/**\n * @notice ERC20-Token Smart-Wallet for Aave Assets\n * @dev Non-upgradeable Contract\n */\ncontract AaveSmartWalletB is SmartWalletBaseB {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 constant internal RAY = 1e27;\n\n IAaveBridge internal _bridge;\n\n uint256 internal _nftCreatorAmountDischarged;\n\n mapping (address => address) internal _assetATokens;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(\n address aaveBridge\n )\n public\n {\n SmartWalletBaseB.initializeBase();\n _bridge = IAaveBridge(aaveBridge);\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _bridge.isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address) {\n return _bridge.getReserveInterestToken(assetToken);\n }\n\n function getPrincipal(address assetToken) external override returns (uint256) {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address assetToken, uint256 creatorPct) external override returns (uint256 creatorInterest, uint256 ownerInterest) {\n return _getInterest(assetToken, creatorPct);\n }\n\n function getTotal(address assetToken) external override returns (uint256) {\n return _getTotal(assetToken);\n }\n\n function getRewards(address rewardToken) external override returns (uint256) {\n return IERC20(rewardToken).balanceOf(address(this));\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _deposit(assetToken, assetAmount, referralCode);\n }\n\n\n function withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (, uint256 ownerInterest) = _getInterest(assetToken, creatorPct);\n return _withdraw(receiver, creator, creatorPct, assetToken, walletPrincipal.add(ownerInterest));\n }\n\n function withdrawAmount(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return _withdraw(receiver, creator, creatorPct, assetToken, assetAmount);\n }\n\n function withdrawAmountForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return _withdrawForCreator(receiver, creatorPct, assetToken, assetAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n return _withdrawRewards(receiver, rewardsToken, rewardsAmount);\n }\n\n function refreshPrincipal(address assetToken) external virtual override onlyWalletManager {\n uint256 aTokenBalance = IERC20(_assetATokens[assetToken]).balanceOf(address(this));\n if (_assetPrincipalBalance[assetToken] > aTokenBalance) {\n _assetPrincipalBalance[assetToken] = aTokenBalance;\n }\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n internal\n returns (uint256)\n {\n _trackAssetToken(assetToken);\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n\n // Deposit Assets into Aave (reverts on fail)\n _sendToken(address(_bridge), assetToken, assetAmount);\n uint256 aTokensAmount = _bridge.deposit(assetToken, assetAmount, referralCode);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function _withdraw(\n address receiver,\n address creator,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 walletPrincipal = _getPrincipal(assetToken);\n (uint256 creatorInterest, uint256 ownerInterest) = _getInterest(assetToken, creatorPct);\n\n // Withdraw from Interest only\n if (assetAmount < ownerInterest) {\n if (creatorInterest > 0) {\n uint256 ratio = assetAmount.mul(RAY).div(ownerInterest);\n creatorAmount = creatorInterest.add(_nftCreatorAmountDischarged).mul(ratio).div(RAY);\n\n if (creatorAmount <= _nftCreatorAmountDischarged) {\n _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.sub(creatorAmount);\n creatorAmount = 0;\n }\n else {\n creatorAmount = creatorAmount.sub(_nftCreatorAmountDischarged);\n _nftCreatorAmountDischarged = 0;\n }\n }\n receiverAmount = assetAmount;\n }\n\n // Withdraw from Interest + Principal\n else {\n uint256 fromPrincipal = assetAmount.sub(ownerInterest);\n if (fromPrincipal > walletPrincipal) {\n fromPrincipal = walletPrincipal.sub(ownerInterest);\n }\n\n creatorAmount = creatorInterest;\n receiverAmount = ownerInterest.add(fromPrincipal);\n _nftCreatorAmountDischarged = 0;\n\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(fromPrincipal);\n }\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, receiverAmount.add(creatorAmount));\n\n // Withdraw Assets for Creator\n if (creatorAmount > 0) {\n if (creator != address(0)) {\n _bridge.withdraw(creator, assetToken, creatorAmount);\n } else {\n receiverAmount = receiverAmount.add(creatorAmount);\n creatorAmount = 0;\n }\n }\n\n // Withdraw Assets for Receiver\n _bridge.withdraw(receiver, assetToken, receiverAmount);\n }\n\n function _withdrawForCreator(\n address receiver,\n uint256 creatorPct,\n address assetToken,\n uint256 assetAmount\n )\n internal\n returns (uint256 receiverAmount)\n {\n (uint256 creatorInterest,) = _getInterest(assetToken, creatorPct);\n if (creatorInterest == 0) { return 0; }\n if (assetAmount > creatorInterest) {\n assetAmount = creatorInterest;\n }\n\n _nftCreatorAmountDischarged = _nftCreatorAmountDischarged.add(assetAmount);\n\n // Send aTokens to Bridge\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _sendToken(address(_bridge), aTokenAddress, assetAmount);\n\n // Withdraw Assets for Receiver on behalf of Creator\n _bridge.withdraw(receiver, assetToken, assetAmount);\n }\n\n function _withdrawRewards(\n address receiver,\n address rewardsTokenAddress,\n uint256 rewardsAmount\n )\n internal\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"ASW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function _getTotal(address assetToken) internal view returns (uint256) {\n return _bridge.getTotalBalance(address(this), assetToken);\n }\n\n function _getInterest(address assetToken, uint256 creatorPct) internal view returns (uint256 creatorInterest, uint256 ownerInterest) {\n uint256 total = _getTotal(assetToken);\n uint256 principal = _getPrincipal(assetToken);\n uint256 interest = total.sub(principal);\n\n // Creator Royalties\n if (creatorPct > 0) {\n\n // Interest too small to calculate percentage;\n if (interest <= PERCENTAGE_SCALE) {\n // creatorInterest = interest.div(2); // split evenly?\n creatorInterest = 0; // All to owner\n }\n\n // Calculate percentage for Creator\n else {\n creatorInterest = interest\n .add(_nftCreatorAmountDischarged)\n .mul(creatorPct)\n .div(PERCENTAGE_SCALE)\n .sub(_nftCreatorAmountDischarged);\n }\n }\n\n // Owner Portion\n ownerInterest = interest.sub(creatorInterest);\n }\n\n function _trackAssetToken(address assetToken) internal override {\n if (!_assetTokens.contains(assetToken)) {\n _assetTokens.add(assetToken);\n address aTokenAddress = _bridge.getReserveInterestToken(assetToken);\n _assetATokens[assetToken] = aTokenAddress;\n }\n }\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n}\n" + }, + "contracts/v1/yield/aave/AaveWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../lib/WalletManagerBase.sol\";\n\nimport \"./AaveSmartWallet.sol\";\n\n/**\n * @notice Wallet Manager for Aave\n * @dev Non-upgradeable Contract\n */\ncontract AaveWalletManager is WalletManagerBase {\n using SafeMath for uint256;\n\n event AaveBridgeSet(address indexed aaveBridge);\n event ValidRewardsTokenSet(address indexed rewardsToken, bool state);\n\n address internal _aaveBridge;\n uint256 internal _referralCode;\n\n mapping (address => bool) public rewardsTokenWhitelist;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new AaveSmartWallet());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return AaveSmartWallet(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return AaveSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return AaveSmartWallet(_wallets[uuid]).getInterest(assetToken);\n }\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getTotal(assetToken);\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWallet(_wallets[uuid]).getRewards(_rewardToken);\n }\n\n\n /***********************************|\n | Only Controller |\n |__________________________________*/\n\n function energize(\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = AaveSmartWallet(wallet).deposit(assetToken, assetAmount, _referralCode);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(ownerInterest > 0, \"AWM:E-412\");\n\n // Discharge the full amount of interest\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, ownerInterest);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(assetAmount > 0 && ownerInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmountForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address creator,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (uint256 creatorInterest,) = AaveSmartWallet(wallet).getInterest(assetToken);\n require(assetAmount > 0 && creatorInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n receiverAmount = AaveSmartWallet(wallet).withdrawAmountForCreator(receiver, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount);\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = AaveSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 ownerInterest) = AaveSmartWallet(wallet).getInterest(assetToken);\n principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0;\n\n // Release from interest first + principal if needed\n (creatorAmount, receiverAmount) = AaveSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n require(rewardsTokenWhitelist[rewardsToken], \"AWM:E-423\");\n\n // Withdraw Rewards to Receiver\n amount = AaveSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 tokenId,\n address externalAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return AaveSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n // no-op\n }\n\n function getWalletAddressById(\n address contractAddress,\n uint256 tokenId,\n address creator,\n uint256 annuityPct\n )\n external\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n\n if (creator != address(0x0)) {\n AaveSmartWallet(wallet).setNftCreator(creator, annuityPct);\n }\n\n emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAaveBridge(address aaveBridge) external onlyOwner {\n require(aaveBridge != address(0x0), \"AWM:E-403\");\n _aaveBridge = aaveBridge;\n emit AaveBridgeSet(aaveBridge);\n }\n\n // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool\n function setReferralCode(uint256 referralCode) external onlyOwner {\n _referralCode = referralCode;\n }\n\n function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner {\n rewardsTokenWhitelist[rewardsToken] = state;\n emit ValidRewardsTokenSet(rewardsToken, state);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n AaveSmartWallet(newWallet).initialize(_aaveBridge);\n return newWallet;\n }\n}" + }, + "contracts/v1/yield/aave/AaveWalletManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../lib/WalletManagerBase.sol\";\nimport \"../../interfaces/IChargedSettings.sol\";\nimport \"./AaveSmartWalletB.sol\";\n\n/**\n * @notice Wallet Manager for Aave\n * @dev Non-upgradeable Contract\n */\ncontract AaveWalletManagerB is WalletManagerBase {\n using SafeMath for uint256;\n\n event AaveBridgeSet(address indexed aaveBridge);\n event ChargedSettingsSet(address indexed settings);\n event ValidRewardsTokenSet(address indexed rewardsToken, bool state);\n\n IChargedSettings internal _chargedSettings;\n\n address internal _aaveBridge;\n uint256 internal _referralCode;\n\n mapping (address => bool) public _rewardsTokenWhitelist;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new AaveSmartWalletB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken) external view override returns (bool) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return AaveSmartWalletB(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken) external view override returns (address) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return AaveSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n return AaveSmartWalletB(_wallets[uuid]).getInterest(assetToken, annuityPct);\n }\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getTotal(assetToken);\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address _rewardToken) external override returns (uint256) {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return AaveSmartWalletB(_wallets[uuid]).getRewards(_rewardToken);\n }\n\n\n /***********************************|\n | Only Controller |\n |__________________________________*/\n\n function energize(\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = AaveSmartWalletB(wallet).deposit(assetToken, assetAmount, _referralCode);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(ownerInterest > 0, \"AWM:E-412\");\n\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Discharge the full amount of interest\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, ownerInterest);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(assetAmount > 0 && ownerInterest >= assetAmount, \"AWM:E-412\");\n\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Discharge a portion of the interest\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischarged(contractAddress, tokenId, assetToken, creatorAmount, receiverAmount);\n }\n\n function dischargeAmountForCreator(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address creator,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n (uint256 creatorInterest,) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n require(assetAmount > 0 && creatorInterest >= assetAmount, \"AWM:E-412\");\n\n // Discharge a portion of the interest\n receiverAmount = AaveSmartWalletB(wallet).withdrawAmountForCreator(receiver, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletDischargedForCreator(contractAddress, tokenId, assetToken, creator, receiverAmount);\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n // Release Principal + Interest\n principalAmount = AaveSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdraw(receiver, creator, annuityPct, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n\n (address creator, uint256 annuityPct) = _chargedSettings.getCreatorAnnuities(contractAddress, tokenId);\n if (creatorRedirect != address(0)) {\n creator = creatorRedirect;\n }\n\n (, uint256 ownerInterest) = AaveSmartWalletB(wallet).getInterest(assetToken, annuityPct);\n principalAmount = (ownerInterest < assetAmount) ? assetAmount.sub(ownerInterest) : 0;\n\n // Release from interest first + principal if needed\n (creatorAmount, receiverAmount) = AaveSmartWalletB(wallet).withdrawAmount(receiver, creator, annuityPct, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address rewardsToken,\n uint256 rewardsAmount\n )\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"AWM:E-403\");\n require(_rewardsTokenWhitelist[rewardsToken], \"AWM:E-423\");\n\n // Withdraw Rewards to Receiver\n amount = AaveSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 tokenId,\n address externalAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return AaveSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n AaveSmartWalletB(wallet).refreshPrincipal(assetToken);\n }\n\n function getWalletAddressById(\n address contractAddress,\n uint256 tokenId,\n address /* creator */,\n uint256 /* annuityPct */\n )\n external\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n function setAaveBridge(address aaveBridge) external onlyOwner {\n require(aaveBridge != address(0x0), \"AWM:E-403\");\n _aaveBridge = aaveBridge;\n emit AaveBridgeSet(aaveBridge);\n }\n\n function setChargedSettings(address settings) external onlyOwner {\n require(settings != address(0x0), \"AWM:E-403\");\n _chargedSettings = IChargedSettings(settings);\n emit ChargedSettingsSet(settings);\n }\n\n // ref: https://docs.aave.com/developers/developing-on-aave/the-protocol/lendingpool\n function setReferralCode(uint256 referralCode) external onlyOwner {\n _referralCode = referralCode;\n }\n\n function setValidRewardsToken(address rewardsToken, bool state) external onlyOwner {\n _rewardsTokenWhitelist[rewardsToken] = state;\n emit ValidRewardsTokenSet(rewardsToken, state);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n AaveSmartWalletB(newWallet).initialize(_aaveBridge);\n return newWallet;\n }\n}" + }, + "contracts/v1/yield/aave/v2/AaveBridgeV2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// AaveBridgeV2.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/utils/SafeCast.sol\";\n\nimport \"./IATokenV2.sol\";\nimport \"./ILendingPoolV2.sol\";\nimport \"./ILendingPoolAddressesProviderV2.sol\";\n\nimport \"../../../interfaces/IAaveBridge.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\n\ncontract AaveBridgeV2 is Ownable, IAaveBridge, BlackholePrevention {\n using SafeMath for uint256;\n using SafeCast for uint256;\n using SafeERC20 for IERC20;\n using ReserveLogic for ReserveLogic.ReserveData;\n\n ILendingPoolAddressesProviderV2 public provider;\n ILendingPoolV2 public lendingPool;\n\n constructor (address lendingPoolProvider) public {\n provider = ILendingPoolAddressesProviderV2(lendingPoolProvider);\n lendingPool = ILendingPoolV2(provider.getLendingPool());\n }\n\n function getReserveInterestToken(address assetToken) external view override returns (address aTokenAddress) {\n return _getReserveInterestToken(assetToken);\n }\n\n function isReserveActive(address assetToken) external view override returns (bool) {\n return _isReserveActive(assetToken);\n }\n\n function getTotalBalance(address account, address assetToken) external view override returns (uint256) {\n address aTokenAddress = _getReserveInterestToken(assetToken);\n if (aTokenAddress == address(0x0)) { return 0; }\n return IATokenV2(aTokenAddress).balanceOf(account);\n }\n\n function deposit(\n address assetToken,\n uint256 assetAmount,\n uint256 referralCode\n )\n external\n override\n returns (uint256)\n {\n address self = address(this);\n address aTokenAddress = _getReserveInterestToken(assetToken);\n require(_isReserveActive(assetToken), \"ABV2:E-424\");\n\n IERC20 token = IERC20(assetToken);\n IATokenV2 aToken = IATokenV2(aTokenAddress);\n\n if (token.allowance(address(this), address(lendingPool)) < assetAmount) {\n token.approve(address(lendingPool), uint256(-1));\n }\n\n // Deposit Assets into Aave\n uint256 preBalance = aToken.balanceOf(self);\n lendingPool.deposit(assetToken, assetAmount, self, referralCode.toUint16());\n uint256 postBalance = aToken.balanceOf(self);\n uint256 aTokensAmount = postBalance.sub(preBalance);\n\n // Transfer back the Interest Tokens\n _sendToken(msg.sender, aTokenAddress, aTokensAmount);\n\n // Return amount of aTokens transfered\n return aTokensAmount;\n }\n\n function withdraw(\n address receiver,\n address assetToken,\n uint256 assetAmount\n )\n external\n override\n {\n address self = address(this);\n require(_isReserveActive(assetToken), \"ABV2:E-424\");\n\n // Redeem aTokens for Asset Tokens\n lendingPool.withdraw(assetToken, assetAmount, self);\n\n // Transfer back the Asset Tokens\n _sendToken(receiver, assetToken, assetAmount);\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external onlyOwner {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawErc20(address payable receiver, address tokenAddress, uint256 amount) external onlyOwner {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external onlyOwner {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _sendToken(address to, address token, uint256 amount) internal {\n IERC20(token).safeTransfer(to, amount);\n }\n\n function _getReserveInterestToken(address assetToken) internal view returns (address aTokenAddress) {\n ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken);\n return config.aTokenAddress;\n }\n\n function _isReserveActive(address assetToken) internal view returns (bool) {\n ReserveLogic.ReserveData memory config = lendingPool.getReserveData(assetToken);\n uint256 isActiveFlag = 2 ** 56; // bit 56: reserve is active\n return (config.configuration.data & isActiveFlag) == isActiveFlag;\n }\n}\n" + }, + "contracts/v1/yield/aave/v2/IATokenV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\n\ninterface IATokenV2 {\n function balanceOf(address account) external view returns (uint256);\n}\n" + }, + "contracts/v1/yield/aave/v2/ILendingPoolAddressesProviderV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\n\ninterface ILendingPoolAddressesProviderV2 {\n function getLendingPool() external view returns (address);\n}" + }, + "contracts/v1/yield/aave/v2/ILendingPoolV2.sol": { + "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nimport \"./ILendingPoolAddressesProviderV2.sol\";\n\nlibrary ReserveConfiguration {\n struct Map {\n uint256 data;\n }\n}\n\nlibrary ReserveLogic {\n struct ReserveData {\n ReserveConfiguration.Map configuration;\n uint128 liquidityIndex;\n uint128 variableBorrowIndex;\n uint128 currentLiquidityRate;\n uint128 currentVariableBorrowRate;\n uint128 currentStableBorrowRate;\n uint40 lastUpdateTimestamp;\n address aTokenAddress;\n address stableDebtTokenAddress;\n address variableDebtTokenAddress;\n address interestRateStrategyAddress;\n uint8 id;\n }\n}\n\ninterface ILendingPoolV2 {\n function deposit(address reserve, uint256 amount, address onBehalfOf, uint16 referralCode) external;\n function withdraw(address reserve, uint256 amount, address to) external;\n function getReserveData(address asset) external view returns (ReserveLogic.ReserveData memory);\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericSmartWallet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"../../../lib/SmartWalletBase.sol\";\n\n\n/**\n * @notice Generic ERC20-Token Smart-Wallet Bridge\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartWallet is SmartWalletBase {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize()\n public\n {\n SmartWalletBase.initializeBase();\n }\n\n function isReserveActive(address assetToken)\n external\n override\n view\n returns (bool)\n {\n return _getPrincipal(assetToken) == 0;\n }\n\n function getReserveInterestToken(address assetToken)\n external\n override\n view\n returns (address)\n {\n return assetToken;\n }\n\n function getPrincipal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address /* assetToken */)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n return (0, 0);\n }\n\n function getTotal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getRewards(address assetToken)\n external\n override\n returns (uint256)\n {\n return IERC20(assetToken).balanceOf(address(this));\n }\n\n function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n // Track Principal\n _trackAssetToken(assetToken);\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n }\n\n function withdraw(address receiver, address /* creatorRedirect */, address assetToken)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmount(address receiver, address /* creatorRedirect */, address assetToken, uint256 assetAmount)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n if (receiverAmount >= assetAmount) {\n receiverAmount = assetAmount;\n }\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmountForCreator(\n address /* receiver */,\n address /* assetToken */,\n uint256 /* assetID */\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericSmartWalletB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWalletB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"../../../lib/SmartWalletBaseB.sol\";\n\n\n/**\n * @notice Generic ERC20-Token Smart-Wallet Bridge\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartWalletB is SmartWalletBaseB {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize()\n public\n {\n SmartWalletBaseB.initializeBase();\n }\n\n function isReserveActive(address assetToken)\n external\n override\n view\n returns (bool)\n {\n return _getPrincipal(assetToken) == 0;\n }\n\n function getReserveInterestToken(address assetToken)\n external\n override\n view\n returns (address)\n {\n return assetToken;\n }\n\n function getPrincipal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getInterest(address /* assetToken */, uint256 /* creatorPct */)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n return (0, 0);\n }\n\n function getTotal(address assetToken)\n external\n override\n returns (uint256)\n {\n return _getPrincipal(assetToken);\n }\n\n function getRewards(address assetToken)\n external\n override\n returns (uint256)\n {\n return IERC20(assetToken).balanceOf(address(this));\n }\n\n function deposit(address assetToken, uint256 assetAmount, uint256 /* referralCode */)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n // Track Principal\n _trackAssetToken(assetToken);\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].add(assetAmount);\n }\n\n function withdraw(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmount(address receiver, address /* creator */, uint256 /* creatorPct */, address assetToken, uint256 assetAmount)\n external\n override\n onlyWalletManager\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n creatorAmount = 0;\n receiverAmount = _getPrincipal(assetToken);\n if (receiverAmount >= assetAmount) {\n receiverAmount = assetAmount;\n }\n // Track Principal\n _assetPrincipalBalance[assetToken] = _assetPrincipalBalance[assetToken].sub(receiverAmount);\n IERC20(assetToken).safeTransfer(receiver, receiverAmount);\n }\n\n function withdrawAmountForCreator(\n address /* receiver */,\n uint256 /* creatorPct */,\n address /* assetToken */,\n uint256 /* assetID */\n )\n external\n override\n onlyWalletManager\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyWalletManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSW:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function refreshPrincipal(address assetToken) external virtual override onlyWalletManager {\n _assetPrincipalBalance[assetToken] = IERC20(assetToken).balanceOf(address(this));\n }\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericWalletManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericWalletManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../../lib/WalletManagerBase.sol\";\nimport \"./GenericSmartWallet.sol\";\n\n/**\n * @notice Generic ERC20 Wallet Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericWalletManager is WalletManagerBase {\n using SafeMath for uint256;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new GenericSmartWallet());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return GenericSmartWallet(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return GenericSmartWallet(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getTotal(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return GenericSmartWallet(_wallets[uuid]).getInterest(assetToken);\n }\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWallet(_wallets[uuid]).getRewards(rewardToken);\n }\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount)\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = GenericSmartWallet(wallet).deposit(assetToken, assetAmount, 0);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmountForCreator(\n address /* receiver */,\n address /* contractAddress */,\n uint256 /* tokenId */,\n address /* creator */,\n address /* assetToken */,\n uint256 /* assetAmount */\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdraw(receiver, creatorRedirect, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release from interest first + principal if needed\n principalAmount = GenericSmartWallet(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWallet(wallet).withdrawAmount(receiver, creatorRedirect, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyController\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartWallet(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n external\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return GenericSmartWallet(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n // no-op\n }\n\n function getWalletAddressById(address contractAddress, uint256 tokenId, address creator, uint256 annuityPct)\n external\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n\n if (creator != address(0x0)) {\n GenericSmartWallet(wallet).setNftCreator(creator, annuityPct);\n }\n\n emit NewSmartWallet(contractAddress, tokenId, wallet, creator, annuityPct);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n GenericSmartWallet(newWallet).initialize();\n return newWallet;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC20/GenericWalletManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericWalletManagerB.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"../../../lib/WalletManagerBase.sol\";\nimport \"./GenericSmartWalletB.sol\";\n\n/**\n * @notice Generic ERC20 Wallet Manager B\n * @dev Non-upgradeable Contract\n */\ncontract GenericWalletManagerB is WalletManagerBase {\n using SafeMath for uint256;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _walletTemplate = address(new GenericSmartWalletB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isReserveActive(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return false; }\n return GenericSmartWalletB(_wallets[uuid]).isReserveActive(assetToken);\n }\n\n function getReserveInterestToken(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n view\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return address(0x0); }\n return GenericSmartWalletB(_wallets[uuid]).getReserveInterestToken(assetToken);\n }\n\n /**\n * @notice Gets the Available Balance of Assets held in the Token\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Available Balance of the Token\n */\n function getTotal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getTotal(assetToken);\n }\n\n /**\n * @notice Gets the Principal-Amount of Assets held in the Smart-Wallet\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return The Principal-Balance of the Smart-Wallet\n */\n function getPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getPrincipal(assetToken);\n }\n\n /**\n * @notice Gets the Interest-Amount that the Token has generated\n * @param contractAddress The Address to the External Contract of the Token\n * @param tokenId The ID of the Token within the External Contract\n * @return creatorInterest The NFT Creator's portion of the Interest\n * @return ownerInterest The NFT Owner's portion of the Interest\n */\n function getInterest(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n returns (uint256 creatorInterest, uint256 ownerInterest)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] != address(0x0)) {\n return GenericSmartWalletB(_wallets[uuid]).getInterest(assetToken, 0);\n }\n }\n\n function getRewards(address contractAddress, uint256 tokenId, address rewardToken)\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n if (_wallets[uuid] == address(0x0)) { return 0; }\n return GenericSmartWalletB(_wallets[uuid]).getRewards(rewardToken);\n }\n\n function energize(address contractAddress, uint256 tokenId, address assetToken, uint256 assetAmount)\n external\n override\n onlyController\n returns (uint256 yieldTokensAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Deposit into Smart-Wallet\n yieldTokensAmount = GenericSmartWalletB(wallet).deposit(assetToken, assetAmount, 0);\n\n // Log Event\n emit WalletEnergized(contractAddress, tokenId, assetToken, assetAmount, yieldTokensAmount);\n }\n\n function discharge(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmount(address /* receiver */, address /* contractAddress */, uint256 /* tokenId */, address /* assetToken */, uint256 /* assetAmount */, address /* creatorRedirect */)\n external\n override\n onlyController\n returns (uint256 creatorAmount, uint256 receiverAmount)\n {\n return (0, 0);\n }\n\n function dischargeAmountForCreator(\n address /* receiver */,\n address /* contractAddress */,\n uint256 /* tokenId */,\n address /* creator */,\n address /* assetToken */,\n uint256 /* assetAmount */\n )\n external\n override\n onlyController\n returns (uint256 receiverAmount)\n {\n return 0;\n }\n\n function release(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release Principal + Interest\n principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdraw(receiver, creatorRedirect, 0, assetToken);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function releaseAmount(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address assetToken,\n uint256 assetAmount,\n address creatorRedirect\n )\n external\n override\n onlyController\n returns (uint256 principalAmount, uint256 creatorAmount, uint256 receiverAmount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Release from interest first + principal if needed\n principalAmount = GenericSmartWalletB(wallet).getPrincipal(assetToken);\n (creatorAmount, receiverAmount) = GenericSmartWalletB(wallet).withdrawAmount(receiver, creatorRedirect, 0, assetToken, assetAmount);\n\n // Log Event\n emit WalletReleased(contractAddress, tokenId, receiver, assetToken, principalAmount, creatorAmount, receiverAmount);\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyControllerOrExecutor\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n require(wallet != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartWalletB(wallet).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit WalletRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n external\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n return GenericSmartWalletB(wallet).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function refreshPrincipal(address contractAddress, uint256 tokenId, address assetToken)\n external\n override\n onlyControllerOrExecutor\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n GenericSmartWalletB(wallet).refreshPrincipal(assetToken);\n }\n\n function getWalletAddressById(address contractAddress, uint256 tokenId, address /* creator */, uint256 /* annuityPct */)\n external\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address wallet = _wallets[uuid];\n\n // Create Smart-Wallet if none exists\n if (wallet == address(0x0)) {\n wallet = _createWallet();\n _wallets[uuid] = wallet;\n emit NewSmartWallet(contractAddress, tokenId, wallet, address(0), 0);\n }\n\n return wallet;\n }\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createWallet()\n internal\n returns (address)\n {\n address newWallet = _createClone(_walletTemplate);\n GenericSmartWalletB(newWallet).initialize();\n return newWallet;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericBasketManager.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"../../../interfaces/IBasketManager.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"./GenericSmartBasket.sol\";\n\n/**\n * @notice Generic ERC721 Basket Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericBasketManager is Ownable, BlackholePrevention, IBasketManager {\n using Counters for Counters.Counter;\n using TokenInfo for address;\n\n // The Controller Contract Address\n address internal _controller;\n\n // Template Contract for creating Token Smart-Baskets\n address internal _basketTemplate;\n\n // TokenID => Token Smart-Basket Address\n mapping (uint256 => address) internal _baskets;\n\n mapping (uint256 => Counters.Counter) internal _totalTokens;\n\n // State of Basket Manager\n bool internal _paused;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _basketTemplate = address(new GenericSmartBasket());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n function getTokenTotalCount(\n address contractAddress,\n uint256 tokenId\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n return _totalTokens[uuid].current();\n }\n\n function getTokenCountByType(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n external\n override\n returns (uint256)\n {\n address basket = getBasketAddressById(contractAddress, tokenId);\n return GenericSmartBasket(basket).getTokenCountByType(basketTokenAddress, basketTokenId);\n }\n\n function prepareTransferAmount(uint256 /* nftTokenAmount */) external override onlyController {\n // no-op\n }\n\n function addToBasket(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n whenNotPaused\n returns (bool added)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n added = GenericSmartBasket(basket).addToBasket(basketTokenAddress, basketTokenId);\n\n // Log Event\n if (added) {\n _totalTokens[uuid].increment();\n emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, 1);\n }\n }\n\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n returns (bool removed)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n removed = GenericSmartBasket(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId);\n\n // Log Event\n if (removed) {\n _totalTokens[uuid].decrement();\n emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, 1);\n }\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyController\n returns (uint256 amount)\n {\n // no-op\n }\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n public\n override\n onlyController\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n return GenericSmartBasket(basket).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function getBasketAddressById(address contractAddress, uint256 tokenId)\n public\n override\n onlyController\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n // Create Smart-Basket if none exists\n if (basket == address(0x0)) {\n basket = _createBasket();\n _baskets[uuid] = basket;\n\n emit NewSmartBasket(contractAddress, tokenId, basket);\n }\n\n return basket;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Basket Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartBasket(basket).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _getTokenUUID(address contractAddress, uint256 tokenId) internal pure returns (uint256) {\n return uint256(keccak256(abi.encodePacked(contractAddress, tokenId)));\n }\n\n function _createBasket()\n internal\n returns (address)\n {\n address newBasket = _createClone(_basketTemplate);\n GenericSmartBasket(newBasket).initialize();\n return newBasket;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"GBM:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"GBM:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericBasketManagerB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericBasketManager.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport \"../../../interfaces/IBasketManager.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../interfaces/ITokenInfoProxy.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"../../../lib/NftTokenType.sol\";\nimport \"./GenericSmartBasketB.sol\";\n\n/**\n * @notice Generic ERC721 Basket Manager\n * @dev Non-upgradeable Contract\n */\ncontract GenericBasketManagerB is Ownable, BlackholePrevention, IBasketManager {\n using Counters for Counters.Counter;\n using TokenInfo for address;\n using NftTokenType for address;\n\n ITokenInfoProxy internal _tokenInfoProxy;\n\n // The Controller Contract Address\n address internal _controller;\n\n // The Executor Contract Address\n address internal _executor;\n\n // Template Contract for creating Token Smart-Baskets\n address internal _basketTemplate;\n\n // TokenID => Token Smart-Basket Address\n mapping (uint256 => address) internal _baskets;\n\n // Prepared Amount\n uint256 internal _preparedAmount;\n\n // State of Basket Manager\n bool internal _paused;\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n constructor () public {\n _basketTemplate = address(new GenericSmartBasketB());\n }\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function isPaused() external view override returns (bool) {\n return _paused;\n }\n\n function getTokenTotalCount(\n address contractAddress,\n uint256 tokenId\n )\n external\n view\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n if (basket == address(0)) { return 0; }\n return GenericSmartBasketB(basket).getNestedNftCount();\n }\n\n function getTokenCountByType(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n external\n override\n returns (uint256)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n if (basket == address(0)) { return 0; }\n return GenericSmartBasketB(basket).getTokenCountByType(basketTokenAddress, basketTokenId);\n }\n\n function prepareTransferAmount(uint256 nftTokenAmount) external override onlyController {\n _preparedAmount = nftTokenAmount;\n }\n\n function addToBasket(\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n whenNotPaused\n returns (bool added)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n uint256 nftTokenAmount = 1;\n if (_preparedAmount > 0) {\n nftTokenAmount = _preparedAmount;\n _preparedAmount = 0;\n }\n\n added = GenericSmartBasketB(basket).addToBasket(basketTokenAddress, basketTokenId, nftTokenAmount);\n if (added) {\n emit BasketAdd(contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount);\n }\n }\n\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n address basketTokenAddress,\n uint256 basketTokenId\n )\n public\n override\n onlyController\n returns (bool removed)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n\n uint256 nftTokenAmount = 1;\n if (_preparedAmount > 0) {\n nftTokenAmount = _preparedAmount;\n _preparedAmount = 0;\n }\n\n removed = GenericSmartBasketB(basket).removeFromBasket(receiver, basketTokenAddress, basketTokenId, nftTokenAmount);\n if (removed) {\n emit BasketRemove(receiver, contractAddress, tokenId, basketTokenAddress, basketTokenId, nftTokenAmount);\n }\n }\n\n function withdrawRewards(address receiver, address contractAddress, uint256 tokenId, address rewardsToken, uint256 rewardsAmount)\n external\n override\n onlyControllerOrExecutor\n returns (uint256 amount)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GWM:E-403\");\n\n // Withdraw Rewards to Receiver\n amount = GenericSmartBasketB(basket).withdrawRewards(receiver, rewardsToken, rewardsAmount);\n\n // Log Event\n emit BasketRewarded(contractAddress, tokenId, receiver, rewardsToken, amount);\n }\n\n\n function executeForAccount(address contractAddress, uint256 tokenId, address externalAddress, uint256 ethValue, bytes memory encodedParams)\n public\n override\n onlyControllerOrExecutor\n returns (bytes memory)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n require(basket != address(0x0), \"GBM:E-403\");\n return GenericSmartBasketB(basket).executeForAccount(externalAddress, ethValue, encodedParams);\n }\n\n function getBasketAddressById(address contractAddress, uint256 tokenId)\n public\n override\n onlyControllerOrExecutor\n returns (address)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n\n // Create Smart-Basket if none exists\n if (basket == address(0x0)) {\n basket = _createBasket();\n _baskets[uuid] = basket;\n\n emit NewSmartBasket(contractAddress, tokenId, basket);\n }\n\n return basket;\n }\n\n /***********************************|\n | Only Admin/DAO |\n |__________________________________*/\n\n /**\n * @dev Sets the Paused-state of the Basket Manager\n */\n function setPausedState(bool paused) external onlyOwner {\n _paused = paused;\n emit PausedStateSet(paused);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setController(address controller) external onlyOwner {\n _controller = controller;\n emit ControllerSet(controller);\n }\n\n /**\n * @dev Connects to the ExecForAccount Controller\n */\n function setExecutor(address executor) external onlyOwner {\n _executor = executor;\n emit ExecutorSet(executor);\n }\n\n /**\n * @dev Connects to the Charged Particles Controller\n */\n function setTokenInfoProxy(address tokenInfoProxy) external onlyOwner {\n _tokenInfoProxy = ITokenInfoProxy(tokenInfoProxy);\n }\n\n function withdrawEther(address contractAddress, uint256 tokenId, address payable receiver, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawEther(receiver, amount);\n return ISmartBasket(basket).withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address contractAddress, uint256 tokenId, address payable receiver, address tokenAddress, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC20(receiver, tokenAddress, amount);\n return ISmartBasket(basket).withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n return ISmartBasket(basket).withdrawERC721(receiver, nftTokenAddress, nftTokenId);\n }\n\n function withdrawERC1155(address contractAddress, uint256 tokenId, address payable receiver, address nftTokenAddress, uint256 nftTokenId, uint256 amount)\n external\n virtual\n override\n onlyOwner\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n address basket = _baskets[uuid];\n _withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n return ISmartBasket(basket).withdrawERC1155(receiver, nftTokenAddress, nftTokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n function _createBasket()\n internal\n returns (address)\n {\n address newBasket = _createClone(_basketTemplate);\n GenericSmartBasketB(newBasket).initialize(_tokenInfoProxy);\n return newBasket;\n }\n\n /**\n * @dev Creates Contracts from a Template via Cloning\n * see: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md\n */\n function _createClone(address target) internal returns (address result) {\n bytes20 targetBytes = bytes20(target);\n assembly {\n let clone := mload(0x40)\n mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n mstore(add(clone, 0x14), targetBytes)\n mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n result := create(0, clone, 0x37)\n }\n }\n\n\n /***********************************|\n | Modifiers |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the Controller contract\n modifier onlyController() {\n require(_controller == msg.sender, \"GBM:E-108\");\n _;\n }\n\n /// @dev Throws if called by any account other than the Controller or Executor contract\n modifier onlyControllerOrExecutor() {\n require(_executor == msg.sender || _controller == msg.sender, \"WMB:E-108\");\n _;\n }\n\n // Throws if called by any account other than the Charged Particles Escrow Controller.\n modifier whenNotPaused() {\n require(_paused != true, \"GBM:E-101\");\n _;\n }\n\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericSmartBasket.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"../../../interfaces/ISmartBasket.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\nimport \"../../../lib/NftTokenType.sol\";\n\n\n/**\n * @notice Generic ERC721-Token Smart-Basket\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartBasket is ISmartBasket, BlackholePrevention, IERC721Receiver {\n using EnumerableSet for EnumerableSet.UintSet;\n using EnumerableSet for EnumerableSet.AddressSet;\n using NftTokenType for address;\n\n address internal _basketManager;\n\n // NFT contract address => Token Ids in Basket\n mapping (address => mapping(uint256 => EnumerableSet.UintSet)) internal _nftContractTokens;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize() public {\n require(_basketManager == address(0x0), \"GSB:E-002\");\n _basketManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n return _nftContractTokens[contractAddress][nftType].length();\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver(0).onERC721Received.selector;\n }\n\n function addToBasket(address contractAddress, uint256 tokenId)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n require(!_nftContractTokens[contractAddress][nftType].contains(tokenId), \"GSB:E-425\");\n\n bool added = _nftContractTokens[contractAddress][nftType].add(tokenId);\n if (added) {\n // NFT should have been Transferred into here via Charged-Particles\n added = (IERC721(contractAddress).ownerOf(tokenId) == address(this));\n }\n return added;\n }\n\n function removeFromBasket(address receiver, address contractAddress, uint256 tokenId)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 nftType = contractAddress.getTokenType(tokenId);\n require(_nftContractTokens[contractAddress][nftType].contains(tokenId), \"GSB:E-426\");\n\n bool removed = _nftContractTokens[contractAddress][nftType].remove(tokenId);\n if (removed) {\n IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId);\n }\n return removed;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyBasketManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the basket manager\n modifier onlyBasketManager() {\n require(_basketManager == msg.sender, \"GSB:E-109\");\n _;\n }\n}\n" + }, + "contracts/v1/yield/generic/ERC721/GenericSmartBasketB.sol": { + "content": "// SPDX-License-Identifier: MIT\n\n// GenericSmartWallet.sol -- Part of the Charged Particles Protocol\n// Copyright (c) 2021 Firma Lux, Inc. \n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npragma solidity 0.6.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/ERC1155Receiver.sol\";\nimport \"../../../interfaces/ISmartBasketB.sol\";\nimport \"../../../interfaces/ITokenInfoProxy.sol\";\nimport \"../../../lib/TokenInfo.sol\";\nimport \"../../../lib/NftTokenType.sol\";\nimport \"../../../lib/BlackholePrevention.sol\";\n\n/**\n * @notice Generic ERC721-Token Smart-Basket\n * @dev Non-upgradeable Contract\n */\ncontract GenericSmartBasketB is ISmartBasketB, BlackholePrevention, IERC721Receiver, ERC1155Receiver {\n using TokenInfo for address;\n using NftTokenType for address;\n\n address internal _basketManager;\n\n // NFT TokenUUID => ERC1155 Balance\n mapping (uint256 => uint256) internal _nftContractTokenBalance;\n uint256 internal _nestedNftCount;\n\n\n /***********************************|\n | Initialization |\n |__________________________________*/\n\n function initialize(ITokenInfoProxy /* tokenInfoProxy */) public {\n require(_basketManager == address(0x0), \"GSB:E-002\");\n _basketManager = msg.sender;\n }\n\n\n /***********************************|\n | Public |\n |__________________________________*/\n\n function getNestedNftCount() external view override returns (uint256) {\n return _nestedNftCount;\n }\n\n function getTokenCountByType(address contractAddress, uint256 tokenId) external view override returns (uint256) {\n return _nftContractTokenBalance[contractAddress.getTokenUUID(tokenId)];\n }\n\n function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) {\n return IERC721Receiver(0).onERC721Received.selector;\n }\n\n function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns (bytes4) {\n return IERC1155Receiver(0).onERC1155Received.selector;\n }\n\n // Unimplemented\n function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) {\n return \"\"; // IERC1155ReceiverUpgradeable(0).onERC1155BatchReceived.selector;\n }\n\n function addToBasket(address contractAddress, uint256 tokenId, uint256 nftTokenAmount)\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n _nftContractTokenBalance[uuid] += nftTokenAmount;\n _nestedNftCount += nftTokenAmount;\n return true;\n }\n\n function removeFromBasket(\n address receiver,\n address contractAddress,\n uint256 tokenId,\n uint256 nftTokenAmount\n )\n external\n override\n onlyBasketManager\n returns (bool)\n {\n uint256 uuid = contractAddress.getTokenUUID(tokenId);\n _nftContractTokenBalance[uuid] -= nftTokenAmount;\n _nestedNftCount -= nftTokenAmount;\n\n if (contractAddress.isERC1155()) {\n IERC1155(contractAddress).safeTransferFrom(address(this), receiver, tokenId, nftTokenAmount, \"\");\n } else {\n IERC721(contractAddress).safeTransferFrom(address(this), receiver, tokenId);\n }\n return true;\n }\n\n function withdrawRewards(address receiver, address rewardsTokenAddress, uint256 rewardsAmount)\n external\n override\n onlyBasketManager\n returns (uint256)\n {\n address self = address(this);\n IERC20 rewardsToken = IERC20(rewardsTokenAddress);\n\n uint256 walletBalance = rewardsToken.balanceOf(self);\n require(walletBalance >= rewardsAmount, \"GSB:E-411\");\n\n // Transfer Rewards to Receiver\n rewardsToken.safeTransfer(receiver, rewardsAmount);\n return rewardsAmount;\n }\n\n function executeForAccount(\n address contractAddress,\n uint256 ethValue,\n bytes memory encodedParams\n )\n external\n override\n onlyBasketManager\n returns (bytes memory)\n {\n (bool success, bytes memory result) = contractAddress.call{value: ethValue}(encodedParams);\n require(success, string(result));\n return result;\n }\n\n\n /***********************************|\n | Only Admin/DAO |\n | (blackhole prevention) |\n |__________________________________*/\n\n function withdrawEther(address payable receiver, uint256 amount) external virtual override onlyBasketManager {\n _withdrawEther(receiver, amount);\n }\n\n function withdrawERC20(address payable receiver, address tokenAddress, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC20(receiver, tokenAddress, amount);\n }\n\n function withdrawERC721(address payable receiver, address tokenAddress, uint256 tokenId) external virtual override onlyBasketManager {\n _withdrawERC721(receiver, tokenAddress, tokenId);\n }\n\n function withdrawERC1155(address payable receiver, address tokenAddress, uint256 tokenId, uint256 amount) external virtual override onlyBasketManager {\n _withdrawERC1155(receiver, tokenAddress, tokenId, amount);\n }\n\n\n /***********************************|\n | Private Functions |\n |__________________________________*/\n\n /// @dev Throws if called by any account other than the basket manager\n modifier onlyBasketManager() {\n require(_basketManager == msg.sender, \"GSB:E-109\");\n _;\n }\n}\n" + }, + "erc20permit/contracts/ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/53516bc555a454862470e7860a9b5254db4d00f5/contracts/token/ERC20/ERC20Permit.sol\npragma solidity ^0.6.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"./IERC2612.sol\";\n\n/**\n * @author Georgios Konstantopoulos\n * @dev Extension of {ERC20} that allows token holders to use their tokens\n * without sending any transactions by setting {IERC20-allowance} with a\n * signature using the {permit} method, and then spend them via\n * {IERC20-transferFrom}.\n *\n * The {permit} signature mechanism conforms to the {IERC2612} interface.\n */\nabstract contract ERC20Permit is ERC20, IERC2612 {\n mapping (address => uint256) public override nonces;\n\n bytes32 public immutable PERMIT_TYPEHASH = keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n bytes32 public immutable DOMAIN_SEPARATOR;\n\n constructor(string memory name_, string memory symbol_) internal ERC20(name_, symbol_) {\n uint256 chainId;\n assembly {\n chainId := chainid()\n }\n\n DOMAIN_SEPARATOR = keccak256(\n abi.encode(\n keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n keccak256(bytes(name_)),\n keccak256(bytes(\"1\")),\n chainId,\n address(this)\n )\n );\n }\n\n /**\n * @dev See {IERC2612-permit}.\n *\n * In cases where the free option is not a concern, deadline can simply be\n * set to uint(-1), so it should be seen as an optional parameter\n */\n function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {\n require(deadline >= block.timestamp, \"ERC20Permit: expired deadline\");\n\n bytes32 hashStruct = keccak256(\n abi.encode(\n PERMIT_TYPEHASH,\n owner,\n spender,\n amount,\n nonces[owner]++,\n deadline\n )\n );\n\n bytes32 hash = keccak256(\n abi.encodePacked(\n '\\x19\\x01',\n DOMAIN_SEPARATOR,\n hashStruct\n )\n );\n\n address signer = ecrecover(hash, v, r, s);\n require(\n signer != address(0) && signer == owner,\n \"ERC20Permit: invalid signature\"\n );\n\n _approve(owner, spender, amount);\n }\n}\n" + }, + "erc20permit/contracts/IERC2612.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/\npragma solidity ^0.6.0;\n\n/**\n * @dev Interface of the ERC2612 standard as defined in the EIP.\n *\n * Adds the {permit} method, which can be used to change one's\n * {IERC20-allowance} without having to send a transaction, by signing a\n * message. This allows users to spend tokens without having to hold Ether.\n *\n * See https://eips.ethereum.org/EIPS/eip-2612.\n */\ninterface IERC2612 {\n /**\n * @dev Sets `amount` 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 * - `owner` cannot be the zero address.\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(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;\n\n /**\n * @dev Returns the current ERC2612 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" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "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/deployments/sepolia/.chainId b/deployments/sepolia/.chainId new file mode 100644 index 0000000..bd8d1cd --- /dev/null +++ b/deployments/sepolia/.chainId @@ -0,0 +1 @@ +11155111 \ No newline at end of file diff --git a/hardhat.config.ts b/hardhat.config.ts index 6f197e0..db827e4 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,10 +1,10 @@ require('dotenv').config() -import { HardhatUserConfig } from "hardhat/config"; +import { HardhatUserConfig } from 'hardhat/config'; import '@typechain/hardhat'; import 'hardhat-deploy'; import 'hardhat-deploy-ethers'; import '@nomicfoundation/hardhat-ethers'; -import "@nomicfoundation/hardhat-toolbox"; +import '@nomicfoundation/hardhat-toolbox'; import '@nomicfoundation/hardhat-chai-matchers' const mnemonic = { @@ -16,14 +16,8 @@ const optimizerDisabled = process.env.OPTIMIZER_DISABLED const config: HardhatUserConfig = { solidity: { compilers: [ - { - version: '0.8.13' - }, - { - version: "0.7.6", - }, { - version: "0.8.17", + version: '0.6.12', settings: { optimizer: { enabled: !optimizerDisabled, @@ -31,6 +25,27 @@ const config: HardhatUserConfig = { } }, }, + // { + // version: '0.8.13', + // settings: { + // optimizer: { + // enabled: !optimizerDisabled, + // runs: 200 + // } + // }, + // }, + // { + // version: '0.7.6', + // }, + // { + // version: '0.8.17', + // settings: { + // optimizer: { + // enabled: !optimizerDisabled, + // runs: 200 + // } + // }, + // }, ], }, namedAccounts: { @@ -51,19 +66,20 @@ const config: HardhatUserConfig = { }, }, paths: { - sources: "./contracts", - tests: "./test", - cache: "./cache", + sources: './contracts', + tests: './test', + cache: './cache', artifacts: './build/contracts', deploy: './deploy', deployments: './deployments' }, networks: { hardhat: { - chainId: 137, + chainId: 1, forking: { - url: "https://polygon-mainnet.g.alchemy.com/v2/" + process.env.ALCHEMY_API_KEY, - blockNumber: 42543137 + url: `https://eth-mainnet.g.alchemy.com/v2/${process.env.ALCHEMY_API_KEY}`, + blockNumber: 19457321 + }, accounts: { mnemonic: mnemonic.testnet, @@ -72,13 +88,24 @@ const config: HardhatUserConfig = { }, }, goerli: { - url: `https://eth-goerli.g.alchemy.com/v2/${process.env.ALCHEMY_API_KEY}`, + url: `https://eth-goerli.g.alchemy.com/v2/${process.env.ALCHEMY_GOERLI_API_KEY}`, gasPrice: 'auto', accounts: { mnemonic: mnemonic.testnet, initialIndex: 0, count: 10, - } + }, + chainId: 5 + }, + sepolia: { + url: `https://eth-sepolia.g.alchemy.com/v2/${process.env.ALCHEMY_SEPOLIA_API_KEY}`, + gasPrice: 'auto', + accounts: { + mnemonic: mnemonic.testnet, + initialIndex: 0, + count: 10, + }, + chainId: 11155111 }, mainnet: { url: `https://eth-mainnet.g.alchemy.com/v2/${process.env.ALCHEMY_API_KEY}`, @@ -90,8 +117,8 @@ const config: HardhatUserConfig = { } }, mumbai: { - url: 'https://rpc-mumbai.maticvigil.com', - gasPrice: 10e9, + url: `https://polygon-mumbai.g.alchemy.io/v2/${process.env.ALCHEMY_MUMBAI_API_KEY}`, + gasPrice: 'auto', accounts: { mnemonic: mnemonic.testnet, initialIndex: 0, @@ -100,24 +127,26 @@ const config: HardhatUserConfig = { chainId: 80001 }, polygon: { - url: "https://polygon-mainnet.g.alchemy.com/v2/" + process.env.ALCHEMY_API_KEY, + url: `https://polygon-mainnet.g.alchemy.com/v2/${process.env.ALCHEMY_POLYGON_API_KEY}`, gasPrice: 'auto', accounts: { mnemonic: mnemonic.mainnet, - count: 8, + count: 10, }, chainId: 137 }, }, etherscan: { apiKey: { + mainnet: process.env.ETHERSCAN_API_KEY ?? '', + goerli: process.env.ETHERSCAN_API_KEY ?? '', polygon: process.env.POLYGONSCAN_APIKEY ?? '', polygonMumbai: process.env.POLYGONSCAN_APIKEY ?? '', } }, gasReporter: { currency: 'USD', - gasPrice: 1, + gasPrice: 32, enabled: (process.env.REPORT_GAS) ? true : false }, }; diff --git a/package.json b/package.json index 20a7751..fc92bfb 100644 --- a/package.json +++ b/package.json @@ -3,21 +3,46 @@ "version": "1.0.0", "main": "index.js", "repository": "https://github.com/Charged-Particles/cpu-v2.git", - "author": "scammi ", - "license": "MIT", + "scripts": { + "reinstall": "rm -rf node_modules && rm -f yarn.lock && yarn clean && yarn", + "clean": "rm -rf build cache coverage coverage.json test-results.xml", + "clean-deployed": "rm -rf abis && rm -f .openzeppelin/unknown-31337.json && rm -f .openzeppelin/kovan.json", + "clean-test": "rm -rf abis .openzeppelin/${npm_config_network:-'unknown-31337'}.json deployments/${npm_config_network:-hardhat}/*.json test-results.xml", + "compile": "hardhat --show-stack-traces --max-memory 8192 compile", + "test-only": "yarn clean-test && hardhat test --show-stack-traces", + "watch-test": "hardhat watch test", + "hint": "solhint \"contracts/**/*.sol\"", + "coverage": "yarn clean-test && hardhat --show-stack-traces coverage --temp coverage_build && yarn clean-test", + "gas": "REPORT_GAS=true hardhat test", + "deploy-test": "hardhat deploy --tags RPSetupTest --network", + "deploy-main": "hardhat deploy --tags RPSetupMain --network", + "deploy-rp": "hardhat deploy --tags RPDeploy --network", + "deploy-rp-poly": "hardhat deploy --tags RPSetupPolygon --network", + "deploy-store": "hardhat deploy --tags LeptonsStore --network", + "deploy-only": "hardhat deploy --tags", + "verify": "hardhat run scripts/verify.ts --network", + "unreg": "hardhat run scripts/unregister.ts --network", + "load-lepton-store": "hardhat run scripts/Lepton2_store_deploy.ts --network", + "migrate-lepton-store": "hardhat run scripts/Lepton2_store_migrate.ts --network", + "gen-docs": "solidity-docgen -i contracts -o docs", + "test": "yarn hardhat test --network hardhat" + }, "devDependencies": { "@nomicfoundation/hardhat-chai-matchers": "^2.0.0", "@nomicfoundation/hardhat-ethers": "^3.0.3", "@nomicfoundation/hardhat-network-helpers": "^1.0.0", "@nomicfoundation/hardhat-toolbox": "^3.0.0", "@nomicfoundation/hardhat-verify": "^1.0.0", + "@opengsn/gsn": "2.0.1", + "@openzeppelin/hardhat-upgrades": "^2.1.0", "@typechain/ethers-v6": "^0.4.3", "@typechain/hardhat": "^8.0.3", "@types/chai": "^4.2.0", "@types/mocha": ">=9.1.0", "@types/node": ">=12.0.0", "chai": "^4.2.0", - "ethers": "^6.6.2", + "erc20permit": "0.0.4", + "ethers": "6.6.4", "hardhat": "^2.14.0", "hardhat-deploy": "^0.11.34", "hardhat-deploy-ethers": "^0.4.1", @@ -28,7 +53,9 @@ "typescript": ">=4.5.0" }, "dependencies": { - "@openzeppelin/contracts": "^4.9.2", - "dotenv": "^16.3.1" + "@openzeppelin/contracts": "^3.2.0", + "@openzeppelin/contracts-upgradeable": "^3.3.0", + "dotenv": "^16.3.1", + "eth-permit": "^0.2.3" } } diff --git a/scripts/Lepton2_store_deploy.ts b/scripts/Lepton2_store_deploy.ts new file mode 100644 index 0000000..fcb1fb2 --- /dev/null +++ b/scripts/Lepton2_store_deploy.ts @@ -0,0 +1,92 @@ +import { ethers } from 'hardhat'; +import { Ionx, Lepton2, LeptonsStore } from "../typechain-types"; +import { LeptonType, leptonConfig } from "../deploy/Lepton2"; +import { isTestnet } from "../utils/isTestnet"; +import { isHardhat } from '../utils/isHardhat'; + +async function main() { + const MAX_LEPTONS_PER_LOAD = 24n; + + let ionx: Ionx; + let lepton: Lepton2; + let leptonsStore: LeptonsStore; + + if (isTestnet() || isHardhat()) { + leptonsStore = await ethers.getContract('LeptonsStore'); + lepton = await ethers.getContract('Lepton2'); + ionx = await ethers.getContract('Ionx'); + } else { + // Ethereum Mainnet + leptonsStore = await ethers.getContractAt('LeptonsStore', '0x7Bf70a3DC2d5Da7c924ce3E414E14C4564A59b1b'); + lepton = await ethers.getContractAt('Lepton2', '0x3Cd2410EAa9c2dCE50aF6CCAb72Dc93879a09c1F'); + ionx = await ethers.getContractAt('Ionx', '0x02D3A27Ac3f55d5D91Fb0f52759842696a864217'); + } + + const leptonStoreAddress = await leptonsStore.getAddress(); + const leptonAddress = await lepton.getAddress(); + const ionxAddress = await ionx.getAddress(); + + console.log('Loading LeptonsStore with:'); + console.log(`Lepton Address: "${leptonAddress}"`); + console.log(`IONX Address: "${ionxAddress}"`); + console.log(`Lepton Store Address: "${leptonStoreAddress}"`); + + // set minting free 0 + const leptonKey = await lepton.getNextType(); + const amountToBuy = 60n; + const chainType = isTestnet() ? 'test' : 'live'; + + // Set Price of Leptons to Zero + const leptonType: LeptonType = leptonConfig.types[Number(leptonKey)]; + await lepton.updateLeptonType( + leptonKey, + leptonType.tokenUri, + 0n, + leptonType.supply[chainType], + leptonType.multiplier, + leptonType.bonus, + ).then(tx => tx.wait()); + + const price = await lepton.getNextPrice(); + if (Number(price) > 0) { + throw new Error('Leptons price not set to zero.'); + } + console.log(`Lepton ${leptonKey} price set to 0`); + + // Load the Store with Leptons + const tokenIdFromBatchStart = Number(await lepton.totalSupply()) + 1; + console.log(`Loading from from ID ${tokenIdFromBatchStart} up to token ${tokenIdFromBatchStart + Number(amountToBuy)}`); + + await leptonsStore.setNextTokenId(0).then(tx => tx.wait()); // 0 = load tokenId from Lepton Contract (totalSupply) + + if (amountToBuy > MAX_LEPTONS_PER_LOAD) { + const remainder = amountToBuy % MAX_LEPTONS_PER_LOAD; + const batches = (amountToBuy - remainder) / MAX_LEPTONS_PER_LOAD; + for (let i = 0; i < batches; i++) { + await leptonsStore.load(MAX_LEPTONS_PER_LOAD, { value: 0 }).then(tx => tx.wait()); + } + if (remainder > 0) { + await leptonsStore.load(remainder, { value: 0 }).then(tx => tx.wait()); + } + } else { + await leptonsStore.load(amountToBuy, { value: 0 }).then(tx => tx.wait()); + } + + // Reset Price of Leptons + await lepton.updateLeptonType( + leptonKey, + leptonType.tokenUri, + leptonType.price[chainType], + leptonType.supply[chainType], + leptonType.multiplier, + leptonType.bonus, + ).then(tx => tx.wait()); + + const priceAfterReset = await lepton.getNextPrice(); + console.log(`Lepton ${leptonKey} price set to ${priceAfterReset}`); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); \ No newline at end of file diff --git a/scripts/Lepton2_store_migrate.ts b/scripts/Lepton2_store_migrate.ts new file mode 100644 index 0000000..41f621a --- /dev/null +++ b/scripts/Lepton2_store_migrate.ts @@ -0,0 +1,56 @@ +import { ethers } from 'hardhat'; +import { Ionx, Lepton2, LeptonsStore } from "../typechain-types"; + +async function main() { + let ionx: Ionx; + let lepton: Lepton2; + let leptonsStore1: LeptonsStore; + let leptonsStore2: LeptonsStore; + let leptonsStore3: LeptonsStore; + + // Ethereum Mainnet + leptonsStore1 = await ethers.getContractAt('LeptonsStore', '0xbD2b4C929D4D05e74B306d88f7A9ce8920d245E3'); // starting at Token ID # 1135 + leptonsStore2 = await ethers.getContractAt('LeptonsStore', '0xD5dE6F1c1cb796C63a039EF68451f285Be60Bc74'); // starting at Token ID # 1139 to 1186 + leptonsStore3 = await ethers.getContractAt('LeptonsStore', '0x7Bf70a3DC2d5Da7c924ce3E414E14C4564A59b1b'); + + lepton = await ethers.getContractAt('Lepton2', '0x3Cd2410EAa9c2dCE50aF6CCAb72Dc93879a09c1F'); + ionx = await ethers.getContractAt('Ionx', '0x02D3A27Ac3f55d5D91Fb0f52759842696a864217'); + + const leptonStoreAddress1 = await leptonsStore1.getAddress(); + const leptonStoreAddress2 = await leptonsStore2.getAddress(); + const leptonStoreAddress3 = await leptonsStore3.getAddress(); + const leptonAddress = await lepton.getAddress(); + const ionxAddress = await ionx.getAddress(); + + console.log('Loading LeptonsStore with:'); + console.log(`Lepton Address: "${leptonAddress}"`); + console.log(`IONX Address: "${ionxAddress}"`); + console.log(`Lepton Store Address 1: "${leptonStoreAddress1}"`); + console.log(`Lepton Store Address 2: "${leptonStoreAddress2}"`); + console.log(`Lepton Store Address 3: "${leptonStoreAddress3}"`); + + + // Move Leptons from + // First Store: + // for (let i = 1135; i < 1139; i++) { + // console.log(`Withdrawing from Lepton Store 1; Token ID ${i}`); + // await leptonsStore1.withdrawERC721(leptonStoreAddress3, leptonAddress, i).then(tx => tx.wait()); + // } + + // Second Store: + for (let i = 1161; i < 1187; i++) { + console.log(`Withdrawing from Lepton Store 2; Token ID ${i}`); + await leptonsStore2.withdrawERC721(leptonStoreAddress3, leptonAddress, i).then(tx => tx.wait()); + } + + // Set Starting Token ID + console.log(`Setting Starting Token ID to 1135`); + await leptonsStore3.setNextTokenId(1135).then(tx => tx.wait()); // 0 = load tokenId from Lepton Contract (totalSupply) + + console.log('Complete!'); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); \ No newline at end of file diff --git a/scripts/ionx_mint.ts b/scripts/ionx_mint.ts new file mode 100644 index 0000000..ff0e09b --- /dev/null +++ b/scripts/ionx_mint.ts @@ -0,0 +1,15 @@ +import { ethers, getNamedAccounts } from "hardhat"; +import { Ionx } from "../typechain-types"; + +async function main() { + const testAccount = '0x6d46b37708dA7Ed4E5C4509495768Fecd3D17C01'; + const ionx: Ionx = await ethers.getContract('Ionx'); + + const transaction = await ionx.transfer(testAccount, ethers.parseEther('1000000')).then(tx => tx.wait()); + console.log(transaction); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); \ No newline at end of file diff --git a/scripts/lepton_mint.ts b/scripts/lepton_mint.ts new file mode 100644 index 0000000..396f8a8 --- /dev/null +++ b/scripts/lepton_mint.ts @@ -0,0 +1,26 @@ +import { ethers, getNamedAccounts } from "hardhat"; +import { Lepton2 } from "../typechain-types"; + +async function main() { + const testAccount = '0x277BFc4a8dc79a9F194AD4a83468484046FAFD3A'; + + const { deployer } = await getNamedAccounts(); + const lepton: Lepton2 = await ethers.getContract('Lepton2'); + // const price = await lepton.getNextPrice(); + // const mintTx = await lepton.batchMintLepton(10, { value: price * 10n }).then(tx => tx.wait()); + + + await lepton.transferFrom(deployer, testAccount, 11).then(tx => tx.wait()); + await lepton.transferFrom(deployer, testAccount, 12).then(tx => tx.wait()); + await lepton.transferFrom(deployer, testAccount, 13).then(tx => tx.wait()); + await lepton.transferFrom(deployer, testAccount, 14).then(tx => tx.wait()); + await lepton.transferFrom(deployer, testAccount, 15).then(tx => tx.wait()); + await lepton.transferFrom(deployer, testAccount, 16).then(tx => tx.wait()); + await lepton.transferFrom(deployer, testAccount, 17).then(tx => tx.wait()); + await lepton.transferFrom(deployer, testAccount, 18).then(tx => tx.wait()); + await lepton.transferFrom(deployer, testAccount, 19).then(tx => tx.wait()); +} + +main().catch((error) => { console.error(error); + process.exitCode = 1; +}); \ No newline at end of file diff --git a/scripts/reward_add_stake.ts b/scripts/reward_add_stake.ts new file mode 100644 index 0000000..d62310c --- /dev/null +++ b/scripts/reward_add_stake.ts @@ -0,0 +1,20 @@ +import { ethers, getNamedAccounts } from "hardhat"; +import { Lepton2, RewardProgram, Universe } from "../typechain-types"; + +async function main() { + const assetAddress = '0x001B3B4d0F3714Ca98ba10F6042DaEbF0B1B7b6F'; + const setBaseMultiplier = '1000A'; + + const lepton: Lepton2 = await ethers.getContract('Lepton2'); + const leptonAddress = await lepton.getAddress(); + const universe: Universe = await ethers.getContract('UniverseRP'); + const rewardProgram : RewardProgram = await ethers.getContract('RewardProgram'); + + // await universe.setRewardProgram(await rewardProgram.getAddress(), dai, leptonAddress).then(tx => tx.wait()); + // await rewardProgram.setBaseMultiplier(assetAddress , setBaseMultiplier).then(tx => tx.wait()); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); \ No newline at end of file diff --git a/deploy/AccountRegistryBridge.ts b/scripts/reward_add_staking_asset_main.ts similarity index 100% rename from deploy/AccountRegistryBridge.ts rename to scripts/reward_add_staking_asset_main.ts diff --git a/scripts/reward_add_staking_asset_testnet.ts b/scripts/reward_add_staking_asset_testnet.ts new file mode 100644 index 0000000..6f50466 --- /dev/null +++ b/scripts/reward_add_staking_asset_testnet.ts @@ -0,0 +1,19 @@ +import { ethers, getNamedAccounts } from "hardhat"; +import { Lepton2, RewardProgram, UniverseRP } from "../typechain-types"; + +async function main() { + const dai = '0x001B3B4d0F3714Ca98ba10F6042DaEbF0B1B7b6F'; + const setBaseMultiplier = '1000'; + + const lepton: Lepton2 = await ethers.getContract('Lepton2'); + const leptonAddress = await lepton.getAddress(); + const universe: UniverseRP = await ethers.getContract('UniverseRP'); + const rewardProgram : RewardProgram = await ethers.getContract('RewardProgram'); + + // TODO +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); \ No newline at end of file diff --git a/scripts/reward_program.tsx b/scripts/reward_program.tsx new file mode 100644 index 0000000..8dfc1c6 --- /dev/null +++ b/scripts/reward_program.tsx @@ -0,0 +1,14 @@ + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Setup RewardProgram + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// await executeTx('1-b', 'RewardProgram: Set Reward Token', async () => +// await rewardProgram.setRewardToken(ddIonx.address) +// ); + +// await executeTx('1-d', 'RewardProgram: Set ChargedManagers', async () => +// await rewardProgram.setChargedManagers(ddChargedManagers.address) +// ); + +// await executeTx('1-e', 'RewardProgram: Set Reward NFT (Lepton2)', async () => +// await rewardProgram.setRewardNft(ddLepton2.address) +// ); diff --git a/scripts/set_reward_program_multiplier.ts b/scripts/set_reward_program_multiplier.ts new file mode 100644 index 0000000..2eb7d3b --- /dev/null +++ b/scripts/set_reward_program_multiplier.ts @@ -0,0 +1,16 @@ +import { ethers } from "hardhat"; +import { UniverseRP } from "../typechain-types"; + +async function main() { + const multiplierContract = '0x71758a4822b0e7b5c21ef8f73c69e528be4882c7'; + const universe: UniverseRP = await ethers.getContract('UniverseRPPolygon'); + + console.log('... setting new multiplier'); + await universe.setMultiplierNft(multiplierContract).then(tx => tx.wait()); + console.log('new address set'); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); \ No newline at end of file diff --git a/scripts/unregister.ts b/scripts/unregister.ts new file mode 100644 index 0000000..b41afda --- /dev/null +++ b/scripts/unregister.ts @@ -0,0 +1,15 @@ +import { ethers } from 'hardhat'; +import { UniverseRP } from "../typechain-types"; + +async function main() { + + const universe: UniverseRP = await ethers.getContract('UniverseRP'); + await universe.removeRewardProgram('0xdAC17F958D2ee523a2206206994597C13D831ec7'); // ETH-USDT + console.log('USDT Reward Program Removed!'); + +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scripts/verify.ts b/scripts/verify.ts new file mode 100644 index 0000000..0ea128d --- /dev/null +++ b/scripts/verify.ts @@ -0,0 +1,33 @@ +import { ethers, run } from 'hardhat'; + +async function main() { + + const verifyContract = async (contractName: string, contract: any, constructorArguments: any = []) => { + try { + const contractAddress = await contract.getAddress(); + console.log(`\nVerifying contract "${contractName}" at address: ${contractAddress}`); + await run('verify:verify', { address: contractAddress, constructorArguments }); + console.log(`${contractName} Verification Complete!\n`); + } catch ( err ) { + console.log(`[ERROR] Failed to Verify ${contractName}`); + console.log(err); + } + }; + + + // Verify UniverseRP + await verifyContract('UniverseRP', await ethers.getContract('UniverseRP')); + + // // Verify RewardProgramFactory + await verifyContract('RewardProgramFactory', await ethers.getContract('RewardProgramFactory')); + + // Verify RewardPrograms + await verifyContract('RewardProgramUSDC', await ethers.getContract('RewardProgramUSDC')); + await verifyContract('RewardProgramUSDT', await ethers.getContract('RewardProgramUSDT')); + await verifyContract('RewardProgramDAI', await ethers.getContract('RewardProgramDAI')); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/test/ChargedParticlesAccount.test.ts b/test/ChargedParticlesAccount.test.ts deleted file mode 100644 index 05fe329..0000000 --- a/test/ChargedParticlesAccount.test.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { expect } from "chai"; -import { ethers, network, getNamedAccounts, deployments } from 'hardhat'; -import { NFTMock, MinimalisticAccount, IRegistry } from "../typechain-types"; - - -describe('ChargedParticlesAccount', async function () { - const REGISTRY = "0x02101dfB77FDE026414827Fdc604ddAF224F0921"; - - // Contracts - let chargedParticlesAccount: MinimalisticAccount, nftMock: NFTMock, registryContract: IRegistry; - - // Addresses - let nftMockAddress: string, chargedParticlesAccountAddress: string; - // Signers - let deployer: string, receiver: string; - - before(async function () { - const { deployer: deployerAccount, user1 } = await getNamedAccounts(); - deployer = deployerAccount; - receiver = user1; - }); - - beforeEach(async function () { - await deployments.fixture([ 'ChargedParticlesAccount', 'NFTMock' ]); - - chargedParticlesAccount = await ethers.getContract('ChargedParticlesAccount'); - nftMock = await ethers.getContract('NFTMock'); - registryContract = await ethers.getContractAt( - 'IRegistry', - REGISTRY - ); - - nftMockAddress = await nftMock.getAddress(); - chargedParticlesAccountAddress = await chargedParticlesAccount.getAddress(); - }); - - it('Deploys ChargedParticlesAccount', async function () { - const chargedParticlesAccountAddress = await chargedParticlesAccount.getAddress(); - expect(chargedParticlesAccountAddress).to.not.be.empty - }); - - it('Deploys account for NFT', async function () { - const tokenId = 1; - - await nftMock.mint(deployer, tokenId).then(tx => tx.wait()); - expect(await nftMock.balanceOf(deployer)).to.be.equal(1); - - const newAccountAddress = await registryContract.account( - chargedParticlesAccountAddress, - network.config.chainId ?? 137, - nftMockAddress, - tokenId, - 0 - ); - expect(newAccountAddress).to.not.be.empty; - - const newAccountReceipt = await registryContract.createAccount( - chargedParticlesAccountAddress, - network.config.chainId ?? 137, - nftMockAddress, - tokenId, - 0, - '0x' - ).then(tx => tx.wait()); - - expect(newAccountReceipt).to.haveOwnProperty('hash'); - - const chargedParticlesAccountContract = chargedParticlesAccount.attach(newAccountAddress) as MinimalisticAccount; - const chargedParticlesDataFromTBA = await chargedParticlesAccountContract.token(); - - expect(chargedParticlesDataFromTBA).to.be.lengthOf(3); - expect(chargedParticlesDataFromTBA[1]).to.be.equal(nftMockAddress); - }); - - it('Bonds and breaks a NFT', async() => { - const tokenId = 1; - const depositedTokenId = 2; - await nftMock.mint(deployer, tokenId).then(tx => tx.wait()); - await nftMock.mint(deployer, depositedTokenId).then(tx => tx.wait()); - - // Create an account - const newAccountAddress = await registryContract.account( - chargedParticlesAccountAddress, - network.config.chainId ?? 137, - nftMockAddress, - tokenId, - 0 - ); - - await registryContract.createAccount( - chargedParticlesAccountAddress, - network.config.chainId ?? 137, - nftMockAddress, - tokenId, - 0, - '0x' - ).then(tx => tx.wait()); - - // Give permission - await nftMock.approve(newAccountAddress, depositedTokenId).then(tx => tx.wait()); - expect(await nftMock.getApproved(depositedTokenId)).to.be.eq(newAccountAddress); - - // Bond - const account = await ethers.getContractAt('ChargedParticlesAccount', newAccountAddress); - - await account.covalentBond( - nftMockAddress, - depositedTokenId, - 1 // amount - ).then(tx => tx.wait()); - - // Check owner - expect(await nftMock.ownerOf(depositedTokenId)).to.be.eq(newAccountAddress); - - await account.breakCovalentBond( - receiver, - nftMockAddress, - depositedTokenId, - 1 - ).then(tx => tx.wait()); - - expect(await nftMock.ownerOf(depositedTokenId)).to.be.eq(receiver); - }); -}); diff --git a/test/Ionx.test.ts b/test/Ionx.test.ts new file mode 100644 index 0000000..1e52e12 --- /dev/null +++ b/test/Ionx.test.ts @@ -0,0 +1,23 @@ +import { expect } from "chai"; +import { ethers, network, getNamedAccounts, deployments } from 'hardhat'; +import { Ionx } from "../typechain-types"; + +describe('Ionx deployment', async () => { + let ionx: Ionx; + let deployer: string; + + beforeEach(async () => { + await deployments.fixture(['Ionx']); + ionx = await ethers.getContract('Ionx'); + }); + + before(async () => { + const { deployer: deployerAccount, user1 } = await getNamedAccounts(); + deployer = deployerAccount; + }); + + it ('Deployer is rich $$', async () => { + const deployerBalance = await ionx.balanceOf(deployer); + expect(deployerBalance).to.greaterThan(1000n) + }); +}); \ No newline at end of file diff --git a/test/LeptonsStore.integration.test.ts b/test/LeptonsStore.integration.test.ts new file mode 100644 index 0000000..bf260e9 --- /dev/null +++ b/test/LeptonsStore.integration.test.ts @@ -0,0 +1,91 @@ +import { expect } from "chai"; +import { ethers, getNamedAccounts, deployments } from 'hardhat'; +import { Ionx, Lepton2, LeptonsStore } from "../typechain-types"; +import { DEAD_ADDRESS } from "../utils/globals"; +import { LeptonType, leptonConfig } from "../deploy/Lepton2"; +import { isTestnet } from "../utils/isTestnet"; + +import { signERC2612Permit } from "eth-permit"; +import { parseEther } from "ethers"; + +describe('Leptons Store Integration', async () => { + let leptonStore: LeptonsStore; + let ionx: Ionx; + let lepton: Lepton2; + + let deployer: string; + let leptonStoreAddress: string; + let ionxAddress: string;// = '0x02D3A27Ac3f55d5D91Fb0f52759842696a864217'; + let leptonAddress: string;// = '0x3Cd2410EAa9c2dCE50aF6CCAb72Dc93879a09c1F'; + + beforeEach(async () => { + await deployments.fixture(['Ionx', 'Lepton2', 'LeptonsStore']); + + leptonStore = await ethers.getContract('LeptonsStore'); + lepton = await ethers.getContract('Lepton2'); + ionx = await ethers.getContract('Ionx'); + + leptonStoreAddress = await leptonStore.getAddress(); + ionxAddress = await ionx.getAddress(); + leptonAddress = await lepton.getAddress(); + }); + + before(async () => { + const { deployer: deployerAccount, user1 } = await getNamedAccounts(); + deployer = deployerAccount; + }); + + it ('Loads leptons', async() => { + // mock lepton deployer + const leptonOwnerAddress = await lepton.owner(); + const owner = await ethers.getImpersonatedSigner(leptonOwnerAddress); + + // give eth to owner + const deployerSigner = await ethers.getSigner(deployer); + deployerSigner.sendTransaction({to: leptonOwnerAddress, value: parseEther('100')}).then(tx => tx.wait()); + + // set minting free 0 + const leptonKey = await lepton.getNextType(); + const amountToBuy = 10n; + const chainType = isTestnet() ? 'test' : 'live'; + + const leptonType: LeptonType = leptonConfig.types[Number(leptonKey)]; + const leptonConnectedOwner = lepton.connect(owner) as Lepton2; + + await leptonConnectedOwner.updateLeptonType( + leptonKey, + leptonType.tokenUri, + 0n, + leptonType.supply[chainType], + leptonType.multiplier, + leptonType.bonus, + ); + + const price = await lepton.getNextPrice(); + expect(price).to.be.eq(0); + + const tokenIdFromBatchStart = Number(await lepton.totalSupply()) + 1; + + //load + await leptonStore.setNextTokenId(0); // 0 = load tokenId from Lepton Contract (totalSupply) + await leptonStore.load(amountToBuy, { value: price }); + + for (let i = tokenIdFromBatchStart; i <= amountToBuy; i++){ + expect(await lepton.ownerOf(i)).to.be.eq(leptonStoreAddress); + } + + await leptonConnectedOwner.updateLeptonType( + leptonKey, + leptonType.tokenUri, + leptonType.price[chainType], + leptonType.supply[chainType], + leptonType.multiplier, + leptonType.bonus, + ); + + const priceAfterReset = await lepton.getNextPrice(); + + expect(priceAfterReset).to.be.eq(leptonType.price[chainType]); + }); + +}); \ No newline at end of file diff --git a/test/LeptonsStore.test.ts b/test/LeptonsStore.test.ts new file mode 100644 index 0000000..c28b3af --- /dev/null +++ b/test/LeptonsStore.test.ts @@ -0,0 +1,230 @@ +import { expect } from "chai"; +import { ethers, getNamedAccounts, deployments } from 'hardhat'; +import { Ionx, Lepton2, LeptonsStore } from "../typechain-types"; +import { DEAD_ADDRESS } from "../utils/globals"; +import { LeptonType, leptonConfig } from "../deploy/Lepton2"; +import { isTestnet } from "../utils/isTestnet"; + +import { signERC2612Permit } from "eth-permit"; + +describe('Leptons Store', async () => { + let leptonStore: LeptonsStore; + let lepton: Lepton2; + let ionx: Ionx; + + let deployer: string; + let leptonStoreAddress: string; + let ionxAddress: string; + + beforeEach(async () => { + await deployments.fixture(['Ionx', 'Lepton2', 'LeptonsStore']); + + leptonStore = await ethers.getContract('LeptonsStore'); + lepton = await ethers.getContract('Lepton2'); + ionx = await ethers.getContract('Ionx'); + + leptonStoreAddress = await leptonStore.getAddress(); + ionxAddress = await ionx.getAddress(); + }); + + before(async () => { + const { deployer: deployerAccount, user1 } = await getNamedAccounts(); + deployer = deployerAccount; + }); + + it ('Holds lepton address in contract state', async () => { + const leptonAddress = await lepton.getAddress(); + expect(await leptonStore.lepton()).to.be.eq(leptonAddress); + + }); + + it ('Changes leptons contract address', async () => { + await leptonStore.setLepton(DEAD_ADDRESS); + expect(await leptonStore.lepton()).to.be.eq(DEAD_ADDRESS); + }); + + it ('Loads: Batch mints paid leptons', async () => { + const amountToBuy = 10n; + const singleMintCost = await lepton.getNextPrice(); + const mintCost = amountToBuy * singleMintCost; + + await leptonStore.setNextTokenId(0); // 0 = load tokenId from Lepton Contract (totalSupply) + await leptonStore.load(amountToBuy, { value: mintCost }); + + for (let i = 1; i <= amountToBuy; i++){ + expect(await lepton.ownerOf(i)).to.be.eq(leptonStoreAddress); + } + }); + + it ('Loads: Batch mint free leptons', async () => { + const leptonKey = 0; + const amountToBuy = 10n; + const chainType = isTestnet() ? 'test' : 'live'; + + const leptonType: LeptonType = leptonConfig.types[leptonKey]; + + await lepton.updateLeptonType( + leptonKey, + leptonType.tokenUri, + 0n, + leptonType.supply[chainType], + leptonType.multiplier, + leptonType.bonus, + ); + + const price = await lepton.getNextPrice(); + expect(price).to.be.eq(0); + + await leptonStore.setNextTokenId(0); // 0 = load tokenId from Lepton Contract (totalSupply) + await leptonStore.load(amountToBuy, { value: price }); + + for (let i = 1; i <= amountToBuy; i++){ + expect(await lepton.ownerOf(i)).to.be.eq(leptonStoreAddress); + } + + await lepton.updateLeptonType( + leptonKey, + leptonType.tokenUri, + leptonType.price[chainType], + leptonType.supply[chainType], + leptonType.multiplier, + leptonType.bonus, + ); + + const priceAfterReset = await lepton.getNextPrice(); + + expect(priceAfterReset).to.be.eq(leptonType.price[chainType]); + }); + + it ('IONX Permit, increases allowance', async () => { + + const signer = await ethers.getSigner(deployer); + const allowance = 10000000n; + + const result = await signERC2612Permit( + signer, + ionxAddress, + deployer, + leptonStoreAddress, + 10000000 + ); + + const storeAllowanceBeforePermit = await ionx.allowance(deployer, leptonStoreAddress); + + expect(storeAllowanceBeforePermit).to.be.eq(0); + + await ionx.permit(deployer, leptonStoreAddress, 10000000, result.deadline, result.v, result.r, result.s).then(tx => tx.wait()); + + const storeAllowancePermit = await ionx.allowance(deployer, leptonStoreAddress); + expect(allowance).to.be.eq(storeAllowancePermit); + }); + + it ('Purchase lepton with ionx', async () => { + // Fund + const leptonKey = 0; + const amountToBuy = 10n; + const chainType = isTestnet() ? 'test' : 'live'; + + const leptonType: LeptonType = leptonConfig.types[leptonKey]; + + await lepton.updateLeptonType( + leptonKey, + leptonType.tokenUri, + 0n, + leptonType.supply[chainType], + leptonType.multiplier, + leptonType.bonus, + ); + + await leptonStore.setNextTokenId(0); // 0 = load tokenId from Lepton Contract (totalSupply) + await leptonStore.load(amountToBuy, { value: 0n }); + + // permit + const signer = await ethers.getSigner(deployer); + + const result = await signERC2612Permit( + signer, + ionxAddress, + deployer, + leptonStoreAddress, + 1 // price of lepton in IONX (see leptonPrice in deploy/LeptonsStore.ts) + ); + + await leptonStore.buyWithIonx( + 1, + result.deadline, + result.v, + result.r, + result.s + ).then(tx => tx.wait()); + + expect(await lepton.ownerOf(1)).to.be.eq(deployer); + }); + + it ('Purchase multiple lepton with ionx', async () => { + // Fund + const leptonKey = 0; + const amountToLoad = 10n; + const amountToBuy = 4; + const costOfLepton = 1; // price of lepton in IONX (see leptonPrice in deploy/LeptonsStore.ts) + const chainType = isTestnet() ? 'test' : 'live'; + + const leptonType: LeptonType = leptonConfig.types[leptonKey]; + + await lepton.updateLeptonType( + leptonKey, + leptonType.tokenUri, + 0n, + leptonType.supply[chainType], + leptonType.multiplier, + leptonType.bonus, + ); + + await leptonStore.setNextTokenId(0); // 0 = load tokenId from Lepton Contract (totalSupply) + await leptonStore.load(amountToLoad, { value: 0n }); + + // permit + const signer = await ethers.getSigner(deployer); + + const signature1 = await signERC2612Permit( + signer, + ionxAddress, + deployer, + leptonStoreAddress, + costOfLepton * amountToBuy + ); + + await leptonStore.buyWithIonx( + amountToBuy, + signature1.deadline, + signature1.v, + signature1.r, + signature1.s + ).then(tx => tx.wait()); + + + for (let i = 1; i <= amountToBuy; i++){ + expect(await lepton.ownerOf(i)).to.be.eq(deployer); + } + + const signature2 = await signERC2612Permit( + signer, + ionxAddress, + deployer, + leptonStoreAddress, + costOfLepton * amountToBuy + ); + + await leptonStore.buyWithIonx( + amountToBuy, + signature2.deadline, + signature2.v, + signature2.r, + signature2.s + ).then(tx => tx.wait()); + + for (let i = 5; i <= amountToBuy; i++){ + expect(await lepton.ownerOf(i)).to.be.eq(deployer); + } + }); +}); \ No newline at end of file diff --git a/test/Letpton2.test.ts b/test/Letpton2.test.ts new file mode 100644 index 0000000..82c441d --- /dev/null +++ b/test/Letpton2.test.ts @@ -0,0 +1,94 @@ +import { expect } from "chai"; +import { ethers, network, getNamedAccounts, deployments } from 'hardhat'; +import { Lepton2 } from "../typechain-types"; +import { LeptonType, leptonConfig } from "../deploy/Lepton2"; +import { isHardhat } from "../utils/isHardhat"; + +describe('Lepton2 deployment', async () => { + let lepton: Lepton2; + let deployer: string; + + beforeEach(async () => { + await deployments.fixture(['Lepton2']); + lepton = await ethers.getContract('Lepton2'); + }); + + before(async () => { + const { deployer: deployerAccount, user1 } = await getNamedAccounts(); + deployer = deployerAccount; + console.log(deployerAccount); + }); + + it('Single mints', async () => { + const price = await lepton.getNextPrice(); + await lepton.mintLepton({ value: price }).then(tx => tx.wait()); + expect(await lepton.balanceOf(deployer)).to.be.eq(1); + + const multiplier = await lepton.getMultiplier(1); + const bonus = await lepton.getBonus(1); + const tokenURI = await lepton.tokenURI(1); + + expect(multiplier).to.be.eq(leptonConfig.types[0].multiplier); + expect(bonus).to.be.eq(leptonConfig.types[0].bonus); + expect(tokenURI).to.be.eq(leptonConfig.types[0].tokenUri); + }); + + it ('Mints a batch', async () => { + const price = await lepton.getNextPrice(); + await lepton.batchMintLepton(20, { value: price * 20n }) + + expect(await lepton.balanceOf(deployer)).to.be.eq(20); + await lepton.batchMintLepton(20, { value: price * 20n }) + expect(await lepton.balanceOf(deployer)).to.be.eq(40); + }); + + + it ('Distributes free leptons', async () => { + await lepton.setMaxMintPerTx(1000000n).then(tx => tx.wait()); + + // updateLeptonType set all leptons mint price to 0 + const chainType = isHardhat() ? 'test' : 'live'; + + let mintCount = 0n; + + for (const leptonKey in leptonConfig.types) { + const leptonType: LeptonType = leptonConfig.types[leptonKey]; + + await lepton.updateLeptonType( + leptonKey, + leptonType.tokenUri, + 0n, + leptonType.supply[chainType], + leptonType.multiplier, + leptonType.bonus, + ); + + const price = await lepton.getNextPrice(); + expect(price).to.be.eq(0); + await lepton.batchMintLepton(leptonType.supply[chainType], { value: 0n }).then(tx => tx.wait()); + + mintCount = leptonType.supply[chainType] + mintCount; + expect(await lepton.balanceOf(deployer)).to.be.eq(mintCount); + } + + // restore previous state after distribution. + await lepton.setMaxMintPerTx(5n).then(tx => tx.wait()); + + for (const leptonKey in leptonConfig.types) { + const leptonType: LeptonType = leptonConfig.types[leptonKey]; + + await lepton.updateLeptonType( + leptonKey, + leptonType.tokenUri, + leptonType.price[chainType], + leptonType.supply[chainType], + leptonType.multiplier, + leptonType.bonus, + ); + } + }); +}); + +function toWei(arg0: string) { + throw new Error("Function not implemented."); +} diff --git a/test/RewardProgramSetupMainnet.test.ts b/test/RewardProgramSetupMainnet.test.ts new file mode 100644 index 0000000..4f692bd --- /dev/null +++ b/test/RewardProgramSetupMainnet.test.ts @@ -0,0 +1,102 @@ +// import { expect } from "chai"; +// import { ethers, network, getNamedAccounts, deployments } from 'hardhat'; +// import { getChargedParticlesOwner } from "../utils/getSigners"; +// import { UniverseRP, ChargedParticles, ChargedSettings, Ionx, Lepton2, RewardProgram, TokenInfoProxy, IERC20Detailed } from "../typechain-types"; +// import { addressBook } from "../utils/globals"; +// import { Signer } from "ethers"; + +// describe('RewardProgramSetupTestnet deployments', async () => { +// let chargedParticles: ChargedParticles, chargedSettings: ChargedSettings, rewardProgram: RewardProgram, tokenInfoProxy: TokenInfoProxy; +// let lepton: Lepton2, ionx: Ionx, universe: UniverseRP, dai: IERC20Detailed; +// let iface, fragment; + +// let deployer: string, user: string, chargedOwner: Signer; +// let leptonAddress: string, chargedParticlesAddress: string, ionxAddress: string, universeAddress: string; +// let chainId; + +// before(async () => { +// const { deployer: deployerAccount, user1 } = await getNamedAccounts(); +// chargedOwner = await getChargedParticlesOwner(); +// deployer = deployerAccount; +// user = user1; +// }); + +// beforeEach(async () => { +// await deployments.fixture(['RPSetupMain']); + +// chainId = network.config.chainId ?? 1; +// dai = await ethers.getContractAt('IERC20Detailed', addressBook[chainId].dai); +// ionx = await ethers.getContractAt('Ionx', addressBook[chainId].ionx); +// lepton = await ethers.getContractAt('Lepton2', addressBook[chainId].lepton); +// universe = await ethers.getContract('UniverseRP'); +// rewardProgram = await ethers.getContract('RewardProgramDAI'); + +// chargedParticles = await ethers.getContractAt('ChargedParticles', addressBook[chainId].chargedParticles, chargedOwner); +// chargedSettings = await ethers.getContractAt('ChargedSettings', addressBook[chainId].chargedSettings, chargedOwner); +// tokenInfoProxy = await ethers.getContractAt('TokenInfoProxy', addressBook[chainId].tokenInfoProxy, chargedOwner); + +// universeAddress = await universe.getAddress(); +// leptonAddress = await lepton.getAddress(); +// ionxAddress = await ionx.getAddress(); +// chargedParticlesAddress = await chargedParticles.getAddress(); + +// chargedSettings.enableNftContracts([ leptonAddress ]).then(tx => tx.wait()); + +// iface = new ethers.Interface([ 'function ownerOf(uint256)' ]); +// fragment = iface.getFunction('ownerOf'); +// if (fragment !== null) { +// tokenInfoProxy.setContractFnCreatorOf(leptonAddress, fragment.selector); +// } +// }); + +// it ('Bonds', async () => { +// await lepton.mintLepton({ value: ethers.parseEther('0.3') }).then(tx => tx.wait()); +// await lepton.mintLepton({ value: ethers.parseEther('0.3') }).then(tx => tx.wait()); +// expect(await lepton.balanceOf(deployer)).to.be.eq(2); + +// await lepton.approve(chargedParticlesAddress, 2).then(tx => tx.wait()); + +// await chargedParticles.connect(await ethers.getSigner(deployer)).covalentBond( +// leptonAddress, +// 1, +// 'generic.B', +// leptonAddress, +// 2, +// 1 +// ).then(tx => tx.wait()); +// }); + +// it ('Energizes ', async () => { +// await lepton.mintLepton({ value: ethers.parseEther('0.3') }).then(tx => tx.wait()); +// await lepton.mintLepton({ value: ethers.parseEther('0.3') }).then(tx => tx.wait()); +// expect(await lepton.balanceOf(deployer)).to.be.eq(2); +// await lepton.approve(chargedParticlesAddress, 2).then(tx => tx.wait()); + +// const amountDeposit = ethers.parseEther('.1'); + +// await dai.approve(chargedParticlesAddress, amountDeposit).then(tx => tx.wait()); + +// await expect(chargedParticles.connect(await ethers.getSigner(deployer)).energizeParticle( +// leptonAddress, +// 1, +// 'generic.B', +// await dai.getAddress(), +// amountDeposit, +// '0x0000000000000000000000000000000000000000' +// )).to.emit(rewardProgram, 'AssetDeposit') +// .withArgs(leptonAddress, 1, 'generic.B', amountDeposit); + +// await expect(chargedParticles.connect(await ethers.getSigner(deployer)).covalentBond( +// leptonAddress, +// 1, +// 'generic.B', +// leptonAddress, +// 2, +// 1 +// )).to.emit(universe, 'NftDeposit'); + +// const uuid = ethers.solidityPackedKeccak256([ 'address', 'uint256' ], [leptonAddress, 1]); +// const gatherGrowthSimulated = await rewardProgram.calculateRewardsEarned(uuid, 100n); +// expect(gatherGrowthSimulated).to.be.greaterThan(0); +// }); +// }); \ No newline at end of file diff --git a/test/RewardProgramSetupTestnet.test.ts b/test/RewardProgramSetupTestnet.test.ts new file mode 100644 index 0000000..31470b8 --- /dev/null +++ b/test/RewardProgramSetupTestnet.test.ts @@ -0,0 +1,344 @@ +import { expect } from 'chai'; +import { ethers, network, getNamedAccounts, deployments } from 'hardhat'; +import { getChargedParticlesOwner } from '../utils/getSigners'; +import { UniverseRP, ChargedParticles, ChargedSettings, Ionx, Lepton2, RewardProgram, TokenInfoProxy, IERC20Detailed } from '../typechain-types'; +import { addressBook } from '../utils/globals'; +import { Signer, parseEther } from 'ethers'; +import { time } from '@nomicfoundation/hardhat-toolbox/network-helpers'; + +describe('RewardProgramSetupTestnet deployments', async () => { + const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; + + let chargedParticles: ChargedParticles, chargedSettings: ChargedSettings, rewardProgram: RewardProgram, tokenInfoProxy: TokenInfoProxy; + let lepton: Lepton2, ionx: Ionx, universe: UniverseRP, dai: Ionx; + let iface, fragment; + + let deployer: string, user: string, chargedOwner: Signer; + let leptonAddress: string, chargedParticlesAddress: string, ionxAddress: string, universeAddress: string, daiAddress: string; + let chainId; + + const _energizeNft = async (holderNftId: number, amount: BigInt, manager: string = 'generic.B') => { + await dai.approve(chargedParticlesAddress, amount.toString()).then(tx => tx.wait()); + return await chargedParticles.connect(await ethers.getSigner(deployer)).energizeParticle( + leptonAddress, + holderNftId, + manager, + daiAddress, + amount.toString(), + '0x0000000000000000000000000000000000000000' + ); + }; + + const _releaseNft = async (holderNftId: number, manager: string = 'generic.B') => { + return await chargedParticles.connect(await ethers.getSigner(deployer)).releaseParticle( + deployer, + leptonAddress, + holderNftId, + manager, + daiAddress + ); + }; + + const _bondNft = async (holderNftId: number, depositNftId: number) => { + await lepton.approve(chargedParticlesAddress, depositNftId).then(tx => tx.wait()); + return await chargedParticles.connect(await ethers.getSigner(deployer)).covalentBond( + leptonAddress, + holderNftId, + 'generic.B', + leptonAddress, + depositNftId, + 1 // amount + ).then(tx => tx.wait()); + }; + + const _mintAllLeptons = async () => { + // Tier 1 + const nftTier1 = 2; + let price = await lepton.getNextPrice(); + await lepton.batchMintLepton(25, { value: price * 25n }).then(tx => tx.wait()); + await lepton.batchMintLepton(15, { value: price * 15n }).then(tx => tx.wait()); + + // Tier 2 + const nftTier2 = 41; + price = await lepton.getNextPrice(); + await lepton.batchMintLepton(20, { value: price * 20n }).then(tx => tx.wait()); + + // Tier 3 + const nftTier3 = 61; + price = await lepton.getNextPrice(); + await lepton.batchMintLepton(12, { value: price * 12n }).then(tx => tx.wait()); + + // Tier 4 + const nftTier4 = 73; + price = await lepton.getNextPrice(); + await lepton.batchMintLepton(8, { value: price * 8n }).then(tx => tx.wait()); + + // Tier 5 + const nftTier5 = 81; + price = await lepton.getNextPrice(); + await lepton.batchMintLepton(5, { value: price * 5n }).then(tx => tx.wait()); + + // Tier 6 + const nftTier6 = 86; + price = await lepton.getNextPrice(); + await lepton.batchMintLepton(2, { value: price * 2n }).then(tx => tx.wait()); + + // Confirm Count + expect(await lepton.balanceOf(deployer)).to.be.eq(87); + + return { tier1: nftTier1, tier2: nftTier2, tier3: nftTier3, tier4: nftTier4, tier5: nftTier5, tier6: nftTier6 } + }; + + const atLeast = (min: bigint) => (value: bigint):boolean => { + const result = value >= min; + if (!result) { + setTimeout(() => { + console.log(`Expected ${value} to be at least ${min}`); + }, 1); + } + return result; + }; + + // + // Before/After Hooks + // + + before(async () => { + const { deployer: deployerAccount, user1 } = await getNamedAccounts(); + chargedOwner = await getChargedParticlesOwner(); + deployer = deployerAccount; + user = user1; + }); + + beforeEach(async () => { + chainId = network.config.chainId ?? 80001; + if (chainId === 137) { + await deployments.fixture(['RPSetupPolygon']); + } else { + await deployments.fixture(['RPSetupTest', 'RPDeploy']); + } + + const deployerSigner = await ethers.getSigner(deployer); + await deployerSigner.sendTransaction({value: parseEther('1'), to: chargedOwner}); + lepton = await ethers.getContract('Lepton2'); + ionx = await ethers.getContract('Ionx'); + universe = await ethers.getContract('UniverseRP'); + rewardProgram = await ethers.getContract(`RewardProgram${addressBook[chainId].stakingTokens[0].id}`); + chargedParticles = await ethers.getContractAt('ChargedParticles', addressBook[chainId].chargedParticles, chargedOwner); + chargedSettings = await ethers.getContractAt('ChargedSettings', addressBook[chainId].chargedSettings, chargedOwner); + tokenInfoProxy = await ethers.getContractAt('TokenInfoProxy', addressBook[chainId].tokenInfoProxy, chargedOwner); + dai = await ethers.getContractAt('Ionx', addressBook[chainId].stakingTokens[0].address); + + const daiOwner = await dai.owner(); + await network.provider.request({ + method: "hardhat_impersonateAccount", + params: [daiOwner], + }); + + await dai.connect(await ethers.getSigner(daiOwner)).transfer(deployer, parseEther('100')).then(tx => tx.wait()); + + universeAddress = await universe.getAddress(); + leptonAddress = await lepton.getAddress(); + ionxAddress = await ionx.getAddress(); + chargedParticlesAddress = await chargedParticles.getAddress(); + daiAddress = await dai.getAddress(); + + await chargedSettings.enableNftContracts([ leptonAddress ]).then(tx => tx.wait()); + + iface = new ethers.Interface([ 'function ownerOf(uint256)' ]); + fragment = iface.getFunction('ownerOf'); + if (fragment !== null) { + tokenInfoProxy.setContractFnCreatorOf(leptonAddress, fragment.selector); + } + }); + + // + // Unit-Tests + // + + it ('is Bondable', async () => { + const price = await lepton.getNextPrice(); + await lepton.batchMintLepton(2, { value: price * 2n }).then(tx => tx.wait()); + expect(await lepton.balanceOf(deployer)).to.be.eq(2); + + await expect(_bondNft(1, 2)).to.emit(universe, 'NftDeposit'); + expect(await lepton.balanceOf(deployer)).to.be.eq(1); + }); + + it ('is Energizable', async () => { + const price = await lepton.getNextPrice(); + await lepton.mintLepton({ value: price }).then(tx => tx.wait()); + + const amountDeposit: BigInt = ethers.parseEther('.1'); + await expect(_energizeNft(1, amountDeposit)) + .to.emit(rewardProgram, 'AssetDeposit') + .withArgs(leptonAddress, 1, 'generic.B', amountDeposit); + }); + + it('Registers Multiplier NFTs', async () => { + const nestedUuid = ethers.solidityPackedKeccak256([ 'address', 'uint256' ], [leptonAddress, 1]); + const nfts = await _mintAllLeptons(); + + // Confirm Multiplier on Single Lepton Deposit + await expect(_bondNft(1, nfts.tier1)).to.emit(universe, 'NftDeposit'); + let nftStake = await universe.getNftStake(nestedUuid); + expect(nftStake[0]).to.be.eq(110); // Tier 1 + + // Confirm Multiplier on Second Lepton Deposit + await expect(_bondNft(1, nfts.tier2)).to.emit(universe, 'NftDeposit'); + nftStake = await universe.getNftStake(nestedUuid); + expect(nftStake[0]).to.be.eq(140); // Tier 1 + 2 + + // Confirm Multiplier on Third Lepton Deposit + await expect(_bondNft(1, nfts.tier3)).to.emit(universe, 'NftDeposit'); + nftStake = await universe.getNftStake(nestedUuid); + expect(nftStake[0]).to.be.eq(240); // Tier 1 + 2 + 3 + + // Confirm Multiplier on Fourth Lepton Deposit + await expect(_bondNft(1, nfts.tier4)).to.emit(universe, 'NftDeposit'); + nftStake = await universe.getNftStake(nestedUuid); + expect(nftStake[0]).to.be.eq(370); // Tier 1 + 2 + 3 + 4 + + // Confirm Multiplier on Fourth Lepton Deposit + await expect(_bondNft(1, nfts.tier5)).to.emit(universe, 'NftDeposit'); + nftStake = await universe.getNftStake(nestedUuid); + expect(nftStake[0]).to.be.eq(550); // Tier 1 + 2 + 3 + 4 + 5 + + // Confirm Multiplier on Fourth Lepton Deposit + await expect(_bondNft(1, nfts.tier6)).to.emit(universe, 'NftDeposit'); + nftStake = await universe.getNftStake(nestedUuid); + expect(nftStake[0]).to.be.eq(1010); // Tier 1 + 2 + 3 + 4 + 5 + 6 + }); + + it('Rewards without Lepton Multiplier', async () => { + const price = await lepton.getNextPrice(); + await lepton.mintLepton({ value: price }).then(tx => tx.wait()); + expect(await lepton.balanceOf(deployer)).to.be.eq(1); + + const amountDeposit: BigInt = ethers.parseEther('1'); + await expect(_energizeNft(1, amountDeposit, 'aave.B')) + .to.emit(rewardProgram, 'AssetDeposit') + .withArgs(leptonAddress, 1, 'aave.B', amountDeposit); + + const timeDelay = (await time.latest()) + ONE_YEAR_IN_SECS; + await time.increaseTo(timeDelay); + + const expectedAaveInterest = 18044931725417798n; + const expectedIonxReward = expectedAaveInterest * 2n; // 2:1 ratio + + await expect(_releaseNft(1, 'aave.B')) + .to.emit(rewardProgram, 'AssetRelease') + .withArgs(leptonAddress, 1, atLeast(expectedAaveInterest / 2n)) + .to.emit(rewardProgram, 'RewardsClaimed') + // .withArgs(leptonAddress, 1, deployer, 1, atLeast(expectedIonxReward)); // TODO + }); + + it('Rewards with One Lepton Multiplier', async () => { + const price = await lepton.getNextPrice(); + await lepton.batchMintLepton(2, { value: price * 2n }).then(tx => tx.wait()); + expect(await lepton.balanceOf(deployer)).to.be.eq(2); + + // Confirm Multiplier on Single Lepton Deposit + const nestedUuid = ethers.solidityPackedKeccak256([ 'address', 'uint256' ], [leptonAddress, 1]); + await expect(_bondNft(1, 2)).to.emit(universe, 'NftDeposit'); + let nftStake = await universe.getNftStake(nestedUuid); + expect(nftStake[0]).to.be.eq(110); // Tier 1 + + // Deposit DAI into Aave + const amountDeposit: BigInt = ethers.parseEther('1'); + await expect(_energizeNft(1, amountDeposit, 'aave.B')) + .to.emit(rewardProgram, 'AssetDeposit') + .withArgs(leptonAddress, 1, 'aave.B', amountDeposit); + + // Increase Blocktime + const timeDelay = (await time.latest()) + ONE_YEAR_IN_SECS; + await time.increaseTo(timeDelay); + + const expectedAaveInterest = 18044931725417798n; + let expectedIonxReward = (expectedAaveInterest * 2n); // 2:1 ratio + expectedIonxReward = (expectedIonxReward * 110n / 100n); // + 1.1x multiplier + + // Release Assets and Confirm + const releaseState = _releaseNft(1, 'aave.B'); + await expect(releaseState) + .to.emit(rewardProgram, 'AssetRelease') + .withArgs(leptonAddress, 1, atLeast(expectedAaveInterest)); + await expect(releaseState) + .to.emit(rewardProgram, 'RewardsClaimed') + // .withArgs(leptonAddress, 1, deployer, atLeast(expectedIonxReward), 0); //TODO + }); + + it('Rewards with Two Lepton Multipliers', async () => { + const nfts = await _mintAllLeptons(); + + // Confirm Multiplier on Two Lepton Deposits + const nestedUuid = ethers.solidityPackedKeccak256([ 'address', 'uint256' ], [leptonAddress, 1]); + await expect(_bondNft(1, nfts.tier1)).to.emit(universe, 'NftDeposit'); + await expect(_bondNft(1, nfts.tier2)).to.emit(universe, 'NftDeposit'); + + let nftStake = await universe.getNftStake(nestedUuid); + expect(nftStake[0]).to.be.eq(140); // Tier 1 + Tier 2 + + // Deposit DAI into Aave + const amountDeposit: BigInt = ethers.parseEther('1'); + await expect(_energizeNft(1, amountDeposit, 'aave.B')) + .to.emit(rewardProgram, 'AssetDeposit') + .withArgs(leptonAddress, 1, 'aave.B', amountDeposit); + + // Increase Blocktime + const timeDelay = (await time.latest()) + ONE_YEAR_IN_SECS; + await time.increaseTo(timeDelay); + + const expectedAaveInterest = 18044931725417798n; + let expectedIonxReward = (expectedAaveInterest * 2n); // 2:1 ratio + expectedIonxReward = (expectedIonxReward * 140n / 100n); // + 1.4x multiplier + + // Release Assets and Confirm + const releaseState = _releaseNft(1, 'aave.B'); + await expect(releaseState) + .to.emit(rewardProgram, 'AssetRelease') + .withArgs(leptonAddress, 1, atLeast(expectedAaveInterest)); + await expect(releaseState) + .to.emit(rewardProgram, 'RewardsClaimed') + // .withArgs(leptonAddress, 1, deployer, atLeast(expectedIonxReward), 0); // TODO + }); + + it('Rewards with Six Lepton Multipliers', async () => { + const nfts = await _mintAllLeptons(); + + // Confirm Multiplier on Six Lepton Deposits + const nestedUuid = ethers.solidityPackedKeccak256([ 'address', 'uint256' ], [leptonAddress, 1]); + await expect(_bondNft(1, nfts.tier1)).to.emit(universe, 'NftDeposit'); + await expect(_bondNft(1, nfts.tier2)).to.emit(universe, 'NftDeposit'); + await expect(_bondNft(1, nfts.tier3)).to.emit(universe, 'NftDeposit'); + await expect(_bondNft(1, nfts.tier4)).to.emit(universe, 'NftDeposit'); + await expect(_bondNft(1, nfts.tier5)).to.emit(universe, 'NftDeposit'); + await expect(_bondNft(1, nfts.tier6)).to.emit(universe, 'NftDeposit'); + + let nftStake = await universe.getNftStake(nestedUuid); + expect(nftStake[0]).to.be.eq(1010); // Tier 1 + 2 + 3 + 4 + 5 + 6 + + // Deposit DAI into Aave + const amountDeposit: BigInt = ethers.parseEther('1'); + await expect(_energizeNft(1, amountDeposit, 'aave.B')) + .to.emit(rewardProgram, 'AssetDeposit') + .withArgs(leptonAddress, 1, 'aave.B', amountDeposit); + + // Increase Blocktime + const timeDelay = (await time.latest()) + ONE_YEAR_IN_SECS; + await time.increaseTo(timeDelay); + + const expectedAaveInterest = 18044931725417798n; + let expectedIonxReward = (expectedAaveInterest * 2n); // 2:1 ratio + expectedIonxReward = (expectedIonxReward * 1010n / 100n); // + 10.1x multiplier + + // Release Assets and Confirm + const releaseState = _releaseNft(1, 'aave.B'); + await expect(releaseState) + .to.emit(rewardProgram, 'AssetRelease') + .withArgs(leptonAddress, 1, atLeast(expectedAaveInterest)); + await expect(releaseState) + .to.emit(rewardProgram, 'RewardsClaimed') + // .withArgs(leptonAddress, 1, deployer, atLeast(expectedIonxReward), 0); + }); +}); \ No newline at end of file diff --git a/test/UniverseRP.test.ts b/test/UniverseRP.test.ts new file mode 100644 index 0000000..1535ea7 --- /dev/null +++ b/test/UniverseRP.test.ts @@ -0,0 +1,23 @@ +import { expect } from "chai"; +import { ethers, network, getNamedAccounts, deployments } from 'hardhat'; +import { UniverseRP } from "../typechain-types"; + +describe('UniverseRP deployment', async () => { + let universe: UniverseRP; + let deployer: string; + + beforeEach(async () => { + await deployments.fixture(['UniverseRP']); + universe = await ethers.getContract('UniverseRP'); + }); + + before(async () => { + const { deployer: deployerAccount } = await getNamedAccounts(); + deployer = deployerAccount; + }); + + it ('is deployed', async () => { + const owner = await universe.owner(); + expect(owner).to.equal(deployer); + }); +}); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 804695c..1d92027 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,6 +8,6 @@ "skipLibCheck": true, "resolveJsonModule": true }, - "include": ["./hardhat.config.ts", "./scripts", "./deploy", "./test", "./typechain-types"], + "include": ["./hardhat.config.ts", "./scripts", "./deploy", "./test", "./typechain-types", "./utils"], "files": ["./hardhat.config.ts"] } diff --git a/utils/getSigners.ts b/utils/getSigners.ts new file mode 100644 index 0000000..95d2cb4 --- /dev/null +++ b/utils/getSigners.ts @@ -0,0 +1,23 @@ +import { ethers, network } from "hardhat"; +import { ChargedParticles } from "../typechain-types"; +import { addressBook } from "./globals"; +import { isHardhat } from './isHardhat'; + +export const getChargedParticlesOwner = async () => { + const chainId = network.config.chainId ?? 1; + const chargedParticles: ChargedParticles = await ethers.getContractAt('ChargedParticles', addressBook[chainId].chargedParticles); + const chargedParticlesOwner = await chargedParticles.owner(); + + if (isHardhat()) { + await network.provider.request({ + method: "hardhat_impersonateAccount", + params: [chargedParticlesOwner], + }); + + const chargedParticlesOwnerSigner = await ethers.getSigner(chargedParticlesOwner); + return chargedParticlesOwnerSigner; + } else { + const chargedParticlesOwnerSigner = await ethers.getSigner(chargedParticlesOwner); + return chargedParticlesOwnerSigner; + } +}; \ No newline at end of file diff --git a/utils/globals.ts b/utils/globals.ts new file mode 100644 index 0000000..bbad5de --- /dev/null +++ b/utils/globals.ts @@ -0,0 +1,95 @@ + +interface StakingToken { + id: string; + address: string; + multiplier: string; + funding: string; +} + +interface AddressBook { + [chainId: number]: { + chargedManager: string; + chargedParticles: string; + chargedSettings: string; + tokenInfoProxy: string; + ionx: string; + lepton: string; + stakingTokens: Array; + }; +} + +export const DEAD_ADDRESS = "0x000000000000000000000000000000000000dEaD"; + +export const addressBook: AddressBook = { + // Ethereum Mainnet + 1: { + 'chargedManager': '0x7b07Ec627d2426b89C44a6cC75Dc57c27a52174d', + 'chargedParticles': '0xaB1a1410EA40930755C1330Cc0fB3367897C8c41', + 'chargedSettings' : '0x07DdB208d52947320d07E0E4611a80Fb7eFD001D', + 'tokenInfoProxy': '0xeF0D1DEDaAF0D9e4B868a049101a9DB1Ba1e50c5', + 'ionx': '0x02D3A27Ac3f55d5D91Fb0f52759842696a864217', + 'lepton': '0x3Cd2410EAa9c2dCE50aF6CCAb72Dc93879a09c1F', + 'stakingTokens': [ + // { id: 'DAI', address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', multiplier: '24500', funding: '10000' }, // Deployed + // { id: 'USDC', address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', multiplier: '21750', funding: '10000' }, // Deployed + // { id: 'LUSD', address: '0x5f98805A4E8be255a32880FDeC7F6728C6568bA0', multiplier: '06300', funding: '10000' }, // Not Deployed + // { id: 'FRAX', address: '0x853d955aCEf822Db058eb8505911ED77F175b99e', multiplier: '31000', funding: '10000' }, // Not Deployed + { id: 'SUSD', address: '0x57Ab1ec28D129707052df4dF418D58a2D46d5f51', multiplier: '32500', funding: '10000' }, // Deployed + ], + }, + + // Polygon Mainnet + 137: { + 'chargedManager': '0x0f42057be75AF6D977a0cE900E732eA4d490B580', + 'chargedParticles': '0x0288280Df6221E7e9f23c1BB398c820ae0Aa6c10', + 'chargedSettings' : '0xdc29C7014d104432B15eD2334e654fCBf3d5E528', + 'tokenInfoProxy': '0x349eEF86Ea34A69D8B880D5Fd5F39a6d2a7DE716', + 'ionx': '0x01b317bC5eD573FAa112eF64DD029F407CecB155', + 'lepton': '0xe349557325164577Ded350A8cAB03159c728B9E7', + 'stakingTokens': [ + { id: 'DAI', address: '0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063', multiplier: '41000', funding: '10000' }, + { id: 'USDC', address: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174', multiplier: '42850', funding: '10000' }, + ], + }, + + // Goerli Testnet + 5: { + 'chargedManager': '0x6B4738a15052f57B07dbF9E762d0E58D5DcE5C55', + 'chargedParticles': '0xA81cd63F345f323b9785048764e906C9C0D9814D', + 'chargedSettings' : '0xA1F97Fc59fafB2C43600731876710654F60c146E', + 'tokenInfoProxy': '0x8fa84be9492aEA190d62d5f0fc11618d23a9ead2', + 'ionx': '0xa817464e5faD7D5928739E1C37Ef845C53ab1eea', + 'lepton': '0xa99294Caed407273A4b6320CaC68B27C58F46c5d', + 'stakingTokens': [ + { id: 'DAI', address: '0x75Ab5AB1Eef154C0352Fc31D2428Cef80C7F8B33', multiplier: '71500', funding: '10000' }, + ], + }, + + // Hardhat Testnet + 31337: { + 'chargedManager': '0x7b07Ec627d2426b89C44a6cC75Dc57c27a52174d', + 'chargedParticles': '0xaB1a1410EA40930755C1330Cc0fB3367897C8c41', + 'chargedSettings' : '0x07DdB208d52947320d07E0E4611a80Fb7eFD001D', + 'tokenInfoProxy': '0xeF0D1DEDaAF0D9e4B868a049101a9DB1Ba1e50c5', + 'lepton': '', + 'ionx': '', + 'stakingTokens': [ + { id: 'DAI', address: '0x001b3b4d0f3714ca98ba10f6042daebf0b1b7b6f', multiplier: '20000', funding: '10000' }, // Do-Not-Modify: used in unit-tests + { id: 'USDC', address: '0x0fa8781a83e46826621b3bc094ea2a0212e71b23', multiplier: '20000', funding: '10000' }, // Do-Not-Modify: used in unit-tests + ], + }, + + // Polygon Mumbai Testnet + 80001: { + 'chargedManager': '0xE8c6462ceEeeC3f8c318e29Af143f623de979D69', + 'chargedParticles': '0x51f845af34c60499a1056FCDf47BcBC681A0fA39', + 'chargedSettings' : '0x60428D3e580907C74Ee8690E4E192317864aAE1d', + 'tokenInfoProxy': '0xda8d21714ea5784d5b6990c170485effb9104883', + 'lepton': '', + 'ionx': '', + 'stakingTokens': [ + { id: 'DAI', address: '0x001b3b4d0f3714ca98ba10f6042daebf0b1b7b6f', multiplier: '20000', funding: '10000' }, // Do-Not-Modify: used in unit-tests + { id: 'USDC', address: '0x0fa8781a83e46826621b3bc094ea2a0212e71b23', multiplier: '20000', funding: '10000' }, // Do-Not-Modify: used in unit-tests + ], + } +} \ No newline at end of file diff --git a/utils/isHardhat.ts b/utils/isHardhat.ts new file mode 100644 index 0000000..816d242 --- /dev/null +++ b/utils/isHardhat.ts @@ -0,0 +1,5 @@ +import { network } from 'hardhat'; + +export const isHardhat = () => { + return network?.config?.forking?.enabled ?? false; +}; \ No newline at end of file diff --git a/utils/isTestnet.ts b/utils/isTestnet.ts new file mode 100644 index 0000000..a77f380 --- /dev/null +++ b/utils/isTestnet.ts @@ -0,0 +1,9 @@ +import { network } from 'hardhat'; + +export const isTestnet = () => { + const chainId = network.config.chainId ?? 1; + if (chainId === 1 || chainId === 137) { + return false; + } + return true; +}; \ No newline at end of file diff --git a/utils/verifyContract.ts b/utils/verifyContract.ts new file mode 100644 index 0000000..cb82933 --- /dev/null +++ b/utils/verifyContract.ts @@ -0,0 +1,13 @@ +import { run } from "hardhat"; + +export const verifyContract = async (contractName: string, contract: any, constructorArguments: any = []) => { + try { + const contractAddress = await contract.getAddress(); + console.log(` - Verifying contract "${contractName}" at address: ${contractAddress}`); + await run('verify:verify', { address: contractAddress, constructorArguments }); + console.log(` -- ${contractName} Verification Complete!\n`); + } catch ( err ) { + console.log(`[ERROR] Failed to Verify ${contractName}`); + console.log(err); + } +}; diff --git a/yarn.lock b/yarn.lock index 147af1b..21337ac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,6 +7,126 @@ resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.9.2.tgz#60111a5d9db45b2e5cbb6231b0bb8d97e8659316" integrity sha512-0h+FrQDqe2Wn+IIGFkTCd4aAwTJ+7834Ek1COohCyV26AXhwQ7WQaz+4F/nLOeVl/3BtWHOHLPsq46V8YB46Eg== +"@adraffy/ens-normalize@^1.8.8": + version "1.9.4" + resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.9.4.tgz#aae21cb858bbb0411949d5b7b3051f4209043f62" + integrity sha512-UK0bHA7hh9cR39V+4gl2/NnBBjoXIxkuWAPCaY4X7fbH4L/azIi7ilWOCjMUYfpJgraLUAqkRi2BqrjME8Rynw== + +"@aws-crypto/sha256-js@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-js/-/sha256-js-1.2.2.tgz#02acd1a1fda92896fc5a28ec7c6e164644ea32fc" + integrity sha512-Nr1QJIbW/afYYGzYvrF70LtaHrIRtd4TNAglX8BvlfxJLZ45SAmueIKYl5tWoNBPzp65ymXGFK0Bb1vZUpuc9g== + dependencies: + "@aws-crypto/util" "^1.2.2" + "@aws-sdk/types" "^3.1.0" + tslib "^1.11.1" + +"@aws-crypto/util@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@aws-crypto/util/-/util-1.2.2.tgz#b28f7897730eb6538b21c18bd4de22d0ea09003c" + integrity sha512-H8PjG5WJ4wz0UXAFXeJjWCW1vkvIJ3qUUD+rGRwJ2/hj+xT58Qle2MTql/2MGzkU+1JLAFuR6aJpLAjHwhmwwg== + dependencies: + "@aws-sdk/types" "^3.1.0" + "@aws-sdk/util-utf8-browser" "^3.0.0" + tslib "^1.11.1" + +"@aws-sdk/types@^3.1.0": + version "3.378.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.378.0.tgz#93a811ccdf15c81b1947f1cd67922c4690792189" + integrity sha512-qP0CvR/ItgktmN8YXpGQglzzR/6s0nrsQ4zIfx3HMwpsBTwuouYahcCtF1Vr82P4NFcoDA412EJahJ2pIqEd+w== + dependencies: + "@smithy/types" "^2.0.2" + tslib "^2.5.0" + +"@aws-sdk/util-utf8-browser@^3.0.0": + version "3.259.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz#3275a6f5eb334f96ca76635b961d3c50259fd9ff" + integrity sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw== + dependencies: + tslib "^2.3.1" + +"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730" + integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== + +"@babel/helper-compilation-targets@^7.22.6": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz#f9d0a7aaaa7cd32a3f31c9316a69f5a9bcacb892" + integrity sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-validator-option" "^7.22.5" + browserslist "^4.21.9" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-define-polyfill-provider@^0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz#82c825cadeeeee7aad237618ebbe8fa1710015d7" + integrity sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw== + dependencies: + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-plugin-utils" "^7.22.5" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + +"@babel/helper-module-imports@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" + integrity sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-plugin-utils@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + +"@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + +"@babel/helper-validator-identifier@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" + integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== + +"@babel/helper-validator-option@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" + integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== + +"@babel/plugin-transform-runtime@^7.5.5": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.9.tgz#a87b11e170cbbfb018e6a2bf91f5c6e533b9e027" + integrity sha512-9KjBH61AGJetCPYp/IEyLEp47SyybZb0nDRpBvmtEkm+rUIwxdlKpyNHI1TmsGkeuLclJdleQHRZ8XLBnnh8CQ== + dependencies: + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + babel-plugin-polyfill-corejs2 "^0.4.4" + babel-plugin-polyfill-corejs3 "^0.8.2" + babel-plugin-polyfill-regenerator "^0.5.1" + semver "^6.3.1" + +"@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.6.tgz#57d64b9ae3cff1d67eb067ae117dac087f5bd438" + integrity sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ== + dependencies: + regenerator-runtime "^0.13.11" + +"@babel/types@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.5.tgz#cd93eeaab025880a3a47ec881f4b096a5b786fbe" + integrity sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" + to-fast-properties "^2.0.0" + "@chainsafe/as-sha256@^0.3.1": version "0.3.1" resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz#3639df0e1435cab03f4d9870cc3ac079e57a6fc9" @@ -50,7 +170,79 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.0.0-beta.146", "@ethersproject/abi@^5.0.9", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.7.0": +"@ensdomains/address-encoder@^0.1.7": + version "0.1.9" + resolved "https://registry.yarnpkg.com/@ensdomains/address-encoder/-/address-encoder-0.1.9.tgz#f948c485443d9ef7ed2c0c4790e931c33334d02d" + integrity sha512-E2d2gP4uxJQnDu2Kfg1tHNspefzbLT8Tyjrm5sEuim32UkU2sm5xL4VXtgc2X33fmPEw9+jUMpGs4veMbf+PYg== + dependencies: + bech32 "^1.1.3" + blakejs "^1.1.0" + bn.js "^4.11.8" + bs58 "^4.0.1" + crypto-addr-codec "^0.1.7" + nano-base32 "^1.0.1" + ripemd160 "^2.0.2" + +"@ensdomains/ens@0.4.5": + version "0.4.5" + resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.5.tgz#e0aebc005afdc066447c6e22feb4eda89a5edbfc" + integrity sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw== + dependencies: + bluebird "^3.5.2" + eth-ens-namehash "^2.0.8" + solc "^0.4.20" + testrpc "0.0.1" + web3-utils "^1.0.0-beta.31" + +"@ensdomains/ensjs@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@ensdomains/ensjs/-/ensjs-2.1.0.tgz#0a7296c1f3d735ef019320d863a7846a0760c460" + integrity sha512-GRbGPT8Z/OJMDuxs75U/jUNEC0tbL0aj7/L/QQznGYKm/tiasp+ndLOaoULy9kKJFC0TBByqfFliEHDgoLhyog== + dependencies: + "@babel/runtime" "^7.4.4" + "@ensdomains/address-encoder" "^0.1.7" + "@ensdomains/ens" "0.4.5" + "@ensdomains/resolver" "0.2.4" + content-hash "^2.5.2" + eth-ens-namehash "^2.0.8" + ethers "^5.0.13" + js-sha3 "^0.8.0" + +"@ensdomains/resolver@0.2.4": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@ensdomains/resolver/-/resolver-0.2.4.tgz#c10fe28bf5efbf49bff4666d909aed0265efbc89" + integrity sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA== + +"@ethereumjs/common@2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.5.0.tgz#ec61551b31bef7a69d1dc634d8932468866a4268" + integrity sha512-DEHjW6e38o+JmB/NO3GZBpW4lpaiBpkFgXF6jLcJ6gETBYpEyaA5nTimsWBUJR3Vmtm/didUEbNjajskugZORg== + dependencies: + crc-32 "^1.2.0" + ethereumjs-util "^7.1.1" + +"@ethereumjs/common@^2.5.0": + version "2.6.5" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.6.5.tgz#0a75a22a046272579d91919cb12d84f2756e8d30" + integrity sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA== + dependencies: + crc-32 "^1.2.0" + ethereumjs-util "^7.1.5" + +"@ethereumjs/rlp@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-4.0.1.tgz#626fabfd9081baab3d0a3074b0c7ecaf674aaa41" + integrity sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw== + +"@ethereumjs/tx@3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.3.2.tgz#348d4624bf248aaab6c44fec2ae67265efe3db00" + integrity sha512-6AaJhwg4ucmwTvw/1qLaZUX5miWrwZ4nLOUsKyb/HtzS3BMw/CasKhdi1ims9mBKeK9sOJCH4qGKOBGyJCeeog== + dependencies: + "@ethereumjs/common" "^2.5.0" + ethereumjs-util "^7.1.2" + +"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.0.0-beta.146", "@ethersproject/abi@^5.0.9", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.6.3", "@ethersproject/abi@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== @@ -325,7 +517,7 @@ "@ethersproject/constants" "^5.7.0" "@ethersproject/logger" "^5.7.0" -"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.7.0": +"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.6.2", "@ethersproject/transactions@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== @@ -421,6 +613,18 @@ tweetnacl "^1.0.3" tweetnacl-util "^0.15.1" +"@metamask/safe-event-emitter@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@metamask/safe-event-emitter/-/safe-event-emitter-2.0.0.tgz#af577b477c683fad17c619a78208cede06f9605c" + integrity sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q== + +"@noble/curves@1.1.0", "@noble/curves@~1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d" + integrity sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA== + dependencies: + "@noble/hashes" "1.3.1" + "@noble/hashes@1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" @@ -431,6 +635,11 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12" integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ== +"@noble/hashes@1.3.1", "@noble/hashes@~1.3.0", "@noble/hashes@~1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" + integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== + "@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": version "1.7.1" resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" @@ -702,10 +911,135 @@ "@nomicfoundation/solidity-analyzer-win32-ia32-msvc" "0.1.1" "@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.1" -"@openzeppelin/contracts@^4.9.2": - version "4.9.2" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.2.tgz#1cb2d5e4d3360141a17dbc45094a8cad6aac16c1" - integrity sha512-mO+y6JaqXjWeMh9glYVzVu8HYPGknAAnWyxTRhGeckOruyXQMNnlcW6w/Dx9ftLeIQk6N+ZJFuVmTwF7lEIFrg== +"@openeth/truffle-typings@0.0.6": + version "0.0.6" + resolved "https://registry.yarnpkg.com/@openeth/truffle-typings/-/truffle-typings-0.0.6.tgz#80bf9969d6287f7a86fad3439556fd59f3b0f67a" + integrity sha512-GWFDMVmisKDLTqIg0dZO3Wkri/EW8KNsETqoQB6iyAf/ULPxcAdMy5fCt02GlarL32s87M+B9kNbJ6znmDIWsw== + dependencies: + "@types/chai" "^4.1.4" + "@types/mocha" "^5.2.5" + "@types/web3" "^1.2.2" + web3 "1.2.6" + +"@opengsn/gsn@2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@opengsn/gsn/-/gsn-2.0.1.tgz#bf77894257d8d0015948215a3ba4759d085873e1" + integrity sha512-AHEU2SOYTxXiTlLtFGpF0p3S6mflPb1ajh4zvQPv890RNsXMqc9U3VsZ5q6HZXpooE7HOkEUHrQtqgT0rJdXGA== + dependencies: + "@openeth/truffle-typings" "0.0.6" + "@openzeppelin/contracts" "^3.2.0" + "@truffle/contract" "^4.2.23" + "@truffle/hdwallet-provider" "1.0.34" + "@types/chai" "^4.2.12" + "@types/chai-as-promised" "^7.1.3" + "@types/cors" "^2.8.7" + "@types/eth-sig-util" "2.1.0" + "@types/express" "^4.17.8" + "@types/lodash" "^4.14.161" + "@types/minimist" "^1.2.0" + "@types/nedb" "^1.8.11" + "@types/node" "^13.0.0" + "@types/semver" "^7.3.4" + "@types/sinon" "^9.0.0" + "@types/sinon-chai" "^3.2.5" + "@types/web3" "1.2.2" + "@types/web3-provider-engine" "^14.0.0" + abi-decoder "^2.3.0" + async-mutex "^0.2.4" + axios "^0.20.0" + bn.js "5.1.2" + body-parser "^1.19.0" + chai "^4.2.0" + chalk "^4.1.0" + commander "^6.1.0" + console-read-write "^0.1.1" + date-format "^3.0.0" + eth-sig-util "2.5.2" + ethereumjs-common "^1.5.2" + ethereumjs-tx "^2.1.2" + ethereumjs-util "^6.2.1" + ethereumjs-wallet "0.6.3" + ethval "^2.1.1" + express "^4.17.1" + jsonrpc-lite "^2.2.0" + lodash "^4.17.20" + loglevel "^1.7.0" + minimist "^1.2.5" + nedb-async "^0.1.3" + ow "^0.17.0" + patch-package "^6.2.2" + semver "^7.3.2" + web3 "1.2.6" + web3-core "1.2.6" + web3-core-helpers "1.2.6" + web3-eth "1.2.6" + web3-eth-abi "1.2.6" + web3-eth-contract "1.2.6" + web3-utils "1.2.6" + +"@openzeppelin/contracts-upgradeable@^3.3.0": + version "3.4.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-3.4.2.tgz#2c2a1b0fa748235a1f495b6489349776365c51b3" + integrity sha512-mDlBS17ymb2wpaLcrqRYdnBAmP1EwqhOXMvqWk2c5Q1N1pm5TkiCtXM9Xzznh4bYsQBq0aIWEkFFE2+iLSN1Tw== + +"@openzeppelin/contracts@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.1.0.tgz#bcea457ef89069fbe5a617f50b25b6a8272895d5" + integrity sha512-dVXDnUKxrAKLzPdCRkz+N8qsVkK1XxJ6kk3zuI6zaQmcKxN7CkizoDP7lXxcs/Mi2I0mxceTRjJBqlzFffLJrQ== + +"@openzeppelin/contracts@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.2.0.tgz#3e6b3a7662d8ed64271ade96ef42655db983fd9d" + integrity sha512-bUOmkSoPkjnUyMiKo6RYnb0VHBk5D9KKDAgNLzF41aqAM3TeE0yGdFF5dVRcV60pZdJLlyFT/jjXIZCWyyEzAQ== + +"@openzeppelin/defender-base-client@^1.47.0": + version "1.47.1" + resolved "https://registry.yarnpkg.com/@openzeppelin/defender-base-client/-/defender-base-client-1.47.1.tgz#2044fd048d73778a42eb0c5ae6f1370d0ab4bac9" + integrity sha512-xnopi1tZIh1zY9KF3mo9S2YgMP0I3T11r6jiO1teAw6M0U5Fx2SCjfCVoKV7CLAQGH1VHmAZ7w2CmcEsFvlQng== + dependencies: + amazon-cognito-identity-js "^6.0.1" + async-retry "^1.3.3" + axios "^1.4.0" + lodash "^4.17.19" + node-fetch "^2.6.0" + +"@openzeppelin/hardhat-upgrades@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-2.1.0.tgz#cb77e212b7e21f8a98c4fbdf6aad730f9e988153" + integrity sha512-cHwWbm5YeRde9y37Tcx9o0xc+hE7t+CrxDAdHt+USELW5agi6IaVECpgtVjPhhpfLR8UDJvSggzaP4HAqQhZtQ== + dependencies: + "@openzeppelin/defender-base-client" "^1.47.0" + "@openzeppelin/platform-deploy-client" "^0.9.0" + "@openzeppelin/upgrades-core" "^1.27.0" + chalk "^4.1.0" + debug "^4.1.1" + proper-lockfile "^4.1.1" + undici "^5.14.0" + +"@openzeppelin/platform-deploy-client@^0.9.0": + version "0.9.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/platform-deploy-client/-/platform-deploy-client-0.9.0.tgz#6d7092066d1c5cf4c25ba6f9d8164e8d1c425b61" + integrity sha512-VepsNJu5B5xhrKMg//hROFljlxlNhlkcgLSKl8rqapKiRFN/dxXtSVmmpNmySrCFnbbV/6twfhuhYGAZiG7oAw== + dependencies: + "@ethersproject/abi" "^5.6.3" + "@openzeppelin/defender-base-client" "^1.47.0" + axios "^1.4.0" + lodash "^4.17.19" + node-fetch "^2.6.0" + +"@openzeppelin/upgrades-core@^1.27.0": + version "1.28.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/upgrades-core/-/upgrades-core-1.28.0.tgz#19405f272dc09e766c756d9d149cbd680168aef7" + integrity sha512-8RKlyg98Adv+46GxDaR0awL3R8bVCcQ27DcSEwrgWOp6siHh8sZg4a2l+2dhPl1510S6uBfhHSydMH5VX2BV5g== + dependencies: + cbor "^9.0.0" + chalk "^4.1.0" + compare-versions "^6.0.0" + debug "^4.1.1" + ethereumjs-util "^7.0.3" + minimist "^1.2.7" + proper-lockfile "^4.1.1" + solidity-ast "^0.4.26" "@scure/base@~1.1.0": version "1.1.1" @@ -721,6 +1055,15 @@ "@noble/secp256k1" "~1.7.0" "@scure/base" "~1.1.0" +"@scure/bip32@1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.1.tgz#7248aea723667f98160f593d621c47e208ccbb10" + integrity sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A== + dependencies: + "@noble/curves" "~1.1.0" + "@noble/hashes" "~1.3.1" + "@scure/base" "~1.1.0" + "@scure/bip39@1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.1.tgz#b54557b2e86214319405db819c4b6a370cf340c5" @@ -729,6 +1072,14 @@ "@noble/hashes" "~1.2.0" "@scure/base" "~1.1.0" +"@scure/bip39@1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.1.tgz#5cee8978656b272a917b7871c981e0541ad6ac2a" + integrity sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg== + dependencies: + "@noble/hashes" "~1.3.0" + "@scure/base" "~1.1.0" + "@sentry/core@5.30.0": version "5.30.0" resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" @@ -797,6 +1148,23 @@ "@sentry/types" "5.30.0" tslib "^1.9.3" +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + +"@sindresorhus/is@^4.0.0", "@sindresorhus/is@^4.6.0": + version "4.6.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" + integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== + +"@smithy/types@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@smithy/types/-/types-2.0.2.tgz#49d42724c909e845bfd80a2e195740614ce497f3" + integrity sha512-wcymEjIXQ9+NEfE5Yt5TInAqe1o4n+Nh+rh00AwoazppmUt8tdo6URhc5gkDcOYrcvlDVAZE7uG69nDpEGUKxw== + dependencies: + tslib "^2.5.0" + "@solidity-parser/parser@^0.14.0", "@solidity-parser/parser@^0.14.1": version "0.14.5" resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.14.5.tgz#87bc3cc7b068e08195c219c91cd8ddff5ef1a804" @@ -804,6 +1172,149 @@ dependencies: antlr4ts "^0.5.0-alpha.4" +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + dependencies: + defer-to-connect "^1.0.1" + +"@szmarczak/http-timer@^4.0.5": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" + integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== + dependencies: + defer-to-connect "^2.0.0" + +"@szmarczak/http-timer@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a" + integrity sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw== + dependencies: + defer-to-connect "^2.0.1" + +"@truffle/abi-utils@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@truffle/abi-utils/-/abi-utils-1.0.1.tgz#bf72d595f2eb03905429210b394f416fb774a61e" + integrity sha512-ZQUY3XUxEPdqxNaoXsOqF0spTtb6f5RNlnN4MUrVsJ64sOh0FJsY7rxZiUI3khfePmNh4i2qcJrQlKT36YcWUA== + dependencies: + change-case "3.0.2" + fast-check "3.1.1" + web3-utils "1.10.0" + +"@truffle/blockchain-utils@^0.1.8": + version "0.1.8" + resolved "https://registry.yarnpkg.com/@truffle/blockchain-utils/-/blockchain-utils-0.1.8.tgz#0c1a369aa72f51df5af095678803242ea0a0d6ae" + integrity sha512-ZskpYDNHkXD3ota4iU3pZz6kLth87RC+wDn66Rp2Or+DqqJCKdnmS9GDctBi1EcMPDEi0BqpkdrfBuzA9uIkGg== + +"@truffle/codec@^0.17.1": + version "0.17.1" + resolved "https://registry.yarnpkg.com/@truffle/codec/-/codec-0.17.1.tgz#08673f3a5a89cf2835d7e816e63fee234d6ff56d" + integrity sha512-f45cuhg92vM2N+ah3Bvm+uxiw/wc6a9o5gKJNqb8oMPCLYRGV4sQXTnNaAlFP1BBxFriciH3kwYt5xPrL39SgA== + dependencies: + "@truffle/abi-utils" "^1.0.1" + "@truffle/compile-common" "^0.9.6" + big.js "^6.0.3" + bn.js "^5.1.3" + cbor "^5.2.0" + debug "^4.3.1" + lodash "^4.17.21" + semver "7.5.2" + utf8 "^3.0.0" + web3-utils "1.10.0" + +"@truffle/compile-common@^0.9.6": + version "0.9.6" + resolved "https://registry.yarnpkg.com/@truffle/compile-common/-/compile-common-0.9.6.tgz#037d74bc00ded33b9212d886531c2cee998662da" + integrity sha512-TCcmr1E0GqMZJ2tOaCRNEllxTBJ/g7TuD6jDJpw5Gt9Bw0YO3Cmp6yPQRynRSO4xMJbHUgiEsSfRgIhswut5UA== + dependencies: + "@truffle/error" "^0.2.1" + colors "1.4.0" + +"@truffle/contract-schema@^3.4.14": + version "3.4.14" + resolved "https://registry.yarnpkg.com/@truffle/contract-schema/-/contract-schema-3.4.14.tgz#ded13d54daa7621dc9894fa7bf813f557e025b58" + integrity sha512-IwVQZG9RVNwTdn321+jbFIcky3/kZLkCtq8tqil4jZwivvmZQg8rIVC8GJ7Lkrmixl9/yTyQNL6GtIUUvkZxyA== + dependencies: + ajv "^6.10.0" + debug "^4.3.1" + +"@truffle/contract@^4.2.23": + version "4.6.27" + resolved "https://registry.yarnpkg.com/@truffle/contract/-/contract-4.6.27.tgz#3b612d89583059e677e34be3b994900c49f2a25c" + integrity sha512-B02sH1TlMqsOsGRpBOEQtGZxcF9BuECGF0duks12sYR/3nU0TdVd2NP25WXo+2GTrUcU6eCTMaWhBPjFyDUSaQ== + dependencies: + "@ensdomains/ensjs" "^2.1.0" + "@truffle/blockchain-utils" "^0.1.8" + "@truffle/contract-schema" "^3.4.14" + "@truffle/debug-utils" "^6.0.55" + "@truffle/error" "^0.2.1" + "@truffle/interface-adapter" "^0.5.35" + bignumber.js "^7.2.1" + debug "^4.3.1" + ethers "^4.0.32" + web3 "1.10.0" + web3-core-helpers "1.10.0" + web3-core-promievent "1.10.0" + web3-eth-abi "1.10.0" + web3-utils "1.10.0" + +"@truffle/debug-utils@^6.0.55": + version "6.0.55" + resolved "https://registry.yarnpkg.com/@truffle/debug-utils/-/debug-utils-6.0.55.tgz#fea70dc9dcdf8676cd6b343730f9852febb41b24" + integrity sha512-53zbPdPCMFx/M4dYWnpzIsY3ndFv3X7BhgB9QIquazmAupwaZpkUJXWmXOPqoB7u6bQXnXYjTuE1V1WmFi/ozw== + dependencies: + "@truffle/codec" "^0.17.1" + "@trufflesuite/chromafi" "^3.0.0" + bn.js "^5.1.3" + chalk "^2.4.2" + debug "^4.3.1" + highlightjs-solidity "^2.0.6" + +"@truffle/error@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@truffle/error/-/error-0.2.1.tgz#71bb8e777a832e0cfe09a8638a70a5177aad8628" + integrity sha512-5Qy+z9dg9hP37WNdLnXH4b9MzemWrjTufRq7/DTKqimjyxCP/1zlL8gQEMdiSx1BBtAZz0xypkID/jb7AF/Osg== + +"@truffle/hdwallet-provider@1.0.34": + version "1.0.34" + resolved "https://registry.yarnpkg.com/@truffle/hdwallet-provider/-/hdwallet-provider-1.0.34.tgz#1e642c415c28e9ae3bb8142bbdbc8506adaaa06a" + integrity sha512-sy7sismdclvzWQmHDjElqPGoU1+ff4w3nODKqBpauacAYpWngu865CrtgRNnETZ1c90zDElU41V6yWrUgKupAQ== + dependencies: + any-promise "^1.3.0" + bindings "^1.5.0" + bip39 "^2.4.2" + ethereum-protocol "^1.0.1" + ethereumjs-tx "^1.0.0" + ethereumjs-util "^6.1.0" + ethereumjs-wallet "^0.6.3" + source-map-support "^0.5.16" + web3 "1.2.1" + web3-provider-engine "https://github.com/trufflesuite/provider-engine#web3-one" + +"@truffle/interface-adapter@^0.5.35": + version "0.5.35" + resolved "https://registry.yarnpkg.com/@truffle/interface-adapter/-/interface-adapter-0.5.35.tgz#f0eb1c4a2803190ca249143f545029a8b641fe96" + integrity sha512-B5gtJnvsum5j2do393n0UfCT8MklrlAZxuqvEFBeMM9UKnreYct0/D368FVMlZwWo1N50HgGeZ0hlpSJqR/nvg== + dependencies: + bn.js "^5.1.3" + ethers "^4.0.32" + web3 "1.10.0" + +"@trufflesuite/chromafi@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@trufflesuite/chromafi/-/chromafi-3.0.0.tgz#f6956408c1af6a38a6ed1657783ce59504a1eb8b" + integrity sha512-oqWcOqn8nT1bwlPPfidfzS55vqcIDdpfzo3HbU9EnUmcSTX+I8z0UyUFI3tZQjByVJulbzxHxUGS3ZJPwK/GPQ== + dependencies: + camelcase "^4.1.0" + chalk "^2.3.2" + cheerio "^1.0.0-rc.2" + detect-indent "^5.0.0" + highlight.js "^10.4.1" + lodash.merge "^4.6.2" + strip-ansi "^4.0.0" + strip-indent "^2.0.0" + "@tsconfig/node10@^1.0.7": version "1.0.9" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" @@ -839,20 +1350,38 @@ dependencies: fs-extra "^9.1.0" -"@types/bn.js@^4.11.3": +"@types/bn.js@^4.11.3", "@types/bn.js@^4.11.4": version "4.11.6" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== dependencies: "@types/node" "*" -"@types/bn.js@^5.1.0": +"@types/bn.js@^5.1.0", "@types/bn.js@^5.1.1": version "5.1.1" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682" integrity sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g== dependencies: "@types/node" "*" +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/cacheable-request@^6.0.1", "@types/cacheable-request@^6.0.2": + version "6.0.3" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183" + integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw== + dependencies: + "@types/http-cache-semantics" "*" + "@types/keyv" "^3.1.4" + "@types/node" "*" + "@types/responselike" "^1.0.0" + "@types/chai-as-promised@^7.1.3": version "7.1.5" resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz#6e016811f6c7a64f2eed823191c3a6955094e255" @@ -860,7 +1389,7 @@ dependencies: "@types/chai" "*" -"@types/chai@*", "@types/chai@^4.2.0": +"@types/chai@*", "@types/chai@^4.1.4", "@types/chai@^4.2.0", "@types/chai@^4.2.12": version "4.3.5" resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.5.tgz#ae69bcbb1bebb68c4ac0b11e9d8ed04526b3562b" integrity sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng== @@ -872,6 +1401,54 @@ dependencies: "@types/node" "*" +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/cors@^2.8.7": + version "2.8.13" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.13.tgz#b8ade22ba455a1b8cb3b5d3f35910fd204f84f94" + integrity sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA== + dependencies: + "@types/node" "*" + +"@types/eth-sig-util@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/eth-sig-util/-/eth-sig-util-2.1.0.tgz#54497e9c01b5ee3a60475686cce1a20ddccc358b" + integrity sha512-GWX0s/FFGWl6lO2nbd9nq3fh1x47vmLL/p4yDG1+VgCqrip1ErQrbHlTZThtEc6JrcmwCKB2H1de32Hdo3JdJg== + dependencies: + "@types/node" "*" + +"@types/ethereum-protocol@*": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/ethereum-protocol/-/ethereum-protocol-1.0.2.tgz#e765d4c6f4b5ebe906932bd20333e307c56a9bc7" + integrity sha512-Ri/hwt4UckZlF7eqhhAQcXsNvcgQmSJOKZteLco1/5NsRcneW/cJuQcrQNILN2Ohs9WUQjeGW3ZRRNqkEVMzuQ== + dependencies: + bignumber.js "7.2.1" + +"@types/express-serve-static-core@^4.17.33": + version "4.17.35" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz#c95dd4424f0d32e525d23812aa8ab8e4d3906c4f" + integrity sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + +"@types/express@^4.17.8": + version "4.17.17" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.17.tgz#01d5437f6ef9cfa8668e616e13c2f2ac9a491ae4" + integrity sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "*" + "@types/form-data@0.0.33": version "0.0.33" resolved "https://registry.yarnpkg.com/@types/form-data/-/form-data-0.0.33.tgz#c9ac85b2a5fd18435b8c85d9ecb50e6d6c893ff8" @@ -887,21 +1464,70 @@ "@types/minimatch" "*" "@types/node" "*" +"@types/http-cache-semantics@*": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" + integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== + +"@types/http-errors@*": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.1.tgz#20172f9578b225f6c7da63446f56d4ce108d5a65" + integrity sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ== + +"@types/keyv@^3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" + integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== + dependencies: + "@types/node" "*" + +"@types/lodash@^4.14.161": + version "4.14.196" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.196.tgz#a7c3d6fc52d8d71328b764e28e080b4169ec7a95" + integrity sha512-22y3o88f4a94mKljsZcanlNWPzO0uBsBdzLAngf2tp533LzZcQzb6+eZPJ+vCTt+bqF2XnvT9gejTLsAcJAJyQ== + "@types/lru-cache@^5.1.0": version "5.1.1" resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef" integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw== +"@types/mime@*": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" + integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== + +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + "@types/minimatch@*": version "5.1.2" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== +"@types/minimist@^1.2.0": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" + integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== + "@types/mocha@>=9.1.0": version "10.0.1" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.1.tgz#2f4f65bb08bc368ac39c96da7b2f09140b26851b" integrity sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q== +"@types/mocha@^5.2.5": + version "5.2.7" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.7.tgz#315d570ccb56c53452ff8638738df60726d5b6ea" + integrity sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ== + +"@types/nedb@^1.8.11": + version "1.8.13" + resolved "https://registry.yarnpkg.com/@types/nedb/-/nedb-1.8.13.tgz#31c608d5b155d33b3c98b946339086703d215865" + integrity sha512-x/aIeHmmiDq1kMzgHvjygxl5RZGzIabFcq2HpRzB3X26AdfPg5Y70EwWrcZM/TuJwNHtWRruD/telSTvPEY6Xw== + dependencies: + "@types/node" "*" + "@types/node@*", "@types/node@>=12.0.0": version "20.3.2" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.2.tgz#fa6a90f2600e052a03c18b8cb3fd83dd4e599898" @@ -912,11 +1538,21 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== -"@types/node@^10.0.3": +"@types/node@^10.0.3", "@types/node@^10.12.18", "@types/node@^10.3.2": version "10.17.60" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== +"@types/node@^12.12.6", "@types/node@^12.6.1": + version "12.20.55" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" + integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== + +"@types/node@^13.0.0": + version "13.13.52" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.52.tgz#03c13be70b9031baaed79481c0c0cfb0045e53f7" + integrity sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ== + "@types/node@^8.0.0": version "8.10.66" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3" @@ -934,11 +1570,16 @@ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== -"@types/qs@^6.2.31", "@types/qs@^6.9.7": +"@types/qs@*", "@types/qs@^6.2.31", "@types/qs@^6.9.7": version "6.9.7" resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + "@types/readable-stream@^2.3.13": version "2.3.15" resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.15.tgz#3d79c9ceb1b6a57d5f6e6976f489b9b5384321ae" @@ -947,6 +1588,13 @@ "@types/node" "*" safe-buffer "~5.1.1" +"@types/responselike@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" + integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== + dependencies: + "@types/node" "*" + "@types/secp256k1@^4.0.1": version "4.0.3" resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.3.tgz#1b8e55d8e00f08ee7220b4d59a6abe89c37a901c" @@ -954,6 +1602,100 @@ dependencies: "@types/node" "*" +"@types/semver@^7.3.4": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" + integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== + +"@types/send@*": + version "0.17.1" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.1.tgz#ed4932b8a2a805f1fe362a70f4e62d0ac994e301" + integrity sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/serve-static@*": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.2.tgz#3e5419ecd1e40e7405d34093f10befb43f63381a" + integrity sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw== + dependencies: + "@types/http-errors" "*" + "@types/mime" "*" + "@types/node" "*" + +"@types/sinon-chai@^3.2.5": + version "3.2.9" + resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-3.2.9.tgz#71feb938574bbadcb176c68e5ff1a6014c5e69d4" + integrity sha512-/19t63pFYU0ikrdbXKBWj9PCdnKyTd0Qkz0X91Ta081cYsq90OxYdcWwK/dwEoDa6dtXgj2HJfmzgq+QZTHdmQ== + dependencies: + "@types/chai" "*" + "@types/sinon" "*" + +"@types/sinon@*": + version "10.0.16" + resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-10.0.16.tgz#4bf10313bd9aa8eef1e50ec9f4decd3dd455b4d3" + integrity sha512-j2Du5SYpXZjJVJtXBokASpPRj+e2z+VUhCPHmM6WMfe3dpHu6iVKJMU6AiBcMp/XTAYnEj6Wc1trJUWwZ0QaAQ== + dependencies: + "@types/sinonjs__fake-timers" "*" + +"@types/sinon@^9.0.0": + version "9.0.11" + resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-9.0.11.tgz#7af202dda5253a847b511c929d8b6dda170562eb" + integrity sha512-PwP4UY33SeeVKodNE37ZlOsR9cReypbMJOhZ7BVE0lB+Hix3efCOxiJWiE5Ia+yL9Cn2Ch72EjFTRze8RZsNtg== + dependencies: + "@types/sinonjs__fake-timers" "*" + +"@types/sinonjs__fake-timers@*": + version "8.1.2" + resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz#bf2e02a3dbd4aecaf95942ecd99b7402e03fad5e" + integrity sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA== + +"@types/web3-provider-engine@^14.0.0": + version "14.0.1" + resolved "https://registry.yarnpkg.com/@types/web3-provider-engine/-/web3-provider-engine-14.0.1.tgz#9ceb76af025e9359a28cff1f0fc4c19070c40ab7" + integrity sha512-SaAfLJY/40wKFDsNFwaNfwqFSL6kVhTx9JD18qM+Gaw1qdAXLYF/6E7TIqWEdoG4so6fki/zxURP5NsoCePYJw== + dependencies: + "@types/ethereum-protocol" "*" + +"@types/web3@1.2.2", "@types/web3@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@types/web3/-/web3-1.2.2.tgz#d95a101547ce625c5ebd0470baa5dbd4b9f3c015" + integrity sha512-eFiYJKggNrOl0nsD+9cMh2MLk4zVBfXfGnVeRFbpiZzBE20eet4KLA3fXcjSuHaBn0RnQzwLAGdgzgzdet4C0A== + dependencies: + web3 "*" + +"@types/ws@^8.5.3": + version "8.5.5" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.5.tgz#af587964aa06682702ee6dcbc7be41a80e4b28eb" + integrity sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg== + dependencies: + "@types/node" "*" + +"@web3-js/scrypt-shim@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@web3-js/scrypt-shim/-/scrypt-shim-0.1.0.tgz#0bf7529ab6788311d3e07586f7d89107c3bea2cc" + integrity sha512-ZtZeWCc/s0nMcdx/+rZwY1EcuRdemOK9ag21ty9UsHkFxsNb/AaoucUz0iPuyGe0Ku+PFuRmWZG7Z7462p9xPw== + dependencies: + scryptsy "^2.1.0" + semver "^6.3.0" + +"@web3-js/websocket@^1.0.29": + version "1.0.30" + resolved "https://registry.yarnpkg.com/@web3-js/websocket/-/websocket-1.0.30.tgz#9ea15b7b582cf3bf3e8bc1f4d3d54c0731a87f87" + integrity sha512-fDwrD47MiDrzcJdSeTLF75aCcxVVt8B1N74rA+vh2XCAvFy4tEWJjtnUtj2QG7/zlQ6g9cQ88bZFBxwd9/FmtA== + dependencies: + debug "^2.2.0" + es5-ext "^0.10.50" + nan "^2.14.0" + typedarray-to-buffer "^3.1.5" + yaeti "^0.0.6" + +"@yarnpkg/lockfile@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" + integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -964,6 +1706,14 @@ abbrev@1.0.x: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" integrity sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q== +abi-decoder@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/abi-decoder/-/abi-decoder-2.4.0.tgz#99f72337c614d6ac45a28dbc83c08b44eba48ad5" + integrity sha512-TOLU2q1HgYOjs1GKGtVzaqrYkar6I2fT9a80rzx6/9EJ/5crb4nCGuro0grZayixem93T7omrajYmLiMkYDLDA== + dependencies: + web3-eth-abi "^1.2.1" + web3-utils "^1.2.1" + abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -971,6 +1721,11 @@ abort-controller@^3.0.0: dependencies: event-target-shim "^5.0.0" +abortcontroller-polyfill@^1.7.3: + version "1.7.5" + resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz#6738495f4e901fbb57b6c0611d0c75f76c485bed" + integrity sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ== + abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.3.tgz#78a67d3d84da55ee15201486ab44c09560070741" @@ -984,6 +1739,28 @@ abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: module-error "^1.0.1" queue-microtask "^1.2.3" +abstract-leveldown@~2.6.0: + version "2.6.3" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz#1c5e8c6a5ef965ae8c35dfb3a8770c476b82c4b8" + integrity sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA== + dependencies: + xtend "~4.0.0" + +abstract-leveldown@~2.7.1: + version "2.7.2" + resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz#87a44d7ebebc341d59665204834c8b7e0932cc93" + integrity sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w== + dependencies: + xtend "~4.0.0" + +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + acorn-walk@^8.1.1: version "8.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" @@ -1014,6 +1791,11 @@ aes-js@4.0.0-beta.5: resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-4.0.0-beta.5.tgz#8d2452c52adedebc3a3e28465d858c11ca315873" integrity sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q== +aes-js@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a" + integrity sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ== + agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -1029,7 +1811,7 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -ajv@^6.12.3: +ajv@^6.10.0, ajv@^6.12.3: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1049,6 +1831,17 @@ ajv@^8.0.1: require-from-string "^2.0.2" uri-js "^4.2.2" +amazon-cognito-identity-js@^6.0.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/amazon-cognito-identity-js/-/amazon-cognito-identity-js-6.3.1.tgz#d9a4c1a92f4b059330df8ea075f65106d2605409" + integrity sha512-PxBdufgS8uZShrcIFAsRjmqNXsh/4fXOWUGQOUhKLHWWK1pcp/y+VeFF48avXIWefM8XwsT3JlN6m9J2eHt4LA== + dependencies: + "@aws-crypto/sha256-js" "1.2.2" + buffer "4.9.2" + fast-base64-decode "^1.0.0" + isomorphic-unfetch "^3.0.0" + js-cookie "^2.2.1" + amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" @@ -1076,6 +1869,11 @@ ansi-escapes@^4.3.0: dependencies: type-fest "^0.21.3" +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== + ansi-regex@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" @@ -1091,6 +1889,11 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA== + ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -1110,6 +1913,11 @@ antlr4ts@^0.5.0-alpha.4: resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ== +any-promise@1.3.0, any-promise@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + anymatch@~3.1.1, anymatch@~3.1.2: version "3.1.3" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" @@ -1153,6 +1961,11 @@ array-buffer-byte-length@^1.0.0: call-bind "^1.0.2" is-array-buffer "^3.0.1" +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -1179,6 +1992,16 @@ asap@~2.0.6: resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== +asn1.js@^5.2.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" + asn1@~0.2.3: version "0.2.6" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" @@ -1201,11 +2024,49 @@ astral-regex@^2.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== -async@1.x: +async-eventemitter@^0.2.2: + version "0.2.4" + resolved "https://registry.yarnpkg.com/async-eventemitter/-/async-eventemitter-0.2.4.tgz#f5e7c8ca7d3e46aab9ec40a292baf686a0bafaca" + integrity sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw== + dependencies: + async "^2.4.0" + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +async-mutex@^0.2.4, async-mutex@^0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.2.6.tgz#0d7a3deb978bc2b984d5908a2038e1ae2e54ff40" + integrity sha512-Hs4R+4SPgamu6rSGW8C7cV9gaWUKEHykfzCCvIRuaVv636Ju10ZdeUbvb4TBEW0INuq2DHZqXbK4Nd3yG4RaRw== + dependencies: + tslib "^2.0.0" + +async-retry@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.3.3.tgz#0e7f36c04d8478e7a58bdbed80cedf977785f280" + integrity sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw== + dependencies: + retry "0.13.1" + +async@0.2.10: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + integrity sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ== + +async@1.x, async@^1.4.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" integrity sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w== +async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0: + version "2.6.4" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" + integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== + dependencies: + lodash "^4.17.14" + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -1221,6 +2082,11 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== +await-lock@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/await-lock/-/await-lock-1.1.3.tgz#e059319aa8212dab51a1a3dd2d888145b9fa40db" + integrity sha512-e0jRB8X/VVxulahjW16cM1dHsO7xjyZBP8p2AnVmg2Vn3q5xJ5sTUAybmkp96+s+QcrtidSJqpCGfWhVOX7NGg== + aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" @@ -1231,6 +2097,13 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== +axios@^0.20.0: + version "0.20.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.20.0.tgz#057ba30f04884694993a8cd07fa394cff11c50bd" + integrity sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA== + dependencies: + follow-redirects "^1.10.0" + axios@^0.21.1: version "0.21.4" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" @@ -1238,20 +2111,579 @@ axios@^0.21.1: dependencies: follow-redirects "^1.14.0" -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +axios@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f" + integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" -base-x@^3.0.2: - version "3.0.9" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" - integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== +babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g== dependencies: - safe-buffer "^5.0.1" + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.0.14, babel-core@^6.26.0: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.1" + debug "^2.6.9" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.8" + slash "^1.0.0" + source-map "^0.5.7" + +babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + integrity sha512-gCtfYORSG1fUMX4kKraymq607FWgMWg+j42IFPc18kFQEsmtaibP4UrqsXt8FlEJle25HUd4tsoDR7H2wDhe9Q== + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + integrity sha512-RL8n2NiEj+kKztlrVJM9JT1cXzzAdvWFh76xh/H1I4nKwunzE4INBXn8ieCZ+wh4zWszZk7NBS1s/8HR5jDkzQ== + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + integrity sha512-bHkmjcC9lM1kmZcVpA5t2om2nzT/xiZpo6TJq7UlZ3wqKfzia4veeXbIhKvJXAMzhhEBd3cR1IElL5AenWEUpA== + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + integrity sha512-qe5csbhbvq6ccry9G7tkXbzNtcDiH4r51rrPUbwwoTzZ18AqxWYRZT6AOmxrpxKnQBW0pYlBI/8vh73Z//78nQ== + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + integrity sha512-Oo6+e2iX+o9eVvJ9Y5eKL5iryeRdsIkwRYheCuhYdVHsdEQysbc2z2QkqCLIYnNxkT5Ss3ggrHdXiDI7Dhrn4Q== + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + integrity sha512-WfgKFX6swFB1jS2vo+DwivRN4NB8XUdM3ij0Y1gnC21y1tdBoe6xjVnd7NSI6alv+gZXCtJqvrTeMW3fR/c0ng== + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + integrity sha512-zAYl3tqerLItvG5cKYw7f1SpvIxS9zi7ohyGHaI9cgDUjAT6YcY9jIEH5CstetP5wHIVSceXwNS7Z5BpJg+rOw== + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + integrity sha512-Op9IhEaxhbRT8MDXx2iNuMgciu2V8lDvYCNQbDGjdBNCjaMvyLf4wl4A3b8IgndCyQF8TwfgsQ8T3VD8aX1/pA== + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + integrity sha512-VlPiWmqmGJp0x0oK27Out1D+71nVVCTSdlbhIVoaBAj2lUgrNjBCRR9+llO4lTSb2O4r7PJg+RobRkhBrf6ofg== + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + integrity sha512-RYqaPD0mQyQIFRu7Ho5wE2yvA/5jxqCIj/Lv4BXNq23mHYu/vxikOy2JueLiBxQknwapwrJeNCesvY0ZcfnlHg== + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + integrity sha512-sLI+u7sXJh6+ToqDr57Bv973kCepItDhMou0xCP2YPVmR1jkHSCY+p1no8xErbV1Siz5QE8qKT1WIwybSWlqjw== + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + integrity sha512-n7pFrqQm44TCYvrCDb0MqabAF+JUBq+ijBvNMUxpkLjJaAu32faIexewMumrH5KLLJ1HDyT0PTEqRyAe/GwwuQ== + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + integrity sha512-B1M5KBP29248dViEo1owyY32lk1ZSH2DaNNrXLGt8lyjjHm7pBqAdQ7VKUPR6EEDO323+OvT3MQXbCin8ooWdA== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-polyfill-corejs2@^0.4.4: + version "0.4.5" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz#8097b4cb4af5b64a1d11332b6fb72ef5e64a054c" + integrity sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg== + dependencies: + "@babel/compat-data" "^7.22.6" + "@babel/helper-define-polyfill-provider" "^0.4.2" + semver "^6.3.1" + +babel-plugin-polyfill-corejs3@^0.8.2: + version "0.8.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.3.tgz#b4f719d0ad9bb8e0c23e3e630c0c8ec6dd7a1c52" + integrity sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.4.2" + core-js-compat "^3.31.0" + +babel-plugin-polyfill-regenerator@^0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz#80d0f3e1098c080c8b5a65f41e9427af692dc326" + integrity sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.4.2" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + integrity sha512-4Zp4unmHgw30A1eWI5EpACji2qMocisdXhAftfhXoSV9j0Tvj6nRFE3tOmRY912E0FMRm/L5xWE7MGVT2FoLnw== + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + integrity sha512-Z/flU+T9ta0aIEKl1tGEmN/pZiI1uXmCiGFRegKacQfEJzp7iNsKloZmyJlQr+75FCJtiFfGIK03SiCvCt9cPQ== + +babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + integrity sha512-Gx9CH3Q/3GKbhs07Bszw5fPTlU+ygrOGfAhEt7W2JICwufpC4SuO0mG0+4NykPBSYPMJhqvVlDBU17qB1D+hMQ== + +babel-plugin-transform-async-to-generator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + integrity sha512-7BgYJujNCg0Ti3x0c/DL3tStvnKS6ktIYOmo9wginv/dfZOrbSZ+qG4IRRHMBOzZ5Awb1skTiAsQXg/+IWkZYw== + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + integrity sha512-PCqwwzODXW7JMrzu+yZIaYbPQSKjDTAsNNlK2l5Gg9g4rz2VzLnZsStvp/3c46GfXpwkyufb3NCyG9+50FF1Vg== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + integrity sha512-2+ujAT2UMBzYFm7tidUsYh+ZoIutxJ3pN9IYrF1/H6dCKtECfhmB8UkHVpyxDwkj0CYbQG35ykoz925TUnBc3A== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.23.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + integrity sha512-YiN6sFAQ5lML8JjCmr7uerS5Yc/EMbgg9G8ZNmk2E3nYX4ckHR01wrkeeMijEf5WHNK5TW0Sl0Uu3pv3EdOJWw== + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-plugin-transform-es2015-classes@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + integrity sha512-5Dy7ZbRinGrNtmWpquZKZ3EGY8sDgIVB4CU8Om8q8tnMLrD/m94cKglVcHps0BCTdZ0TJeeAWOq2TK9MIY6cag== + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + integrity sha512-C/uAv4ktFP/Hmh01gMTvYvICrKze0XVX9f2PdIXuriCSvUmV9j+u+BB9f5fJK3+878yMK6dkdcq+Ymr9mrcLzw== + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + integrity sha512-aNv/GDAW0j/f4Uy1OEPZn1mqD+Nfy9viFGBfQ5bZyT35YqOiqx7/tXdyfZkJ1sC21NyEsBdfDY6PYmLHF4r5iA== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + integrity sha512-ossocTuPOssfxO2h+Z3/Ea1Vo1wWx31Uqy9vIiJusOP4TbF7tPs9U0sJ9pX9OJPf4lXRGj5+6Gkl/HHKiAP5ug== + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + integrity sha512-DLuRwoygCoXx+YfxHLkVx5/NpeSbVwfoTeBykpJK7JhYWlL/O8hgAK/reforUnZDlxasOrVPPJVI/guE3dCwkw== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + integrity sha512-iFp5KIcorf11iBqu/y/a7DK3MN5di3pNCzto61FqCNnUX4qeBwcV1SLqe10oXNnCaxBUImX3SckX2/o1nsrTcg== + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + integrity sha512-tjFl0cwMPpDYyoqYA9li1/7mGFit39XiNX5DKC/uCNjBctMxyL1/PT/l4rSlbvBG1pOKI88STRdUsWXB3/Q9hQ== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + integrity sha512-LnIIdGWIKdw7zwckqx+eGjcS8/cl8D74A3BpJbGjKTFFNJSMrjN4bIh22HY1AlkUbeLG6X6OZj56BDvWD+OeFA== + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.26.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" + integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q== + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-es2015-modules-systemjs@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + integrity sha512-ONFIPsq8y4bls5PPsAWYXH/21Hqv64TBxdje0FvU3MhIV6QM2j5YS7KvAzg/nTIVLot2D2fmFQrFWCbgHlFEjg== + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + integrity sha512-LpVbiT9CLsuAIp3IG0tfbVo81QIhn6pE8xBJ7XSeCtFlMltuar5VuBV6y6Q45tpui9QWcy5i0vLQfCfrnF7Kiw== + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + integrity sha512-8G5hpZMecb53vpD3mjs64NhI1au24TAmokQ4B+TBFBjN9cVoGoOvotdrMMRmHvVZUEvqGUPWL514woru1ChZMA== + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + integrity sha512-8HxlW+BB5HqniD+nLkQ4xSAVq3bR/pcYW9IigY+2y0dI+Y7INFeTbfAQr+63T3E4UDsZGjyb+l9txUnABWxlOQ== + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + integrity sha512-mDdocSfUVm1/7Jw/FIRNw9vPrBQNePy6wZJlR8HAUBLybNp1w/6lr6zZ2pjMShee65t/ybR5pT8ulkLzD1xwiw== + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + integrity sha512-3Ghhi26r4l3d0Js933E5+IhHwk0A1yiutj9gwvzmFbVV0sPMYk2lekhOufHBswX7NCoSeF4Xrl3sCIuSIa+zOg== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + integrity sha512-CYP359ADryTo3pCsH0oxRo/0yn6UsEZLqYohHmvLQdfS9xkf+MbCzE3/Kolw9OYIY4ZMilH25z/5CbQbwDD+lQ== + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + integrity sha512-x8b9W0ngnKzDMHimVtTfn5ryimars1ByTqsfBDwAqLibmuuQY6pgBQi5z1ErIsUOWBdw1bW9FSz5RZUojM4apg== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + integrity sha512-fz6J2Sf4gYN6gWgRZaoFXmq93X+Li/8vf+fb0sGDVtdeWvxC9y5/bTD7bvfWMEq6zetGEHpWjtzRGSugt5kNqw== + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + integrity sha512-v61Dbbihf5XxnYjtBN04B/JBvsScY37R1cZT5r9permN1cp+b70DY3Ib3fIkgn1DI9U3tGgBJZVD8p/mE/4JbQ== + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + integrity sha512-LzXDmbMkklvNhprr20//RStKVcT8Cu+SQtX18eMHLhjHf2yFzwtQ0S2f0jQ+89rokoNdmwoSqYzAhq86FxlLSQ== + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-regenerator@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + integrity sha512-LS+dBkUGlNR15/5WHKe/8Neawx663qttS6AGqoOUhICc9d1KciBvtrQSuc0PI+CxQ2Q/S1aKuJ+u64GtLdcEZg== + dependencies: + regenerator-transform "^0.10.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + integrity sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw== + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" -base64-js@^1.3.1: - version "1.5.1" +babel-preset-env@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" + integrity sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg== + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.23.0" + babel-plugin-transform-es2015-classes "^6.23.0" + babel-plugin-transform-es2015-computed-properties "^6.22.0" + babel-plugin-transform-es2015-destructuring "^6.23.0" + babel-plugin-transform-es2015-duplicate-keys "^6.22.0" + babel-plugin-transform-es2015-for-of "^6.23.0" + babel-plugin-transform-es2015-function-name "^6.22.0" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.23.0" + babel-plugin-transform-es2015-modules-systemjs "^6.23.0" + babel-plugin-transform-es2015-modules-umd "^6.23.0" + babel-plugin-transform-es2015-object-super "^6.22.0" + babel-plugin-transform-es2015-parameters "^6.23.0" + babel-plugin-transform-es2015-shorthand-properties "^6.22.0" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.22.0" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.23.0" + babel-plugin-transform-es2015-unicode-regex "^6.22.0" + babel-plugin-transform-exponentiation-operator "^6.22.0" + babel-plugin-transform-regenerator "^6.22.0" + browserslist "^3.2.6" + invariant "^2.2.2" + semver "^5.3.0" + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + integrity sha512-veliHlHX06wjaeY8xNITbveXSiI+ASFnOqvne/LaIJIqOWi2Ogmj91KOugEz/hoh/fwMhXNBJPCv8Xaz5CyM4A== + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g== + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + integrity sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg== + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.24.1, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + integrity sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA== + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + integrity sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g== + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babelify@^7.3.0: + version "7.3.0" + resolved "https://registry.yarnpkg.com/babelify/-/babelify-7.3.0.tgz#aa56aede7067fd7bd549666ee16dc285087e88e5" + integrity sha512-vID8Fz6pPN5pJMdlUnNFSfrlcx5MUule4k9aKs/zbZPyXxMTcRrB0M4Tarw22L8afr8eYSWxDPYCob3TdrqtlA== + dependencies: + babel-core "^6.0.14" + object-assign "^4.0.0" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + +backoff@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/backoff/-/backoff-2.5.0.tgz#f616eda9d3e4b66b8ca7fca79f695722c5f8e26f" + integrity sha512-wC5ihrnUXmR2douXmXLCe5O3zg3GKIyvRi/hi58a/XyRxVI+3/yM0PYueQOZXPXQ9pxBislYkw+sF9b7C/RuMA== + dependencies: + precond "0.2" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base-x@^3.0.2, base-x@^3.0.8: + version "3.0.9" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" + integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== + dependencies: + safe-buffer "^5.0.1" + +base64-js@^1.0.2, base64-js@^1.3.1: + version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -1262,41 +2694,157 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" -bech32@1.1.4: +bech32@1.1.4, bech32@^1.1.3: version "1.1.4" resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== +big-integer@1.6.36: + version "1.6.36" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.36.tgz#78631076265d4ae3555c04f85e7d9d2f3a071a36" + integrity sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg== + +big.js@^6.0.3: + version "6.2.1" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-6.2.1.tgz#7205ce763efb17c2e41f26f121c420c6a7c2744f" + integrity sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ== + bigint-crypto-utils@^3.0.23: version "3.3.0" resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz#72ad00ae91062cf07f2b1def9594006c279c1d77" integrity sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg== +bignumber.js@7.2.1, bignumber.js@^7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f" + integrity sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ== + +bignumber.js@^9.0.0, bignumber.js@^9.0.1: + version "9.1.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.1.tgz#c4df7dc496bd849d4c9464344c1aa74228b4dac6" + integrity sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig== + binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== +binary-search-tree@0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/binary-search-tree/-/binary-search-tree-0.2.5.tgz#7dbb3b210fdca082450dad2334c304af39bdc784" + integrity sha512-CvNVKS6iXagL1uGwLagSXz1hzSMezxOuGnFi5FHGKqaTO3nPPWrAbyALUzK640j+xOTVm7lzD9YP8W1f/gvUdw== + dependencies: + underscore "~1.4.4" + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bip39@^2.4.2: + version "2.6.0" + resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.6.0.tgz#9e3a720b42ec8b3fbe4038f1e445317b6a99321c" + integrity sha512-RrnQRG2EgEoqO24ea+Q/fftuPUZLmrEM3qNhhGsA3PbaXaCW791LTzPuVyx/VprXQcTbPJ3K3UeTna8ZnVl2sg== + dependencies: + create-hash "^1.1.0" + pbkdf2 "^3.0.9" + randombytes "^2.0.1" + safe-buffer "^5.0.1" + unorm "^1.3.3" + +bip66@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22" + integrity sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw== + dependencies: + safe-buffer "^5.0.1" + +bl@^1.0.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.3.tgz#1e8dd80142eac80d7158c9dccc047fb620e035e7" + integrity sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww== + dependencies: + readable-stream "^2.3.5" + safe-buffer "^5.1.1" + blakejs@^1.1.0: version "1.2.1" resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814" integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ== +bluebird@^3.5.0, bluebird@^3.5.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + bn.js@4.11.6: version "4.11.6" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" integrity sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA== -bn.js@^4.11.0, bn.js@^4.11.8, bn.js@^4.11.9: +bn.js@4.11.8: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +bn.js@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.2.tgz#c9686902d3c9a27729f43ab10f9d79c2004da7b0" + integrity sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA== + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^4.4.0, bn.js@^4.8.0: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== -bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: +bn.js@^5.0.0, bn.js@^5.1.1, bn.js@^5.1.2, bn.js@^5.1.3, bn.js@^5.2.0, bn.js@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +body-parser@^1.16.0, body-parser@^1.19.0: + version "1.20.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1319,7 +2867,7 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -brorand@^1.1.0: +brorand@^1.0.1, brorand@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== @@ -1339,7 +2887,7 @@ browser-stdout@1.3.1: resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== -browserify-aes@^1.2.0: +browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.0.6, browserify-aes@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== @@ -1351,7 +2899,67 @@ browserify-aes@^1.2.0: inherits "^2.0.1" safe-buffer "^5.0.1" -bs58@^4.0.0: +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== + dependencies: + bn.js "^5.0.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" + integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== + dependencies: + bn.js "^5.1.1" + browserify-rsa "^4.0.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.3" + inherits "^2.0.4" + parse-asn1 "^5.1.5" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +browserslist@^3.2.6: + version "3.2.8" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" + integrity sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ== + dependencies: + caniuse-lite "^1.0.30000844" + electron-to-chromium "^1.3.47" + +browserslist@^4.21.9: + version "4.21.10" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.10.tgz#dbbac576628c13d3b2231332cb2ec5a46e015bb0" + integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ== + dependencies: + caniuse-lite "^1.0.30001517" + electron-to-chromium "^1.4.477" + node-releases "^2.0.13" + update-browserslist-db "^1.0.11" + +bs58@^4.0.0, bs58@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== @@ -1367,17 +2975,59 @@ bs58check@^2.1.2: create-hash "^1.1.0" safe-buffer "^5.1.2" +btoa@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73" + integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g== + +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ== + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +buffer-to-arraybuffer@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a" + integrity sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ== + buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== -buffer@^6.0.3: +buffer@4.9.2: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +buffer@6.0.3, buffer@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== @@ -1385,6 +3035,21 @@ buffer@^6.0.3: base64-js "^1.3.1" ieee754 "^1.2.1" +buffer@^5.0.5, buffer@^5.2.1, buffer@^5.5.0, buffer@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +bufferutil@^4.0.1: + version "4.0.7" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" + integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== + dependencies: + node-gyp-build "^4.3.0" + busboy@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" @@ -1397,7 +3062,43 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== -call-bind@^1.0.0, call-bind@^1.0.2: +cacheable-lookup@^5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" + integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== + +cacheable-lookup@^6.0.4: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz#0330a543471c61faa4e9035db583aad753b36385" + integrity sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww== + +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + +cacheable-request@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.4.tgz#7a33ebf08613178b403635be7b899d3e69bbe817" + integrity sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^4.0.0" + lowercase-keys "^2.0.0" + normalize-url "^6.0.1" + responselike "^2.0.0" + +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== @@ -1405,6 +3106,24 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" +camel-case@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" + integrity sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w== + dependencies: + no-case "^2.2.0" + upper-case "^1.1.1" + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg== + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw== + camelcase@^5.0.0: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" @@ -1415,6 +3134,11 @@ camelcase@^6.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== +caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001517: + version "1.0.30001519" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001519.tgz#3e7b8b8a7077e78b0eb054d69e6edf5c7df35601" + integrity sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg== + case@^1.6.3: version "1.6.3" resolved "https://registry.yarnpkg.com/case/-/case-1.6.3.tgz#0a4386e3e9825351ca2e6216c60467ff5f1ea1c9" @@ -1430,6 +3154,14 @@ catering@^2.1.0, catering@^2.1.1: resolved "https://registry.yarnpkg.com/catering/-/catering-2.1.1.tgz#66acba06ed5ee28d5286133982a927de9a04b510" integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w== +cbor@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/cbor/-/cbor-5.2.0.tgz#4cca67783ccd6de7b50ab4ed62636712f287a67c" + integrity sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A== + dependencies: + bignumber.js "^9.0.1" + nofilter "^1.0.4" + cbor@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/cbor/-/cbor-8.1.0.tgz#cfc56437e770b73417a2ecbfc9caf6b771af60d5" @@ -1437,6 +3169,13 @@ cbor@^8.1.0: dependencies: nofilter "^3.1.0" +cbor@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/cbor/-/cbor-9.0.1.tgz#b16e393d4948d44758cd54ac6151379d443b37ae" + integrity sha512-/TQOWyamDxvVIv+DY9cOLNuABkoyz8K/F3QE56539pGVYohx0+MEA1f4lChFTX79dBTBS7R1PF6ovH7G+VtBfQ== + dependencies: + nofilter "^3.1.0" + chai-as-promised@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0" @@ -1457,7 +3196,18 @@ chai@^4.2.0: pathval "^1.1.1" type-detect "^4.0.5" -chalk@^2.4.2: +chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A== + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.3.2, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1474,6 +3224,30 @@ chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" +change-case@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/change-case/-/change-case-3.0.2.tgz#fd48746cce02f03f0a672577d1d3a8dc2eceb037" + integrity sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA== + dependencies: + camel-case "^3.0.0" + constant-case "^2.0.0" + dot-case "^2.1.0" + header-case "^1.0.0" + is-lower-case "^1.1.0" + is-upper-case "^1.1.0" + lower-case "^1.1.1" + lower-case-first "^1.0.0" + no-case "^2.3.2" + param-case "^2.1.0" + pascal-case "^2.0.0" + path-case "^2.1.0" + sentence-case "^2.1.0" + snake-case "^2.1.0" + swap-case "^1.1.0" + title-case "^2.1.0" + upper-case "^1.1.1" + upper-case-first "^1.1.0" + "charenc@>= 0.0.1": version "0.0.2" resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" @@ -1484,6 +3258,38 @@ check-error@^1.0.2: resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== +checkpoint-store@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/checkpoint-store/-/checkpoint-store-1.1.0.tgz#04e4cb516b91433893581e6d4601a78e9552ea06" + integrity sha512-J/NdY2WvIx654cc6LWSq/IYFFCUf75fFTgwzFnmbqyORH4MwgiQCgswLLKBGzmsyTI5V7i5bp/So6sMbDWhedg== + dependencies: + functional-red-black-tree "^1.0.1" + +cheerio-select@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4" + integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g== + dependencies: + boolbase "^1.0.0" + css-select "^5.1.0" + css-what "^6.1.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + +cheerio@^1.0.0-rc.2: + version "1.0.0-rc.12" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.12.tgz#788bf7466506b1c6bf5fae51d24a2c4d62e47683" + integrity sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q== + dependencies: + cheerio-select "^2.1.0" + dom-serializer "^2.0.0" + domhandler "^5.0.3" + domutils "^3.0.1" + htmlparser2 "^8.0.1" + parse5 "^7.0.0" + parse5-htmlparser2-tree-adapter "^7.0.0" + chokidar@3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.0.tgz#12c0714668c55800f659e262d4962a97faf554a6" @@ -1514,11 +3320,27 @@ chokidar@3.5.3, chokidar@^3.4.0, chokidar@^3.5.2: optionalDependencies: fsevents "~2.3.2" +chownr@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== +cids@^0.7.1: + version "0.7.5" + resolved "https://registry.yarnpkg.com/cids/-/cids-0.7.5.tgz#60a08138a99bfb69b6be4ceb63bfef7a396b28b2" + integrity sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA== + dependencies: + buffer "^5.5.0" + class-is "^1.1.0" + multibase "~0.6.0" + multicodec "^1.0.0" + multihashes "~0.4.15" + cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" @@ -1527,6 +3349,11 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" +class-is@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825" + integrity sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw== + classic-level@^1.2.0: version "1.3.0" resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.3.0.tgz#5e36680e01dc6b271775c093f2150844c5edd5c8" @@ -1553,6 +3380,15 @@ cli-table3@^0.5.0: optionalDependencies: colors "^1.1.2" +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + cliui@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" @@ -1571,6 +3407,23 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.0.0" +clone-response@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" + integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== + dependencies: + mimic-response "^1.0.0" + +clone@^2.0.0, clone@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -1637,12 +3490,27 @@ commander@3.0.2: resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== +commander@^2.8.1: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + +compare-versions@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-6.0.0.tgz#a3edb527e4487bfab9a8b62ffe70cebc9b87675b" + integrity sha512-s2MzYxfRsE9f/ow8hjn7ysa7pod1xhHdQMsgiJtKx6XSNf4x2N1KG4fjrkUmXcP/e9Y2ZX4zB6sHIso0Lm6evQ== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -concat-stream@^1.6.0, concat-stream@^1.6.2: +concat-stream@^1.5.1, concat-stream@^1.6.0, concat-stream@^1.6.2: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== @@ -1652,11 +3520,79 @@ concat-stream@^1.6.0, concat-stream@^1.6.2: readable-stream "^2.2.2" typedarray "^0.0.6" +console-read-write@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/console-read-write/-/console-read-write-0.1.1.tgz#d04da22616a9291390b95c3c854e1aa9d2fcdefe" + integrity sha512-oznwP8YnhYzN+72C6+LA4LnbcletRyz4ZQfNCBdvtXnE/RnpnRskaTljl7X4EAijkc2PQ3oYHU+C5r88Y8JC3A== + dependencies: + await-lock "1.1.3" + +constant-case@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-2.0.0.tgz#4175764d389d3fa9c8ecd29186ed6005243b6a46" + integrity sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ== + dependencies: + snake-case "^2.1.0" + upper-case "^1.1.1" + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-hash@^2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/content-hash/-/content-hash-2.5.2.tgz#bbc2655e7c21f14fd3bfc7b7d4bfe6e454c9e211" + integrity sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw== + dependencies: + cids "^0.7.1" + multicodec "^0.5.5" + multihashes "^0.4.15" + +content-type@~1.0.4, content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +convert-source-map@^1.5.1: + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + cookie@^0.4.1: version "0.4.2" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== +cookiejar@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.4.tgz#ee669c1fea2cf42dc31585469d193fef0d65771b" + integrity sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw== + +core-js-compat@^3.31.0: + version "3.32.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.32.0.tgz#f41574b6893ab15ddb0ac1693681bd56c8550a90" + integrity sha512-7a9a3D1k4UCVKnLhrgALyFcP7YCsLOQIxPd0dKjf/6GuPcgyiGP70ewWdCGrSK7evyhymi0qO4EqCmSJofDeYw== + dependencies: + browserslist "^4.21.9" + +core-js@^2.4.0, core-js@^2.5.0: + version "2.6.12" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" + integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== + core-util-is@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -1667,11 +3603,27 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== -crc-32@^1.2.0: +cors@^2.8.1: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +crc-32@^1.2.0, crc-32@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== +create-ecdh@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== + dependencies: + bn.js "^4.1.0" + elliptic "^6.5.3" + create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" @@ -1683,7 +3635,7 @@ create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: ripemd160 "^2.0.1" sha.js "^2.4.0" -create-hmac@^1.1.4, create-hmac@^1.1.7: +create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== @@ -1700,11 +3652,91 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== +cross-fetch@^2.1.0, cross-fetch@^2.1.1: + version "2.2.6" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.6.tgz#2ef0bb39a24ac034787965c457368a28730e220a" + integrity sha512-9JZz+vXCmfKUZ68zAptS7k4Nu8e2qcibe7WVZYps7sAgk5R8GYTc+T1WR0v1rlP9HxgARmOX1UTIJZFytajpNA== + dependencies: + node-fetch "^2.6.7" + whatwg-fetch "^2.0.4" + +cross-fetch@^3.1.4, cross-fetch@^3.1.5: + version "3.1.8" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" + integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg== + dependencies: + node-fetch "^2.6.12" + +cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + "crypt@>= 0.0.1": version "0.0.2" resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow== +crypto-addr-codec@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/crypto-addr-codec/-/crypto-addr-codec-0.1.7.tgz#e16cea892730178fe25a38f6d15b680cab3124ae" + integrity sha512-X4hzfBzNhy4mAc3UpiXEC/L0jo5E8wAa9unsnA8nNXYzXjCcGk83hfC5avJWCSGT8V91xMnAS9AKMHmjw5+XCg== + dependencies: + base-x "^3.0.8" + big-integer "1.6.36" + blakejs "^1.1.0" + bs58 "^4.0.1" + ripemd160-min "0.0.6" + safe-buffer "^5.2.0" + sha3 "^2.1.1" + +crypto-browserify@3.12.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +css-select@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" + integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== + dependencies: + boolbase "^1.0.0" + css-what "^6.1.0" + domhandler "^5.0.2" + domutils "^3.0.1" + nth-check "^2.0.1" + +css-what@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -1712,11 +3744,23 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" +date-format@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/date-format/-/date-format-3.0.0.tgz#eb8780365c7d2b1511078fb491e6479780f3ad95" + integrity sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w== + death@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" integrity sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w== +debug@2.6.9, debug@^2.2.0, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + debug@3.2.6: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" @@ -1731,7 +3775,7 @@ debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3: dependencies: ms "2.1.2" -decamelize@^1.2.0: +decamelize@^1.1.1, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== @@ -1741,6 +3785,83 @@ decamelize@^4.0.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== +decimal.js@^10.0.1: + version "10.4.3" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" + integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== + +decode-uri-component@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" + integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== + +decompress-response@^3.2.0, decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA== + dependencies: + mimic-response "^1.0.0" + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" + integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ== + dependencies: + file-type "^5.2.0" + is-stream "^1.1.0" + tar-stream "^1.5.2" + +decompress-tarbz2@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" + integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A== + dependencies: + decompress-tar "^4.1.0" + file-type "^6.1.0" + is-stream "^1.1.0" + seek-bzip "^1.0.5" + unbzip2-stream "^1.0.9" + +decompress-targz@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" + integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w== + dependencies: + decompress-tar "^4.1.1" + file-type "^5.2.0" + is-stream "^1.1.0" + +decompress-unzip@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" + integrity sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw== + dependencies: + file-type "^3.8.0" + get-stream "^2.2.0" + pify "^2.3.0" + yauzl "^2.4.2" + +decompress@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.1.tgz#007f55cc6a62c055afa37c07eb6a4ee1b773f118" + integrity sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ== + dependencies: + decompress-tar "^4.0.0" + decompress-tarbz2 "^4.0.0" + decompress-targz "^4.0.0" + decompress-unzip "^4.0.1" + graceful-fs "^4.1.10" + make-dir "^1.0.0" + pify "^2.3.0" + strip-dirs "^2.0.0" + deep-eql@^4.0.1, deep-eql@^4.1.2: version "4.1.3" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" @@ -1748,6 +3869,18 @@ deep-eql@^4.0.1, deep-eql@^4.1.2: dependencies: type-detect "^4.0.0" +deep-equal@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + deep-extend@~0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -1758,6 +3891,23 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== + +defer-to-connect@^2.0.0, defer-to-connect@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== + +deferred-leveldown@~1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz#3acd2e0b75d1669924bc0a4b642851131173e1eb" + integrity sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA== + dependencies: + abstract-leveldown "~2.6.0" + define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" @@ -1766,6 +3916,11 @@ define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.1.4, de has-property-descriptors "^1.0.0" object-keys "^1.1.1" +defined@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.1.tgz#c0b9db27bfaffd95d6f61399419b893df0f91ebf" + integrity sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q== + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -1776,13 +3931,38 @@ depd@2.0.0: resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== -detect-port@^1.3.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.5.1.tgz#451ca9b6eaf20451acb0799b8ab40dff7718727b" - integrity sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ== +des.js@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.1.0.tgz#1d37f5766f3bbff4ee9638e871a8768c173b81da" + integrity sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg== dependencies: - address "^1.0.1" - debug "4" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + integrity sha512-BDKtmHlOzwI7iRuEkhzsnPoi5ypEhWAJB5RvHWe1kMr06js3uK5B3734i3ui5Yd+wOJV1cpE4JnivPD283GU/A== + dependencies: + repeating "^2.0.0" + +detect-indent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" + integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g== + +detect-port@^1.3.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.5.1.tgz#451ca9b6eaf20451acb0799b8ab40dff7718727b" + integrity sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ== + dependencies: + address "^1.0.1" + debug "4" diff@3.5.0: version "3.5.0" @@ -1799,6 +3979,15 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + difflib@^0.2.4: version "0.2.4" resolved "https://registry.yarnpkg.com/difflib/-/difflib-0.2.4.tgz#b5e30361a6db023176d562892db85940a718f47e" @@ -1813,11 +4002,74 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + +dom-walk@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" + integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== + +domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + +domutils@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e" + integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + +dot-case@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-2.1.1.tgz#34dcf37f50a8e93c2b3bca8bb7fb9155c7da3bee" + integrity sha512-HnM6ZlFqcajLsyudHq7LeeLDr2rFAVYtDv/hV5qchQEidSck8j9OPUsXY9KwJv/lHMtYlX4DjRQqwFYa+0r8Ug== + dependencies: + no-case "^2.2.0" + dotenv@^16.3.1: version "16.3.1" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== +dotignore@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/dotignore/-/dotignore-0.1.2.tgz#f942f2200d28c3a76fbdd6f0ee9f3257c8a2e905" + integrity sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw== + dependencies: + minimatch "^3.0.4" + +drbg.js@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/drbg.js/-/drbg.js-1.0.1.tgz#3e36b6c42b37043823cdbc332d58f31e2445480b" + integrity sha512-F4wZ06PvqxYLFEZKkFxTDcns9oFNk34hvmJSEwdzsxVQ8YI5YaxtACgQatkYgv2VI2CFkUd2Y+xosPQnHv809g== + dependencies: + browserify-aes "^1.0.6" + create-hash "^1.1.2" + create-hmac "^1.1.4" + +duplexer3@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e" + integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA== + ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -1826,7 +4078,27 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -elliptic@6.5.4, elliptic@^6.5.2, elliptic@^6.5.4: +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.3.47, electron-to-chromium@^1.4.477: + version "1.4.485" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.485.tgz#fde3ee9ee8112a3414c0dfa545385ad08ec43408" + integrity sha512-1ndQ5IBNEnFirPwvyud69GHL+31FkE09gH/CJ6m3KCbkx3i0EVOrjwz4UNxRmN9H8OVHbC6vMRZGN1yCvjSs9w== + +elliptic@6.3.3: + version "6.3.3" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.3.3.tgz#5482d9646d54bcb89fd7d994fc9e2e9568876e3f" + integrity sha512-cIky9SO2H8W2eU1NOLySnhOYJnuEWCq9ZJeHvHd/lXzEL9vyraIMfilZSn57X3aVX+wkfYmqkch2LvmTzkjFpA== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + inherits "^2.0.1" + +elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4: version "6.5.4" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== @@ -1854,6 +4126,25 @@ encode-utf8@^1.0.2: resolved "https://registry.yarnpkg.com/encode-utf8/-/encode-utf8-1.0.3.tgz#f30fdd31da07fb596f281beb2f6b027851994cda" integrity sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw== +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +encoding@^0.1.11: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + enquirer@^2.3.0, enquirer@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" @@ -1861,11 +4152,37 @@ enquirer@^2.3.0, enquirer@^2.3.6: dependencies: ansi-colors "^4.1.1" +entities@^4.2.0, entities@^4.4.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + env-paths@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== +erc20permit@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/erc20permit/-/erc20permit-0.0.4.tgz#f994213b1e1eceecb9dcf6eaf198ecbf0fb2b233" + integrity sha512-I2KW1wU3Hzz/ytoZxhRfbsz+VPFORHCM4KcgtbhAG6nrQEolaer4MgOFB+4pFu45QIZiUeJP3XxfMFVOfO7Z8g== + dependencies: + "@openzeppelin/contracts" "3.1.0" + +errno@~0.1.1: + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + es-abstract@^1.19.0, es-abstract@^1.20.4, es-abstract@^1.21.2: version "1.21.2" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.2.tgz#a56b9695322c8a185dc25975aa3b8ec31d0e7eff" @@ -1929,12 +4246,48 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es5-ext@^0.10.35, es5-ext@^0.10.50: + version "0.10.62" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5" + integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + next-tick "^1.1.0" + +es6-iterator@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-promise@^4.2.8: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-symbol@^3.1.1, es6-symbol@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== @@ -1976,6 +4329,31 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +eth-block-tracker@^4.2.0: + version "4.4.3" + resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-4.4.3.tgz#766a0a0eb4a52c867a28328e9ae21353812cf626" + integrity sha512-A8tG4Z4iNg4mw5tP1Vung9N9IjgMNqpiMoJ/FouSFwNCGHv2X0mmOYwtQOJzki6XN7r7Tyo01S29p7b224I4jw== + dependencies: + "@babel/plugin-transform-runtime" "^7.5.5" + "@babel/runtime" "^7.5.5" + eth-query "^2.1.0" + json-rpc-random-id "^1.0.1" + pify "^3.0.0" + safe-event-emitter "^1.0.1" + +eth-ens-namehash@2.0.8, eth-ens-namehash@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz#229ac46eca86d52e0c991e7cb2aef83ff0f68bcf" + integrity sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw== + dependencies: + idna-uts46-hx "^2.3.1" + js-sha3 "^0.5.7" + eth-gas-reporter@^0.2.25: version "0.2.25" resolved "https://registry.yarnpkg.com/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz#546dfa946c1acee93cb1a94c2a1162292d6ff566" @@ -1997,6 +4375,186 @@ eth-gas-reporter@^0.2.25: sha1 "^1.1.1" sync-request "^6.0.0" +eth-json-rpc-errors@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/eth-json-rpc-errors/-/eth-json-rpc-errors-1.1.1.tgz#148377ef55155585981c21ff574a8937f9d6991f" + integrity sha512-WT5shJ5KfNqHi9jOZD+ID8I1kuYWNrigtZat7GOQkvwo99f8SzAVaEcWhJUv656WiZOAg3P1RiJQANtUmDmbIg== + dependencies: + fast-safe-stringify "^2.0.6" + +eth-json-rpc-filters@^4.0.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/eth-json-rpc-filters/-/eth-json-rpc-filters-4.2.2.tgz#eb35e1dfe9357ace8a8908e7daee80b2cd60a10d" + integrity sha512-DGtqpLU7bBg63wPMWg1sCpkKCf57dJ+hj/k3zF26anXMzkmtSBDExL8IhUu7LUd34f0Zsce3PYNO2vV2GaTzaw== + dependencies: + "@metamask/safe-event-emitter" "^2.0.0" + async-mutex "^0.2.6" + eth-json-rpc-middleware "^6.0.0" + eth-query "^2.1.2" + json-rpc-engine "^6.1.0" + pify "^5.0.0" + +eth-json-rpc-infura@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/eth-json-rpc-infura/-/eth-json-rpc-infura-3.2.1.tgz#26702a821067862b72d979c016fd611502c6057f" + integrity sha512-W7zR4DZvyTn23Bxc0EWsq4XGDdD63+XPUCEhV2zQvQGavDVC4ZpFDK4k99qN7bd7/fjj37+rxmuBOBeIqCA5Mw== + dependencies: + cross-fetch "^2.1.1" + eth-json-rpc-middleware "^1.5.0" + json-rpc-engine "^3.4.0" + json-rpc-error "^2.0.0" + +eth-json-rpc-middleware@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz#5c9d4c28f745ccb01630f0300ba945f4bef9593f" + integrity sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q== + dependencies: + async "^2.5.0" + eth-query "^2.1.2" + eth-tx-summary "^3.1.2" + ethereumjs-block "^1.6.0" + ethereumjs-tx "^1.3.3" + ethereumjs-util "^5.1.2" + ethereumjs-vm "^2.1.0" + fetch-ponyfill "^4.0.0" + json-rpc-engine "^3.6.0" + json-rpc-error "^2.0.0" + json-stable-stringify "^1.0.1" + promise-to-callback "^1.0.0" + tape "^4.6.3" + +eth-json-rpc-middleware@^4.1.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-4.4.1.tgz#07d3dd0724c24a8d31e4a172ee96271da71b4228" + integrity sha512-yoSuRgEYYGFdVeZg3poWOwAlRI+MoBIltmOB86MtpoZjvLbou9EB/qWMOWSmH2ryCWLW97VYY6NWsmWm3OAA7A== + dependencies: + btoa "^1.2.1" + clone "^2.1.1" + eth-json-rpc-errors "^1.0.1" + eth-query "^2.1.2" + eth-sig-util "^1.4.2" + ethereumjs-block "^1.6.0" + ethereumjs-tx "^1.3.7" + ethereumjs-util "^5.1.2" + ethereumjs-vm "^2.6.0" + fetch-ponyfill "^4.0.0" + json-rpc-engine "^5.1.3" + json-stable-stringify "^1.0.1" + pify "^3.0.0" + safe-event-emitter "^1.0.1" + +eth-json-rpc-middleware@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-6.0.0.tgz#4fe16928b34231a2537856f08a5ebbc3d0c31175" + integrity sha512-qqBfLU2Uq1Ou15Wox1s+NX05S9OcAEL4JZ04VZox2NS0U+RtCMjSxzXhLFWekdShUPZ+P8ax3zCO2xcPrp6XJQ== + dependencies: + btoa "^1.2.1" + clone "^2.1.1" + eth-query "^2.1.2" + eth-rpc-errors "^3.0.0" + eth-sig-util "^1.4.2" + ethereumjs-util "^5.1.2" + json-rpc-engine "^5.3.0" + json-stable-stringify "^1.0.1" + node-fetch "^2.6.1" + pify "^3.0.0" + safe-event-emitter "^1.0.1" + +eth-lib@0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.7.tgz#2f93f17b1e23aec3759cd4a3fe20c1286a3fc1ca" + integrity sha512-VqEBQKH92jNsaE8lG9CTq8M/bc12gdAfb5MY8Ro1hVyXkh7rOtY3m5tRHK3Hus5HqIAAwU2ivcUjTLVwsvf/kw== + dependencies: + bn.js "^4.11.6" + elliptic "^6.4.0" + xhr-request-promise "^0.1.2" + +eth-lib@0.2.8, eth-lib@^0.2.8: + version "0.2.8" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.8.tgz#b194058bef4b220ad12ea497431d6cb6aa0623c8" + integrity sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw== + dependencies: + bn.js "^4.11.6" + elliptic "^6.4.0" + xhr-request-promise "^0.1.2" + +eth-lib@^0.1.26: + version "0.1.29" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.1.29.tgz#0c11f5060d42da9f931eab6199084734f4dbd1d9" + integrity sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ== + dependencies: + bn.js "^4.11.6" + elliptic "^6.4.0" + nano-json-stream-parser "^0.1.2" + servify "^0.1.12" + ws "^3.0.0" + xhr-request-promise "^0.1.2" + +eth-permit@^0.2.3: + version "0.2.3" + resolved "https://registry.npmjs.org/eth-permit/-/eth-permit-0.2.3.tgz#7d8b051e329d2166fef32553ed397970d369cafe" + integrity sha512-d4tbiRQgbpdeJbdC9hdyT0SUJcJx28FIy3o2RxEAoeYI+zyYbNC0ZpdE6kxBK+7iY2payjHRE7rs7tr5EcOVLg== + dependencies: + utf8 "^3.0.0" + +eth-query@^2.0.2, eth-query@^2.1.0, eth-query@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/eth-query/-/eth-query-2.1.2.tgz#d6741d9000106b51510c72db92d6365456a6da5e" + integrity sha512-srES0ZcvwkR/wd5OQBRA1bIJMww1skfGS0s8wlwK3/oNP4+wnds60krvu5R1QbpRQjMmpG5OMIWro5s7gvDPsA== + dependencies: + json-rpc-random-id "^1.0.0" + xtend "^4.0.1" + +eth-rpc-errors@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eth-rpc-errors/-/eth-rpc-errors-3.0.0.tgz#d7b22653c70dbf9defd4ef490fd08fe70608ca10" + integrity sha512-iPPNHPrLwUlR9xCSYm7HHQjWBasor3+KZfRvwEWxMz3ca0yqnlBeJrnyphkGIXZ4J7AMAaOLmwy4AWhnxOiLxg== + dependencies: + fast-safe-stringify "^2.0.6" + +eth-rpc-errors@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eth-rpc-errors/-/eth-rpc-errors-4.0.3.tgz#6ddb6190a4bf360afda82790bb7d9d5e724f423a" + integrity sha512-Z3ymjopaoft7JDoxZcEb3pwdGh7yiYMhOwm2doUt6ASXlMavpNlK6Cre0+IMl2VSGyEU9rkiperQhp5iRxn5Pg== + dependencies: + fast-safe-stringify "^2.0.6" + +eth-sig-util@2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-2.5.2.tgz#f30b94509786fa4fbf71adb3164b1701e15724a8" + integrity sha512-xvDojS/4reXsw8Pz/+p/qcM5rVB61FOdPbEtMZ8FQ0YHnPEzPy5F8zAAaZ+zj5ud0SwRLWPfor2Cacjm7EzMIw== + dependencies: + buffer "^5.2.1" + elliptic "^6.4.0" + ethereumjs-abi "0.6.5" + ethereumjs-util "^5.1.1" + tweetnacl "^1.0.0" + tweetnacl-util "^0.15.0" + +eth-sig-util@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.2.tgz#8d958202c7edbaae839707fba6f09ff327606210" + integrity sha512-iNZ576iTOGcfllftB73cPB5AN+XUQAT/T8xzsILsghXC1o8gJUqe3RHlcDqagu+biFpYQ61KQrZZJza8eRSYqw== + dependencies: + ethereumjs-abi "git+https://github.com/ethereumjs/ethereumjs-abi.git" + ethereumjs-util "^5.1.1" + +eth-tx-summary@^3.1.2: + version "3.2.4" + resolved "https://registry.yarnpkg.com/eth-tx-summary/-/eth-tx-summary-3.2.4.tgz#e10eb95eb57cdfe549bf29f97f1e4f1db679035c" + integrity sha512-NtlDnaVZah146Rm8HMRUNMgIwG/ED4jiqk0TME9zFheMl1jOp6jL1m0NKGjJwehXQ6ZKCPr16MTr+qspKpEXNg== + dependencies: + async "^2.1.2" + clone "^2.0.0" + concat-stream "^1.5.1" + end-of-stream "^1.1.0" + eth-query "^2.0.2" + ethereumjs-block "^1.4.1" + ethereumjs-tx "^1.1.1" + ethereumjs-util "^5.0.1" + ethereumjs-vm "^2.6.0" + through2 "^2.0.3" + ethereum-bloom-filters@^1.0.6: version "1.0.10" resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz#3ca07f4aed698e75bd134584850260246a5fed8a" @@ -2004,6 +4562,16 @@ ethereum-bloom-filters@^1.0.6: dependencies: js-sha3 "^0.8.0" +ethereum-common@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.2.0.tgz#13bf966131cce1eeade62a1b434249bb4cb120ca" + integrity sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA== + +ethereum-common@^0.0.18: + version "0.0.18" + resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.0.18.tgz#2fdc3576f232903358976eb39da783213ff9523f" + integrity sha512-EoltVQTRNg2Uy4o84qpa2aXymXDJhxm7eos/ACOg0DG4baAbMjhbdAEsx9GeE8sC3XCxnYvrrzZDH8D8MtA2iQ== + ethereum-cryptography@0.1.3, ethereum-cryptography@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191" @@ -2035,15 +4603,113 @@ ethereum-cryptography@^1.0.3: "@scure/bip32" "1.1.5" "@scure/bip39" "1.1.1" -ethereumjs-abi@^0.6.8: +ethereum-cryptography@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz#18fa7108622e56481157a5cb7c01c0c6a672eb67" + integrity sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug== + dependencies: + "@noble/curves" "1.1.0" + "@noble/hashes" "1.3.1" + "@scure/bip32" "1.3.1" + "@scure/bip39" "1.2.1" + +ethereum-protocol@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ethereum-protocol/-/ethereum-protocol-1.0.1.tgz#b7d68142f4105e0ae7b5e178cf42f8d4dc4b93cf" + integrity sha512-3KLX1mHuEsBW0dKG+c6EOJS1NBNqdCICvZW9sInmZTt5aY0oxmHVggYRE0lJu1tcnMD1K+AKHdLi6U43Awm1Vg== + +ethereumjs-abi@0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz#5a637ef16ab43473fa72a29ad90871405b3f5241" + integrity sha512-rCjJZ/AE96c/AAZc6O3kaog4FhOsAViaysBxqJNy2+LHP0ttH0zkZ7nXdVHOAyt6lFwLO0nlCwWszysG/ao1+g== + dependencies: + bn.js "^4.10.0" + ethereumjs-util "^4.3.0" + +ethereumjs-abi@^0.6.8, "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git": version "0.6.8" - resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" - integrity sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA== + resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#ee3994657fa7a427238e6ba92a84d0b529bbcde0" dependencies: bn.js "^4.11.8" ethereumjs-util "^6.0.0" -ethereumjs-util@^6.0.0, ethereumjs-util@^6.2.1: +ethereumjs-account@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz#eeafc62de544cb07b0ee44b10f572c9c49e00a84" + integrity sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA== + dependencies: + ethereumjs-util "^5.0.0" + rlp "^2.0.0" + safe-buffer "^5.1.1" + +ethereumjs-block@^1.2.2, ethereumjs-block@^1.4.1, ethereumjs-block@^1.6.0: + version "1.7.1" + resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz#78b88e6cc56de29a6b4884ee75379b6860333c3f" + integrity sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg== + dependencies: + async "^2.0.1" + ethereum-common "0.2.0" + ethereumjs-tx "^1.2.2" + ethereumjs-util "^5.0.0" + merkle-patricia-tree "^2.1.2" + +ethereumjs-block@~2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz#c7654be7e22df489fda206139ecd63e2e9c04965" + integrity sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg== + dependencies: + async "^2.0.1" + ethereumjs-common "^1.5.0" + ethereumjs-tx "^2.1.1" + ethereumjs-util "^5.0.0" + merkle-patricia-tree "^2.1.2" + +ethereumjs-common@^1.1.0, ethereumjs-common@^1.3.2, ethereumjs-common@^1.5.0, ethereumjs-common@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.5.2.tgz#2065dbe9214e850f2e955a80e650cb6999066979" + integrity sha512-hTfZjwGX52GS2jcVO6E2sx4YuFnf0Fhp5ylo4pEPhEffNln7vS59Hr5sLnp3/QCazFLluuBZ+FZ6J5HTp0EqCA== + +ethereumjs-tx@^1.0.0, ethereumjs-tx@^1.1.1, ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@^1.3.3, ethereumjs-tx@^1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz#88323a2d875b10549b8347e09f4862b546f3d89a" + integrity sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA== + dependencies: + ethereum-common "^0.0.18" + ethereumjs-util "^5.0.0" + +ethereumjs-tx@^2.1.1, ethereumjs-tx@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz#5dfe7688bf177b45c9a23f86cf9104d47ea35fed" + integrity sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw== + dependencies: + ethereumjs-common "^1.5.0" + ethereumjs-util "^6.0.0" + +ethereumjs-util@^4.3.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-4.5.1.tgz#f4bf9b3b515a484e3cc8781d61d9d980f7c83bd0" + integrity sha512-WrckOZ7uBnei4+AKimpuF1B3Fv25OmoRgmYCpGsP7u8PFxXAmAgiJSYT2kRWnt6fVIlKaQlZvuwXp7PIrmn3/w== + dependencies: + bn.js "^4.8.0" + create-hash "^1.1.2" + elliptic "^6.5.2" + ethereum-cryptography "^0.1.3" + rlp "^2.0.0" + +ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2, ethereumjs-util@^5.1.5: + version "5.2.1" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz#a833f0e5fca7e5b361384dc76301a721f537bf65" + integrity sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ== + dependencies: + bn.js "^4.11.0" + create-hash "^1.1.2" + elliptic "^6.5.2" + ethereum-cryptography "^0.1.3" + ethjs-util "^0.1.3" + rlp "^2.0.0" + safe-buffer "^5.1.1" + +ethereumjs-util@^6.0.0, ethereumjs-util@^6.1.0, ethereumjs-util@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" integrity sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw== @@ -2056,7 +4722,7 @@ ethereumjs-util@^6.0.0, ethereumjs-util@^6.2.1: ethjs-util "0.1.6" rlp "^2.2.3" -ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.4: +ethereumjs-util@^7.0.3, ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.2, ethereumjs-util@^7.1.4, ethereumjs-util@^7.1.5: version "7.1.5" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz#9ecf04861e4fbbeed7465ece5f23317ad1129181" integrity sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg== @@ -2067,7 +4733,83 @@ ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.4: ethereum-cryptography "^0.1.3" rlp "^2.2.4" -ethers@^4.0.40: +ethereumjs-vm@^2.1.0, ethereumjs-vm@^2.3.4, ethereumjs-vm@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz#76243ed8de031b408793ac33907fb3407fe400c6" + integrity sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw== + dependencies: + async "^2.1.2" + async-eventemitter "^0.2.2" + ethereumjs-account "^2.0.3" + ethereumjs-block "~2.2.0" + ethereumjs-common "^1.1.0" + ethereumjs-util "^6.0.0" + fake-merkle-patricia-tree "^1.0.1" + functional-red-black-tree "^1.0.1" + merkle-patricia-tree "^2.3.2" + rustbn.js "~0.2.0" + safe-buffer "^5.1.1" + +ethereumjs-wallet@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.3.tgz#b0eae6f327637c2aeb9ccb9047b982ac542e6ab1" + integrity sha512-qiXPiZOsStem+Dj/CQHbn5qex+FVkuPmGH7SvSnA9F3tdRDt8dLMyvIj3+U05QzVZNPYh4HXEdnzoYI4dZkr9w== + dependencies: + aes-js "^3.1.1" + bs58check "^2.1.2" + ethereumjs-util "^6.0.0" + hdkey "^1.1.0" + randombytes "^2.0.6" + safe-buffer "^5.1.2" + scrypt.js "^0.3.0" + utf8 "^3.0.0" + uuid "^3.3.2" + +ethereumjs-wallet@^0.6.3: + version "0.6.5" + resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.5.tgz#685e9091645cee230ad125c007658833991ed474" + integrity sha512-MDwjwB9VQVnpp/Dc1XzA6J1a3wgHQ4hSvA1uWNatdpOrtCbPVuQSKSyRnjLvS0a+KKMw2pvQ9Ybqpb3+eW8oNA== + dependencies: + aes-js "^3.1.1" + bs58check "^2.1.2" + ethereum-cryptography "^0.1.3" + ethereumjs-util "^6.0.0" + randombytes "^2.0.6" + safe-buffer "^5.1.2" + scryptsy "^1.2.1" + utf8 "^3.0.0" + uuid "^3.3.2" + +ethers@4.0.0-beta.3: + version "4.0.0-beta.3" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.0-beta.3.tgz#15bef14e57e94ecbeb7f9b39dd0a4bd435bc9066" + integrity sha512-YYPogooSknTwvHg3+Mv71gM/3Wcrx+ZpCzarBj3mqs9njjRkrOo2/eufzhHloOCo3JSoNI4TQJJ6yU5ABm3Uog== + dependencies: + "@types/node" "^10.3.2" + aes-js "3.0.0" + bn.js "^4.4.0" + elliptic "6.3.3" + hash.js "1.1.3" + js-sha3 "0.5.7" + scrypt-js "2.0.3" + setimmediate "1.0.4" + uuid "2.0.1" + xmlhttprequest "1.8.0" + +ethers@6.6.4: + version "6.6.4" + resolved "https://registry.npmjs.org/ethers/-/ethers-6.6.4.tgz#f03a86effcd55e82aed96a2fb9a56a9febd3e3d5" + integrity sha512-r3myN2hEnydmu23iiIj5kjWnCh5JNzlqrE/z+Kw5UqH173F+JOWzU6qkFB4HVC50epgxzKSL2Hq1oNXA877vwQ== + dependencies: + "@adraffy/ens-normalize" "1.9.2" + "@noble/hashes" "1.1.2" + "@noble/secp256k1" "1.7.1" + "@types/node" "18.15.13" + aes-js "4.0.0-beta.5" + tslib "2.4.0" + ws "8.5.0" + +ethers@^4.0.32, ethers@^4.0.40: version "4.0.49" resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.49.tgz#0eb0e9161a0c8b4761be547396bbe2fb121a8894" integrity sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg== @@ -2082,7 +4824,7 @@ ethers@^4.0.40: uuid "2.0.1" xmlhttprequest "1.8.0" -ethers@^5.5.3, ethers@^5.7.1: +ethers@^5.0.13, ethers@^5.5.3, ethers@^5.7.1: version "5.7.2" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== @@ -2118,19 +4860,6 @@ ethers@^5.5.3, ethers@^5.7.1: "@ethersproject/web" "5.7.1" "@ethersproject/wordlists" "5.7.0" -ethers@^6.6.2: - version "6.6.2" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.6.2.tgz#0b6131b5fa291fec69b7ae379cb6bb2405c505a7" - integrity sha512-vyWfVAj2g7xeZIivOqlbpt7PbS2MzvJkKgsncgn4A/1xZr8Q3BznBmEBRQyPXKCgHmX4PzRQLpnYG7jl/yutMg== - dependencies: - "@adraffy/ens-normalize" "1.9.2" - "@noble/hashes" "1.1.2" - "@noble/secp256k1" "1.7.1" - "@types/node" "18.15.13" - aes-js "4.0.0-beta.5" - tslib "2.4.0" - ws "8.5.0" - ethjs-unit@0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" @@ -2139,7 +4868,7 @@ ethjs-unit@0.1.6: bn.js "4.11.6" number-to-bn "1.7.0" -ethjs-util@0.1.6, ethjs-util@^0.1.6: +ethjs-util@0.1.6, ethjs-util@^0.1.3, ethjs-util@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== @@ -2147,12 +4876,34 @@ ethjs-util@0.1.6, ethjs-util@^0.1.6: is-hex-prefixed "1.0.0" strip-hex-prefix "1.0.0" +ethval@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ethval/-/ethval-2.1.1.tgz#3d2a2d07ed799a0a02f1d4e7fc8098a43596d563" + integrity sha512-XpmquiApE7bnLUNRfSiv6RVMem84CZEJqcGPLHiaNEqsEppR10+ETeLq2OWcPFcG17RCxRD+HBY5xEi12RH7KA== + dependencies: + decimal.js "^10.0.1" + event-target-shim@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== -evp_bytestokey@^1.0.3: +eventemitter3@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" + integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== + +eventemitter3@4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" + integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== + +events@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== @@ -2160,6 +4911,50 @@ evp_bytestokey@^1.0.3: md5.js "^1.3.4" safe-buffer "^5.1.1" +express@^4.14.0, express@^4.17.1: + version "4.18.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +ext@^1.1.2: + version "1.7.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" + integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== + dependencies: + type "^2.7.2" + extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" @@ -2175,6 +4970,25 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== +fake-merkle-patricia-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz#4b8c3acfb520afadf9860b1f14cd8ce3402cddd3" + integrity sha512-Tgq37lkc9pUIgIKw5uitNUKcgcYL3R6JvXtKQbOf/ZSavXbidsksgp/pAY6p//uhw0I4yoMsvTSovvVIsk/qxA== + dependencies: + checkpoint-store "^1.1.0" + +fast-base64-decode@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz#b434a0dd7d92b12b43f26819300d2dafb83ee418" + integrity sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q== + +fast-check@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-check/-/fast-check-3.1.1.tgz#72c5ae7022a4e86504762e773adfb8a5b0b01252" + integrity sha512-3vtXinVyuUKCKFKYcwXhGE6NtGWkqF8Yh3rvMZNzmwz8EPrgoc/v4pDdLHyLnCyCI5MZpZZkDEwFyXyEONOxpA== + dependencies: + pure-rand "^5.0.1" + fast-deep-equal@^3.1.1: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -2201,6 +5015,11 @@ fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== +fast-safe-stringify@^2.0.6: + version "2.1.1" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" + integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== + fastq@^1.6.0: version "1.15.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" @@ -2208,6 +5027,40 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== + dependencies: + pend "~1.2.0" + +fetch-ponyfill@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz#ae3ce5f732c645eab87e4ae8793414709b239893" + integrity sha512-knK9sGskIg2T7OnYLdZ2hZXn0CtDrAIBxYQLpmEf0BqfdWnwmM1weccUl5+4EdA44tzNSFAuxITPbXtPehUB3g== + dependencies: + node-fetch "~1.7.1" + +file-type@^3.8.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" + integrity sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA== + +file-type@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" + integrity sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ== + +file-type@^6.1.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" + integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -2215,6 +5068,19 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + find-replace@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" @@ -2237,6 +5103,14 @@ find-up@5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA== + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" @@ -2244,6 +5118,13 @@ find-up@^2.1.0: dependencies: locate-path "^2.0.0" +find-yarn-workspace-root@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd" + integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ== + dependencies: + micromatch "^4.0.2" + flat@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.1.tgz#a392059cc382881ff98642f5da4dde0a959f309b" @@ -2263,12 +5144,12 @@ fmix@^0.1.0: dependencies: imul "^1.0.0" -follow-redirects@^1.12.1, follow-redirects@^1.14.0: +follow-redirects@^1.10.0, follow-redirects@^1.12.1, follow-redirects@^1.14.0, follow-redirects@^1.15.0: version "1.15.2" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== -for-each@^0.3.3: +for-each@^0.3.3, for-each@~0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== @@ -2280,6 +5161,11 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== +form-data-encoder@1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.1.tgz#ac80660e4f87ee0d3d3c3638b7da8278ddb8ec96" + integrity sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg== + form-data@^2.2.0: version "2.5.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" @@ -2307,6 +5193,11 @@ form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + fp-ts@1.19.3: version "1.19.3" resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" @@ -2317,6 +5208,16 @@ fp-ts@^1.0.0: resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a" integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A== +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + fs-extra@^0.30.0: version "0.30.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" @@ -2337,6 +5238,15 @@ fs-extra@^10.0.0: jsonfile "^6.0.1" universalify "^2.0.0" +fs-extra@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-extra@^7.0.0, fs-extra@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" @@ -2355,7 +5265,7 @@ fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@^9.1.0: +fs-extra@^9.0.0, fs-extra@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== @@ -2365,6 +5275,13 @@ fs-extra@^9.1.0: jsonfile "^6.0.1" universalify "^2.0.0" +fs-minipass@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== + dependencies: + minipass "^2.6.0" + fs-readdir-recursive@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" @@ -2410,7 +5327,26 @@ functions-have-names@^1.2.2, functions-have-names@^1.2.3: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== -get-caller-file@^2.0.1, get-caller-file@^2.0.5: +generate-function@^2.0.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f" + integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ== + dependencies: + is-property "^1.0.2" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + integrity sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ== + dependencies: + is-property "^1.0.0" + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-caller-file@^2.0.1, get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== @@ -2435,6 +5371,38 @@ get-port@^3.1.0: resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" integrity sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg== +get-stream@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" + integrity sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA== + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ== + +get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + get-symbol-description@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" @@ -2512,7 +5480,7 @@ glob@^5.0.15: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.0, glob@^7.1.3: +glob@^7.0.0, glob@^7.1.3, glob@~7.2.3: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -2540,6 +5508,19 @@ global-prefix@^3.0.0: kind-of "^6.0.2" which "^1.3.1" +global@~4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" + integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== + dependencies: + min-document "^2.19.0" + process "^0.11.10" + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== + globalthis@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" @@ -2568,7 +5549,80 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0: +got@12.1.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/got/-/got-12.1.0.tgz#099f3815305c682be4fd6b0ee0726d8e4c6b0af4" + integrity sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig== + dependencies: + "@sindresorhus/is" "^4.6.0" + "@szmarczak/http-timer" "^5.0.1" + "@types/cacheable-request" "^6.0.2" + "@types/responselike" "^1.0.0" + cacheable-lookup "^6.0.4" + cacheable-request "^7.0.2" + decompress-response "^6.0.0" + form-data-encoder "1.7.1" + get-stream "^6.0.1" + http2-wrapper "^2.1.10" + lowercase-keys "^3.0.0" + p-cancelable "^3.0.0" + responselike "^2.0.0" + +got@9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + dependencies: + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + +got@^11.8.5: + version "11.8.6" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" + integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== + dependencies: + "@sindresorhus/is" "^4.0.0" + "@szmarczak/http-timer" "^4.0.5" + "@types/cacheable-request" "^6.0.1" + "@types/responselike" "^1.0.0" + cacheable-lookup "^5.0.3" + cacheable-request "^7.0.2" + decompress-response "^6.0.0" + http2-wrapper "^1.0.0-beta.5.2" + lowercase-keys "^2.0.0" + p-cancelable "^2.0.0" + responselike "^2.0.0" + +got@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" + integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw== + dependencies: + decompress-response "^3.2.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-plain-obj "^1.1.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + p-cancelable "^0.3.0" + p-timeout "^1.1.1" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + url-parse-lax "^1.0.0" + url-to-options "^1.0.1" + +graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -2702,6 +5756,13 @@ hardhat@^2.14.0: uuid "^8.3.2" ws "^7.4.6" +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg== + dependencies: + ansi-regex "^2.0.0" + has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" @@ -2734,11 +5795,23 @@ has-proto@^1.0.1: resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== +has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== + has-symbols@^1.0.0, has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== +has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== + dependencies: + has-symbol-support-x "^1.4.1" + has-tostringtag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" @@ -2746,7 +5819,7 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" -has@^1.0.3: +has@^1.0.3, has@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== @@ -2778,16 +5851,43 @@ hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: inherits "^2.0.3" minimalistic-assert "^1.0.1" +hdkey@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/hdkey/-/hdkey-1.1.2.tgz#c60f9cf6f90fbf24a8a52ea06893f36a0108cd3e" + integrity sha512-PTQ4VKu0oRnCrYfLp04iQZ7T2Cxz0UsEXYauk2j8eh6PJXCpbXuCFhOmtIFtbET0i3PMWmHN9J11gU8LEgUljQ== + dependencies: + bs58check "^2.1.2" + safe-buffer "^5.1.1" + secp256k1 "^3.0.1" + he@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +header-case@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/header-case/-/header-case-1.0.1.tgz#9535973197c144b09613cd65d317ef19963bd02d" + integrity sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ== + dependencies: + no-case "^2.2.0" + upper-case "^1.1.3" + "heap@>= 0.2.0": version "0.2.7" resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.7.tgz#1e6adf711d3f27ce35a81fe3b7bd576c2260a8fc" integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg== +highlight.js@^10.4.1: + version "10.7.3" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" + integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== + +highlightjs-solidity@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/highlightjs-solidity/-/highlightjs-solidity-2.0.6.tgz#e7a702a2b05e0a97f185e6ba39fd4846ad23a990" + integrity sha512-DySXWfQghjm2l6a/flF+cteroJqD4gI8GSdL4PtvxZSsAHie8m3yVe2JFoRg03ROKT6hp2Lc/BxXkqerNmtQYg== + hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -2797,6 +5897,29 @@ hmac-drbg@^1.0.1: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + integrity sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +htmlparser2@^8.0.1: + version "8.0.2" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21" + integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + entities "^4.4.0" + http-basic@^8.1.1: version "8.1.3" resolved "https://registry.yarnpkg.com/http-basic/-/http-basic-8.1.3.tgz#a7cabee7526869b9b710136970805b1004261bbf" @@ -2807,6 +5930,11 @@ http-basic@^8.1.1: http-response-object "^3.0.1" parse-cache-control "^1.0.1" +http-cache-semantics@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + http-errors@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" @@ -2818,6 +5946,11 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" +http-https@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b" + integrity sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg== + http-response-object@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/http-response-object/-/http-response-object-3.0.2.tgz#7f435bb210454e4360d074ef1f989d5ea8aa9810" @@ -2834,6 +5967,22 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" +http2-wrapper@^1.0.0-beta.5.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" + integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.0.0" + +http2-wrapper@^2.1.10: + version "2.2.0" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.2.0.tgz#b80ad199d216b7d3680195077bd7b9060fa9d7f3" + integrity sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.2.0" + https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -2849,7 +5998,21 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -ieee754@^1.2.1: +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +idna-uts46-hx@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz#a1dc5c4df37eee522bf66d969cc980e00e8711f9" + integrity sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA== + dependencies: + punycode "2.1.0" + +ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -2859,6 +6022,16 @@ ignore@^5.1.1: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== +immediate@^3.2.3: + version "3.3.0" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.3.0.tgz#1aef225517836bcdf7f2a2de2600c79ff0269266" + integrity sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q== + +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== + immutable@^4.0.0-rc.12: version "4.3.0" resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.0.tgz#eb1738f14ffb39fd068b1dbe1296117484dd34be" @@ -2882,7 +6055,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -2906,6 +6079,18 @@ interpret@^1.0.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== +invariant@^2.2.2: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ== + io-ts@1.10.4: version "1.10.4" resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" @@ -2913,6 +6098,19 @@ io-ts@1.10.4: dependencies: fp-ts "^1.0.0" +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" @@ -2922,6 +6120,11 @@ is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: get-intrinsic "^1.2.0" is-typed-array "^1.1.10" +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + is-bigint@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" @@ -2954,6 +6157,13 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + is-core-module@^2.11.0: version "2.12.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" @@ -2968,11 +6178,33 @@ is-date-object@^1.0.1: dependencies: has-tostringtag "^1.0.0" +is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== +is-finite@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" + integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== + +is-fn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fn/-/is-fn-1.0.0.tgz#9543d5de7bcf5b08a22ec8a20bae6e286d510d8c" + integrity sha512-XoFPJQmsAShb3jEQRfzf2rqXavq7fIqF/jOekp308JlThqrODnMpweVSGilKTCXELfLhltGP2AGgbQGVP8F1dg== + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -2983,6 +6215,18 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== +is-function@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" + integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== + +is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" @@ -2995,6 +6239,34 @@ is-hex-prefixed@1.0.0: resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" integrity sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA== +is-lower-case@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-lower-case/-/is-lower-case-1.1.3.tgz#7e147be4768dc466db3bfb21cc60b31e6ad69393" + integrity sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA== + dependencies: + lower-case "^1.1.0" + +is-my-ip-valid@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-my-ip-valid/-/is-my-ip-valid-1.0.1.tgz#f7220d1146257c98672e6fba097a9f3f2d348442" + integrity sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg== + +is-my-json-valid@^2.20.6: + version "2.20.6" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz#a9d89e56a36493c77bda1440d69ae0dc46a08387" + integrity sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw== + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + is-my-ip-valid "^1.0.0" + jsonpointer "^5.0.0" + xtend "^4.0.0" + +is-natural-number@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" + integrity sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ== + is-negative-zero@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" @@ -3012,12 +6284,27 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" + integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== + +is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== + is-plain-obj@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== -is-regex@^1.1.4: +is-property@^1.0.0, is-property@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + integrity sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g== + +is-regex@^1.0.4, is-regex@^1.1.4, is-regex@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== @@ -3025,6 +6312,11 @@ is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-retry-allowed@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" + integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== + is-shared-array-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" @@ -3032,6 +6324,11 @@ is-shared-array-buffer@^1.0.2: dependencies: call-bind "^1.0.2" +is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== + is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" @@ -3057,7 +6354,14 @@ is-typed-array@^1.1.10, is-typed-array@^1.1.9: gopd "^1.0.1" has-tostringtag "^1.0.0" -is-typedarray@~1.0.0: +is-typed-array@^1.1.3: + version "1.1.12" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" + integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== + dependencies: + which-typed-array "^1.1.11" + +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== @@ -3067,6 +6371,18 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +is-upper-case@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-upper-case/-/is-upper-case-1.1.2.tgz#8d0b1fa7e7933a1e58483600ec7d9661cbaf756f" + integrity sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw== + dependencies: + upper-case "^1.1.0" + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== + is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" @@ -3074,32 +6390,70 @@ is-weakref@^1.0.2: dependencies: call-bind "^1.0.2" -isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== +is-wsl@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== -isarray@~1.0.0: +isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== +isomorphic-unfetch@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz#87341d5f4f7b63843d468438128cb087b7c3e98f" + integrity sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q== + dependencies: + node-fetch "^2.6.1" + unfetch "^4.2.0" + +isomorphic-ws@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" + integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== + isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== +isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + +js-cookie@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8" + integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ== + js-sdsl@^4.1.4: version "4.4.1" resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.1.tgz#9e3c7b566d8d9a7e1fe8fc26d00b5ab0f8918ab3" integrity sha512-6Gsx8R0RucyePbWqPssR8DyfuXmLBooYN5cZFZKjHGnQuaf7pEzhtpceagJxVu4LqhYY5EYA7nko3FmeHZ1KbA== -js-sha3@0.5.7: +js-sha3@0.5.7, js-sha3@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" integrity sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g== @@ -3109,6 +6463,16 @@ js-sha3@0.8.0, js-sha3@^0.8.0: resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg== + js-yaml@3.13.1: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" @@ -3137,6 +6501,66 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + integrity sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== + +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ== + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +json-rpc-engine@^3.4.0, json-rpc-engine@^3.6.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz#9d4ff447241792e1d0a232f6ef927302bb0c62a9" + integrity sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA== + dependencies: + async "^2.0.1" + babel-preset-env "^1.7.0" + babelify "^7.3.0" + json-rpc-error "^2.0.0" + promise-to-callback "^1.0.0" + safe-event-emitter "^1.0.1" + +json-rpc-engine@^5.1.3, json-rpc-engine@^5.3.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-5.4.0.tgz#75758609d849e1dba1e09021ae473f3ab63161e5" + integrity sha512-rAffKbPoNDjuRnXkecTjnsE3xLLrb00rEkdgalINhaYVYIxDwWtvYBr9UFbhTvPB1B2qUOLoFd/cV6f4Q7mh7g== + dependencies: + eth-rpc-errors "^3.0.0" + safe-event-emitter "^1.0.1" + +json-rpc-engine@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-6.1.0.tgz#bf5ff7d029e1c1bf20cb6c0e9f348dcd8be5a393" + integrity sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ== + dependencies: + "@metamask/safe-event-emitter" "^2.0.0" + eth-rpc-errors "^4.0.2" + +json-rpc-error@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/json-rpc-error/-/json-rpc-error-2.0.0.tgz#a7af9c202838b5e905c7250e547f1aff77258a02" + integrity sha512-EwUeWP+KgAZ/xqFpaP6YDAXMtCJi+o/QQpCQFIYyxr01AdADi2y413eM8hSqJcoQym9WMePAJWoaODEJufC4Ug== + dependencies: + inherits "^2.0.1" + +json-rpc-random-id@^1.0.0, json-rpc-random-id@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz#ba49d96aded1444dbb8da3d203748acbbcdec8c8" + integrity sha512-RJ9YYNCkhVDBuP4zN5BBtYAzEl03yq/jIIsyif0JY9qyJuQQZNeDK7anAPKKlyEtLSj2s8h6hNh2F8zO5q7ScA== + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -3152,11 +6576,23 @@ json-schema@0.4.0: resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== +json-stable-stringify@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz#e06f23128e0bbe342dc996ed5a19e28b57b580e0" + integrity sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g== + dependencies: + jsonify "^0.0.1" + json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== +json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw== + jsonfile@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" @@ -3180,6 +6616,21 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" +jsonify@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.1.tgz#2aa3111dae3d34a0f151c63f3a45d995d9420978" + integrity sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg== + +jsonpointer@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559" + integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== + +jsonrpc-lite@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/jsonrpc-lite/-/jsonrpc-lite-2.2.0.tgz#fb3aa9d292c8970eb7f83c6040c6554767bbc6a6" + integrity sha512-/cbbSxtZWs1O7R4tWqabrCM/t3N8qKUZMAg9IUqpPvUs6UyRvm6pCNYkskyKN/XU0UgffW+NY2ZRr8t0AknX7g== + jsonschema@^1.2.4: version "1.4.1" resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.1.tgz#cc4c3f0077fb4542982973d8a083b6b34f482dab" @@ -3204,11 +6655,32 @@ keccak@^3.0.0, keccak@^3.0.2: node-gyp-build "^4.2.0" readable-stream "^3.6.0" +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + +keyv@^4.0.0: + version "4.5.3" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.3.tgz#00873d2b046df737963157bd04f294ca818c9c25" + integrity sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug== + dependencies: + json-buffer "3.0.1" + kind-of@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== +klaw-sync@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/klaw-sync/-/klaw-sync-6.0.0.tgz#1fd2cfd56ebb6250181114f0a581167099c2b28c" + integrity sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ== + dependencies: + graceful-fs "^4.1.11" + klaw@^1.0.0: version "1.3.1" resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" @@ -3216,6 +6688,42 @@ klaw@^1.0.0: optionalDependencies: graceful-fs "^4.1.9" +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw== + dependencies: + invert-kv "^1.0.0" + +level-codec@~7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-7.0.1.tgz#341f22f907ce0f16763f24bddd681e395a0fb8a7" + integrity sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ== + +level-errors@^1.0.3: + version "1.1.2" + resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.1.2.tgz#4399c2f3d3ab87d0625f7e3676e2d807deff404d" + integrity sha512-Sw/IJwWbPKF5Ai4Wz60B52yj0zYeqzObLh8k1Tk88jVmD51cJSKWSYpRyhVIvFzZdvsPqlH5wfhp/yxdsaQH4w== + dependencies: + errno "~0.1.1" + +level-errors@~1.0.3: + version "1.0.5" + resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.0.5.tgz#83dbfb12f0b8a2516bdc9a31c4876038e227b859" + integrity sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig== + dependencies: + errno "~0.1.1" + +level-iterator-stream@~1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz#e43b78b1a8143e6fa97a4f485eb8ea530352f2ed" + integrity sha512-1qua0RHNtr4nrZBgYlpV0qHHeHpcRRWTxEZJ8xsemoHAXNL5tbooh4tPEEqIqsbWCAJBmUmkwYK/sW5OrFjWWw== + dependencies: + inherits "^2.0.1" + level-errors "^1.0.3" + readable-stream "^1.0.33" + xtend "^4.0.0" + level-supports@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a" @@ -3229,6 +6737,14 @@ level-transcoder@^1.0.1: buffer "^6.0.3" module-error "^1.0.1" +level-ws@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-0.0.0.tgz#372e512177924a00424b0b43aef2bb42496d228b" + integrity sha512-XUTaO/+Db51Uiyp/t7fCMGVFOTdtLS/NIACxE/GHsij15mKzxksZifKVjlXDF41JMUP/oM1Oc4YNGdKnc3dVLw== + dependencies: + readable-stream "~1.0.15" + xtend "~2.1.1" + level@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/level/-/level-8.0.0.tgz#41b4c515dabe28212a3e881b61c161ffead14394" @@ -3237,6 +6753,19 @@ level@^8.0.0: browser-level "^1.0.1" classic-level "^1.2.0" +levelup@^1.2.1: + version "1.3.9" + resolved "https://registry.yarnpkg.com/levelup/-/levelup-1.3.9.tgz#2dbcae845b2bb2b6bea84df334c475533bbd82ab" + integrity sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ== + dependencies: + deferred-leveldown "~1.2.1" + level-codec "~7.0.0" + level-errors "~1.0.3" + level-iterator-stream "~1.3.0" + prr "~1.0.1" + semver "~5.4.1" + xtend "~4.0.0" + levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -3245,6 +6774,31 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +lie@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" + integrity sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw== + dependencies: + immediate "~3.0.5" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A== + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +localforage@^1.3.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.10.0.tgz#5c465dc5f62b2807c3a84c0c6a1b1b3212781dd4" + integrity sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg== + dependencies: + lie "3.1.1" + locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -3268,6 +6822,11 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" +lodash.assign@^4.0.3, lodash.assign@^4.0.6: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" + integrity sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw== + lodash.camelcase@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" @@ -3278,17 +6837,27 @@ lodash.clonedeep@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== + lodash.isequal@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + lodash.truncate@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== -lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21: +lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -3308,6 +6877,18 @@ log-symbols@4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" +loglevel@^1.7.0: + version "1.8.1" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.8.1.tgz#5c621f83d5b48c54ae93b6156353f555963377b4" + integrity sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg== + +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + loupe@^2.3.1: version "2.3.6" resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.6.tgz#76e4af498103c532d1ecc9be102036a21f787b53" @@ -3315,6 +6896,33 @@ loupe@^2.3.1: dependencies: get-func-name "^2.0.0" +lower-case-first@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/lower-case-first/-/lower-case-first-1.0.2.tgz#e5da7c26f29a7073be02d52bac9980e5922adfa1" + integrity sha512-UuxaYakO7XeONbKrZf5FEgkantPf5DUqDayzP5VXZrtRPdH86s4kN47I8B3TW10S4QKiE3ziHNf3kRN//okHjA== + dependencies: + lower-case "^1.1.2" + +lower-case@^1.1.0, lower-case@^1.1.1, lower-case@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + integrity sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA== + +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lowercase-keys@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" + integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -3334,6 +6942,18 @@ lru_map@^0.3.3: resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" integrity sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ== +ltgt@~2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" + integrity sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA== + +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" @@ -3363,6 +6983,23 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +memdown@^1.0.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/memdown/-/memdown-1.4.1.tgz#b4e4e192174664ffbae41361aa500f3119efe215" + integrity sha512-iVrGHZB8i4OQfM155xx8akvG9FIj+ht14DX5CQkCTG4EHzZ3d3sgckIf/Lm9ivZalEsFuEVnWv2B2WZvbrro2w== + dependencies: + abstract-leveldown "~2.7.1" + functional-red-black-tree "^1.0.1" + immediate "^3.2.3" + inherits "~2.0.1" + ltgt "~2.2.0" + safe-buffer "~5.1.1" + memory-level@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/memory-level/-/memory-level-1.0.0.tgz#7323c3fd368f9af2f71c3cd76ba403a17ac41692" @@ -3377,12 +7014,36 @@ memorystream@^0.3.1: resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + merge2@^1.2.3, merge2@^1.3.0: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -micromatch@^4.0.4: +merkle-patricia-tree@^2.1.2, merkle-patricia-tree@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz#982ca1b5a0fde00eed2f6aeed1f9152860b8208a" + integrity sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g== + dependencies: + async "^1.4.2" + ethereumjs-util "^5.0.0" + level-ws "0.0.0" + levelup "^1.2.1" + memdown "^1.0.0" + readable-stream "^2.0.0" + rlp "^2.0.0" + semaphore ">=1.0.1" + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromatch@^4.0.2, micromatch@^4.0.4: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== @@ -3390,18 +7051,48 @@ micromatch@^4.0.4: braces "^3.0.2" picomatch "^2.3.1" +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12, mime-types@~2.1.19: +mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-response@^1.0.0, mimic-response@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ== + dependencies: + dom-walk "^0.1.0" + minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -3433,11 +7124,38 @@ minimatch@5.0.1: dependencies: brace-expansion "^2.0.1" -minimist@^1.2.5, minimist@^1.2.6: +minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.7, minimist@~1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== +minipass@^2.6.0, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== + dependencies: + minipass "^2.9.0" + +mkdirp-promise@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1" + integrity sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w== + dependencies: + mkdirp "*" + +mkdirp@*: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" + integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== + mkdirp@0.5.5: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" @@ -3445,7 +7163,7 @@ mkdirp@0.5.5: dependencies: minimist "^1.2.5" -mkdirp@0.5.x: +mkdirp@0.5.x, mkdirp@^0.5.1, mkdirp@^0.5.5, mkdirp@~0.5.1: version "0.5.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== @@ -3551,11 +7269,21 @@ mocha@^7.1.1: yargs-parser "13.1.2" yargs-unparser "1.6.0" +mock-fs@^4.1.0: + version "4.14.0" + resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.14.0.tgz#ce5124d2c601421255985e6e94da80a7357b1b18" + integrity sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw== + module-error@^1.0.1, module-error@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA== +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + ms@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" @@ -3571,6 +7299,46 @@ ms@2.1.3, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +multibase@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.7.0.tgz#1adfc1c50abe05eefeb5091ac0c2728d6b84581b" + integrity sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg== + dependencies: + base-x "^3.0.8" + buffer "^5.5.0" + +multibase@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.6.1.tgz#b76df6298536cc17b9f6a6db53ec88f85f8cc12b" + integrity sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw== + dependencies: + base-x "^3.0.8" + buffer "^5.5.0" + +multicodec@^0.5.5: + version "0.5.7" + resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-0.5.7.tgz#1fb3f9dd866a10a55d226e194abba2dcc1ee9ffd" + integrity sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA== + dependencies: + varint "^5.0.0" + +multicodec@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-1.0.4.tgz#46ac064657c40380c28367c90304d8ed175a714f" + integrity sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg== + dependencies: + buffer "^5.6.0" + varint "^5.0.0" + +multihashes@^0.4.15, multihashes@~0.4.15: + version "0.4.21" + resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-0.4.21.tgz#dc02d525579f334a7909ade8a122dabb58ccfcb5" + integrity sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw== + dependencies: + buffer "^5.5.0" + multibase "^0.7.0" + varint "^5.0.0" + murmur-128@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/murmur-128/-/murmur-128-0.2.1.tgz#a9f6568781d2350ecb1bf80c14968cadbeaa4b4d" @@ -3580,6 +7348,21 @@ murmur-128@^0.2.1: fmix "^0.1.0" imul "^1.0.0" +nan@^2.0.8, nan@^2.14.0: + version "2.17.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" + integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== + +nano-base32@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/nano-base32/-/nano-base32-1.0.1.tgz#ba548c879efcfb90da1c4d9e097db4a46c9255ef" + integrity sha512-sxEtoTqAPdjWVGv71Q17koMFGsOMSiHsIFEvzOM7cNp8BXB4AnEwmDabm5dorusJf/v1z7QxaZYxUorU9RKaAw== + +nano-json-stream-parser@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" + integrity sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew== + nanoid@3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" @@ -3590,11 +7373,51 @@ napi-macros@^2.2.2: resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.2.2.tgz#817fef20c3e0e40a963fbf7b37d1600bd0201044" integrity sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g== +nedb-async@^0.1.3: + version "0.1.6" + resolved "https://registry.yarnpkg.com/nedb-async/-/nedb-async-0.1.6.tgz#0a2b7937f346fa586dca4b99b8c74196b073a4f4" + integrity sha512-q01WccZA4R/bkxWueY4fxafMe68Z1FJpYQBreXBuVd09q6N5hZXqDD0sUDvEaxZQy+xG7f3tQsgtwLPTl0xk2g== + dependencies: + nedb "^1.8.0" + +nedb@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/nedb/-/nedb-1.8.0.tgz#0e3502cd82c004d5355a43c9e55577bd7bd91d88" + integrity sha512-ip7BJdyb5m+86ZbSb4y10FCCW9g35+U8bDRrZlAfCI6m4dKwEsQ5M52grcDcVK4Vm/vnPlDLywkyo3GliEkb5A== + dependencies: + async "0.2.10" + binary-search-tree "0.2.5" + localforage "^1.3.0" + mkdirp "~0.5.1" + underscore "~1.4.4" + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + neo-async@^2.6.0: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +no-case@^2.2.0, no-case@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" + integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== + dependencies: + lower-case "^1.1.1" + node-addon-api@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" @@ -3615,11 +7438,36 @@ node-environment-flags@1.0.6: object.getownpropertydescriptors "^2.0.3" semver "^5.7.0" +node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.12, node-fetch@^2.6.7: + version "2.6.12" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.12.tgz#02eb8e22074018e3d5a83016649d04df0e348fba" + integrity sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g== + dependencies: + whatwg-url "^5.0.0" + +node-fetch@~1.7.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: version "4.6.0" resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== +node-releases@^2.0.13: + version "2.0.13" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== + +nofilter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-1.0.4.tgz#78d6f4b6a613e7ced8b015cec534625f7667006e" + integrity sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA== + nofilter@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-3.1.0.tgz#c757ba68801d41ff930ba2ec55bab52ca184aa66" @@ -3632,11 +7480,43 @@ nopt@3.x: dependencies: abbrev "1" +normalize-package-data@^2.3.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== +normalize-url@^4.1.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" + integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== + +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== + +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== + number-to-bn@1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" @@ -3650,21 +7530,34 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -object-assign@^4.1.0: +object-assign@^4, object-assign@^4.0.0, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== -object-inspect@^1.12.3, object-inspect@^1.9.0: +object-inspect@^1.12.3, object-inspect@^1.9.0, object-inspect@~1.12.3: version "1.12.3" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== +object-is@^1.0.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + object-keys@^1.0.11, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== +object-keys@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" + integrity sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw== + object.assign@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" @@ -3701,13 +7594,42 @@ obliterator@^2.0.0: resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.4.tgz#fa650e019b2d075d745e44f1effeb13a2adbe816" integrity sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ== -once@1.x, once@^1.3.0: +oboe@2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.4.tgz#20c88cdb0c15371bb04119257d4fdd34b0aa49f6" + integrity sha512-ymBJ4xSC6GBXLT9Y7lirj+xbqBLa+jADGJldGEYG7u8sZbS9GyG+u1Xk9c5cbriKwSpCg41qUhPjvU5xOpvIyQ== + dependencies: + http-https "^1.0.0" + +oboe@2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.5.tgz#5554284c543a2266d7a38f17e073821fbde393cd" + integrity sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA== + dependencies: + http-https "^1.0.0" + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" +open@^7.4.2: + version "7.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" + integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== + dependencies: + is-docker "^2.0.0" + is-wsl "^2.1.1" + optionator@^0.8.1: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" @@ -3725,11 +7647,55 @@ ordinal@^1.0.3: resolved "https://registry.yarnpkg.com/ordinal/-/ordinal-1.0.3.tgz#1a3c7726a61728112f50944ad7c35c06ae3a0d4d" integrity sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ== -os-tmpdir@~1.0.2: +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ== + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g== + dependencies: + lcid "^1.0.0" + +os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== +ow@^0.17.0: + version "0.17.0" + resolved "https://registry.yarnpkg.com/ow/-/ow-0.17.0.tgz#4f938999fed6264c9048cd6254356e0f1e7f688c" + integrity sha512-i3keDzDQP5lWIe4oODyDFey1qVrq2hXKTuTH2VpqwpYtzPiKZt2ziRI4NBQmgW40AnV5Euz17OyWweCb+bNEQA== + dependencies: + type-fest "^0.11.0" + +p-cancelable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" + integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw== + +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== + +p-cancelable@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" + integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== + +p-cancelable@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050" + integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw== + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== + p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -3779,6 +7745,13 @@ p-map@^4.0.0: dependencies: aggregate-error "^3.0.0" +p-timeout@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" + integrity sha512-gb0ryzr+K2qFqFv6qi3khoeqMZF/+ajxQipEF6NteZVnvz9tzdsfAVj3lYtn1gAXvH5lfLwfxEII799gt/mRIA== + dependencies: + p-finally "^1.0.0" + p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" @@ -3789,11 +7762,103 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +param-case@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" + integrity sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w== + dependencies: + no-case "^2.2.0" + +parse-asn1@^5.0.0, parse-asn1@^5.1.5: + version "5.1.6" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" + integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== + dependencies: + asn1.js "^5.2.0" + browserify-aes "^1.0.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + parse-cache-control@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/parse-cache-control/-/parse-cache-control-1.0.1.tgz#8eeab3e54fa56920fe16ba38f77fa21aacc2d74e" integrity sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg== +parse-headers@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.5.tgz#069793f9356a54008571eb7f9761153e6c770da9" + integrity sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA== + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ== + dependencies: + error-ex "^1.2.0" + +parse5-htmlparser2-tree-adapter@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz#23c2cc233bcf09bb7beba8b8a69d46b08c62c2f1" + integrity sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g== + dependencies: + domhandler "^5.0.2" + parse5 "^7.0.0" + +parse5@^7.0.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32" + integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== + dependencies: + entities "^4.4.0" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascal-case@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-2.0.1.tgz#2d578d3455f660da65eca18ef95b4e0de912761e" + integrity sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ== + dependencies: + camel-case "^3.0.0" + upper-case-first "^1.1.0" + +patch-package@^6.2.2: + version "6.5.1" + resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.5.1.tgz#3e5d00c16997e6160291fee06a521c42ac99b621" + integrity sha512-I/4Zsalfhc6bphmJTlrLoOcAF87jcxko4q0qsv4bGcurbr8IskEOtdnt9iCmsQVGL1B+iUhSQqweyTLJfCF9rA== + dependencies: + "@yarnpkg/lockfile" "^1.1.0" + chalk "^4.1.2" + cross-spawn "^6.0.5" + find-yarn-workspace-root "^2.0.0" + fs-extra "^9.0.0" + is-ci "^2.0.0" + klaw-sync "^6.0.0" + minimist "^1.2.6" + open "^7.4.2" + rimraf "^2.6.3" + semver "^5.6.0" + slash "^2.0.0" + tmp "^0.0.33" + yaml "^1.10.2" + +path-case@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/path-case/-/path-case-2.1.1.tgz#94b8037c372d3fe2906e465bb45e25d226e8eea5" + integrity sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q== + dependencies: + no-case "^2.2.0" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ== + dependencies: + pinkie-promise "^2.0.0" + path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -3804,16 +7869,35 @@ path-exists@^4.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== -path-is-absolute@^1.0.0: +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== +path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== + path-parse@^1.0.6, path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg== + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -3824,7 +7908,7 @@ pathval@^1.1.1: resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== -pbkdf2@^3.0.17: +pbkdf2@^3.0.17, pbkdf2@^3.0.3, pbkdf2@^3.0.9: version "3.1.2" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== @@ -3835,36 +7919,106 @@ pbkdf2@^3.0.17: safe-buffer "^5.0.1" sha.js "^2.4.8" +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== + performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +pify@^2.0.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== + pify@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== +pify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f" + integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== + +precond@0.2: + version "0.2.3" + resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac" + integrity sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ== + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg== + +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA== + prettier@^2.3.1: version "2.8.8" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== +private@^0.1.6, private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + +promise-to-callback@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/promise-to-callback/-/promise-to-callback-1.0.0.tgz#5d2a749010bfb67d963598fcd3960746a68feef7" + integrity sha512-uhMIZmKM5ZteDMfLgJnoSq9GCwsNKrYau73Awf1jIy6/eUcuuZ3P+CD9zUv0kJsIUbU+x6uLNIhXhLHDs1pNPA== + dependencies: + is-fn "^1.0.0" + set-immediate-shim "^1.0.1" + promise@^8.0.0: version "8.3.0" resolved "https://registry.yarnpkg.com/promise/-/promise-8.3.0.tgz#8cb333d1edeb61ef23869fbb8a4ea0279ab60e0a" @@ -3872,16 +8026,80 @@ promise@^8.0.0: dependencies: asap "~2.0.6" +proper-lockfile@^4.1.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-4.1.2.tgz#c8b9de2af6b2f1601067f98e01ac66baa223141f" + integrity sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA== + dependencies: + graceful-fs "^4.2.4" + retry "^0.12.0" + signal-exit "^3.0.2" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== + psl@^1.1.28: version "1.9.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" + integrity sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA== + punycode@^2.1.0, punycode@^2.1.1: version "2.3.0" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== +pure-rand@^5.0.1: + version "5.0.5" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-5.0.5.tgz#bda2a7f6a1fc0f284d78d78ca5902f26f2ad35cf" + integrity sha512-BwQpbqxSCBJVpamI6ydzcKqyFmnd5msMWUGvzXLm1aXvusbbgkbOto/EUPM00hjveJEaJtdbhUjKSzWRhQVkaw== + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + qs@^6.4.0, qs@^6.9.4: version "6.11.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" @@ -3894,19 +8112,61 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + queue-microtask@^1.2.2, queue-microtask@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -randombytes@^2.1.0: +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.0.6, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" -raw-body@^2.4.1: +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +randomhex@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/randomhex/-/randomhex-0.1.5.tgz#baceef982329091400f2a2912c6cd02f1094f585" + integrity sha512-2+Kkw7UiZGQWOz7rw8hPW44utkBYMEciQfziaZ71RcyDu+refQWzS/0DgfUSa5MwclrOD3sf3vI5vmrTYjwpjQ== + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +raw-body@2.5.2, raw-body@^2.4.1: version "2.5.2" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== @@ -3916,7 +8176,34 @@ raw-body@^2.4.1: iconv-lite "0.4.24" unpipe "1.0.0" -readable-stream@^2.2.2: +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A== + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ== + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +readable-stream@^1.0.33: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^2.0.0, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.5, readable-stream@~2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== @@ -3938,6 +8225,16 @@ readable-stream@^3.6.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" +readable-stream@~1.0.15: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readdirp@~3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.2.0.tgz#c30c33352b12c96dfb4b895421a49fd5a9593839" @@ -3971,7 +8268,31 @@ reduce-flatten@^2.0.0: resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== -regexp.prototype.flags@^1.4.3: +regenerate@^1.2.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regenerator-runtime@^0.13.11: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + integrity sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q== + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.4.3: version "1.5.0" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb" integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== @@ -3980,6 +8301,34 @@ regexp.prototype.flags@^1.4.3: define-properties "^1.2.0" functions-have-names "^1.2.3" +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + integrity sha512-tJ9+S4oKjxY8IZ9jmjnp/mtytu1u3iyIQAfmI51IKWH6bFf7XR1ybtaO6j7INhZKXOTYADk7V5qxaqLkmNxiZQ== + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + integrity sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g== + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + integrity sha512-jlQ9gYLfk2p3V5Ag5fYhA7fv7OHzd1KUH0PRP46xc3TgwjwgROIW572AfYg/X9kaNq/LJnu6oJcFRXlIrGoTRw== + dependencies: + jsesc "~0.5.0" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A== + dependencies: + is-finite "^1.0.0" + req-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/req-cwd/-/req-cwd-2.0.0.tgz#d4082b4d44598036640fb73ddea01ed53db49ebc" @@ -4010,7 +8359,7 @@ request-promise-native@^1.0.5: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@^2.88.0: +request@^2.79.0, request@^2.85.0, request@^2.88.0: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -4041,16 +8390,31 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== +require-from-string@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" + integrity sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q== + require-from-string@^2.0.0, require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug== + require-main-filename@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== +resolve-alpn@^1.0.0, resolve-alpn@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== + resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" @@ -4068,7 +8432,7 @@ resolve@1.17.0: dependencies: path-parse "^1.0.6" -resolve@^1.1.6: +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.14.2, resolve@~1.22.1: version "1.22.2" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== @@ -4077,19 +8441,55 @@ resolve@^1.1.6: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ== + dependencies: + lowercase-keys "^1.0.0" + +responselike@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc" + integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw== + dependencies: + lowercase-keys "^2.0.0" + +resumer@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" + integrity sha512-Fn9X8rX8yYF4m81rZCK/5VmrmsSbqS/i3rDLl6ZZHAXgC2nTAx3dhwG8q8odP/RmdLa2YrybDJaAMg+X1ajY3w== + dependencies: + through "~2.3.4" + +retry@0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@^2.2.8: +rimraf@^2.2.8, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== dependencies: glob "^7.1.3" -ripemd160@^2.0.0, ripemd160@^2.0.1: +ripemd160-min@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/ripemd160-min/-/ripemd160-min-0.0.6.tgz#a904b77658114474d02503e819dcc55853b67e62" + integrity sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A== + +ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== @@ -4097,7 +8497,7 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" -rlp@^2.2.3, rlp@^2.2.4: +rlp@^2.0.0, rlp@^2.2.3, rlp@^2.2.4: version "2.2.7" resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.7.tgz#33f31c4afac81124ac4b283e2bd4d9720b30beaf" integrity sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ== @@ -4133,7 +8533,7 @@ safe-array-concat@^1.0.0: has-symbols "^1.0.3" isarray "^2.0.5" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -4143,6 +8543,13 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-event-emitter@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz#5b692ef22329ed8f69fdce607e50ca734f6f20af" + integrity sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg== + dependencies: + events "^3.0.0" + safe-regex-test@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" @@ -4152,7 +8559,7 @@ safe-regex-test@^1.0.0: get-intrinsic "^1.1.3" is-regex "^1.1.4" -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -4177,16 +8584,63 @@ sc-istanbul@^0.4.5: which "^1.1.1" wordwrap "^1.0.0" +scrypt-js@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.3.tgz#bb0040be03043da9a012a2cea9fc9f852cfc87d4" + integrity sha512-d8DzQxNivoNDogyYmb/9RD5mEQE/Q7vG2dLDUgvfPmKL9xCVzgqUntOdS0me9Cq9Sh9VxIZuoNEFcsfyXRnyUw== + scrypt-js@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw== -scrypt-js@3.0.1, scrypt-js@^3.0.0: +scrypt-js@3.0.1, scrypt-js@^3.0.0, scrypt-js@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== +scrypt.js@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/scrypt.js/-/scrypt.js-0.3.0.tgz#6c62d61728ad533c8c376a2e5e3e86d41a95c4c0" + integrity sha512-42LTc1nyFsyv/o0gcHtDztrn+aqpkaCNt5Qh7ATBZfhEZU7IC/0oT/qbBH+uRNoAPvs2fwiOId68FDEoSRA8/A== + dependencies: + scryptsy "^1.2.1" + optionalDependencies: + scrypt "^6.0.2" + +scrypt@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/scrypt/-/scrypt-6.0.3.tgz#04e014a5682b53fa50c2d5cce167d719c06d870d" + integrity sha512-NDrWb9hCm6Ev170XYVl7TSgu4R44Rjc8EVw1ce0TMN8EkfLvkhlwcfp61OVNc8EJDiHaQwVErn1fIU0RO3kSZw== + dependencies: + nan "^2.0.8" + +scryptsy@2.1.0, scryptsy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-2.1.0.tgz#8d1e8d0c025b58fdd25b6fa9a0dc905ee8faa790" + integrity sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w== + +scryptsy@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-1.2.1.tgz#a3225fa4b2524f802700761e2855bdf3b2d92163" + integrity sha512-aldIRgMozSJ/Gl6K6qmJZysRP82lz83Wb42vl4PWN8SaLFHIaOzLPc9nUUW2jQN88CuGm5q5HefJ9jZ3nWSmTw== + dependencies: + pbkdf2 "^3.0.3" + +secp256k1@^3.0.1: + version "3.8.0" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.8.0.tgz#28f59f4b01dbee9575f56a47034b7d2e3b3b352d" + integrity sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw== + dependencies: + bindings "^1.5.0" + bip66 "^1.1.5" + bn.js "^4.11.8" + create-hash "^1.2.0" + drbg.js "^1.0.1" + elliptic "^6.5.2" + nan "^2.14.0" + safe-buffer "^5.1.2" + secp256k1@^4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.3.tgz#c4559ecd1b8d3c1827ed2d1b94190d69ce267303" @@ -4196,6 +8650,35 @@ secp256k1@^4.0.1: node-addon-api "^2.0.0" node-gyp-build "^4.2.0" +seek-bzip@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.6.tgz#35c4171f55a680916b52a07859ecf3b5857f21c4" + integrity sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ== + dependencies: + commander "^2.8.1" + +semaphore@>=1.0.1, semaphore@^1.0.3: + version "1.1.0" + resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa" + integrity sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA== + +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.6.0: + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +semver@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.2.0.tgz#4d813d9590aaf8a9192693d6c85b9344de5901db" + integrity sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A== + +semver@7.5.2: + version "7.5.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.2.tgz#5b851e66d1be07c1cdaf37dfc856f543325a2beb" + integrity sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ== + dependencies: + lru-cache "^6.0.0" + semver@^5.5.0, semver@^5.7.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" @@ -4206,6 +8689,18 @@ semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.3.2: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + semver@^7.3.4: version "7.5.3" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" @@ -4213,6 +8708,38 @@ semver@^7.3.4: dependencies: lru-cache "^6.0.0" +semver@~5.4.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" + integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg== + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +sentence-case@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-2.1.1.tgz#1f6e2dda39c168bf92d13f86d4a918933f667ed4" + integrity sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ== + dependencies: + no-case "^2.2.0" + upper-case-first "^1.1.2" + serialize-javascript@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -4220,11 +8747,37 @@ serialize-javascript@6.0.0: dependencies: randombytes "^2.1.0" +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +servify@^0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/servify/-/servify-0.1.12.tgz#142ab7bee1f1d033b66d0707086085b17c06db95" + integrity sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw== + dependencies: + body-parser "^1.16.0" + cors "^2.8.1" + express "^4.14.0" + request "^2.79.0" + xhr "^2.3.3" + set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== +set-immediate-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + integrity sha512-Li5AOqrZWCVA2n5kryzEmqai6bKSIvpz5oUJHPVj6+dsbD3X1ixtsY5tEnsaNpH3pFAHmG8eIHUrtEtohrg+UQ== + setimmediate@1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.4.tgz#20e81de622d4a02588ce0c8da8973cbcf1d3138f" @@ -4256,6 +8809,25 @@ sha1@^1.1.1: charenc ">= 0.0.1" crypt ">= 0.0.1" +sha3@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/sha3/-/sha3-2.1.4.tgz#000fac0fe7c2feac1f48a25e7a31b52a6492cc8f" + integrity sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg== + dependencies: + buffer "6.0.3" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== + shelljs@^0.8.3: version "0.8.5" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" @@ -4274,6 +8846,35 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" +signal-exit@^3.0.2: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^2.7.0: + version "2.8.2" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.2.tgz#5708fb0919d440657326cd5fe7d2599d07705019" + integrity sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw== + dependencies: + decompress-response "^3.3.0" + once "^1.3.1" + simple-concat "^1.0.0" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg== + +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -4288,6 +8889,13 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" +snake-case@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-2.1.0.tgz#41bdb1b73f30ec66a04d4e2cad1b76387d4d6d9f" + integrity sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q== + dependencies: + no-case "^2.2.0" + solc@0.7.3: version "0.7.3" resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" @@ -4303,6 +8911,22 @@ solc@0.7.3: semver "^5.5.0" tmp "0.0.33" +solc@^0.4.20: + version "0.4.26" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.26.tgz#5390a62a99f40806b86258c737c1cf653cc35cb5" + integrity sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA== + dependencies: + fs-extra "^0.30.0" + memorystream "^0.3.1" + require-from-string "^1.1.0" + semver "^5.3.0" + yargs "^4.7.1" + +solidity-ast@^0.4.26: + version "0.4.49" + resolved "https://registry.yarnpkg.com/solidity-ast/-/solidity-ast-0.4.49.tgz#ecba89d10c0067845b7848c3a3e8cc61a4fc5b82" + integrity sha512-Pr5sCAj1SFqzwFZw1HPKSq0PehlQNdM8GwKyAVYh2DOn7/cCK8LUKD1HeHnKtTgBW7hi9h4nnnan7hpAg5RhWQ== + solidity-coverage@^0.8.0: version "0.8.3" resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.8.3.tgz#72ce51e5ca9ea1182bbf6085eb1cf526f0603b52" @@ -4329,7 +8953,14 @@ solidity-coverage@^0.8.0: shelljs "^0.8.3" web3-utils "^1.3.6" -source-map-support@^0.5.13: +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== + dependencies: + source-map "^0.5.6" + +source-map-support@^0.5.13, source-map-support@^0.5.16: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== @@ -4337,6 +8968,11 @@ source-map-support@^0.5.13: buffer-from "^1.0.0" source-map "^0.6.0" +source-map@^0.5.6, source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== + source-map@^0.6.0, source-map@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" @@ -4349,6 +8985,32 @@ source-map@~0.2.0: dependencies: amdefine ">=0.0.4" +spdx-correct@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.13" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz#7189a474c46f8d47c7b0da4b987bb45e908bd2d5" + integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -4391,11 +9053,25 @@ streamsearch@^1.1.0: resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ== + string-format@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b" integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA== +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + "string-width@^1.0.2 || 2", string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" @@ -4422,7 +9098,7 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string.prototype.trim@^1.2.7: +string.prototype.trim@^1.2.7, string.prototype.trim@~1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533" integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== @@ -4456,6 +9132,11 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== + string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -4463,6 +9144,13 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== + dependencies: + ansi-regex "^2.0.0" + strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -4484,6 +9172,20 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g== + dependencies: + is-utf8 "^0.2.0" + +strip-dirs@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" + integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g== + dependencies: + is-natural-number "^4.0.1" + strip-hex-prefix@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" @@ -4491,6 +9193,11 @@ strip-hex-prefix@1.0.0: dependencies: is-hex-prefixed "1.0.0" +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + integrity sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA== + strip-json-comments@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -4515,6 +9222,11 @@ supports-color@8.1.1: dependencies: has-flag "^4.0.0" +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g== + supports-color@^3.1.0: version "3.2.3" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" @@ -4541,6 +9253,49 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +swap-case@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/swap-case/-/swap-case-1.1.2.tgz#c39203a4587385fad3c850a0bd1bcafa081974e3" + integrity sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ== + dependencies: + lower-case "^1.1.1" + upper-case "^1.1.1" + +swarm-js@0.1.39: + version "0.1.39" + resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.39.tgz#79becb07f291d4b2a178c50fee7aa6e10342c0e8" + integrity sha512-QLMqL2rzF6n5s50BptyD6Oi0R1aWlJC5Y17SRIVXRj6OR1DRIPM7nepvrxxkjA1zNzFz6mUOMjfeqeDaWB7OOg== + dependencies: + bluebird "^3.5.0" + buffer "^5.0.5" + decompress "^4.0.0" + eth-lib "^0.1.26" + fs-extra "^4.0.2" + got "^7.1.0" + mime-types "^2.1.16" + mkdirp-promise "^5.0.1" + mock-fs "^4.1.0" + setimmediate "^1.0.5" + tar "^4.0.2" + xhr-request-promise "^0.1.2" + +swarm-js@^0.1.40: + version "0.1.42" + resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.42.tgz#497995c62df6696f6e22372f457120e43e727979" + integrity sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ== + dependencies: + bluebird "^3.5.0" + buffer "^5.0.5" + eth-lib "^0.1.26" + fs-extra "^4.0.2" + got "^11.8.5" + mime-types "^2.1.16" + mkdirp-promise "^5.0.1" + mock-fs "^4.1.0" + setimmediate "^1.0.5" + tar "^4.0.2" + xhr-request "^1.0.1" + sync-request@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/sync-request/-/sync-request-6.1.0.tgz#e96217565b5e50bbffe179868ba75532fb597e68" @@ -4578,6 +9333,58 @@ table@^6.8.0: string-width "^4.2.3" strip-ansi "^6.0.1" +tape@^4.6.3: + version "4.16.2" + resolved "https://registry.yarnpkg.com/tape/-/tape-4.16.2.tgz#7565e6af20426565557266e9dda7215869b297b6" + integrity sha512-TUChV+q0GxBBCEbfCYkGLkv8hDJYjMdSWdE0/Lr331sB389dsvFUHNV9ph5iQqKzt8Ss9drzcda/YeexclBFqg== + dependencies: + call-bind "~1.0.2" + deep-equal "~1.1.1" + defined "~1.0.1" + dotignore "~0.1.2" + for-each "~0.3.3" + glob "~7.2.3" + has "~1.0.3" + inherits "~2.0.4" + is-regex "~1.1.4" + minimist "~1.2.7" + object-inspect "~1.12.3" + resolve "~1.22.1" + resumer "~0.0.0" + string.prototype.trim "~1.2.7" + through "~2.3.8" + +tar-stream@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" + integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== + dependencies: + bl "^1.0.0" + buffer-alloc "^1.2.0" + end-of-stream "^1.0.0" + fs-constants "^1.0.0" + readable-stream "^2.3.0" + to-buffer "^1.1.1" + xtend "^4.0.0" + +tar@^4.0.2: + version "4.4.19" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3" + integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA== + dependencies: + chownr "^1.1.4" + fs-minipass "^1.2.7" + minipass "^2.9.0" + minizlib "^1.3.3" + mkdirp "^0.5.5" + safe-buffer "^5.2.1" + yallist "^3.1.1" + +testrpc@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/testrpc/-/testrpc-0.0.1.tgz#83e2195b1f5873aec7be1af8cbe6dcf39edb7aed" + integrity sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA== + then-request@^6.0.0: version "6.0.2" resolved "https://registry.yarnpkg.com/then-request/-/then-request-6.0.2.tgz#ec18dd8b5ca43aaee5cb92f7e4c1630e950d4f0c" @@ -4595,13 +9402,59 @@ then-request@^6.0.0: promise "^8.0.0" qs "^6.4.0" -tmp@0.0.33: +through2@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through@^2.3.8, through@~2.3.4, through@~2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + +timed-out@^4.0.0, timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA== + +title-case@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/title-case/-/title-case-2.1.1.tgz#3e127216da58d2bc5becf137ab91dae3a7cd8faa" + integrity sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q== + dependencies: + no-case "^2.2.0" + upper-case "^1.0.3" + +tmp@0.0.33, tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== dependencies: os-tmpdir "~1.0.2" +to-buffer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" + integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + integrity sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -4622,6 +9475,16 @@ tough-cookie@^2.3.3, tough-cookie@~2.5.0: psl "^1.1.28" punycode "^2.1.1" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + integrity sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw== + ts-command-line-args@^2.2.0: version "2.5.1" resolved "https://registry.yarnpkg.com/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz#e64456b580d1d4f6d948824c274cf6fa5f45f7f0" @@ -4661,11 +9524,16 @@ tslib@2.4.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== -tslib@^1.9.3: +tslib@^1.11.1, tslib@^1.9.3: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.0.0, tslib@^2.3.1, tslib@^2.5.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.1.tgz#fd8c9a0ff42590b25703c0acb3de3d3f4ede0410" + integrity sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig== + tsort@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" @@ -4678,7 +9546,7 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" -tweetnacl-util@^0.15.1: +tweetnacl-util@^0.15.0, tweetnacl-util@^0.15.1: version "0.15.1" resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== @@ -4688,7 +9556,7 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== -tweetnacl@^1.0.3: +tweetnacl@^1.0.0, tweetnacl@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== @@ -4705,6 +9573,11 @@ type-detect@^4.0.0, type-detect@^4.0.5: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== +type-fest@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" + integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== + type-fest@^0.21.3: version "0.21.3" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" @@ -4715,6 +9588,24 @@ type-fest@^0.7.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" + integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== + typechain@^8.3.1: version "8.3.1" resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.3.1.tgz#dccbc839b94877997536c356380eff7325395cfb" @@ -4740,6 +9631,13 @@ typed-array-length@^1.0.4: for-each "^0.3.3" is-typed-array "^1.1.9" +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -4765,6 +9663,11 @@ uglify-js@^3.1.4: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== + unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" @@ -4775,6 +9678,24 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" +unbzip2-stream@^1.0.9: + version "1.4.3" + resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" + integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== + dependencies: + buffer "^5.2.1" + through "^2.3.8" + +underscore@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961" + integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg== + +underscore@~1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.4.4.tgz#61a6a32010622afa07963bf325203cf12239d604" + integrity sha512-ZqGrAgaqqZM7LGRzNjLnw5elevWb5M8LEoDMadxIW3OWbcv72wMMgKdwOKpd5Fqxe8choLD8HN3iSj3TUh/giQ== + undici@^5.14.0: version "5.22.1" resolved "https://registry.yarnpkg.com/undici/-/undici-5.22.1.tgz#877d512effef2ac8be65e695f3586922e1a57d7b" @@ -4782,6 +9703,11 @@ undici@^5.14.0: dependencies: busboy "^1.6.0" +unfetch@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" + integrity sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA== + universalify@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" @@ -4792,11 +9718,36 @@ universalify@^2.0.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== -unpipe@1.0.0: +unorm@^1.3.3: + version "1.6.0" + resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.6.0.tgz#029b289661fba714f1a9af439eb51d9b16c205af" + integrity sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA== + +unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== +update-browserslist-db@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +upper-case-first@^1.1.0, upper-case-first@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-1.1.2.tgz#5d79bedcff14419518fd2edb0a0507c9b6859115" + integrity sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ== + dependencies: + upper-case "^1.1.1" + +upper-case@^1.0.3, upper-case@^1.1.0, upper-case@^1.1.1, upper-case@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" + integrity sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA== + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -4804,7 +9755,38 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -utf8@3.0.0: +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + integrity sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA== + dependencies: + prepend-http "^1.0.1" + +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ== + dependencies: + prepend-http "^2.0.0" + +url-set-query@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" + integrity sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg== + +url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + integrity sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A== + +utf-8-validate@^5.0.2: + version "5.0.10" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" + integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== + dependencies: + node-gyp-build "^4.3.0" + +utf8@3.0.0, utf8@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== @@ -4814,11 +9796,32 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== +util@^0.12.5: + version "0.12.5" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" + integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + which-typed-array "^1.1.2" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + uuid@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.1.tgz#c2a30dedb3e535d72ccf82e343941a50ba8533ac" integrity sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg== +uuid@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + uuid@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" @@ -4829,11 +9832,34 @@ uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +uuid@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" + integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== + v8-compile-cache-lib@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +varint@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.2.tgz#5b47f8a947eb668b848e034dcfa87d0ff8a7f7a4" + integrity sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow== + +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" @@ -4843,7 +9869,819 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" -web3-utils@^1.3.6: +web3-bzz@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.10.0.tgz#ac74bc71cdf294c7080a79091079192f05c5baed" + integrity sha512-o9IR59io3pDUsXTsps5pO5hW1D5zBmg46iNc2t4j2DkaYHNdDLwk2IP9ukoM2wg47QILfPEJYzhTfkS/CcX0KA== + dependencies: + "@types/node" "^12.12.6" + got "12.1.0" + swarm-js "^0.1.40" + +web3-bzz@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.1.tgz#c3bd1e8f0c02a13cd6d4e3c3e9e1713f144f6f0d" + integrity sha512-LdOO44TuYbGIPfL4ilkuS89GQovxUpmLz6C1UC7VYVVRILeZS740FVB3j9V4P4FHUk1RenaDfKhcntqgVCHtjw== + dependencies: + got "9.6.0" + swarm-js "0.1.39" + underscore "1.9.1" + +web3-bzz@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.6.tgz#0b88c0b96029eaf01b10cb47c4d5f79db4668883" + integrity sha512-9NiHLlxdI1XeFtbPJAmi2jnnIHVF+GNy517wvOS72P7ZfuJTPwZaSNXfT01vWgPPE9R96/uAHDWHOg+T4WaDQQ== + dependencies: + "@types/node" "^10.12.18" + got "9.6.0" + swarm-js "0.1.39" + underscore "1.9.1" + +web3-core-helpers@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.10.0.tgz#1016534c51a5df77ed4f94d1fcce31de4af37fad" + integrity sha512-pIxAzFDS5vnbXvfvLSpaA1tfRykAe9adw43YCKsEYQwH0gCLL0kMLkaCX3q+Q8EVmAh+e1jWL/nl9U0de1+++g== + dependencies: + web3-eth-iban "1.10.0" + web3-utils "1.10.0" + +web3-core-helpers@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.2.1.tgz#f5f32d71c60a4a3bd14786118e633ce7ca6d5d0d" + integrity sha512-Gx3sTEajD5r96bJgfuW377PZVFmXIH4TdqDhgGwd2lZQCcMi+DA4TgxJNJGxn0R3aUVzyyE76j4LBrh412mXrw== + dependencies: + underscore "1.9.1" + web3-eth-iban "1.2.1" + web3-utils "1.2.1" + +web3-core-helpers@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.2.6.tgz#7aacd25bf8015adcdfc0f3243d0dcfdff0373f7d" + integrity sha512-gYKWmC2HmO7RcDzpo4L1K8EIoy5L8iubNDuTC6q69UxczwqKF/Io0kbK/1Z10Av++NlzOSiuyGp2gc4t4UOsDw== + dependencies: + underscore "1.9.1" + web3-eth-iban "1.2.6" + web3-utils "1.2.6" + +web3-core-method@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.10.0.tgz#82668197fa086e8cc8066742e35a9d72535e3412" + integrity sha512-4R700jTLAMKDMhQ+nsVfIXvH6IGJlJzGisIfMKWAIswH31h5AZz7uDUW2YctI+HrYd+5uOAlS4OJeeT9bIpvkA== + dependencies: + "@ethersproject/transactions" "^5.6.2" + web3-core-helpers "1.10.0" + web3-core-promievent "1.10.0" + web3-core-subscriptions "1.10.0" + web3-utils "1.10.0" + +web3-core-method@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.2.1.tgz#9df1bafa2cd8be9d9937e01c6a47fc768d15d90a" + integrity sha512-Ghg2WS23qi6Xj8Od3VCzaImLHseEA7/usvnOItluiIc5cKs00WYWsNy2YRStzU9a2+z8lwQywPYp0nTzR/QXdQ== + dependencies: + underscore "1.9.1" + web3-core-helpers "1.2.1" + web3-core-promievent "1.2.1" + web3-core-subscriptions "1.2.1" + web3-utils "1.2.1" + +web3-core-method@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.2.6.tgz#f5a3e4d304abaf382923c8ab88ec8eeef45c1b3b" + integrity sha512-r2dzyPEonqkBg7Mugq5dknhV5PGaZTHBZlS/C+aMxNyQs3T3eaAsCTqlQDitwNUh/sUcYPEGF0Vo7ahYK4k91g== + dependencies: + underscore "1.9.1" + web3-core-helpers "1.2.6" + web3-core-promievent "1.2.6" + web3-core-subscriptions "1.2.6" + web3-utils "1.2.6" + +web3-core-promievent@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.10.0.tgz#cbb5b3a76b888df45ed3a8d4d8d4f54ccb66a37b" + integrity sha512-68N7k5LWL5R38xRaKFrTFT2pm2jBNFaM4GioS00YjAKXRQ3KjmhijOMG3TICz6Aa5+6GDWYelDNx21YAeZ4YTg== + dependencies: + eventemitter3 "4.0.4" + +web3-core-promievent@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.1.tgz#003e8a3eb82fb27b6164a6d5b9cad04acf733838" + integrity sha512-IVUqgpIKoeOYblwpex4Hye6npM0aMR+kU49VP06secPeN0rHMyhGF0ZGveWBrGvf8WDPI7jhqPBFIC6Jf3Q3zw== + dependencies: + any-promise "1.3.0" + eventemitter3 "3.1.2" + +web3-core-promievent@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.6.tgz#b1550a3a4163e48b8b704c1fe4b0084fc2dad8f5" + integrity sha512-km72kJef/qtQNiSjDJJVHIZvoVOm6ytW3FCYnOcCs7RIkviAb5JYlPiye0o4pJOLzCXYID7DK7Q9bhY8qWb1lw== + dependencies: + any-promise "1.3.0" + eventemitter3 "3.1.2" + +web3-core-requestmanager@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.10.0.tgz#4b34f6e05837e67c70ff6f6993652afc0d54c340" + integrity sha512-3z/JKE++Os62APml4dvBM+GAuId4h3L9ckUrj7ebEtS2AR0ixyQPbrBodgL91Sv7j7cQ3Y+hllaluqjguxvSaQ== + dependencies: + util "^0.12.5" + web3-core-helpers "1.10.0" + web3-providers-http "1.10.0" + web3-providers-ipc "1.10.0" + web3-providers-ws "1.10.0" + +web3-core-requestmanager@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.2.1.tgz#fa2e2206c3d738db38db7c8fe9c107006f5c6e3d" + integrity sha512-xfknTC69RfYmLKC+83Jz73IC3/sS2ZLhGtX33D4Q5nQ8yc39ElyAolxr9sJQS8kihOcM6u4J+8gyGMqsLcpIBg== + dependencies: + underscore "1.9.1" + web3-core-helpers "1.2.1" + web3-providers-http "1.2.1" + web3-providers-ipc "1.2.1" + web3-providers-ws "1.2.1" + +web3-core-requestmanager@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.2.6.tgz#5808c0edc0d6e2991a87b65508b3a1ab065b68ec" + integrity sha512-QU2cbsj9Dm0r6om40oSwk8Oqbp3wTa08tXuMpSmeOTkGZ3EMHJ1/4LiJ8shwg1AvPMrKVU0Nri6+uBNCdReZ+g== + dependencies: + underscore "1.9.1" + web3-core-helpers "1.2.6" + web3-providers-http "1.2.6" + web3-providers-ipc "1.2.6" + web3-providers-ws "1.2.6" + +web3-core-subscriptions@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.10.0.tgz#b534592ee1611788fc0cb0b95963b9b9b6eacb7c" + integrity sha512-HGm1PbDqsxejI075gxBc5OSkwymilRWZufIy9zEpnWKNmfbuv5FfHgW1/chtJP6aP3Uq2vHkvTDl3smQBb8l+g== + dependencies: + eventemitter3 "4.0.4" + web3-core-helpers "1.10.0" + +web3-core-subscriptions@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.2.1.tgz#8c2368a839d4eec1c01a4b5650bbeb82d0e4a099" + integrity sha512-nmOwe3NsB8V8UFsY1r+sW6KjdOS68h8nuh7NzlWxBQT/19QSUGiERRTaZXWu5BYvo1EoZRMxCKyCQpSSXLc08g== + dependencies: + eventemitter3 "3.1.2" + underscore "1.9.1" + web3-core-helpers "1.2.1" + +web3-core-subscriptions@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.2.6.tgz#9d44189e2321f8f1abc31f6c09103b5283461b57" + integrity sha512-M0PzRrP2Ct13x3wPulFtc5kENH4UtnPxO9YxkfQlX2WRKENWjt4Rfq+BCVGYEk3rTutDfWrjfzjmqMRvXqEY5Q== + dependencies: + eventemitter3 "3.1.2" + underscore "1.9.1" + web3-core-helpers "1.2.6" + +web3-core@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.10.0.tgz#9aa07c5deb478cf356c5d3b5b35afafa5fa8e633" + integrity sha512-fWySwqy2hn3TL89w5TM8wXF1Z2Q6frQTKHWmP0ppRQorEK8NcHJRfeMiv/mQlSKoTS1F6n/nv2uyZsixFycjYQ== + dependencies: + "@types/bn.js" "^5.1.1" + "@types/node" "^12.12.6" + bignumber.js "^9.0.0" + web3-core-helpers "1.10.0" + web3-core-method "1.10.0" + web3-core-requestmanager "1.10.0" + web3-utils "1.10.0" + +web3-core@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.2.1.tgz#7278b58fb6495065e73a77efbbce781a7fddf1a9" + integrity sha512-5ODwIqgl8oIg/0+Ai4jsLxkKFWJYE0uLuE1yUKHNVCL4zL6n3rFjRMpKPokd6id6nJCNgeA64KdWQ4XfpnjdMg== + dependencies: + web3-core-helpers "1.2.1" + web3-core-method "1.2.1" + web3-core-requestmanager "1.2.1" + web3-utils "1.2.1" + +web3-core@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.2.6.tgz#bb42a1d7ae49a7258460f0d95ddb00906f59ef92" + integrity sha512-y/QNBFtr5cIR8vxebnotbjWJpOnO8LDYEAzZjeRRUJh2ijmhjoYk7dSNx9ExgC0UCfNFRoNCa9dGRu/GAxwRlw== + dependencies: + "@types/bn.js" "^4.11.4" + "@types/node" "^12.6.1" + web3-core-helpers "1.2.6" + web3-core-method "1.2.6" + web3-core-requestmanager "1.2.6" + web3-utils "1.2.6" + +web3-core@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-4.0.3.tgz#eab6cc23a43ff202d8f38bbd9801a7a2ec750cc2" + integrity sha512-KJaH1+ajm/gelvhImkXZx8HrBaGZDERqhOCRpikuwReVDTf4X3TlXqF+oKt153qf5HUXWR4CUL6NkNKNQWjhbA== + dependencies: + web3-errors "^1.0.2" + web3-eth-iban "^4.0.3" + web3-providers-http "^4.0.3" + web3-providers-ws "^4.0.3" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + optionalDependencies: + web3-providers-ipc "^4.0.3" + +web3-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/web3-errors/-/web3-errors-1.0.2.tgz#e8ce6e22dfdfd9aeaf8d7535653e55b094b5accd" + integrity sha512-LtRUASAQKeCKyxHRhfyU5xiE9asUmo7KJ9bEzzaPlkVYLl5lzhUXzd6lvnQfSaSXJnlzoUXvhI5I0Hpzc8Lohg== + dependencies: + web3-types "^1.0.2" + +web3-eth-abi@1.10.0, web3-eth-abi@^1.2.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.10.0.tgz#53a7a2c95a571e205e27fd9e664df4919483cce1" + integrity sha512-cwS+qRBWpJ43aI9L3JS88QYPfFcSJJ3XapxOQ4j40v6mk7ATpA8CVK1vGTzpihNlOfMVRBkR95oAj7oL6aiDOg== + dependencies: + "@ethersproject/abi" "^5.6.3" + web3-utils "1.10.0" + +web3-eth-abi@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.2.1.tgz#9b915b1c9ebf82f70cca631147035d5419064689" + integrity sha512-jI/KhU2a/DQPZXHjo2GW0myEljzfiKOn+h1qxK1+Y9OQfTcBMxrQJyH5AP89O6l6NZ1QvNdq99ThAxBFoy5L+g== + dependencies: + ethers "4.0.0-beta.3" + underscore "1.9.1" + web3-utils "1.2.1" + +web3-eth-abi@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.2.6.tgz#b495383cc5c0d8e2857b26e7fe25606685983b25" + integrity sha512-w9GAyyikn8nSifSDZxAvU9fxtQSX+W2xQWMmrtTXmBGCaE4/ywKOSPAO78gq8AoU4Wq5yqVGKZLLbfpt7/sHlA== + dependencies: + ethers "4.0.0-beta.3" + underscore "1.9.1" + web3-utils "1.2.6" + +web3-eth-abi@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-4.0.3.tgz#cc06cc39868d8bcc181528aa46ae9d5c80ed93b6" + integrity sha512-is1sKkTna5LQri25iRbxJ43kQ6qlFR/Syi6dnpwsFua0qAyKuDTxLZDoMaBfdH8NvxvjuGWFUWALwuSk8gk5Xg== + dependencies: + "@ethersproject/abi" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + +web3-eth-accounts@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.10.0.tgz#2942beca0a4291455f32cf09de10457a19a48117" + integrity sha512-wiq39Uc3mOI8rw24wE2n15hboLE0E9BsQLdlmsL4Zua9diDS6B5abXG0XhFcoNsXIGMWXVZz4TOq3u4EdpXF/Q== + dependencies: + "@ethereumjs/common" "2.5.0" + "@ethereumjs/tx" "3.3.2" + eth-lib "0.2.8" + ethereumjs-util "^7.1.5" + scrypt-js "^3.0.1" + uuid "^9.0.0" + web3-core "1.10.0" + web3-core-helpers "1.10.0" + web3-core-method "1.10.0" + web3-utils "1.10.0" + +web3-eth-accounts@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.2.1.tgz#2741a8ef337a7219d57959ac8bd118b9d68d63cf" + integrity sha512-26I4qq42STQ8IeKUyur3MdQ1NzrzCqPsmzqpux0j6X/XBD7EjZ+Cs0lhGNkSKH5dI3V8CJasnQ5T1mNKeWB7nQ== + dependencies: + any-promise "1.3.0" + crypto-browserify "3.12.0" + eth-lib "0.2.7" + scryptsy "2.1.0" + semver "6.2.0" + underscore "1.9.1" + uuid "3.3.2" + web3-core "1.2.1" + web3-core-helpers "1.2.1" + web3-core-method "1.2.1" + web3-utils "1.2.1" + +web3-eth-accounts@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.2.6.tgz#a1ba4bf75fa8102a3ec6cddd0eccd72462262720" + integrity sha512-cDVtonHRgzqi/ZHOOf8kfCQWFEipcfQNAMzXIaKZwc0UUD9mgSI5oJrN45a89Ze+E6Lz9m77cDG5Ax9zscSkcw== + dependencies: + "@web3-js/scrypt-shim" "^0.1.0" + any-promise "1.3.0" + crypto-browserify "3.12.0" + eth-lib "^0.2.8" + ethereumjs-common "^1.3.2" + ethereumjs-tx "^2.1.1" + underscore "1.9.1" + uuid "3.3.2" + web3-core "1.2.6" + web3-core-helpers "1.2.6" + web3-core-method "1.2.6" + web3-utils "1.2.6" + +web3-eth-accounts@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-4.0.3.tgz#7e570b3170aca052b358975235637a94b5313826" + integrity sha512-qS4r25weJYlKzHPIneL3g33LG+I6QkRCs25ZtooK6elurlZY4HyRE04BIWv12xZswtsvdmMt4HysMUNKgLrgPg== + dependencies: + "@ethereumjs/rlp" "^4.0.1" + crc-32 "^1.2.2" + ethereum-cryptography "^2.0.0" + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + +web3-eth-contract@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.10.0.tgz#8e68c7654576773ec3c91903f08e49d0242c503a" + integrity sha512-MIC5FOzP/+2evDksQQ/dpcXhSqa/2hFNytdl/x61IeWxhh6vlFeSjq0YVTAyIzdjwnL7nEmZpjfI6y6/Ufhy7w== + dependencies: + "@types/bn.js" "^5.1.1" + web3-core "1.10.0" + web3-core-helpers "1.10.0" + web3-core-method "1.10.0" + web3-core-promievent "1.10.0" + web3-core-subscriptions "1.10.0" + web3-eth-abi "1.10.0" + web3-utils "1.10.0" + +web3-eth-contract@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.2.1.tgz#3542424f3d341386fd9ff65e78060b85ac0ea8c4" + integrity sha512-kYFESbQ3boC9bl2rYVghj7O8UKMiuKaiMkxvRH5cEDHil8V7MGEGZNH0slSdoyeftZVlaWSMqkRP/chfnKND0g== + dependencies: + underscore "1.9.1" + web3-core "1.2.1" + web3-core-helpers "1.2.1" + web3-core-method "1.2.1" + web3-core-promievent "1.2.1" + web3-core-subscriptions "1.2.1" + web3-eth-abi "1.2.1" + web3-utils "1.2.1" + +web3-eth-contract@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.2.6.tgz#39111543960035ed94c597a239cf5aa1da796741" + integrity sha512-ak4xbHIhWgsbdPCkSN+HnQc1SH4c856y7Ly+S57J/DQVzhFZemK5HvWdpwadJrQTcHET3ZeId1vq3kmW7UYodw== + dependencies: + "@types/bn.js" "^4.11.4" + underscore "1.9.1" + web3-core "1.2.6" + web3-core-helpers "1.2.6" + web3-core-method "1.2.6" + web3-core-promievent "1.2.6" + web3-core-subscriptions "1.2.6" + web3-eth-abi "1.2.6" + web3-utils "1.2.6" + +web3-eth-contract@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-4.0.3.tgz#667e8f8052034f49a9130e0f286976bcf43c5d77" + integrity sha512-x8YsIVVUeONwLCnUmswk5KD3luYxaKuN/xnSzxpb8fE4/KBA6eJswYcIGPrK9QILrVR26yDV/QQpgLU1IJS14g== + dependencies: + web3-core "^4.0.3" + web3-errors "^1.0.2" + web3-eth "^4.0.3" + web3-eth-abi "^4.0.3" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + +web3-eth-ens@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.10.0.tgz#96a676524e0b580c87913f557a13ed810cf91cd9" + integrity sha512-3hpGgzX3qjgxNAmqdrC2YUQMTfnZbs4GeLEmy8aCWziVwogbuqQZ+Gzdfrym45eOZodk+lmXyLuAdqkNlvkc1g== + dependencies: + content-hash "^2.5.2" + eth-ens-namehash "2.0.8" + web3-core "1.10.0" + web3-core-helpers "1.10.0" + web3-core-promievent "1.10.0" + web3-eth-abi "1.10.0" + web3-eth-contract "1.10.0" + web3-utils "1.10.0" + +web3-eth-ens@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.2.1.tgz#a0e52eee68c42a8b9865ceb04e5fb022c2d971d5" + integrity sha512-lhP1kFhqZr2nnbu3CGIFFrAnNxk2veXpOXBY48Tub37RtobDyHijHgrj+xTh+mFiPokyrapVjpFsbGa+Xzye4Q== + dependencies: + eth-ens-namehash "2.0.8" + underscore "1.9.1" + web3-core "1.2.1" + web3-core-helpers "1.2.1" + web3-core-promievent "1.2.1" + web3-eth-abi "1.2.1" + web3-eth-contract "1.2.1" + web3-utils "1.2.1" + +web3-eth-ens@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.2.6.tgz#bf86a624c4c72bc59913c2345180d3ea947e110d" + integrity sha512-8UEqt6fqR/dji/jBGPFAyBs16OJjwi0t2dPWXPyGXmty/fH+osnXwWXE4HRUyj4xuafiM5P1YkXMsPhKEadjiw== + dependencies: + eth-ens-namehash "2.0.8" + underscore "1.9.1" + web3-core "1.2.6" + web3-core-helpers "1.2.6" + web3-core-promievent "1.2.6" + web3-eth-abi "1.2.6" + web3-eth-contract "1.2.6" + web3-utils "1.2.6" + +web3-eth-ens@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-4.0.3.tgz#9b17bdcdc262ddcb5b9fd0b4893c0a9a56bf07ca" + integrity sha512-1tk1WWJB6lsViRFxHR9kt8qgfMV0cySeNBa8H/bZ9/HZ1G8L/c2cboVrG4D0QsPO1im1jQl4Cf3ceKH0PW1KZg== + dependencies: + "@adraffy/ens-normalize" "^1.8.8" + web3-core "^4.0.3" + web3-errors "^1.0.2" + web3-eth "^4.0.3" + web3-eth-contract "^4.0.3" + web3-net "^4.0.3" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + +web3-eth-iban@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.10.0.tgz#5a46646401965b0f09a4f58e7248c8a8cd22538a" + integrity sha512-0l+SP3IGhInw7Q20LY3IVafYEuufo4Dn75jAHT7c2aDJsIolvf2Lc6ugHkBajlwUneGfbRQs/ccYPQ9JeMUbrg== + dependencies: + bn.js "^5.2.1" + web3-utils "1.10.0" + +web3-eth-iban@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.2.1.tgz#2c3801718946bea24e9296993a975c80b5acf880" + integrity sha512-9gkr4QPl1jCU+wkgmZ8EwODVO3ovVj6d6JKMos52ggdT2YCmlfvFVF6wlGLwi0VvNa/p+0BjJzaqxnnG/JewjQ== + dependencies: + bn.js "4.11.8" + web3-utils "1.2.1" + +web3-eth-iban@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.2.6.tgz#0b22191fd1aa6e27f7ef0820df75820bfb4ed46b" + integrity sha512-TPMc3BW9Iso7H+9w+ytbqHK9wgOmtocyCD3PaAe5Eie50KQ/j7ThA60dGJnxItVo6yyRv5pZAYxPVob9x/fJlg== + dependencies: + bn.js "4.11.8" + web3-utils "1.2.6" + +web3-eth-iban@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-4.0.3.tgz#3fca87323c00a29f1b3870d397153803eb0bcf4e" + integrity sha512-9gn6fb034fh3DvQeutuhaG3J9+ZSriPC/O/H7K+lgUWJZh/lpaZy5A06nhHzNcleCWC07Q6J7d7VZlNjaBPtOA== + dependencies: + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + +web3-eth-personal@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.10.0.tgz#94d525f7a29050a0c2a12032df150ac5ea633071" + integrity sha512-anseKn98w/d703eWq52uNuZi7GhQeVjTC5/svrBWEKob0WZ5kPdo+EZoFN0sp5a5ubbrk/E0xSl1/M5yORMtpg== + dependencies: + "@types/node" "^12.12.6" + web3-core "1.10.0" + web3-core-helpers "1.10.0" + web3-core-method "1.10.0" + web3-net "1.10.0" + web3-utils "1.10.0" + +web3-eth-personal@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.2.1.tgz#244e9911b7b482dc17c02f23a061a627c6e47faf" + integrity sha512-RNDVSiaSoY4aIp8+Hc7z+X72H7lMb3fmAChuSBADoEc7DsJrY/d0R5qQDK9g9t2BO8oxgLrLNyBP/9ub2Hc6Bg== + dependencies: + web3-core "1.2.1" + web3-core-helpers "1.2.1" + web3-core-method "1.2.1" + web3-net "1.2.1" + web3-utils "1.2.1" + +web3-eth-personal@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.2.6.tgz#47a0a0657ec04dd77f95451a6869d4751d324b6b" + integrity sha512-T2NUkh1plY8d7wePXSoHnaiKOd8dLNFaQfgBl9JHU6S7IJrG9jnYD9bVxLEgRUfHs9gKf9tQpDf7AcPFdq/A8g== + dependencies: + "@types/node" "^12.6.1" + web3-core "1.2.6" + web3-core-helpers "1.2.6" + web3-core-method "1.2.6" + web3-net "1.2.6" + web3-utils "1.2.6" + +web3-eth-personal@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-4.0.3.tgz#df4c59bf2a0e07cd6966259d1312be6b5b61846e" + integrity sha512-Gugz45w/D4wlUNbUth8iHWkv0c5fFZGWZqFvpACJul0z9h0Ou8HzuJMUv3U0xFOQJF5fniVegfp6l0FJQ3hGrQ== + dependencies: + web3-core "^4.0.3" + web3-eth "^4.0.3" + web3-rpc-methods "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + +web3-eth@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.10.0.tgz#38b905e2759697c9624ab080cfcf4e6c60b3a6cf" + integrity sha512-Z5vT6slNMLPKuwRyKGbqeGYC87OAy8bOblaqRTgg94CXcn/mmqU7iPIlG4506YdcdK3x6cfEDG7B6w+jRxypKA== + dependencies: + web3-core "1.10.0" + web3-core-helpers "1.10.0" + web3-core-method "1.10.0" + web3-core-subscriptions "1.10.0" + web3-eth-abi "1.10.0" + web3-eth-accounts "1.10.0" + web3-eth-contract "1.10.0" + web3-eth-ens "1.10.0" + web3-eth-iban "1.10.0" + web3-eth-personal "1.10.0" + web3-net "1.10.0" + web3-utils "1.10.0" + +web3-eth@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.2.1.tgz#b9989e2557c73a9e8ffdc107c6dafbe72c79c1b0" + integrity sha512-/2xly4Yry5FW1i+uygPjhfvgUP/MS/Dk+PDqmzp5M88tS86A+j8BzKc23GrlA8sgGs0645cpZK/999LpEF5UdA== + dependencies: + underscore "1.9.1" + web3-core "1.2.1" + web3-core-helpers "1.2.1" + web3-core-method "1.2.1" + web3-core-subscriptions "1.2.1" + web3-eth-abi "1.2.1" + web3-eth-accounts "1.2.1" + web3-eth-contract "1.2.1" + web3-eth-ens "1.2.1" + web3-eth-iban "1.2.1" + web3-eth-personal "1.2.1" + web3-net "1.2.1" + web3-utils "1.2.1" + +web3-eth@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.2.6.tgz#15a8c65fdde0727872848cae506758d302d8d046" + integrity sha512-ROWlDPzh4QX6tlGGGlAK6X4kA2n0/cNj/4kb0nNVWkRouGmYO0R8k6s47YxYHvGiXt0s0++FUUv5vAbWovtUQw== + dependencies: + underscore "1.9.1" + web3-core "1.2.6" + web3-core-helpers "1.2.6" + web3-core-method "1.2.6" + web3-core-subscriptions "1.2.6" + web3-eth-abi "1.2.6" + web3-eth-accounts "1.2.6" + web3-eth-contract "1.2.6" + web3-eth-ens "1.2.6" + web3-eth-iban "1.2.6" + web3-eth-personal "1.2.6" + web3-net "1.2.6" + web3-utils "1.2.6" + +web3-eth@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-4.0.3.tgz#b7f311eba95151f547ccce285893af9917da9e35" + integrity sha512-4t1+lpqzk3ljubr0CKE9Ila82p2Pim6Bn7ZIruVfMt9AOA5wL6M0OeMTy0fWBODLJiZJ7R77Ugm0kvEVWD3lqg== + dependencies: + setimmediate "^1.0.5" + web3-core "^4.0.3" + web3-errors "^1.0.2" + web3-eth-abi "^4.0.3" + web3-eth-accounts "^4.0.3" + web3-net "^4.0.3" + web3-providers-ws "^4.0.3" + web3-rpc-methods "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + +web3-net@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.10.0.tgz#be53e7f5dafd55e7c9013d49c505448b92c9c97b" + integrity sha512-NLH/N3IshYWASpxk4/18Ge6n60GEvWBVeM8inx2dmZJVmRI6SJIlUxbL8jySgiTn3MMZlhbdvrGo8fpUW7a1GA== + dependencies: + web3-core "1.10.0" + web3-core-method "1.10.0" + web3-utils "1.10.0" + +web3-net@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.2.1.tgz#edd249503315dd5ab4fa00220f6509d95bb7ab10" + integrity sha512-Yt1Bs7WgnLESPe0rri/ZoPWzSy55ovioaP35w1KZydrNtQ5Yq4WcrAdhBzcOW7vAkIwrsLQsvA+hrOCy7mNauw== + dependencies: + web3-core "1.2.1" + web3-core-method "1.2.1" + web3-utils "1.2.1" + +web3-net@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.2.6.tgz#035ca0fbe55282fda848ca17ebb4c8966147e5ea" + integrity sha512-hsNHAPddrhgjWLmbESW0KxJi2GnthPcow0Sqpnf4oB6+/+ZnQHU9OsIyHb83bnC1OmunrK2vf9Ye2mLPdFIu3A== + dependencies: + web3-core "1.2.6" + web3-core-method "1.2.6" + web3-utils "1.2.6" + +web3-net@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-4.0.3.tgz#9aeed6fa3d48adcf63d8377900acbe3e64020154" + integrity sha512-qe+stvVgYhO8AiPgDykZW5gS4mZ3GRWdQ8xn3eTvderresIMvdZYSAoUla2jWl1CgpcqzaoOSO9Pf8t43fr8SA== + dependencies: + web3-core "^4.0.3" + web3-rpc-methods "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + +"web3-provider-engine@https://github.com/trufflesuite/provider-engine#web3-one": + version "14.0.6" + resolved "https://github.com/trufflesuite/provider-engine#9694f5b4e5500651bd2ff689df8529bb5cf6b96f" + dependencies: + async "^2.5.0" + backoff "^2.5.0" + clone "^2.0.0" + cross-fetch "^2.1.0" + eth-block-tracker "^4.2.0" + eth-json-rpc-filters "^4.0.2" + eth-json-rpc-infura "^3.1.0" + eth-json-rpc-middleware "^4.1.1" + eth-sig-util "^1.4.2" + ethereumjs-block "^1.2.2" + ethereumjs-tx "^1.2.0" + ethereumjs-util "^5.1.5" + ethereumjs-vm "^2.3.4" + json-rpc-error "^2.0.0" + json-stable-stringify "^1.0.1" + promise-to-callback "^1.0.0" + readable-stream "^2.2.9" + request "^2.85.0" + semaphore "^1.0.3" + ws "^5.1.1" + xhr "^2.2.0" + xtend "^4.0.1" + +web3-providers-http@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.10.0.tgz#864fa48675e7918c9a4374e5f664b32c09d0151b" + integrity sha512-eNr965YB8a9mLiNrkjAWNAPXgmQWfpBfkkn7tpEFlghfww0u3I0tktMZiaToJVcL2+Xq+81cxbkpeWJ5XQDwOA== + dependencies: + abortcontroller-polyfill "^1.7.3" + cross-fetch "^3.1.4" + es6-promise "^4.2.8" + web3-core-helpers "1.10.0" + +web3-providers-http@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.2.1.tgz#c93ea003a42e7b894556f7e19dd3540f947f5013" + integrity sha512-BDtVUVolT9b3CAzeGVA/np1hhn7RPUZ6YYGB/sYky+GjeO311Yoq8SRDUSezU92x8yImSC2B+SMReGhd1zL+bQ== + dependencies: + web3-core-helpers "1.2.1" + xhr2-cookies "1.1.0" + +web3-providers-http@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.2.6.tgz#3c7b1252751fb37e53b873fce9dbb6340f5e31d9" + integrity sha512-2+SaFCspb5f82QKuHB3nEPQOF9iSWxRf7c18fHtmnLNVkfG9SwLN1zh67bYn3tZGUdOI3gj8aX4Uhfpwx9Ezpw== + dependencies: + web3-core-helpers "1.2.6" + xhr2-cookies "1.1.0" + +web3-providers-http@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-4.0.3.tgz#c6c8364ed56c4183e6bed58de20c1972f513c7ae" + integrity sha512-5E6nKjWrwlJdhGImOxyTnFDT6UcZu4waO6AJrENBRh2vdoCfP/Piiv3PLywHs71gwTMsAjy6CNPL5lZdGf+JQA== + dependencies: + cross-fetch "^3.1.5" + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + +web3-providers-ipc@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.10.0.tgz#9747c7a6aee96a51488e32fa7c636c3460b39889" + integrity sha512-OfXG1aWN8L1OUqppshzq8YISkWrYHaATW9H8eh0p89TlWMc1KZOL9vttBuaBEi96D/n0eYDn2trzt22bqHWfXA== + dependencies: + oboe "2.1.5" + web3-core-helpers "1.10.0" + +web3-providers-ipc@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.2.1.tgz#017bfc687a8fc5398df2241eb98f135e3edd672c" + integrity sha512-oPEuOCwxVx8L4CPD0TUdnlOUZwGBSRKScCz/Ws2YHdr9Ium+whm+0NLmOZjkjQp5wovQbyBzNa6zJz1noFRvFA== + dependencies: + oboe "2.1.4" + underscore "1.9.1" + web3-core-helpers "1.2.1" + +web3-providers-ipc@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.2.6.tgz#adabab5ac66b3ff8a26c7dc97af3f1a6a7609701" + integrity sha512-b0Es+/GTZyk5FG3SgUDW+2/mBwJAXWt5LuppODptiOas8bB2khLjG6+Gm1K4uwOb+1NJGPt5mZZ8Wi7vibtQ+A== + dependencies: + oboe "2.1.4" + underscore "1.9.1" + web3-core-helpers "1.2.6" + +web3-providers-ipc@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-4.0.3.tgz#d7af699a2afae0f7396d08ef8cc82b5ab4374398" + integrity sha512-v+Ugp5XXUVcAQju/u4ThdjI3FM9lq674F6cJ7yz3R6uTel+wNPDiT47Se8hvm5grgHid7z3MbVYCQpDCiiAFHw== + dependencies: + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + +web3-providers-ws@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.10.0.tgz#cb0b87b94c4df965cdf486af3a8cd26daf3975e5" + integrity sha512-sK0fNcglW36yD5xjnjtSGBnEtf59cbw4vZzJ+CmOWIKGIR96mP5l684g0WD0Eo+f4NQc2anWWXG74lRc9OVMCQ== + dependencies: + eventemitter3 "4.0.4" + web3-core-helpers "1.10.0" + websocket "^1.0.32" + +web3-providers-ws@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.2.1.tgz#2d941eaf3d5a8caa3214eff8dc16d96252b842cb" + integrity sha512-oqsQXzu+ejJACVHy864WwIyw+oB21nw/pI65/sD95Zi98+/HQzFfNcIFneF1NC4bVF3VNX4YHTNq2I2o97LAiA== + dependencies: + underscore "1.9.1" + web3-core-helpers "1.2.1" + websocket "github:web3-js/WebSocket-Node#polyfill/globalThis" + +web3-providers-ws@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.2.6.tgz#3cecc49f7c99f07a75076d3c54247050bc4f7e11" + integrity sha512-20waSYX+gb5M5yKhug5FIwxBBvkKzlJH7sK6XEgdOx6BZ9YYamLmvg9wcRVtnSZO8hV/3cWenO/tRtTrHVvIgQ== + dependencies: + "@web3-js/websocket" "^1.0.29" + underscore "1.9.1" + web3-core-helpers "1.2.6" + +web3-providers-ws@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-4.0.3.tgz#c611a0ae81ac022d8ccb01f71da761f7b4decd85" + integrity sha512-V2bYiMvhv+xBYxFdf8V1zGTwhJoAkBQNMECVGNjQIz1qBKuqu6hXHasmkYSJV780LD6qoL58KlfTggjf4SUSaA== + dependencies: + "@types/ws" "^8.5.3" + isomorphic-ws "^5.0.0" + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + ws "^8.8.1" + +web3-rpc-methods@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/web3-rpc-methods/-/web3-rpc-methods-1.0.2.tgz#3ff35c5d4e38ad31ef3cf77eb3fe2fd08e2a3f4a" + integrity sha512-VhLHvgR62JUNgo0op8hP4LcRkvdF0WaHD9xhcEKGLcri9VfYvR1yTZ3CVh6NTgRCmfDePObbp5blHfbla1cC5Q== + dependencies: + web3-core "^4.0.3" + web3-types "^1.0.2" + web3-validator "^1.0.2" + +web3-shh@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.10.0.tgz#c2979b87e0f67a7fef2ce9ee853bd7bfbe9b79a8" + integrity sha512-uNUUuNsO2AjX41GJARV9zJibs11eq6HtOe6Wr0FtRUcj8SN6nHeYIzwstAvJ4fXA53gRqFMTxdntHEt9aXVjpg== + dependencies: + web3-core "1.10.0" + web3-core-method "1.10.0" + web3-core-subscriptions "1.10.0" + web3-net "1.10.0" + +web3-shh@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.2.1.tgz#4460e3c1e07faf73ddec24ccd00da46f89152b0c" + integrity sha512-/3Cl04nza5kuFn25bV3FJWa0s3Vafr5BlT933h26xovQ6HIIz61LmvNQlvX1AhFL+SNJOTcQmK1SM59vcyC8bA== + dependencies: + web3-core "1.2.1" + web3-core-method "1.2.1" + web3-core-subscriptions "1.2.1" + web3-net "1.2.1" + +web3-shh@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.2.6.tgz#2492616da4cac32d4c7534b890f43bac63190c14" + integrity sha512-rouWyOOM6YMbLQd65grpj8BBezQfgNeRRX+cGyW4xsn6Xgu+B73Zvr6OtA/ftJwwa9bqHGpnLrrLMeWyy4YLUw== + dependencies: + web3-core "1.2.6" + web3-core-method "1.2.6" + web3-core-subscriptions "1.2.6" + web3-net "1.2.6" + +web3-types@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/web3-types/-/web3-types-1.0.2.tgz#1655a400d31984153fc26ca1f8960f547ca1f2df" + integrity sha512-tLzA9vevGGWdHlxXvPRJjEIIR0UnZBI5Kq9qiENRS/vSekTHAHp7u+WGDxt+6kP105gKlbep50TogQIvJqLfnA== + +web3-utils@1.10.0, web3-utils@^1.0.0-beta.31, web3-utils@^1.2.1, web3-utils@^1.3.6: version "1.10.0" resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.0.tgz#ca4c1b431a765c14ac7f773e92e0fd9377ccf578" integrity sha512-kSaCM0uMcZTNUSmn5vMEhlo02RObGNRRCkdX0V9UTAU0+lrvn0HSaudyCo6CQzuXUsnuY2ERJGCGPfeWmv19Rg== @@ -4856,6 +10694,156 @@ web3-utils@^1.3.6: randombytes "^2.1.0" utf8 "3.0.0" +web3-utils@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.1.tgz#21466e38291551de0ab34558de21512ac4274534" + integrity sha512-Mrcn3l58L+yCKz3zBryM6JZpNruWuT0OCbag8w+reeNROSGVlXzUQkU+gtAwc9JCZ7tKUyg67+2YUGqUjVcyBA== + dependencies: + bn.js "4.11.8" + eth-lib "0.2.7" + ethjs-unit "0.1.6" + number-to-bn "1.7.0" + randomhex "0.1.5" + underscore "1.9.1" + utf8 "3.0.0" + +web3-utils@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.6.tgz#b9a25432da00976457fcc1094c4af8ac6d486db9" + integrity sha512-8/HnqG/l7dGmKMgEL9JeKPTtjScxOePTzopv5aaKFExPfaBrYRkgoMqhoowCiAl/s16QaTn4DoIF1QC4YsT7Mg== + dependencies: + bn.js "4.11.8" + eth-lib "0.2.7" + ethereum-bloom-filters "^1.0.6" + ethjs-unit "0.1.6" + number-to-bn "1.7.0" + randombytes "^2.1.0" + underscore "1.9.1" + utf8 "3.0.0" + +web3-utils@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-4.0.3.tgz#80c077e56c0841528ea4513c67d83e460217b379" + integrity sha512-clBvm/vWR2mAc9nPnsPYBZMikIhVG9RAsXdrxvXI4e2jAQ3DTtHKMhqy+Cl214dQaAdAEYyVb5ILW5lKKqk2vA== + dependencies: + ethereum-cryptography "^2.0.0" + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-validator "^1.0.2" + +web3-validator@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/web3-validator/-/web3-validator-1.0.2.tgz#ca7d247b49f4f690db86e5b953272a627dc5950a" + integrity sha512-orx1CQAEnwJUnl/8iF2II2zSA4wiooNJvFmVE0Dbmt/kE370SugIDViQP76snhxtouG2AXzz4GyKbPCMlLGh/A== + dependencies: + ethereum-cryptography "^2.0.0" + is-my-json-valid "^2.20.6" + util "^0.12.5" + web3-errors "^1.0.2" + web3-types "^1.0.2" + +web3@*: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3/-/web3-4.0.3.tgz#afeb977c9f883ff683d630ab9f5937eb56bc7cf4" + integrity sha512-rUMxui5f52yPWjiMRQV6xqIrTQSovYM2CNhl57y+xj/fGXNLbI1D5FsLPnUMZjMaFHJBTteaBxq/sTEaw/1jNA== + dependencies: + web3-core "^4.0.3" + web3-errors "^1.0.2" + web3-eth "^4.0.3" + web3-eth-abi "^4.0.3" + web3-eth-accounts "^4.0.3" + web3-eth-contract "^4.0.3" + web3-eth-ens "^4.0.3" + web3-eth-iban "^4.0.3" + web3-eth-personal "^4.0.3" + web3-net "^4.0.3" + web3-providers-http "^4.0.3" + web3-providers-ws "^4.0.3" + web3-rpc-methods "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + +web3@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.10.0.tgz#2fde0009f59aa756c93e07ea2a7f3ab971091274" + integrity sha512-YfKY9wSkGcM8seO+daR89oVTcbu18NsVfvOngzqMYGUU0pPSQmE57qQDvQzUeoIOHAnXEBNzrhjQJmm8ER0rng== + dependencies: + web3-bzz "1.10.0" + web3-core "1.10.0" + web3-eth "1.10.0" + web3-eth-personal "1.10.0" + web3-net "1.10.0" + web3-shh "1.10.0" + web3-utils "1.10.0" + +web3@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.2.1.tgz#5d8158bcca47838ab8c2b784a2dee4c3ceb4179b" + integrity sha512-nNMzeCK0agb5i/oTWNdQ1aGtwYfXzHottFP2Dz0oGIzavPMGSKyVlr8ibVb1yK5sJBjrWVnTdGaOC2zKDFuFRw== + dependencies: + web3-bzz "1.2.1" + web3-core "1.2.1" + web3-eth "1.2.1" + web3-eth-personal "1.2.1" + web3-net "1.2.1" + web3-shh "1.2.1" + web3-utils "1.2.1" + +web3@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.2.6.tgz#c497dcb14cdd8d6d9fb6b445b3b68ff83f8ccf68" + integrity sha512-tpu9fLIComgxGrFsD8LUtA4s4aCZk7px8UfcdEy6kS2uDi/ZfR07KJqpXZMij7Jvlq+cQrTAhsPSiBVvoMaivA== + dependencies: + "@types/node" "^12.6.1" + web3-bzz "1.2.6" + web3-core "1.2.6" + web3-eth "1.2.6" + web3-eth-personal "1.2.6" + web3-net "1.2.6" + web3-shh "1.2.6" + web3-utils "1.2.6" + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +websocket@^1.0.32: + version "1.0.34" + resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.34.tgz#2bdc2602c08bf2c82253b730655c0ef7dcab3111" + integrity sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ== + dependencies: + bufferutil "^4.0.1" + debug "^2.2.0" + es5-ext "^0.10.50" + typedarray-to-buffer "^3.1.5" + utf-8-validate "^5.0.2" + yaeti "^0.0.6" + +"websocket@github:web3-js/WebSocket-Node#polyfill/globalThis": + version "1.0.29" + resolved "https://codeload.github.com/web3-js/WebSocket-Node/tar.gz/ef5ea2f41daf4a2113b80c9223df884b4d56c400" + dependencies: + debug "^2.2.0" + es5-ext "^0.10.50" + nan "^2.14.0" + typedarray-to-buffer "^3.1.5" + yaeti "^0.0.6" + +whatwg-fetch@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" + integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" @@ -4867,11 +10855,27 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ== + which-module@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== +which-typed-array@^1.1.11, which-typed-array@^1.1.2: + version "1.1.11" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.11.tgz#99d691f23c72aab6768680805a271b69761ed61a" + integrity sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + which-typed-array@^1.1.9: version "1.1.9" resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" @@ -4884,7 +10888,7 @@ which-typed-array@^1.1.9: has-tostringtag "^1.0.0" is-typed-array "^1.1.10" -which@1.3.1, which@^1.1.1, which@^1.3.1: +which@1.3.1, which@^1.1.1, which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -4898,6 +10902,11 @@ wide-align@1.1.3: dependencies: string-width "^1.0.2 || 2" +window-size@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" + integrity sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw== + word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" @@ -4921,6 +10930,14 @@ workerpool@6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" @@ -4954,16 +10971,91 @@ ws@8.5.0: resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== +ws@^3.0.0: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + +ws@^5.1.1: + version "5.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.3.tgz#05541053414921bc29c63bee14b8b0dd50b07b3d" + integrity sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA== + dependencies: + async-limiter "~1.0.0" + ws@^7.4.6: version "7.5.9" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== +ws@^8.8.1: + version "8.13.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" + integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== + +xhr-request-promise@^0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz#2d5f4b16d8c6c893be97f1a62b0ed4cf3ca5f96c" + integrity sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg== + dependencies: + xhr-request "^1.1.0" + +xhr-request@^1.0.1, xhr-request@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/xhr-request/-/xhr-request-1.1.0.tgz#f4a7c1868b9f198723444d82dcae317643f2e2ed" + integrity sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA== + dependencies: + buffer-to-arraybuffer "^0.0.5" + object-assign "^4.1.1" + query-string "^5.0.1" + simple-get "^2.7.0" + timed-out "^4.0.1" + url-set-query "^1.0.0" + xhr "^2.0.4" + +xhr2-cookies@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz#7d77449d0999197f155cb73b23df72505ed89d48" + integrity sha512-hjXUA6q+jl/bd8ADHcVfFsSPIf+tyLIjuO9TwJC9WI6JP2zKcS7C+p56I9kCLLsaCiNT035iYvEUUzdEFj/8+g== + dependencies: + cookiejar "^2.1.1" + +xhr@^2.0.4, xhr@^2.2.0, xhr@^2.3.3: + version "2.6.0" + resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.6.0.tgz#b69d4395e792b4173d6b7df077f0fc5e4e2b249d" + integrity sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA== + dependencies: + global "~4.4.0" + is-function "^1.0.1" + parse-headers "^2.0.0" + xtend "^4.0.0" + xmlhttprequest@1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" integrity sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA== +xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +xtend@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" + integrity sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ== + dependencies: + object-keys "~0.4.0" + +y18n@^3.2.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" + integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== + y18n@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" @@ -4974,7 +11066,12 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yallist@^3.0.2: +yaeti@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" + integrity sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug== + +yallist@^3.0.0, yallist@^3.0.2, yallist@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== @@ -4984,6 +11081,11 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yaml@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + yargs-parser@13.1.2, yargs-parser@^13.1.2: version "13.1.2" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" @@ -4997,6 +11099,14 @@ yargs-parser@20.2.4: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== +yargs-parser@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" + integrity sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA== + dependencies: + camelcase "^3.0.0" + lodash.assign "^4.0.6" + yargs-parser@^20.2.2: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" @@ -5050,6 +11160,34 @@ yargs@16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" +yargs@^4.7.1: + version "4.8.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" + integrity sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA== + dependencies: + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + lodash.assign "^4.0.3" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.1" + which-module "^1.0.0" + window-size "^0.2.0" + y18n "^3.2.1" + yargs-parser "^2.4.1" + +yauzl@^2.4.2: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"